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

Commit 0636c67d authored by Josh Tsuji's avatar Josh Tsuji
Browse files

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
parent 4e528edd
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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