Loading packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +12 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.Context import android.graphics.Matrix import android.graphics.Rect import android.os.Handler import android.os.PowerManager import android.os.RemoteException import android.util.Log import android.view.RemoteAnimationTarget Loading Loading @@ -145,7 +146,8 @@ class KeyguardUnlockAnimationController @Inject constructor( private val featureFlags: FeatureFlags, private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, private val statusBarStateController: SysuiStatusBarStateController, private val notificationShadeWindowController: NotificationShadeWindowController private val notificationShadeWindowController: NotificationShadeWindowController, private val powerManager: PowerManager ) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() { interface KeyguardUnlockAnimationListener { Loading Loading @@ -784,10 +786,15 @@ class KeyguardUnlockAnimationController @Inject constructor( surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y ) val animationAlpha = when { // If we're snapping the keyguard back, immediately begin fading it out. val animationAlpha = if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount else surfaceBehindAlpha keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount // If the screen has turned back off, the unlock animation is going to be cancelled, // so set the surface alpha to 0f so it's no longer visible. !powerManager.isInteractive -> 0f else -> surfaceBehindAlpha } // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is // unable to draw Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt +65 −8 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.app.ActivityManager import android.app.WindowConfiguration import android.graphics.Point import android.graphics.Rect import android.os.PowerManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.RemoteAnimationTarget Loading @@ -19,15 +20,16 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.whenever import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.After import org.junit.Before 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 Loading Loading @@ -56,6 +58,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { private lateinit var statusBarStateController: SysuiStatusBarStateController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var powerManager: PowerManager @Mock private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub Loading @@ -79,12 +83,13 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { keyguardUnlockAnimationController = KeyguardUnlockAnimationController( context, keyguardStateController, { keyguardViewMediator }, keyguardViewController, featureFlags, { biometricUnlockController }, statusBarStateController, notificationShadeWindowController notificationShadeWindowController, powerManager ) keyguardUnlockAnimationController.setLauncherUnlockController( launcherUnlockAnimationController) `when`(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) whenever(powerManager.isInteractive).thenReturn(true) // 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. Loading @@ -96,6 +101,12 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { keyguardUnlockAnimationController.surfaceTransactionApplier = surfaceTransactionApplier } @After fun tearDown() { keyguardUnlockAnimationController.surfaceBehindEntryAnimator.cancel() keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.cancel() } /** * If we're wake and unlocking, we are animating from the black/AOD screen to the app/launcher * underneath. The LightRevealScrim will animate circularly from the fingerprint reader, Loading @@ -104,7 +115,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun noSurfaceAnimation_ifWakeAndUnlocking() { `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading Loading @@ -135,7 +146,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun surfaceAnimation_ifNotWakeAndUnlocking() { `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(false) whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading @@ -159,7 +170,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun fadeInSurfaceBehind_ifRequestedShowSurface_butNotFlinging() { `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false) whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading @@ -181,7 +192,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun playCannedUnlockAnimation_ifRequestedShowSurface_andFlinging() { `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true) whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading Loading @@ -215,7 +226,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { @Test fun doNotPlayCannedUnlockAnimation_ifLaunchingApp() { `when`(notificationShadeWindowController.isLaunchingActivity).thenReturn(true) whenever(notificationShadeWindowController.isLaunchingActivity).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading Loading @@ -275,4 +286,50 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) } @Test fun surfaceBehindAlphaOverriddenTo0_ifNotInteractive() { whenever(powerManager.isInteractive).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, 0 /* startTime */, false /* requestedShowSurfaceBehindKeyguard */ ) keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f) val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java) verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture()) val params = captor.value // We expect that we've set the surface behind to alpha = 0f since we're not interactive. assertEquals(params.alpha, 0f) assertTrue(params.matrix.isIdentity) verifyNoMoreInteractions(surfaceTransactionApplier) } @Test fun surfaceBehindAlphaNotOverriddenTo0_ifInteractive() { whenever(powerManager.isInteractive).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, 0 /* startTime */, false /* requestedShowSurfaceBehindKeyguard */ ) keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f) val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java) verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture()) val params = captor.value assertEquals(params.alpha, 1f) assertTrue(params.matrix.isIdentity) verifyNoMoreInteractions(surfaceTransactionApplier) } } Loading
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +12 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.Context import android.graphics.Matrix import android.graphics.Rect import android.os.Handler import android.os.PowerManager import android.os.RemoteException import android.util.Log import android.view.RemoteAnimationTarget Loading Loading @@ -145,7 +146,8 @@ class KeyguardUnlockAnimationController @Inject constructor( private val featureFlags: FeatureFlags, private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, private val statusBarStateController: SysuiStatusBarStateController, private val notificationShadeWindowController: NotificationShadeWindowController private val notificationShadeWindowController: NotificationShadeWindowController, private val powerManager: PowerManager ) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() { interface KeyguardUnlockAnimationListener { Loading Loading @@ -784,10 +786,15 @@ class KeyguardUnlockAnimationController @Inject constructor( surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y ) val animationAlpha = when { // If we're snapping the keyguard back, immediately begin fading it out. val animationAlpha = if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount else surfaceBehindAlpha keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount // If the screen has turned back off, the unlock animation is going to be cancelled, // so set the surface alpha to 0f so it's no longer visible. !powerManager.isInteractive -> 0f else -> surfaceBehindAlpha } // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is // unable to draw Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt +65 −8 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.app.ActivityManager import android.app.WindowConfiguration import android.graphics.Point import android.graphics.Rect import android.os.PowerManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.RemoteAnimationTarget Loading @@ -19,15 +20,16 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.whenever import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.After import org.junit.Before 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 Loading Loading @@ -56,6 +58,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { private lateinit var statusBarStateController: SysuiStatusBarStateController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var powerManager: PowerManager @Mock private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub Loading @@ -79,12 +83,13 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { keyguardUnlockAnimationController = KeyguardUnlockAnimationController( context, keyguardStateController, { keyguardViewMediator }, keyguardViewController, featureFlags, { biometricUnlockController }, statusBarStateController, notificationShadeWindowController notificationShadeWindowController, powerManager ) keyguardUnlockAnimationController.setLauncherUnlockController( launcherUnlockAnimationController) `when`(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) whenever(powerManager.isInteractive).thenReturn(true) // 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. Loading @@ -96,6 +101,12 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { keyguardUnlockAnimationController.surfaceTransactionApplier = surfaceTransactionApplier } @After fun tearDown() { keyguardUnlockAnimationController.surfaceBehindEntryAnimator.cancel() keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.cancel() } /** * If we're wake and unlocking, we are animating from the black/AOD screen to the app/launcher * underneath. The LightRevealScrim will animate circularly from the fingerprint reader, Loading @@ -104,7 +115,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun noSurfaceAnimation_ifWakeAndUnlocking() { `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading Loading @@ -135,7 +146,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun surfaceAnimation_ifNotWakeAndUnlocking() { `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(false) whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading @@ -159,7 +170,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun fadeInSurfaceBehind_ifRequestedShowSurface_butNotFlinging() { `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false) whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading @@ -181,7 +192,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun playCannedUnlockAnimation_ifRequestedShowSurface_andFlinging() { `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true) whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading Loading @@ -215,7 +226,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { @Test fun doNotPlayCannedUnlockAnimation_ifLaunchingApp() { `when`(notificationShadeWindowController.isLaunchingActivity).thenReturn(true) whenever(notificationShadeWindowController.isLaunchingActivity).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, Loading Loading @@ -275,4 +286,50 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) } @Test fun surfaceBehindAlphaOverriddenTo0_ifNotInteractive() { whenever(powerManager.isInteractive).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, 0 /* startTime */, false /* requestedShowSurfaceBehindKeyguard */ ) keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f) val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java) verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture()) val params = captor.value // We expect that we've set the surface behind to alpha = 0f since we're not interactive. assertEquals(params.alpha, 0f) assertTrue(params.matrix.isIdentity) verifyNoMoreInteractions(surfaceTransactionApplier) } @Test fun surfaceBehindAlphaNotOverriddenTo0_ifInteractive() { whenever(powerManager.isInteractive).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, 0 /* startTime */, false /* requestedShowSurfaceBehindKeyguard */ ) keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f) val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java) verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture()) val params = captor.value assertEquals(params.alpha, 1f) assertTrue(params.matrix.isIdentity) verifyNoMoreInteractions(surfaceTransactionApplier) } }