summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt66
2 files changed, 85 insertions, 8 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index a8c286241141..c90fa4db1588 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -259,7 +259,9 @@ class KeyguardUnlockAnimationController @Inject constructor(
* animation plays.
*/
private var surfaceBehindAlpha = 1f
- private var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
+
+ @VisibleForTesting
+ var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
private var smartspaceAnimator = ValueAnimator.ofFloat(0f, 1f)
/**
@@ -422,12 +424,22 @@ class KeyguardUnlockAnimationController @Inject constructor(
surfaceBehindRemoteAnimationTarget = target
surfaceBehindRemoteAnimationStartTime = startTime
- // If we specifically requested that the surface behind be made visible, it means we are
- // swiping to unlock. In that case, the surface visibility is tied to the dismiss amount,
- // and we'll handle that in onKeyguardDismissAmountChanged(). If we didn't request that, the
- // keyguard is being dismissed for a different reason (biometric auth, etc.) and we should
- // play a canned animation to make the surface fully visible.
- if (!requestedShowSurfaceBehindKeyguard) {
+ // If we specifically requested that the surface behind be made visible (vs. it being made
+ // visible because we're unlocking), then we're in the middle of a swipe-to-unlock touch
+ // gesture and the surface behind the keyguard should be made visible.
+ if (requestedShowSurfaceBehindKeyguard) {
+ // Fade in the surface, as long as we're not now flinging. The touch gesture ending in
+ // a fling during the time it takes the keyguard exit animation to start is an edge
+ // case race condition, and we'll handle it by playing a canned animation on the
+ // now-visible surface to finish unlocking.
+ if (!keyguardStateController.isFlingingToDismissKeyguard) {
+ fadeInSurfaceBehind()
+ } else {
+ playCannedUnlockAnimation()
+ }
+ } else {
+ // The surface was made visible since we're unlocking not from a swipe (fingerprint,
+ // lock icon long-press, etc). Play the full unlock animation.
playCannedUnlockAnimation()
}
@@ -786,7 +798,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
prepareLauncherWorkspaceForUnlockAnimation()
}
keyguardViewMediator.get().showSurfaceBehindKeyguard()
- fadeInSurfaceBehind()
} else if (dismissAmount < DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
// We're no longer past the threshold but we are showing the surface. Animate it
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index fb1a968acceb..2d8c4d5dceb0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -17,6 +17,7 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.policy.KeyguardStateController
import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@@ -125,4 +126,69 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
false /* cancelled */)
}
+
+ /**
+ * If we requested that the surface behind be made visible, and we're not flinging away the
+ * keyguard, it means that we're swiping to unlock and want the surface visible so it can follow
+ * the user's touch event as they swipe to unlock.
+ *
+ * In this case, we should verify that the surface was made visible via the alpha fade in
+ * animator, and verify that we did not start the canned animation to animate the surface in
+ * (since it's supposed to be following the touch events).
+ */
+ @Test
+ fun fadeInSurfaceBehind_ifRequestedShowSurface_butNotFlinging() {
+ `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false)
+
+ keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+ remoteAnimationTarget,
+ 0 /* startTime */,
+ true /* requestedShowSurfaceBehindKeyguard */
+ )
+
+ assertTrue(keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.isRunning)
+ assertFalse(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
+ }
+
+ /**
+ * We requested the surface behind to be made visible, but we're now flinging to dismiss the
+ * keyguard. This means this was a swipe to dismiss gesture but the user flung the keyguard and
+ * lifted their finger while we were requesting the surface be made visible.
+ *
+ * In this case, we should verify that we are playing the canned unlock animation and not
+ * simply fading in the surface.
+ */
+ @Test
+ fun playCannedUnlockAnimation_ifRequestedShowSurface_andFlinging() {
+ `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true)
+
+ keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+ remoteAnimationTarget,
+ 0 /* startTime */,
+ true /* requestedShowSurfaceBehindKeyguard */
+ )
+
+ assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
+ assertFalse(keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.isRunning)
+ }
+
+ /**
+ * We never requested the surface behind to be made visible, which means no swiping to unlock
+ * ever happened and we're just playing the simple canned animation (happens via UDFPS unlock,
+ * long press on the lock icon, etc).
+ *
+ * In this case, we should verify that we are playing the canned unlock animation and not
+ * simply fading in the surface.
+ */
+ @Test
+ fun playCannedUnlockAnimation_ifDidNotRequestShowSurface() {
+ keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+ remoteAnimationTarget,
+ 0 /* startTime */,
+ false /* requestedShowSurfaceBehindKeyguard */
+ )
+
+ assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
+ assertFalse(keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.isRunning)
+ }
} \ No newline at end of file