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

Commit 7a563cf4 authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Wait to handle a pending lock until after keyguardGoingAway = false.

If we attempt to re-lock the device in the middle of the unlock sequence,
we can end up in a partially or totally unlocked state indefinitely.

This should have occurred any time the device was re-locked during unlock.
However, the UnlockedScreenOffAnimation delays the pending lock until
after the animation ends. This meant that it was ~always applied after
the going away sequence had already ended.

Because we still can't smoothly animate from the shade to AOD, we disable
the unlocked screen off animation temporarily when the shade is expanded.
During an activity launch from a notification, we leave the shade expanded
for the animation. This meant that the screen off animation was disabled
when the power button was pressed during activity launch, so we applied
the lock immediately, where it was subsequently re-unlocked by the launch
animator's end callbacks.

Fixes: 220907477
Test: atest SystemUITests
Test: No lock screen set, w/ AOD: PASS
Test: No lock screen set, no AOD: PASS
Test: Swipe, w/ AOD: PASS
Test: Swipe, no AOD: PASS
Test: PIN, w/ AOD: PASS
Test: PIN, no AOD: PASS
Test: PIN, w/ AOD, power button does not instantly lock, unlock in < 5s: PASS (does not lock)
Test: PIN, w/ AOD, power button does not instantly lock, unlock in > 5s: PASS
Test: PIN, no AOD, power button does not instantly lock, unlock in < 5s: PASS (does not lock)
Test: PIN, no AOD, power button does not instantly lock, unlock in > 5s: PASS
Test: UDFPS, w/ AOD: PASS
Test: UDFPS, no AOD: PASS
Change-Id: I5ca6f7be21f6c68471fb9e66f9fa1ee65d7ffaaf
parent cb2836e2
Loading
Loading
Loading
Loading
+44 −6
Original line number Original line Diff line number Diff line
@@ -123,11 +123,11 @@ import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -1237,14 +1237,52 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
    }
    }


    /**
    /**
     * Locks the keyguard if {@link #mPendingLock} is true, unless we're playing the screen off
     * Locks the keyguard if {@link #mPendingLock} is true, and there are no reasons to further
     * animation.
     * delay the pending lock.
     *
     *
     * If we are, we will lock the keyguard either when the screen off animation ends, or in
     * If you do delay handling the pending lock, you must ensure that this method is ALWAYS called
     * {@link #onStartedWakingUp} if the animation is cancelled.
     * again when the condition causing the delay changes. Otherwise, the device may remain unlocked
     * indefinitely.
     */
     */
    public void maybeHandlePendingLock() {
    public void maybeHandlePendingLock() {
        if (mPendingLock && !mScreenOffAnimationController.isKeyguardShowDelayed()) {
        if (mPendingLock) {

            // The screen off animation is playing, so if we lock now, the foreground app will
            // vanish and the keyguard will jump-cut in. Delay it, until either:
            //   - The screen off animation ends. We will call maybeHandlePendingLock from
            //     the end action in UnlockedScreenOffAnimationController#animateInKeyguard.
            //   - The screen off animation is cancelled by the device waking back up. We will call
            //     maybeHandlePendingLock from KeyguardViewMediator#onStartedWakingUp.
            if (mScreenOffAnimationController.isKeyguardShowDelayed()) {
                if (DEBUG) {
                    Log.d(TAG, "#maybeHandlePendingLock: not handling because the screen off "
                            + "animation's isKeyguardShowDelayed() returned true. This should be "
                            + "handled soon by #onStartedWakingUp, or by the end actions of the "
                            + "screen off animation.");
                }

                return;
            }

            // The device was re-locked while in the process of unlocking. If we lock now, callbacks
            // in the unlock sequence might end up re-unlocking the device. Delay the lock until the
            // keyguard is done going away. We'll call maybeHandlePendingLock again in
            // StatusBar#finishKeyguardFadingAway, which is always responsible for setting
            // isKeyguardGoingAway to false.
            if (mKeyguardStateController.isKeyguardGoingAway()) {
                if (DEBUG) {
                    Log.d(TAG, "#maybeHandlePendingLock: not handling because the keyguard is "
                            + "going away. This should be handled shortly by "
                            + "StatusBar#finishKeyguardFadingAway.");
                }

                return;
            }

            if (DEBUG) {
                Log.d(TAG, "#maybeHandlePendingLock: handling pending lock; locking keyguard.");
            }

            doKeyguardLocked(null);
            doKeyguardLocked(null);
            mPendingLock = false;
            mPendingLock = false;
        }
        }
+4 −0
Original line number Original line Diff line number Diff line
@@ -3126,6 +3126,10 @@ public class CentralSurfaces extends CoreStartable implements
    public void finishKeyguardFadingAway() {
    public void finishKeyguardFadingAway() {
        mKeyguardStateController.notifyKeyguardDoneFading();
        mKeyguardStateController.notifyKeyguardDoneFading();
        mScrimController.setExpansionAffectsAlpha(true);
        mScrimController.setExpansionAffectsAlpha(true);

        // If the device was re-locked while unlocking, we might have a pending lock that was
        // delayed because the keyguard was in the middle of going away.
        mKeyguardViewMediator.maybeHandlePendingLock();
    }
    }


    /**
    /**