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

Commit cdc2faeb authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix stuck unlock animation state" into main

parents ef90b94e dcdd876c
Loading
Loading
Loading
Loading
+25 −19
Original line number Diff line number Diff line
@@ -929,28 +929,41 @@ class KeyguardUnlockAnimationController @Inject constructor(

    /**
     * Called by [KeyguardViewMediator] to let us know that the remote animation has finished, and
     * we should clean up all of our state.
     * we should clean up all of our state. [showKeyguard] will tell us which surface should be
     * visible after the animation has been completed or canceled.
     *
     * This is generally triggered by us, calling
     * [KeyguardViewMediator.finishSurfaceBehindRemoteAnimation].
     */
    fun notifyFinishedKeyguardExitAnimation(cancelled: Boolean) {
    fun notifyFinishedKeyguardExitAnimation(showKeyguard: Boolean) {
        // Cancel any pending actions.
        handler.removeCallbacksAndMessages(null)

        // The lockscreen surface is gone, so it is now safe to re-show the smartspace.
        if (lockscreenSmartspace?.visibility == View.INVISIBLE) {
            lockscreenSmartspace?.visibility = View.VISIBLE
        }

        if (!showKeyguard) {
            // Make sure we made the surface behind fully visible, just in case. It should already be
            // fully visible. The exit animation is finished, and we should not hold the leash anymore,
            // so forcing it to 1f.
            surfaceBehindAlpha = 1f
            setSurfaceBehindAppearAmount(1f)
        surfaceBehindAlphaAnimator.cancel()
        surfaceBehindEntryAnimator.cancel()
        wallpaperCannedUnlockAnimator.cancel()

            try {
                launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
            } catch (e: RemoteException) {
                Log.e(TAG, "Remote exception in notifyFinishedKeyguardExitAnimation", e)
            }
        }

        listeners.forEach { it.onUnlockAnimationFinished() }

        // Reset all state
        surfaceBehindAlphaAnimator.cancel()
        surfaceBehindEntryAnimator.cancel()
        wallpaperCannedUnlockAnimator.cancel()

        // That target is no longer valid since the animation finished, null it out.
        surfaceBehindRemoteAnimationTargets = null
@@ -960,13 +973,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
        dismissAmountThresholdsReached = false
        willUnlockWithInWindowLauncherAnimations = false
        willUnlockWithSmartspaceTransition = false

        // The lockscreen surface is gone, so it is now safe to re-show the smartspace.
        if (lockscreenSmartspace?.visibility == View.INVISIBLE) {
            lockscreenSmartspace?.visibility = View.VISIBLE
        }

        listeners.forEach { it.onUnlockAnimationFinished() }
    }

    /**
+13 −11
Original line number Diff line number Diff line
@@ -2561,7 +2561,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
        } else if (mSurfaceBehindRemoteAnimationRunning) {
            // We're already running the keyguard exit animation, likely due to an in-progress swipe
            // to unlock.
           exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* cancelled */);
            exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* showKeyguard */);
        } else if (!mHideAnimationRun) {
            if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
            mHideAnimationRun = true;
@@ -3003,7 +3003,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                mContext.getMainExecutor().execute(() -> {
                    if (finishedCallback == null) {
                        mKeyguardUnlockAnimationControllerLazy.get()
                                .notifyFinishedKeyguardExitAnimation(false /* cancelled */);
                                .notifyFinishedKeyguardExitAnimation(false /* showKeyguard */);
                        mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                        return;
                    }
@@ -3120,7 +3120,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
            // A lock is pending, meaning the keyguard exit animation was cancelled because we're
            // re-locking. We should just end the surface-behind animation without exiting the
            // keyguard. The pending lock will be handled by onFinishedGoingToSleep().
            finishSurfaceBehindRemoteAnimation(true);
            finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
            maybeHandlePendingLock();
        } else {
            Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
@@ -3129,7 +3129,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
            // No lock is pending, so the animation was cancelled during the unlock sequence, but
            // we should end up unlocked. Show the surface and exit the keyguard.
            showSurfaceBehindKeyguard();
            exitKeyguardAndFinishSurfaceBehindRemoteAnimation(true /* cancelled */);
            exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* showKeyguard */);
        }
    }

@@ -3140,12 +3140,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
     * with the RemoteAnimation, actually hide the keyguard, and clean up state related to the
     * keyguard exit animation.
     *
     * @param cancelled {@code true} if the animation was cancelled before it finishes.
     * @param showKeyguard {@code true} if the animation was cancelled and keyguard should remain
     *                        visible
     */
    public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean cancelled) {
    public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean showKeyguard) {
        Log.d(TAG, "onKeyguardExitRemoteAnimationFinished");
        if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
            Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished cancelled=" + cancelled
            Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished showKeyguard=" + showKeyguard
                    + " surfaceAnimationRunning=" + mSurfaceBehindRemoteAnimationRunning
                    + " surfaceAnimationRequested=" + mSurfaceBehindRemoteAnimationRequested);
            return;
@@ -3170,9 +3171,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                        + " wasShowing=" + wasShowing);
            }

            mKeyguardUnlockAnimationControllerLazy.get()
                    .notifyFinishedKeyguardExitAnimation(cancelled);
            finishSurfaceBehindRemoteAnimation(cancelled);
            finishSurfaceBehindRemoteAnimation(showKeyguard);

            // Dispatch the callback on animation finishes.
            mUpdateMonitor.dispatchKeyguardDismissAnimationFinished();
@@ -3236,7 +3235,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
     * This does not set keyguard state to either locked or unlocked, it simply ends the remote
     * animation on the surface behind the keyguard. This can be called by
     */
    void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
    void finishSurfaceBehindRemoteAnimation(boolean showKeyguard) {
        mKeyguardUnlockAnimationControllerLazy.get()
                .notifyFinishedKeyguardExitAnimation(showKeyguard);

        mSurfaceBehindRemoteAnimationRequested = false;
        mSurfaceBehindRemoteAnimationRunning = false;
        mKeyguardStateController.notifyKeyguardGoingAway(false);
+1 −0
Original line number Diff line number Diff line
@@ -508,6 +508,7 @@ public class NotificationShadeWindowViewController {
                        MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
                event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
            }
            Log.w(TAG, "Canceling current touch event (should be very rare)");
            mView.dispatchTouchEvent(event);
            event.recycle();
            mTouchCancelled = true;
+11 −1
Original line number Diff line number Diff line
@@ -634,6 +634,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        TestableLooper.get(this).processAllMessages();

        assertFalse(mViewMediator.isShowingAndNotOccluded());
        verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
    }

    @Test
@@ -650,6 +651,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        TestableLooper.get(this).processAllMessages();

        assertTrue(mViewMediator.isShowingAndNotOccluded());
        verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(true);
    }

    @Test
@@ -658,6 +660,9 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        startMockKeyguardExitAnimation();
        cancelMockKeyguardExitAnimation();

        // Calling cancel above results in keyguard not visible, as there is no pending lock
        verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);

        mViewMediator.maybeHandlePendingLock();
        TestableLooper.get(this).processAllMessages();

@@ -672,10 +677,15 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimation() {
    public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimationAndExits() {
        startMockKeyguardExitAnimation();
        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());

        mViewMediator.mViewMediatorCallback.keyguardDonePending(true,
                mUpdateMonitor.getCurrentUser());
        mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
        TestableLooper.get(this).processAllMessages();
        verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
    }

    @Test