summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt121
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt69
3 files changed, 113 insertions, 87 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index bd75ab2adb54..6f38f4f53b7c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -241,9 +241,8 @@ class KeyguardUnlockAnimationController @Inject constructor(
*/
@VisibleForTesting
var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier? = null
- private var surfaceBehindRemoteAnimationTarget: RemoteAnimationTarget? = null
+ private var surfaceBehindRemoteAnimationTargets: Array<RemoteAnimationTarget>? = null
private var surfaceBehindRemoteAnimationStartTime: Long = 0
- private var surfaceBehindParams: SyncRtSurfaceTransactionApplier.SurfaceParams? = null
/**
* Alpha value applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
@@ -458,7 +457,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
* (fingerprint, tap, etc.) and the keyguard is going away.
*/
fun notifyStartSurfaceBehindRemoteAnimation(
- target: RemoteAnimationTarget,
+ targets: Array<RemoteAnimationTarget>,
startTime: Long,
requestedShowSurfaceBehindKeyguard: Boolean
) {
@@ -467,10 +466,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
keyguardViewController.viewRootImpl.view)
}
- // New animation, new params.
- surfaceBehindParams = null
-
- surfaceBehindRemoteAnimationTarget = target
+ surfaceBehindRemoteAnimationTargets = targets
surfaceBehindRemoteAnimationStartTime = startTime
// If we specifically requested that the surface behind be made visible (vs. it being made
@@ -597,7 +593,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
* keyguard dismiss amount and the method of dismissal.
*/
private fun updateSurfaceBehindAppearAmount() {
- if (surfaceBehindRemoteAnimationTarget == null) {
+ if (surfaceBehindRemoteAnimationTargets == null) {
return
}
@@ -715,63 +711,60 @@ class KeyguardUnlockAnimationController @Inject constructor(
* cancelled).
*/
fun setSurfaceBehindAppearAmount(amount: Float) {
- if (surfaceBehindRemoteAnimationTarget == null) {
- return
- }
+ surfaceBehindRemoteAnimationTargets?.forEach { surfaceBehindRemoteAnimationTarget ->
+ val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget.screenSpaceBounds.height()
+
+ var scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
+ (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
+ MathUtils.clamp(amount, 0f, 1f))
- // Otherwise, animate in the surface's scale/transltion.
- val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
-
- var scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
- (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
- MathUtils.clamp(amount, 0f, 1f))
-
- // If we're dismissing via swipe to the Launcher, we'll play in-window scale animations, so
- // don't also scale the window.
- if (keyguardStateController.isDismissingFromSwipe &&
- willUnlockWithInWindowLauncherAnimations) {
- scaleFactor = 1f
- }
-
- // Scale up from a point at the center-bottom of the surface.
- surfaceBehindMatrix.setScale(
- scaleFactor,
- scaleFactor,
- surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.width() / 2f,
- surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
- )
-
- // Translate up from the bottom.
- surfaceBehindMatrix.postTranslate(
- 0f,
- surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
- )
-
- // If we're snapping the keyguard back, immediately begin fading it out.
- val animationAlpha =
- if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
- else surfaceBehindAlpha
-
- // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is unable
- // to draw
- val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget?.leash
- if (keyguardViewController.viewRootImpl.view?.visibility != View.VISIBLE &&
- sc?.isValid == true) {
- with(SurfaceControl.Transaction()) {
- setMatrix(sc, surfaceBehindMatrix, tmpFloat)
- setCornerRadius(sc, roundedCornerRadius)
- setAlpha(sc, animationAlpha)
- apply()
+ // If we're dismissing via swipe to the Launcher, we'll play in-window scale animations,
+ // so don't also scale the window.
+ if (keyguardStateController.isDismissingFromSwipe &&
+ willUnlockWithInWindowLauncherAnimations) {
+ scaleFactor = 1f
}
- } else {
- applyParamsToSurface(
- SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
- surfaceBehindRemoteAnimationTarget!!.leash)
- .withMatrix(surfaceBehindMatrix)
- .withCornerRadius(roundedCornerRadius)
- .withAlpha(animationAlpha)
- .build()
+
+ // Translate up from the bottom.
+ surfaceBehindMatrix.setTranslate(
+ surfaceBehindRemoteAnimationTarget.screenSpaceBounds.left.toFloat(),
+ surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
)
+
+ // Scale up from a point at the center-bottom of the surface.
+ surfaceBehindMatrix.postScale(
+ scaleFactor,
+ scaleFactor,
+ keyguardViewController.viewRootImpl.width / 2f,
+ surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
+ )
+
+ // If we're snapping the keyguard back, immediately begin fading it out.
+ val animationAlpha =
+ if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
+ else surfaceBehindAlpha
+
+ // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
+ // unable to draw
+ val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget.leash
+ if (keyguardViewController.viewRootImpl.view?.visibility != View.VISIBLE &&
+ sc?.isValid == true) {
+ with(SurfaceControl.Transaction()) {
+ setMatrix(sc, surfaceBehindMatrix, tmpFloat)
+ setCornerRadius(sc, roundedCornerRadius)
+ setAlpha(sc, animationAlpha)
+ apply()
+ }
+ } else {
+ applyParamsToSurface(
+ SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
+ surfaceBehindRemoteAnimationTarget.leash)
+ .withMatrix(surfaceBehindMatrix)
+ .withCornerRadius(roundedCornerRadius)
+ .withAlpha(animationAlpha)
+ .build()
+ )
+ }
}
}
@@ -796,8 +789,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
// That target is no longer valid since the animation finished, null it out.
- surfaceBehindRemoteAnimationTarget = null
- surfaceBehindParams = null
+ surfaceBehindRemoteAnimationTargets = null
playingCannedUnlockAnimation = false
willUnlockWithInWindowLauncherAnimations = false
@@ -829,7 +821,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
surfaceTransactionApplier!!.scheduleApply(params)
- surfaceBehindParams = params
}
private fun fadeInSurfaceBehind() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d4e0f061ba06..5dcdb109aae8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2587,18 +2587,10 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mInteractionJankMonitor.begin(
createInteractionJankMonitorConf("DismissPanel"));
- // Apply the opening animation on root task if exists
- RemoteAnimationTarget aniTarget = apps[0];
- for (RemoteAnimationTarget tmpTarget : apps) {
- if (tmpTarget.taskId != -1 && !tmpTarget.hasAnimatingParent) {
- aniTarget = tmpTarget;
- break;
- }
- }
// Pass the surface and metadata to the unlock animation controller.
mKeyguardUnlockAnimationControllerLazy.get()
.notifyStartSurfaceBehindRemoteAnimation(
- aniTarget, startTime, mSurfaceBehindRemoteAnimationRequested);
+ apps, startTime, mSurfaceBehindRemoteAnimationRequested);
} else {
mInteractionJankMonitor.begin(
createInteractionJankMonitorConf("RemoteAnimationDisabled"));
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 eecbee56d203..a78c902a1f30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -27,11 +27,11 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor.forClass
import org.mockito.Mock
+import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -60,7 +60,18 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
@Mock
private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub
- private lateinit var remoteAnimationTarget: RemoteAnimationTarget
+ private var surfaceControl1 = mock(SurfaceControl::class.java)
+ private var remoteTarget1 = RemoteAnimationTarget(
+ 0 /* taskId */, 0, surfaceControl1, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
+ mock(WindowConfiguration::class.java), false, surfaceControl1, Rect(),
+ mock(ActivityManager.RunningTaskInfo::class.java), false)
+
+ private var surfaceControl2 = mock(SurfaceControl::class.java)
+ private var remoteTarget2 = RemoteAnimationTarget(
+ 1 /* taskId */, 0, surfaceControl2, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
+ mock(WindowConfiguration::class.java), false, surfaceControl2, Rect(),
+ mock(ActivityManager.RunningTaskInfo::class.java), false)
+ private lateinit var remoteAnimationTargets: Array<RemoteAnimationTarget>
@Before
fun setUp() {
@@ -77,10 +88,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
// All of these fields are final, so we can't mock them, but are needed so that the surface
// appear amount setter doesn't short circuit.
- remoteAnimationTarget = RemoteAnimationTarget(
- 0, 0, null, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
- mock(WindowConfiguration::class.java), false, mock(SurfaceControl::class.java), Rect(),
- mock(ActivityManager.RunningTaskInfo::class.java), false)
+ remoteAnimationTargets = arrayOf(remoteTarget1)
// Set the surface applier to our mock so that we can verify the arguments passed to it.
// This applier does not have any side effects within the unlock animation controller, so
@@ -99,7 +107,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -130,7 +138,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(false)
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -154,7 +162,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
`when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false)
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
true /* requestedShowSurfaceBehindKeyguard */
)
@@ -176,7 +184,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
`when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true)
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
true /* requestedShowSurfaceBehindKeyguard */
)
@@ -196,7 +204,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
@Test
fun playCannedUnlockAnimation_ifDidNotRequestShowSurface() {
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -210,7 +218,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
`when`(notificationShadeWindowController.isLaunchingActivity).thenReturn(true)
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
true /* requestedShowSurfaceBehindKeyguard */
)
@@ -225,11 +233,46 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
keyguardUnlockAnimationController.willUnlockWithInWindowLauncherAnimations = true
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
- remoteAnimationTarget,
+ remoteAnimationTargets,
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
}
+
+ /**
+ * If we are not wake and unlocking, we expect the unlock animation to play normally.
+ */
+ @Test
+ fun surfaceAnimation_multipleTargets() {
+ keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+ arrayOf(remoteTarget1, remoteTarget2),
+ 0 /* startTime */,
+ false /* requestedShowSurfaceBehindKeyguard */
+ )
+
+ // Set appear to 50%, we'll just verify that we're not applying the identity matrix which
+ // means an animation is in progress.
+ keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(0.5f)
+
+ val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java)
+ verify(surfaceTransactionApplier, times(2)).scheduleApply(captor.capture())
+
+ val allParams = captor.allValues
+
+ val remainingTargets = mutableListOf(surfaceControl1, surfaceControl2)
+ allParams.forEach { params ->
+ assertTrue(!params.matrix.isIdentity)
+ remainingTargets.remove(params.surface)
+ }
+
+ // Make sure we called applyParams with each of the surface controls once. The order does
+ // not matter, so don't explicitly check for that.
+ assertTrue(remainingTargets.isEmpty())
+
+ // Since the animation is running, we should not have finished the remote animation.
+ verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
+ false /* cancelled */)
+ }
}