1414import android .os .Looper ;
1515import android .os .Process ;
1616import android .os .SystemClock ;
17+ import android .util .Log ;
18+ import androidx .annotation .NonNull ;
1719import io .sentry .ILogger ;
1820import io .sentry .ITransactionProfiler ;
1921import io .sentry .JsonSerializer ;
3335import java .io .FileNotFoundException ;
3436import java .io .InputStreamReader ;
3537import java .io .Reader ;
36- import java .util .concurrent .TimeUnit ;
3738import java .util .concurrent .atomic .AtomicBoolean ;
39+ import java .util .concurrent .atomic .AtomicInteger ;
3840import org .jetbrains .annotations .ApiStatus ;
3941import org .jetbrains .annotations .NotNull ;
4042import org .jetbrains .annotations .Nullable ;
@@ -52,6 +54,8 @@ public final class SentryPerformanceProvider extends EmptySecureContentProvider
5254
5355 private final @ NotNull ILogger logger ;
5456 private final @ NotNull BuildInfoProvider buildInfoProvider ;
57+ private final AtomicInteger activeActivitiesCounter = new AtomicInteger ();
58+ private final AtomicBoolean firstDrawDone = new AtomicBoolean (false );
5559
5660 @ TestOnly
5761 SentryPerformanceProvider (
@@ -201,35 +205,22 @@ private void onAppLaunched(
201205 appStartTimespan .setStartedAt (Process .getStartUptimeMillis ());
202206 appStartMetrics .registerApplicationForegroundCheck (app );
203207
204- final AtomicBoolean firstDrawDone = new AtomicBoolean (false );
205-
206208 activityCallback =
207209 new ActivityLifecycleCallbacksAdapter () {
208210
209211 @ Override
210212 public void onActivityCreated (
211213 @ NotNull Activity activity , @ Nullable Bundle savedInstanceState ) {
214+ Log .d ("TAG" , "onActivityCreated" );
215+ activeActivitiesCounter .incrementAndGet ();
216+
212217 // In case the SDK gets initialized async or the
213218 // ActivityLifecycleIntegration is not enabled (e.g on RN due to Context not being
214219 // instanceof Application)
215220 // the app start type never gets set
216- if (appStartMetrics .getAppStartType () == AppStartMetrics .AppStartType .UNKNOWN ) {
217- // We consider pre-loaded application loads as warm starts
218- // This usually happens e.g. due to BroadcastReceivers triggering
219- // Application.onCreate only, but no Activity.onCreate
221+ if (!firstDrawDone .get ()) {
220222 final long now = SystemClock .uptimeMillis ();
221- final long durationMs =
222- now - appStartMetrics .getAppStartTimeSpan ().getStartUptimeMs ();
223- if (durationMs > TimeUnit .SECONDS .toMillis (1 )) {
224- appStartMetrics .restartAppStart (now );
225- appStartMetrics .setAppStartType (AppStartMetrics .AppStartType .WARM );
226- } else {
227- // Otherwise a non-null bundle determines the behavior
228- appStartMetrics .setAppStartType (
229- savedInstanceState == null
230- ? AppStartMetrics .AppStartType .COLD
231- : AppStartMetrics .AppStartType .WARM );
232- }
223+ AppStartMetrics .getInstance ().updateAppStartType (savedInstanceState != null , now );
233224 }
234225 }
235226
@@ -245,20 +236,26 @@ public void onActivityStarted(@NotNull Activity activity) {
245236 new Handler (Looper .getMainLooper ()).post (() -> onAppStartDone ());
246237 }
247238 }
239+
240+ @ Override
241+ public void onActivityDestroyed (@ NonNull Activity activity ) {
242+ final int remainingActivities = activeActivitiesCounter .decrementAndGet ();
243+ // if the app is moving into background, reset firstDrawDone
244+ // as the next Activity is considered like a new app start
245+ if (remainingActivities == 0 && !activity .isChangingConfigurations ()) {
246+ firstDrawDone .set (false );
247+ }
248+ }
248249 };
249250
250251 app .registerActivityLifecycleCallbacks (activityCallback );
251252 }
252253
253254 synchronized void onAppStartDone () {
254- final @ NotNull AppStartMetrics appStartMetrics = AppStartMetrics .getInstance ();
255- appStartMetrics .getSdkInitTimeSpan ().stop ();
256- appStartMetrics .getAppStartTimeSpan ().stop ();
257-
258- if (app != null ) {
259- if (activityCallback != null ) {
260- app .unregisterActivityLifecycleCallbacks (activityCallback );
261- }
255+ if (!firstDrawDone .getAndSet (true )) {
256+ final @ NotNull AppStartMetrics appStartMetrics = AppStartMetrics .getInstance ();
257+ appStartMetrics .getSdkInitTimeSpan ().stop ();
258+ appStartMetrics .getAppStartTimeSpan ().stop ();
262259 }
263260 }
264261}
0 commit comments