@@ -75,6 +75,8 @@ public class AppStartTrace implements ActivityLifecycleCallbacks, LifecycleObser
75
75
private static final @ NonNull Timer PERF_CLASS_LOAD_TIME = new Clock ().getTime ();
76
76
private static final long MAX_LATENCY_BEFORE_UI_INIT = TimeUnit .MINUTES .toMicros (1 );
77
77
78
+ private static final long MAX_BACKGROUND_THREAD_DELAY = TimeUnit .MILLISECONDS .toMicros (100 );
79
+
78
80
// Core pool size 0 allows threads to shut down if they're idle
79
81
private static final int CORE_POOL_SIZE = 0 ;
80
82
private static final int MAX_POOL_SIZE = 1 ; // Only need single thread
@@ -111,6 +113,8 @@ public class AppStartTrace implements ActivityLifecycleCallbacks, LifecycleObser
111
113
private final @ Nullable Timer processStartTime ;
112
114
private final @ Nullable Timer firebaseClassLoadTime ;
113
115
private Timer onCreateTime = null ;
116
+
117
+ private Timer mainThreadRunnableTime = null ;
114
118
private Timer onStartTime = null ;
115
119
private Timer onResumeTime = null ;
116
120
private Timer firstForegroundTime = null ;
@@ -319,10 +323,28 @@ private void recordOnDrawFrontOfQueue() {
319
323
logExperimentTrace (this .experimentTtid );
320
324
}
321
325
326
+ private boolean isStartedFromBackground () {
327
+ // This a fix for b/339891952 where the runnable on the background thread can run before the
328
+ // activity lifecycle callbacks.
329
+ if (mainThreadRunnableTime == null ) {
330
+ return false ;
331
+ }
332
+
333
+ if (isStartedFromBackground
334
+ && (mainThreadRunnableTime .getDurationMicros () < MAX_BACKGROUND_THREAD_DELAY )) {
335
+ // Reset it to false as it was executed pre-emptively.
336
+ isStartedFromBackground = false ;
337
+ }
338
+
339
+ return isStartedFromBackground ;
340
+ }
341
+
322
342
@ Override
323
343
public synchronized void onActivityCreated (Activity activity , Bundle savedInstanceState ) {
324
- if (isStartedFromBackground || onCreateTime != null // An activity already called onCreate()
344
+ if (isStartedFromBackground () || onCreateTime != null // An activity already called onCreate()
325
345
) {
346
+ AndroidLogger .getInstance ()
347
+ .debug ("onActivityCreated: isStartedFromBackground - " + isStartedFromBackground ());
326
348
return ;
327
349
}
328
350
@@ -337,7 +359,7 @@ public synchronized void onActivityCreated(Activity activity, Bundle savedInstan
337
359
338
360
@ Override
339
361
public synchronized void onActivityStarted (Activity activity ) {
340
- if (isStartedFromBackground
362
+ if (isStartedFromBackground ()
341
363
|| onStartTime != null // An activity already called onStart()
342
364
|| isTooLateToInitUI ) {
343
365
return ;
@@ -347,7 +369,7 @@ public synchronized void onActivityStarted(Activity activity) {
347
369
348
370
@ Override
349
371
public synchronized void onActivityResumed (Activity activity ) {
350
- if (isStartedFromBackground || isTooLateToInitUI ) {
372
+ if (isStartedFromBackground () || isTooLateToInitUI ) {
351
373
return ;
352
374
}
353
375
@@ -440,7 +462,7 @@ private void logAppStartTrace() {
440
462
441
463
@ Override
442
464
public void onActivityPaused (Activity activity ) {
443
- if (isStartedFromBackground
465
+ if (isStartedFromBackground ()
444
466
|| isTooLateToInitUI
445
467
|| !configResolver .getIsExperimentTTIDEnabled ()) {
446
468
return ;
@@ -458,7 +480,7 @@ public void onActivityStopped(Activity activity) {}
458
480
@ Keep
459
481
@ OnLifecycleEvent (Lifecycle .Event .ON_START )
460
482
public void onAppEnteredForeground () {
461
- if (isStartedFromBackground || isTooLateToInitUI || firstForegroundTime != null ) {
483
+ if (isStartedFromBackground () || isTooLateToInitUI || firstForegroundTime != null ) {
462
484
return ;
463
485
}
464
486
// firstForeground is equivalent to the first Activity onStart. This marks the beginning of
@@ -476,7 +498,7 @@ public void onAppEnteredForeground() {
476
498
@ Keep
477
499
@ OnLifecycleEvent (Lifecycle .Event .ON_STOP )
478
500
public void onAppEnteredBackground () {
479
- if (isStartedFromBackground || isTooLateToInitUI || firstBackgroundTime != null ) {
501
+ if (isStartedFromBackground () || isTooLateToInitUI || firstBackgroundTime != null ) {
480
502
return ;
481
503
}
482
504
firstBackgroundTime = clock .getTime ();
@@ -574,6 +596,9 @@ public StartFromBackgroundRunnable(final AppStartTrace trace) {
574
596
public void run () {
575
597
// if no activity has ever been created.
576
598
if (trace .onCreateTime == null ) {
599
+ trace .mainThreadRunnableTime = new Timer ();
600
+ AndroidLogger .getInstance ()
601
+ .debug ("StartFromBackgroundThreadRunnable: " + trace .onCreateTime );
577
602
trace .isStartedFromBackground = true ;
578
603
}
579
604
}
0 commit comments