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

Commit 3669f265 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: EXEMPT bugfix
Change-Id: I732fb7d577a5f4c65c8d84cc66a61f5006ed8d53
Merged-In: I732fb7d577a5f4c65c8d84cc66a61f5006ed8d53
(cherry picked from commit 8853b2c7)
parent ea1c3734
Loading
Loading
Loading
Loading
+40 −5
Original line number Diff line number Diff line
@@ -403,6 +403,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
     * */
    private boolean mHiding;

    /**
     * Tracks SHOW/HIDE requests, in order to determine if a HIDE request show be completed after a
     * series of binder calls returns from WM.
     */
    private int mLastShowRequest = 0;
    private int mLastHideRequest = 0;

    /**
     * we send this intent when the keyguard is dismissed.
     */
@@ -1750,6 +1757,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                mNeedToReshowWhenReenabled = false;
                updateInputRestrictedLocked();

                mHandler.removeMessages(HIDE);
                mHandler.removeMessages(START_KEYGUARD_EXIT_ANIM);
                showLocked(null);

                // block until we know the keyguard is done drawing (and post a message
@@ -2110,6 +2119,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
        if (DEBUG) Log.d(TAG, "showLocked");
        // ensure we stay awake until we are finished displaying the keyguard
        mShowKeyguardWakeLock.acquire();
        mLastShowRequest++;
        Message msg = mHandler.obtainMessage(SHOW, options);
        // Treat these messages with priority - This call can originate from #doKeyguardTimeout,
        // meaning the device should lock as soon as possible and not wait for other messages on
@@ -2122,7 +2132,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
     * Send message to keyguard telling it to hide itself
     * @see #handleHide()
     */
    private void hideLocked() {
    @VisibleForTesting
    void hideLocked() {
        Trace.beginSection("KeyguardViewMediator#hideLocked");
        if (DEBUG) Log.d(TAG, "hideLocked");
        Message msg = mHandler.obtainMessage(HIDE);
@@ -2546,7 +2557,17 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
            }
            mHiding = false;

            // Any valid exit animation will set this to false before proceeding
            mIsKeyguardExitAnimationCanceled = true;
            // Make sure to remove any pending exit animation requests that would override a SHOW
            mHandler.removeMessages(START_KEYGUARD_EXIT_ANIM);
            mHandler.removeMessages(HIDE);
            mShadeController.get().instantCollapseShade();
            mKeyguardStateController.notifyKeyguardGoingAway(false);

            // Handled directly in StatusBarKeyguardViewManager if enabled.
            mKeyguardViewControllerLazy.get().show(options);

            resetKeyguardDonePendingLocked();
            mHideAnimationRun = false;
            adjustStatusBarLocked();
@@ -2673,10 +2694,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                return;
            }
            mHiding = true;
            mLastHideRequest = mLastShowRequest;

            if (mShowing && !mOccluded) {
                mKeyguardGoingAwayRunnable.run();
            } else {
                mGoingAwayRequestedForUserId = KeyguardUpdateMonitor.getCurrentUser();
                // TODO(bc-unlock): Fill parameters
                mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(() -> {
                    handleStartKeyguardExitAnimation(
@@ -2703,11 +2726,22 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
        Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
                + " fadeoutDuration=" + fadeoutDuration);
        int currentUserId = KeyguardUpdateMonitor.getCurrentUser();

        // Requests to exit directly from WM are valid if the lockscreen can be dismissed
        if (mKeyguardStateController.canDismissLockScreen()) {
            mLastHideRequest = mLastShowRequest;
        }

        String error = null;
        if (mGoingAwayRequestedForUserId != currentUserId) {
            Log.e(TAG, "Not executing handleStartKeyguardExitAnimation() due to userId "
            error = "Not executing handleStartKeyguardExitAnimation() due to userId "
                    + "mismatch. Requested: " + mGoingAwayRequestedForUserId + ", current: "
                    + currentUserId);
            mIsKeyguardExitAnimationCanceled = true;
                    + currentUserId;
        } else if (mLastHideRequest != mLastShowRequest) {
            error = "Show requested after hide, cancel animation";
        }
        if (error != null) {
            Log.e(TAG, error);
            if (finishedCallback != null) {
                // There will not execute animation, send a finish callback to ensure the remote
                // animation won't hang there.
@@ -3037,7 +3071,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
        if (KeyguardUnlockAnimationController.Companion.isNexusLauncherUnderneath()) {
            flags |= KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
        }

        mLastHideRequest = mLastShowRequest;
        mIsKeyguardExitAnimationCanceled = false;
        mKeyguardStateController.notifyKeyguardGoingAway(true);

        mGoingAwayRequestedForUserId = KeyguardUpdateMonitor.getCurrentUser();
+2 −1
Original line number Diff line number Diff line
@@ -549,7 +549,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);

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