From 762073a76b81b84410ab4cc2723c0c6615270990 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 12 Dec 2023 09:27:42 +0100 Subject: [PATCH 1/2] Fix wrong txn duration in case SDK init is deferred --- .../core/ActivityLifecycleIntegration.java | 8 +++++ .../core/ActivityLifecycleIntegrationTest.kt | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java index 425d26ad32..197d7afef0 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java @@ -431,6 +431,10 @@ public void onActivityPostResumed(@NonNull Activity activity) { public void onActivityPrePaused(@NonNull Activity activity) { // only executed if API >= 29 otherwise it happens on onActivityPaused if (isAllActivityCallbacksAvailable) { + // as the SDK may gets (re-)initialized mid activity lifecycle, ensure we set the flag here as + // well + // this ensures any newly launched activity will not use the app start timestamp as txn start + firstActivityCreated = true; if (hub == null) { lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); } else { @@ -443,6 +447,10 @@ public void onActivityPrePaused(@NonNull Activity activity) { public synchronized void onActivityPaused(final @NotNull Activity activity) { // only executed if API < 29 otherwise it happens on onActivityPrePaused if (!isAllActivityCallbacksAvailable) { + // as the SDK may gets (re-)initialized mid activity lifecycle, ensure we set the flag here as + // well + // this ensures any newly launched activity will not use the app start timestamp as txn start + firstActivityCreated = true; if (hub == null) { lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); } else { diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt index 1e280d173b..ada757ac00 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt @@ -21,6 +21,7 @@ import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.Sentry import io.sentry.SentryDate +import io.sentry.SentryDateProvider import io.sentry.SentryLevel import io.sentry.SentryNanotimeDate import io.sentry.SentryOptions @@ -1479,6 +1480,34 @@ class ActivityLifecycleIntegrationTest { verify(fixture.activityFramesTracker).setMetrics(activity, fixture.transaction.eventId) } + @Test + fun `When sentry is initialized mid activity lifecycle, last paused time should be used in favor of app start time`() { + val sut = fixture.getSut(importance = RunningAppProcessInfo.IMPORTANCE_FOREGROUND) + val now = SentryNanotimeDate(Date(1234), 456) + + fixture.options.tracesSampleRate = 1.0 + fixture.options.dateProvider = SentryDateProvider { now } + sut.register(fixture.hub, fixture.options) + + // usually done by SentryPerformanceProvider + val startDate = SentryNanotimeDate(Date(5678), 910) + setAppStartTime(startDate) + AppStartMetrics.getInstance().appStartType = AppStartType.COLD + + // when activity is paused without being created + // indicating a delayed SDK init + val oldActivity = mock() + sut.onActivityPrePaused(oldActivity) + sut.onActivityPaused(oldActivity) + + // and the next activity is created + val newActivity = mock() + sut.onActivityCreated(newActivity, null) + + // then the transaction should start with the paused time + assertEquals(now.nanoTimestamp(), fixture.transaction.startDate.nanoTimestamp()) + } + private fun runFirstDraw(view: View) { // Removes OnDrawListener in the next OnGlobalLayout after onDraw view.viewTreeObserver.dispatchOnDraw() From a1fad41abf0b750951a9faaa19bc01605887d485 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 12 Dec 2023 09:36:44 +0100 Subject: [PATCH 2/2] Add Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ee5e78243..dcf0828eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixes - Send breadcrumbs and client error even without transactions ([#3087](https://github.com/getsentry/sentry-java/pull/3087)) +- (Android) Fix wrong activity transaction duration in case SDK init is deferred ([#3092](https://github.com/getsentry/sentry-java/pull/3092)) ### Dependencies