diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 68e72c58972b3..4418740e545fa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -934,28 +934,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) - // 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) + // 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) + + 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() - try { - launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */) - } catch (e: RemoteException) { - Log.e(TAG, "Remote exception in notifyFinishedKeyguardExitAnimation", e) - } // That target is no longer valid since the animation finished, null it out. surfaceBehindRemoteAnimationTargets = null @@ -965,13 +978,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() } } /** diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 1a06b0184bc57..49ae876b677e0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2520,7 +2520,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; @@ -2966,7 +2966,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; } @@ -3083,7 +3083,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. " @@ -3092,7 +3092,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 */); } } @@ -3103,12 +3103,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; @@ -3133,9 +3134,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(); @@ -3199,7 +3198,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); diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 2f7644eb5c82d..c7a7d97aff4f8 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -499,6 +499,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; diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 34ea91b944149..cb2daca1fe974 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -480,6 +480,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertFalse(mViewMediator.isShowingAndNotOccluded()); + verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false); } @Test @@ -496,6 +497,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertTrue(mViewMediator.isShowingAndNotOccluded()); + verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(true); } @Test @@ -504,6 +506,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(); @@ -518,9 +523,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); } /**