Previously, we used isKeyguardActive to determine whether we should
resume an activity. This does not account for the keyguard going
away, which can leads to a timing issue where we do not resume an
activity when coming out of sleep from fingerprint unlock.
This change also prevents us from pausing a stopped activity that is
is considered to be the resumed activity as it will be brought to
the resumed state.
Fixes:
73991496
Test: Open display settings, lock screen, fingerprint unlock, press
back, verify main settings page is shown immediately.
Change-Id: I3a7a33f5359a41fc958e3d8e799c39f5193ecb56
// this when there is an activity waiting to become translucent as the extra binder
// calls will lead to noticeable jank. A later call to
// ActivityStack#ensureActivitiesVisibleLocked will bring the activity to the proper
- // paused state.
- if (isState(STOPPED, STOPPING) && stack.mTranslucentActivityWaiting == null) {
+ // paused state. We also avoid doing this for the activity the stack supervisor
+ // considers the resumed activity, as normal means will bring the activity from STOPPED
+ // to RESUMED. Adding PAUSING in this scenario will lead to double lifecycles.
+ if (isState(STOPPED, STOPPING) && stack.mTranslucentActivityWaiting == null
+ && mStackSupervisor.getResumedActivityLocked() != this) {
// Capture reason before state change
final String reason = getLifecycleDescription("makeVisibleIfNeeded");
stack.goToSleepIfPossible(false /* shuttingDown */);
} else {
stack.awakeFromSleepingLocked();
- if (isFocusedStack(stack)
- && !mKeyguardController.isKeyguardActive(display.mDisplayId)) {
- // If there is no keyguard on this display - resume immediately. Otherwise
- // we'll wait for keyguard visibility callback and resume while ensuring
- // activities visibility
+ if (isFocusedStack(stack) && !mKeyguardController.isKeyguardLocked()) {
+ // If the keyguard is unlocked - resume immediately.
+ // It is possible that the display will not be awake at the time we
+ // process the keyguard going away, which can happen before the sleep token
+ // is released. As a result, it is important we resume the activity here.
resumeFocusedStackTopActivityLocked();
}
}
* display, false otherwise
*/
boolean isKeyguardShowing(int displayId) {
- return isKeyguardActive(displayId) && !mKeyguardGoingAway;
- }
-
- /**
- * @return true if Keyguard is showing and not occluded. We ignore whether it is going away or
- * not here.
- */
- boolean isKeyguardActive(int displayId) {
- return mKeyguardShowing && (displayId == DEFAULT_DISPLAY ? !mOccluded
- : displayId == mSecondaryDisplayShowing);
+ return mKeyguardShowing && !mKeyguardGoingAway &&
+ (displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
}
/**
}
return null;
}).when(mActivity.app.thread).scheduleTransaction(any());
+
mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
+ // The activity is in the focused stack so it should not move to paused.
mActivity.makeVisibleIfNeeded(null /* starting */);
+ assertTrue(mActivity.isState(STOPPED));
+ assertFalse(pauseFound.value);
- assertTrue(mActivity.isState(PAUSING));
+ // Clear focused stack
+ mActivity.mStackSupervisor.mFocusedStack = null;
+ // In the unfocused stack, the activity should move to paused.
+ mActivity.makeVisibleIfNeeded(null /* starting */);
+ assertTrue(mActivity.isState(PAUSING));
assertTrue(pauseFound.value);
// Make sure that the state does not change for current non-stopping states.