From 0636c67de1723e4d8a7092797b3561215baf3564 Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Wed, 28 Sep 2022 15:00:39 -0400 Subject: Set unlockAmount = 1f when keyguardGoingAway = false. This is a fail-safe to fix the ongoing tiny launcher issue that has been reported but with no reliable repro steps. My best guess is that this involves occluding activities that also dismiss an already-unlocked keyguard (such as one unlocked by face auth), such that we prepare to unlock to Launcher but then never start the animation since we are already unlocked + Launcher is no longer underneath. I am able to force reproduce this by modifying canPerformInWindowAnimations to always return true, and then launching an occluding activity. This should be a safe fix as it only applies the unlockAmount = 1f if we think the keyguard is no longer going away and we've left the Launcher at unlockAmount < 1f. At the very least, the worst possible regression should be that we set unlockAmount = 1f at an inopportune time, cancelling the unlock animation but leaving the device in a good state. Fixes: 240906324 Test: always return true from canPerformInWindowAnimations and unlock Change-Id: Id9c0e6c66cd4995b817e7a145576c5424b6561e0 --- .../keyguard/KeyguardUnlockAnimationController.kt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 6f38f4f53b7c..5f96a3b56e27 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -284,6 +284,14 @@ class KeyguardUnlockAnimationController @Inject constructor( @VisibleForTesting var willUnlockWithInWindowLauncherAnimations: Boolean = false + /** + * Whether we called [ILauncherUnlockAnimationController.prepareForUnlock], but have not yet + * called [ILauncherUnlockAnimationController.playUnlockAnimation]. This is used exclusively for + * logging purposes to help track down bugs where the Launcher surface is prepared for unlock + * but then never animated. + */ + private var launcherPreparedForUnlock = false + /** * Whether we decided in [prepareForInWindowLauncherAnimations] that we are able to and want to * play the smartspace shared element animation. If true, @@ -375,6 +383,20 @@ class KeyguardUnlockAnimationController @Inject constructor( !isFoldable(context) } + /** + * Logging helper to log the conditions under which we decide to perform the in-window + * animations. This is used if we prepare to unlock but then somehow decide later to not play + * the animation, which would leave Launcher in a bad state. + */ + private fun logInWindowAnimationConditions() { + Log.wtf(TAG, "canPerformInWindowLauncherAnimations expected all of these to be true: ") + Log.wtf(TAG, " isNexusLauncherUnderneath: ${isNexusLauncherUnderneath()}") + Log.wtf(TAG, " !notificationShadeWindowController.isLaunchingActivity: " + + "${!notificationShadeWindowController.isLaunchingActivity}") + Log.wtf(TAG, " launcherUnlockController != null: ${launcherUnlockController != null}") + Log.wtf(TAG, " !isFoldable(context): ${!isFoldable(context)}") + } + /** * Called from [KeyguardStateController] to let us know that the keyguard going away state has * changed. @@ -384,6 +406,15 @@ class KeyguardUnlockAnimationController @Inject constructor( !statusBarStateController.leaveOpenOnKeyguardHide()) { prepareForInWindowLauncherAnimations() } + + // If the keyguard is no longer going away and we were unlocking with in-window animations, + // make sure that we've left the launcher at 100% unlocked. This is a fail-safe to prevent + // against "tiny launcher" and similar states where the launcher is left in the prepared to + // animate state. + if (!keyguardStateController.isKeyguardGoingAway && + willUnlockWithInWindowLauncherAnimations) { + launcherUnlockController?.setUnlockAmount(1f, true /* forceIfAnimating */) + } } /** @@ -437,6 +468,8 @@ class KeyguardUnlockAnimationController @Inject constructor( lockscreenSmartspaceBounds, /* lockscreenSmartspaceBounds */ selectedPage /* selectedPage */ ) + + launcherPreparedForUnlock = true } catch (e: RemoteException) { Log.e(TAG, "Remote exception in prepareForInWindowUnlockAnimations.", e) } @@ -495,6 +528,8 @@ class KeyguardUnlockAnimationController @Inject constructor( true, UNLOCK_ANIMATION_DURATION_MS + CANNED_UNLOCK_START_DELAY, 0 /* startDelay */) + + launcherPreparedForUnlock = false } else { // Otherwise, we're swiping in an app and should just fade it in. The swipe gesture // will translate it until the end of the swipe gesture. @@ -554,6 +589,12 @@ class KeyguardUnlockAnimationController @Inject constructor( surfaceBehindEntryAnimator.start() } } + + if (launcherPreparedForUnlock && !willUnlockWithInWindowLauncherAnimations) { + Log.wtf(TAG, "Launcher is prepared for unlock, so we should have started the " + + "in-window animation, however we apparently did not.") + logInWindowAnimationConditions() + } } /** @@ -569,6 +610,8 @@ class KeyguardUnlockAnimationController @Inject constructor( LAUNCHER_ICONS_ANIMATION_DURATION_MS /* duration */, CANNED_UNLOCK_START_DELAY /* startDelay */) + launcherPreparedForUnlock = false + // Now that the Launcher surface (with its smartspace positioned identically to ours) is // visible, hide our smartspace. lockscreenSmartspace?.visibility = View.INVISIBLE -- cgit v1.2.3-59-g8ed1b