Loading packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +25 −19 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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() } } /** Loading packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +13 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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. " Loading @@ -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 */); } } Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +11 −1 Original line number Diff line number Diff line Loading @@ -634,6 +634,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertFalse(mViewMediator.isShowingAndNotOccluded()); verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false); } @Test Loading @@ -650,6 +651,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertTrue(mViewMediator.isShowingAndNotOccluded()); verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(true); } @Test Loading @@ -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(); Loading @@ -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 Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +25 −19 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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() } } /** Loading
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +13 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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. " Loading @@ -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 */); } } Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +11 −1 Original line number Diff line number Diff line Loading @@ -634,6 +634,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertFalse(mViewMediator.isShowingAndNotOccluded()); verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false); } @Test Loading @@ -650,6 +651,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertTrue(mViewMediator.isShowingAndNotOccluded()); verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(true); } @Test Loading @@ -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(); Loading @@ -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 Loading