Skip to content

Commit

Permalink
Fix wrong txn duration in case SDK init is deferred (#3092)
Browse files Browse the repository at this point in the history
  • Loading branch information
markushi authored Dec 18, 2023
1 parent 941e097 commit eefb169
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

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

### Dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,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 {
Expand All @@ -425,6 +429,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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.Sentry
import io.sentry.SentryDate
import io.sentry.SentryDateProvider
import io.sentry.SentryNanotimeDate
import io.sentry.SentryTracer
import io.sentry.Span
Expand Down Expand Up @@ -1320,6 +1321,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<Activity>()
sut.onActivityPrePaused(oldActivity)
sut.onActivityPaused(oldActivity)

// and the next activity is created
val newActivity = mock<Activity>()
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()
Expand Down

0 comments on commit eefb169

Please sign in to comment.