Merge "Fix stuck unlock animation state" into udc-d1-dev

This commit is contained in:
Zheng Pan
2023-08-11 00:15:47 +00:00
committed by Android (Google) Code Review
4 changed files with 51 additions and 31 deletions

View File

@@ -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() }
}
/**

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}
/**