Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ec9bcc4 authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge "Don't make smartspace INVISIBLE unless it will be animated" into main

parents 11afee8d c9e0f9f8
Loading
Loading
Loading
Loading
+318 −236

File changed.

Preview size limit exceeded, changes collapsed.

+213 −122
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argThat
import com.android.systemui.util.mockito.whenever
import java.util.function.Predicate
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
@@ -46,7 +47,6 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.clearInvocations
import java.util.function.Predicate

@RunWith(AndroidJUnit4::class)
@RunWithLooper
@@ -54,70 +54,134 @@ import java.util.function.Predicate
class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
    private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController

    @Mock
    private lateinit var windowManager: WindowManager
    @Mock
    private lateinit var keyguardViewMediator: KeyguardViewMediator
    @Mock
    private lateinit var keyguardStateController: KeyguardStateController
    @Mock
    private lateinit var keyguardViewController: KeyguardViewController
    @Mock
    private lateinit var featureFlags: FeatureFlags
    @Mock
    private lateinit var biometricUnlockController: BiometricUnlockController
    @Mock
    private lateinit var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier
    @Mock
    private lateinit var statusBarStateController: SysuiStatusBarStateController
    @Mock
    private lateinit var notificationShadeWindowController: NotificationShadeWindowController
    @Mock
    private lateinit var powerManager: PowerManager
    @Mock
    private lateinit var wallpaperManager: WallpaperManager
    @Mock private lateinit var windowManager: WindowManager
    @Mock private lateinit var keyguardViewMediator: KeyguardViewMediator
    @Mock private lateinit var keyguardStateController: KeyguardStateController
    @Mock private lateinit var keyguardViewController: KeyguardViewController
    @Mock private lateinit var featureFlags: FeatureFlags
    @Mock private lateinit var biometricUnlockController: BiometricUnlockController
    @Mock private lateinit var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier
    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
    @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
    @Mock private lateinit var powerManager: PowerManager
    @Mock private lateinit var wallpaperManager: WallpaperManager

    @Mock
    private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub

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

    private var surfaceControlWp = mock(SurfaceControl::class.java)
    private var wallpaperTarget = RemoteAnimationTarget(
            2 /* taskId */, 0, surfaceControlWp, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
            mock(WindowConfiguration::class.java), false, surfaceControlWp, Rect(),
            mock(ActivityManager.RunningTaskInfo::class.java), false)
    private var wallpaperTarget =
        RemoteAnimationTarget(
            2 /* taskId */,
            0,
            surfaceControlWp,
            false,
            Rect(),
            Rect(),
            0,
            Point(),
            Rect(),
            Rect(),
            mock(WindowConfiguration::class.java),
            false,
            surfaceControlWp,
            Rect(),
            mock(ActivityManager.RunningTaskInfo::class.java),
            false
        )
    private lateinit var wallpaperTargets: Array<RemoteAnimationTarget>

    private var surfaceControlLockWp = mock(SurfaceControl::class.java)
    private var lockWallpaperTarget = RemoteAnimationTarget(
            3 /* taskId */, 0, surfaceControlLockWp, false, Rect(), Rect(), 0, Point(), Rect(),
            Rect(), mock(WindowConfiguration::class.java), false, surfaceControlLockWp,
            Rect(), mock(ActivityManager.RunningTaskInfo::class.java), false)
    private var lockWallpaperTarget =
        RemoteAnimationTarget(
            3 /* taskId */,
            0,
            surfaceControlLockWp,
            false,
            Rect(),
            Rect(),
            0,
            Point(),
            Rect(),
            Rect(),
            mock(WindowConfiguration::class.java),
            false,
            surfaceControlLockWp,
            Rect(),
            mock(ActivityManager.RunningTaskInfo::class.java),
            false
        )
    private lateinit var lockWallpaperTargets: Array<RemoteAnimationTarget>
    private var shouldPerformSmartspaceTransition = false

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        keyguardUnlockAnimationController = KeyguardUnlockAnimationController(
            windowManager, context.resources,
            keyguardStateController, { keyguardViewMediator }, keyguardViewController,
            featureFlags, { biometricUnlockController }, statusBarStateController,
            notificationShadeWindowController, powerManager, wallpaperManager
        )
        keyguardUnlockAnimationController =
            object :
                KeyguardUnlockAnimationController(
                    windowManager,
                    context.resources,
                    keyguardStateController,
                    { keyguardViewMediator },
                    keyguardViewController,
                    featureFlags,
                    { biometricUnlockController },
                    statusBarStateController,
                    notificationShadeWindowController,
                    powerManager,
                    wallpaperManager
                ) {
                override fun shouldPerformSmartspaceTransition(): Boolean =
                    shouldPerformSmartspaceTransition
            }
        keyguardUnlockAnimationController.setLauncherUnlockController(
            "", launcherUnlockAnimationController)
            "",
            launcherUnlockAnimationController
        )

        whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java))
        whenever(powerManager.isInteractive).thenReturn(true)
@@ -159,8 +223,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        )

        val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, times(1)).scheduleApply(
                captorSb.capture { sp -> sp.surface == surfaceControl1 })
        verify(surfaceTransactionApplier, times(1))
            .scheduleApply(captorSb.capture { sp -> sp.surface == surfaceControl1 })

        val params = captorSb.getLastValue()

@@ -171,15 +235,13 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {

        // Also expect we've immediately asked the keyguard view mediator to finish the remote
        // animation.
        verify(keyguardViewMediator, times(1)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
            false /* cancelled */)
        verify(keyguardViewMediator, times(1))
            .exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* cancelled */)

        verifyNoMoreInteractions(surfaceTransactionApplier)
    }

    /**
     * If we are not wake and unlocking, we expect the unlock animation to play normally.
     */
    /** If we are not wake and unlocking, we expect the unlock animation to play normally. */
    @Test
    fun surfaceAnimation_ifNotWakeAndUnlocking() {
        whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(false)
@@ -193,18 +255,18 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        )

        // Since the animation is running, we should not have finished the remote animation.
        verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
            false /* cancelled */)
        verify(keyguardViewMediator, times(0))
            .exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* cancelled */)
    }

    @Test
    fun onWakeAndUnlock_notifiesListenerWithTrue() {
        whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
        whenever(biometricUnlockController.mode).thenReturn(
            BiometricUnlockController.MODE_WAKE_AND_UNLOCK)
        whenever(biometricUnlockController.mode)
            .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK)

        val listener = mock(
            KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener::class.java)
        val listener =
            mock(KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener::class.java)
        keyguardUnlockAnimationController.addKeyguardUnlockAnimationListener(listener)

        keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
@@ -221,11 +283,11 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
    @Test
    fun onWakeAndUnlockFromDream_notifiesListenerWithFalse() {
        whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
        whenever(biometricUnlockController.mode).thenReturn(
            BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM)
        whenever(biometricUnlockController.mode)
            .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM)

        val listener = mock(
            KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener::class.java)
        val listener =
            mock(KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener::class.java)
        keyguardUnlockAnimationController.addKeyguardUnlockAnimationListener(listener)

        keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
@@ -269,8 +331,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
     * 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.
     * 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() {
@@ -293,8 +355,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
     * 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.
     * 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() {
@@ -367,9 +429,12 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
            keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(amount)

            val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
            verify(surfaceTransactionApplier, times(2)).scheduleApply(
            verify(surfaceTransactionApplier, times(2))
                .scheduleApply(
                    captorSb.capture { sp ->
                        sp.surface == surfaceControlWp || sp.surface == surfaceControlLockWp })
                        sp.surface == surfaceControlWp || sp.surface == surfaceControlLockWp
                    }
                )

            val fadeInAlpha = captorSb.getLastValue { it.surface == surfaceControlWp }.alpha
            val fadeOutAlpha = captorSb.getLastValue { it.surface == surfaceControlLockWp }.alpha
@@ -389,9 +454,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        }
    }

    /**
     * If we are not wake and unlocking, we expect the unlock animation to play normally.
     */
    /** If we are not wake and unlocking, we expect the unlock animation to play normally. */
    @Test
    @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun surfaceAnimation_multipleTargets() {
@@ -412,12 +475,18 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(0.5f)

        val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, times(2)).scheduleApply(captorSb
                .capture { sp -> sp.surface == surfaceControl1 || sp.surface == surfaceControl2 })
        verify(surfaceTransactionApplier, times(2))
            .scheduleApply(
                captorSb.capture { sp ->
                    sp.surface == surfaceControl1 || sp.surface == surfaceControl2
                }
            )
        val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, times(1).description(
                "WallpaperSurface was expected to receive scheduleApply once"
        )).scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp})
        verify(
                surfaceTransactionApplier,
                times(1).description("WallpaperSurface was expected to receive scheduleApply once")
            )
            .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp })

        val allParams = captorSb.getAllValues()

@@ -432,8 +501,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        assertTrue(remainingTargets.isEmpty())

        // Since the animation is running, we should not have finished the remote animation.
        verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                false /* cancelled */)
        verify(keyguardViewMediator, times(0))
            .exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* cancelled */)
    }

    @Test
@@ -457,12 +526,14 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        keyguardUnlockAnimationController.setWallpaperAppearAmount(1f, wallpaperTargets)

        val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, times(1)).scheduleApply(
                captorSb.capture { sp -> sp.surface == surfaceControl1})
        verify(surfaceTransactionApplier, times(1))
            .scheduleApply(captorSb.capture { sp -> sp.surface == surfaceControl1 })
        val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, atLeastOnce().description("Wallpaper surface has  not " +
                "received scheduleApply")).scheduleApply(
                captorWp.capture { sp -> sp.surface == surfaceControlWp })
        verify(
                surfaceTransactionApplier,
                atLeastOnce().description("Wallpaper surface has  not " + "received scheduleApply")
            )
            .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp })

        val params = captorSb.getLastValue()

@@ -494,24 +565,31 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        keyguardUnlockAnimationController.setWallpaperAppearAmount(1f, wallpaperTargets)

        val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, times(1)).scheduleApply(
                captorSb.capture { sp -> sp.surface == surfaceControl1 })
        verify(surfaceTransactionApplier, times(1))
            .scheduleApply(captorSb.capture { sp -> sp.surface == surfaceControl1 })
        val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
        verify(surfaceTransactionApplier, atLeastOnce().description("Wallpaper surface has  not " +
                "received scheduleApply")).scheduleApply(
                captorWp.capture { sp -> sp.surface == surfaceControlWp })
        verify(
                surfaceTransactionApplier,
                atLeastOnce().description("Wallpaper surface has  not " + "received scheduleApply")
            )
            .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp })

        val params = captorSb.getLastValue()
        assertEquals(1f, params.alpha)
        assertTrue(params.matrix.isIdentity)
        assertEquals("Wallpaper surface was expected to have opacity 1",
                1f, captorWp.getLastValue().alpha)
        assertEquals(
            "Wallpaper surface was expected to have opacity 1",
            1f,
            captorWp.getLastValue().alpha
        )

        verifyNoMoreInteractions(surfaceTransactionApplier)
    }

    @Test
    fun unlockToLauncherWithInWindowAnimations_ssViewIsVisible() {
    fun unlockToLauncherWithInWindowAnimations_ssViewInVisible_whenPerformSSTransition() {
        shouldPerformSmartspaceTransition = true

        val mockLockscreenSmartspaceView = mock(View::class.java)
        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.VISIBLE)
        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
@@ -521,6 +599,19 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        verify(mockLockscreenSmartspaceView).visibility = View.INVISIBLE
    }

    @Test
    fun unlockToLauncherWithInWindowAnimations_ssViewVisible_whenNotPerformSSTransition() {
        shouldPerformSmartspaceTransition = false

        val mockLockscreenSmartspaceView = mock(View::class.java)
        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.VISIBLE)
        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView

        keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()

        verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE
    }

    @Test
    fun unlockToLauncherWithInWindowAnimations_ssViewIsInvisible() {
        val mockLockscreenSmartspaceView = mock(View::class.java)