From 7a563cf478a3746ec105e6744e2c5a7b116a015b Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Tue, 15 Mar 2022 15:21:37 -0400 Subject: [PATCH] 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 --- .../keyguard/KeyguardViewMediator.java | 50 ++++++++++++++++--- .../statusbar/phone/CentralSurfaces.java | 4 ++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 736e2e0e4035b..91b5a229c47ee 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -123,11 +123,11 @@ import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SysuiStatusBarStateController; 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.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; 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.policy.KeyguardStateController; 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 - * animation. + * Locks the keyguard if {@link #mPendingLock} is true, and there are no reasons to further + * delay the pending lock. * - * If we are, we will lock the keyguard either when the screen off animation ends, or in - * {@link #onStartedWakingUp} if the animation is cancelled. + * If you do delay handling the pending lock, you must ensure that this method is ALWAYS called + * again when the condition causing the delay changes. Otherwise, the device may remain unlocked + * indefinitely. */ 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); mPendingLock = false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index ec2d608b26833..cf305e25ae146 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -3126,6 +3126,10 @@ public class CentralSurfaces extends CoreStartable implements public void finishKeyguardFadingAway() { mKeyguardStateController.notifyKeyguardDoneFading(); 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(); } /**