Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de2d7d3d authored by Matt Pietal's avatar Matt Pietal
Browse files

Remove all pending keyguard exits on SHOW

Noticed during rapid requests to enabled/disable keyguard,
prevent any preexisting requests to hide or dismiss keyguard
from running when a SHOW message is handled. Reset goingAway,
and also make sure to prevent any WM callbacks in flight from
continuing.

Test: atest KeyguardViewMediatorTest
Bug: 395640609
Bug: 419095873
Flag: com.android.systemui.keyguard_show_cancels_all_pending_exits
Change-Id: I0c70f09c5b736b108eb6cef9249dc5c90a7fd4cd
parent 4b03c792
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1435,6 +1435,16 @@ flag {
   }
}

flag {
   name: "keyguard_show_cancels_all_pending_exits"
   namespace: "systemui"
   description: "When keyguard becomes visible, prevent any preexisting exit calls from proceeding"
   bug: "395640609"
   metadata {
       purpose: PURPOSE_BUGFIX
   }
}

flag {
    name: "qs_tile_detailed_view"
    namespace: "systemui"
+20 −4
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.Flags.keyguardShowCancelsAllPendingExits;
import static com.android.systemui.Flags.simPinBouncerReset;
import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;

@@ -3103,6 +3104,16 @@ public class KeyguardViewMediator implements CoreStartable,
            setShowingLocked(true, hidingOrGoingAway /* force */, "handleShowInner");
            mHiding = false;

            if (keyguardShowCancelsAllPendingExits()) {
                // Make sure to remove any pending exit animation requests that would override a
                // SHOW
                mIsKeyguardExitAnimationCanceled = true;
                mHandler.removeMessages(START_KEYGUARD_EXIT_ANIM);
                mHandler.removeMessages(HIDE);
                mKeyguardInteractor.showKeyguard();
                mKeyguardStateController.notifyKeyguardGoingAway(false);
            }

            if (!KeyguardWmStateRefactor.isEnabled()) {
                // Handled directly in StatusBarKeyguardViewManager if enabled.
                mKeyguardViewControllerLazy.get().show(options);
@@ -3325,10 +3336,15 @@ public class KeyguardViewMediator implements CoreStartable,
        Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
                + " fadeoutDuration=" + fadeoutDuration);
        int currentUserId = mSelectedUserInteractor.getSelectedUserId();
        if (!KeyguardWmStateRefactor.isEnabled() && mGoingAwayRequestedForUserId != currentUserId) {
        if (!KeyguardWmStateRefactor.isEnabled() && (mGoingAwayRequestedForUserId != currentUserId
                || !mKeyguardStateController.isKeyguardGoingAway())) {
            if (!mKeyguardStateController.isKeyguardGoingAway()) {
                Log.e(TAG, "Keyguard no longer going away, not processing exit animation");
            } else {
                Log.e(TAG, "Not executing handleStartKeyguardExitAnimationInner() due to userId "
                        + "mismatch. Requested: " + mGoingAwayRequestedForUserId + ", current: "
                        + currentUserId);
            }
            if (finishedCallback != null) {
                // There will not execute animation, send a finish callback to ensure the remote
                // animation won't hang there.
+40 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOM
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.systemui.Flags.FLAG_KEYGUARD_SHOW_CANCELS_ALL_PENDING_EXITS;
import static com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR;
import static com.android.systemui.Flags.FLAG_SIM_PIN_BOUNCER_RESET;
import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION;
@@ -1037,6 +1038,37 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    @EnableFlags(FLAG_KEYGUARD_SHOW_CANCELS_ALL_PENDING_EXITS)
    public void testStartKeyguardExitAnimation_isCanceledWhenDismissibleKeyguardIsShown() {
        when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);

        startMockKeyguardExitAnimation();
        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());

        mViewMediator.showDismissibleKeyguard();
        TestableLooper.get(this).processAllMessages();

        mViewMediator.mViewMediatorCallback.keyguardDonePending(mDefaultUserId);
        mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
        TestableLooper.get(this).processAllMessages();
        verify(mKeyguardUnlockAnimationController, never())
                .notifyFinishedKeyguardExitAnimation(false);
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    @EnableFlags(FLAG_KEYGUARD_SHOW_CANCELS_ALL_PENDING_EXITS)
    public void testStartKeyguardExitAnimation_isCanceledWhenGoingAwayIsReset() {
        when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);

        startMockKeyguardExitAnimation(/* goingAway=*/false);
        assertFalse(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
        verify(mKeyguardUnlockAnimationController, never())
                .notifyFinishedKeyguardExitAnimation(false);
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testKeyguardDelayedOnGoingToSleep_ifScreenOffAnimationWillPlayButIsntPlayingYet() {
@@ -1248,6 +1280,13 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
     * Configures mocks appropriately, then starts the keyguard exit animation.
     */
    private void startMockKeyguardExitAnimation() {
        startMockKeyguardExitAnimation(true);
    }

    /**
     * Configures mocks appropriately, then starts the keyguard exit animation.
     */
    private void startMockKeyguardExitAnimation(boolean goingAway) {
        mViewMediator.onSystemReady();
        processAllMessagesAndBgExecutorMessages();

@@ -1261,7 +1300,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        };
        IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);

        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(goingAway);
        mViewMediator.mKeyguardGoingAwayRunnable.run();
        mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers,
                null, callback);