Skip to content

Commit eefb169

Browse files
authored
Fix wrong txn duration in case SDK init is deferred (#3092)
1 parent 941e097 commit eefb169

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
- Send breadcrumbs and client error in `SentryOkHttpEventListener` even without transactions ([#3087](https://github.com/getsentry/sentry-java/pull/3087))
2323
- Keep `io.sentry.exception.SentryHttpClientException` from obfuscation to display proper issue title on Sentry ([#3093](https://github.com/getsentry/sentry-java/pull/3093))
24+
- (Android) Fix wrong activity transaction duration in case SDK init is deferred ([#3092](https://github.com/getsentry/sentry-java/pull/3092))
2425

2526
### Dependencies
2627

sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,10 @@ public void onActivityPostResumed(@NonNull Activity activity) {
413413
public void onActivityPrePaused(@NonNull Activity activity) {
414414
// only executed if API >= 29 otherwise it happens on onActivityPaused
415415
if (isAllActivityCallbacksAvailable) {
416+
// as the SDK may gets (re-)initialized mid activity lifecycle, ensure we set the flag here as
417+
// well
418+
// this ensures any newly launched activity will not use the app start timestamp as txn start
419+
firstActivityCreated = true;
416420
if (hub == null) {
417421
lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime();
418422
} else {
@@ -425,6 +429,10 @@ public void onActivityPrePaused(@NonNull Activity activity) {
425429
public synchronized void onActivityPaused(final @NotNull Activity activity) {
426430
// only executed if API < 29 otherwise it happens on onActivityPrePaused
427431
if (!isAllActivityCallbacksAvailable) {
432+
// as the SDK may gets (re-)initialized mid activity lifecycle, ensure we set the flag here as
433+
// well
434+
// this ensures any newly launched activity will not use the app start timestamp as txn start
435+
firstActivityCreated = true;
428436
if (hub == null) {
429437
lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime();
430438
} else {

sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import io.sentry.Scope
2020
import io.sentry.ScopeCallback
2121
import io.sentry.Sentry
2222
import io.sentry.SentryDate
23+
import io.sentry.SentryDateProvider
2324
import io.sentry.SentryNanotimeDate
2425
import io.sentry.SentryTracer
2526
import io.sentry.Span
@@ -1320,6 +1321,34 @@ class ActivityLifecycleIntegrationTest {
13201321
verify(fixture.activityFramesTracker).setMetrics(activity, fixture.transaction.eventId)
13211322
}
13221323

1324+
@Test
1325+
fun `When sentry is initialized mid activity lifecycle, last paused time should be used in favor of app start time`() {
1326+
val sut = fixture.getSut(importance = RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
1327+
val now = SentryNanotimeDate(Date(1234), 456)
1328+
1329+
fixture.options.tracesSampleRate = 1.0
1330+
fixture.options.dateProvider = SentryDateProvider { now }
1331+
sut.register(fixture.hub, fixture.options)
1332+
1333+
// usually done by SentryPerformanceProvider
1334+
val startDate = SentryNanotimeDate(Date(5678), 910)
1335+
setAppStartTime(startDate)
1336+
AppStartMetrics.getInstance().appStartType = AppStartType.COLD
1337+
1338+
// when activity is paused without being created
1339+
// indicating a delayed SDK init
1340+
val oldActivity = mock<Activity>()
1341+
sut.onActivityPrePaused(oldActivity)
1342+
sut.onActivityPaused(oldActivity)
1343+
1344+
// and the next activity is created
1345+
val newActivity = mock<Activity>()
1346+
sut.onActivityCreated(newActivity, null)
1347+
1348+
// then the transaction should start with the paused time
1349+
assertEquals(now.nanoTimestamp(), fixture.transaction.startDate.nanoTimestamp())
1350+
}
1351+
13231352
private fun runFirstDraw(view: View) {
13241353
// Removes OnDrawListener in the next OnGlobalLayout after onDraw
13251354
view.viewTreeObserver.dispatchOnDraw()

0 commit comments

Comments
 (0)