|
31 | 31 | import io.sentry.protocol.MeasurementValue; |
32 | 32 | import io.sentry.protocol.TransactionNameSource; |
33 | 33 | import io.sentry.util.Objects; |
| 34 | +import io.sentry.util.TracingUtils; |
34 | 35 | import java.io.Closeable; |
35 | 36 | import java.io.IOException; |
36 | 37 | import java.lang.ref.WeakReference; |
@@ -122,11 +123,9 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio |
122 | 123 | fullyDisplayedReporter = this.options.getFullyDisplayedReporter(); |
123 | 124 | timeToFullDisplaySpanEnabled = this.options.isEnableTimeToFullDisplayTracing(); |
124 | 125 |
|
125 | | - if (this.options.isEnableActivityLifecycleBreadcrumbs() || performanceEnabled) { |
126 | | - application.registerActivityLifecycleCallbacks(this); |
127 | | - this.options.getLogger().log(SentryLevel.DEBUG, "ActivityLifecycleIntegration installed."); |
128 | | - addIntegrationToSdkVersion(); |
129 | | - } |
| 126 | + application.registerActivityLifecycleCallbacks(this); |
| 127 | + this.options.getLogger().log(SentryLevel.DEBUG, "ActivityLifecycleIntegration installed."); |
| 128 | + addIntegrationToSdkVersion(); |
130 | 129 | } |
131 | 130 |
|
132 | 131 | private boolean isPerformanceEnabled(final @NotNull SentryAndroidOptions options) { |
@@ -176,7 +175,9 @@ private void stopPreviousTransactions() { |
176 | 175 |
|
177 | 176 | private void startTracing(final @NotNull Activity activity) { |
178 | 177 | WeakReference<Activity> weakActivity = new WeakReference<>(activity); |
179 | | - if (performanceEnabled && !isRunningTransaction(activity) && hub != null) { |
| 178 | + if (!performanceEnabled && hub != null) { |
| 179 | + TracingUtils.startNewTrace(hub); |
| 180 | + } else if (performanceEnabled && !isRunningTransaction(activity) && hub != null) { |
180 | 181 | // as we allow a single transaction running on the bound Scope, we finish the previous ones |
181 | 182 | stopPreviousTransactions(); |
182 | 183 |
|
@@ -367,44 +368,48 @@ public synchronized void onActivityCreated( |
367 | 368 |
|
368 | 369 | @Override |
369 | 370 | public synchronized void onActivityStarted(final @NotNull Activity activity) { |
370 | | - // The docs on the screen rendering performance tracing |
371 | | - // (https://firebase.google.com/docs/perf-mon/screen-traces?platform=android#definition), |
372 | | - // state that the tracing starts for every Activity class when the app calls .onActivityStarted. |
373 | | - // Adding an Activity in onActivityCreated leads to Window.FEATURE_NO_TITLE not |
374 | | - // working. Moving this to onActivityStarted fixes the problem. |
375 | | - activityFramesTracker.addActivity(activity); |
| 371 | + if (performanceEnabled || options.isEnableActivityLifecycleBreadcrumbs()) { |
| 372 | + // The docs on the screen rendering performance tracing |
| 373 | + // (https://firebase.google.com/docs/perf-mon/screen-traces?platform=android#definition), |
| 374 | + // state that the tracing starts for every Activity class when the app calls |
| 375 | + // .onActivityStarted. |
| 376 | + // Adding an Activity in onActivityCreated leads to Window.FEATURE_NO_TITLE not |
| 377 | + // working. Moving this to onActivityStarted fixes the problem. |
| 378 | + activityFramesTracker.addActivity(activity); |
| 379 | + } |
376 | 380 |
|
377 | 381 | addBreadcrumb(activity, "started"); |
378 | 382 | } |
379 | 383 |
|
380 | 384 | @SuppressLint("NewApi") |
381 | 385 | @Override |
382 | 386 | public synchronized void onActivityResumed(final @NotNull Activity activity) { |
383 | | - |
384 | | - // app start span |
385 | | - @Nullable final SentryDate appStartStartTime = AppStartState.getInstance().getAppStartTime(); |
386 | | - @Nullable final SentryDate appStartEndTime = AppStartState.getInstance().getAppStartEndTime(); |
387 | | - // in case the SentryPerformanceProvider is disabled it does not set the app start times, |
388 | | - // and we need to set the end time manually here, |
389 | | - // the start time gets set manually in SentryAndroid.init() |
390 | | - if (appStartStartTime != null && appStartEndTime == null) { |
391 | | - AppStartState.getInstance().setAppStartEnd(); |
392 | | - } |
393 | | - finishAppStartSpan(); |
394 | | - |
395 | | - final @Nullable ISpan ttidSpan = ttidSpanMap.get(activity); |
396 | | - final @Nullable ISpan ttfdSpan = ttfdSpanMap.get(activity); |
397 | | - final View rootView = activity.findViewById(android.R.id.content); |
398 | | - if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN |
399 | | - && rootView != null) { |
400 | | - FirstDrawDoneListener.registerForNextDraw( |
401 | | - rootView, () -> onFirstFrameDrawn(ttfdSpan, ttidSpan), buildInfoProvider); |
402 | | - } else { |
403 | | - // Posting a task to the main thread's handler will make it executed after it finished |
404 | | - // its current job. That is, right after the activity draws the layout. |
405 | | - mainHandler.post(() -> onFirstFrameDrawn(ttfdSpan, ttidSpan)); |
| 387 | + if (performanceEnabled || options.isEnableActivityLifecycleBreadcrumbs()) { |
| 388 | + // app start span |
| 389 | + @Nullable final SentryDate appStartStartTime = AppStartState.getInstance().getAppStartTime(); |
| 390 | + @Nullable final SentryDate appStartEndTime = AppStartState.getInstance().getAppStartEndTime(); |
| 391 | + // in case the SentryPerformanceProvider is disabled it does not set the app start times, |
| 392 | + // and we need to set the end time manually here, |
| 393 | + // the start time gets set manually in SentryAndroid.init() |
| 394 | + if (appStartStartTime != null && appStartEndTime == null) { |
| 395 | + AppStartState.getInstance().setAppStartEnd(); |
| 396 | + } |
| 397 | + finishAppStartSpan(); |
| 398 | + |
| 399 | + final @Nullable ISpan ttidSpan = ttidSpanMap.get(activity); |
| 400 | + final @Nullable ISpan ttfdSpan = ttfdSpanMap.get(activity); |
| 401 | + final View rootView = activity.findViewById(android.R.id.content); |
| 402 | + if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN |
| 403 | + && rootView != null) { |
| 404 | + FirstDrawDoneListener.registerForNextDraw( |
| 405 | + rootView, () -> onFirstFrameDrawn(ttfdSpan, ttidSpan), buildInfoProvider); |
| 406 | + } else { |
| 407 | + // Posting a task to the main thread's handler will make it executed after it finished |
| 408 | + // its current job. That is, right after the activity draws the layout. |
| 409 | + mainHandler.post(() -> onFirstFrameDrawn(ttfdSpan, ttidSpan)); |
| 410 | + } |
| 411 | + addBreadcrumb(activity, "resumed"); |
406 | 412 | } |
407 | | - addBreadcrumb(activity, "resumed"); |
408 | 413 | } |
409 | 414 |
|
410 | 415 | @Override |
@@ -450,35 +455,38 @@ public synchronized void onActivitySaveInstanceState( |
450 | 455 |
|
451 | 456 | @Override |
452 | 457 | public synchronized void onActivityDestroyed(final @NotNull Activity activity) { |
453 | | - addBreadcrumb(activity, "destroyed"); |
454 | | - |
455 | | - // in case the appStartSpan isn't completed yet, we finish it as cancelled to avoid |
456 | | - // memory leak |
457 | | - finishSpan(appStartSpan, SpanStatus.CANCELLED); |
| 458 | + if (performanceEnabled || options.isEnableActivityLifecycleBreadcrumbs()) { |
| 459 | + addBreadcrumb(activity, "destroyed"); |
458 | 460 |
|
459 | | - // we finish the ttidSpan as cancelled in case it isn't completed yet |
460 | | - final ISpan ttidSpan = ttidSpanMap.get(activity); |
461 | | - final ISpan ttfdSpan = ttfdSpanMap.get(activity); |
462 | | - finishSpan(ttidSpan, SpanStatus.DEADLINE_EXCEEDED); |
463 | | - |
464 | | - // we finish the ttfdSpan as deadline_exceeded in case it isn't completed yet |
465 | | - finishExceededTtfdSpan(ttfdSpan, ttidSpan); |
466 | | - cancelTtfdAutoClose(); |
| 461 | + // in case the appStartSpan isn't completed yet, we finish it as cancelled to avoid |
| 462 | + // memory leak |
| 463 | + finishSpan(appStartSpan, SpanStatus.CANCELLED); |
467 | 464 |
|
468 | | - // in case people opt-out enableActivityLifecycleTracingAutoFinish and forgot to finish it, |
469 | | - // we make sure to finish it when the activity gets destroyed. |
470 | | - stopTracing(activity, true); |
| 465 | + // we finish the ttidSpan as cancelled in case it isn't completed yet |
| 466 | + final ISpan ttidSpan = ttidSpanMap.get(activity); |
| 467 | + final ISpan ttfdSpan = ttfdSpanMap.get(activity); |
| 468 | + finishSpan(ttidSpan, SpanStatus.DEADLINE_EXCEEDED); |
471 | 469 |
|
472 | | - // set it to null in case its been just finished as cancelled |
473 | | - appStartSpan = null; |
474 | | - ttidSpanMap.remove(activity); |
475 | | - ttfdSpanMap.remove(activity); |
| 470 | + // we finish the ttfdSpan as deadline_exceeded in case it isn't completed yet |
| 471 | + finishExceededTtfdSpan(ttfdSpan, ttidSpan); |
| 472 | + cancelTtfdAutoClose(); |
476 | 473 |
|
477 | | - // clear it up, so we don't start again for the same activity if the activity is in the activity |
478 | | - // stack still. |
479 | | - // if the activity is opened again and not in memory, transactions will be created normally. |
480 | | - if (performanceEnabled) { |
481 | | - activitiesWithOngoingTransactions.remove(activity); |
| 474 | + // in case people opt-out enableActivityLifecycleTracingAutoFinish and forgot to finish it, |
| 475 | + // we make sure to finish it when the activity gets destroyed. |
| 476 | + stopTracing(activity, true); |
| 477 | + |
| 478 | + // set it to null in case its been just finished as cancelled |
| 479 | + appStartSpan = null; |
| 480 | + ttidSpanMap.remove(activity); |
| 481 | + ttfdSpanMap.remove(activity); |
| 482 | + |
| 483 | + // clear it up, so we don't start again for the same activity if the activity is in the |
| 484 | + // activity |
| 485 | + // stack still. |
| 486 | + // if the activity is opened again and not in memory, transactions will be created normally. |
| 487 | + if (performanceEnabled) { |
| 488 | + activitiesWithOngoingTransactions.remove(activity); |
| 489 | + } |
482 | 490 | } |
483 | 491 | } |
484 | 492 |
|
|
0 commit comments