Loading packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt +143 −91 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneKey import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository Loading @@ -31,12 +30,17 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockSource import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeTransitionModel import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.shade.domain.interactor.enableSingleShade import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.ScrimState Loading @@ -47,10 +51,8 @@ import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlin.reflect.full.memberProperties import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.BeforeClass import org.junit.Test Loading @@ -63,6 +65,7 @@ import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(ParameterizedAndroidJunit4::class) @OptIn(ExperimentalCoroutinesApi::class) @EnableSceneContainer class ScrimStartableTest : SysuiTestCase() { Loading @@ -75,7 +78,7 @@ class ScrimStartableTest : SysuiTestCase() { id = 0, expectedState = ScrimState.KEYGUARD, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isAlternateBouncerVisible = true, isTransitioningAwayFromKeyguard = true, ), Loading @@ -84,90 +87,104 @@ class ScrimStartableTest : SysuiTestCase() { id = 1, expectedState = null, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isAlternateBouncerVisible = true, isTransitioningToShade = true, isTransitioningToShadeScene = true, ), ), TestSpec( id = 2, expectedState = ScrimState.BOUNCER, Preconditions(isOnKeyguard = true, isIdleOnBouncer = true), expectedState = null, Preconditions( isDeviceEntered = false, isAlternateBouncerVisible = true, isTransitioningToShadeOverlay = true, ), ), TestSpec( id = 3, expectedState = ScrimState.BOUNCER, Preconditions(isDeviceEntered = false, isIdleOnBouncer = true), ), TestSpec( id = 4, expectedState = ScrimState.BOUNCER_SCRIMMED, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isIdleOnBouncer = true, isBouncerScrimmingNeeded = true, ), ), TestSpec( id = 4, id = 5, expectedState = ScrimState.BRIGHTNESS_MIRROR, Preconditions(isOnKeyguard = true, isBrightnessMirrorVisible = true), Preconditions(isDeviceEntered = false, isBrightnessMirrorVisible = true), ), TestSpec( id = 5, id = 6, expectedState = ScrimState.BRIGHTNESS_MIRROR, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isIdleOnBouncer = true, isBiometricWakeAndUnlock = true, isBrightnessMirrorVisible = true, ), ), TestSpec( id = 6, id = 7, expectedState = ScrimState.SHADE_LOCKED, Preconditions(isOnKeyguard = true, isCurrentSceneShade = true), Preconditions(isDeviceEntered = false, isIdleOnShadeScene = true), ), TestSpec( id = 7, id = 8, expectedState = ScrimState.SHADE_LOCKED, Preconditions(isDeviceEntered = false, isIdleOnShadeOverlay = true), ), TestSpec( id = 9, expectedState = ScrimState.PULSING, Preconditions(isOnKeyguard = true, isDozing = true, isPulsing = true), Preconditions(isDeviceEntered = false, isDozing = true, isPulsing = true), ), TestSpec( id = 8, id = 10, expectedState = ScrimState.OFF, Preconditions(isOnKeyguard = true, hasPendingScreenOffCallback = true), Preconditions(isDeviceEntered = false, hasPendingScreenOffCallback = true), ), TestSpec( id = 9, id = 11, expectedState = ScrimState.AOD, Preconditions(isOnKeyguard = true, isDozing = true), Preconditions(isDeviceEntered = false, isDozing = true), ), TestSpec( id = 10, id = 12, expectedState = ScrimState.GLANCEABLE_HUB, Preconditions(isIdleOnCommunal = true), ), TestSpec( id = 11, id = 13, expectedState = ScrimState.GLANCEABLE_HUB_OVER_DREAM, Preconditions(isIdleOnCommunal = true, isDreaming = true), ), TestSpec( id = 12, id = 14, expectedState = ScrimState.UNLOCKED, Preconditions(isDeviceEntered = true), ), TestSpec( id = 13, id = 15, expectedState = ScrimState.UNLOCKED, Preconditions(isOnKeyguard = true, isBiometricWakeAndUnlock = true), Preconditions(isBiometricWakeAndUnlock = true), ), TestSpec(id = 14, expectedState = ScrimState.KEYGUARD, Preconditions()), TestSpec(id = 16, expectedState = ScrimState.KEYGUARD, Preconditions()), TestSpec( id = 15, id = 17, expectedState = ScrimState.DREAMING, Preconditions(isOnKeyguard = true, isOccluded = true, isDreaming = true), Preconditions(isOccluded = true, isDreaming = true), ), TestSpec( id = 16, id = 18, expectedState = ScrimState.UNLOCKED, Preconditions(isOnKeyguard = true, isOccluded = true), Preconditions(isOccluded = true), ), ) } Loading @@ -185,10 +202,9 @@ class ScrimStartableTest : SysuiTestCase() { } } private val kosmos = testKosmos() private val testScope = kosmos.testScope private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val underTest = kosmos.scrimStartable private val underTest: ScrimStartable by lazy { kosmos.scrimStartable } @JvmField @Parameter(0) var testSpec: TestSpec? = null Loading @@ -205,94 +221,101 @@ class ScrimStartableTest : SysuiTestCase() { @Test fun test() = testScope.runTest { kosmos.runTest { val observedState by collectLastValue(underTest.scrimState) val preconditions = checkNotNull(testSpec).preconditions preconditions.assertValid() setUpWith(preconditions) runCurrent() assertThat(observedState).isEqualTo(checkNotNull(testSpec).expectedState) } /** Sets up the state to match what's specified in the given [preconditions]. */ private fun TestScope.setUpWith(preconditions: Preconditions) { kosmos.fakeKeyguardBouncerRepository.setAlternateVisible( preconditions.isAlternateBouncerVisible ) private fun Kosmos.setUpWith(preconditions: Preconditions) { whenever(statusBarKeyguardViewManager.primaryBouncerNeedsScrimming()) .thenReturn(preconditions.isBouncerScrimmingNeeded) fakeKeyguardBouncerRepository.setAlternateVisible(preconditions.isAlternateBouncerVisible) if (preconditions.isDeviceEntered) { kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) whenIdle(on = Scenes.Gone) } else { whenIdle(on = Scenes.Lockscreen) } runCurrent() when { preconditions.isTransitioningToShade -> preconditions.isTransitioningToShadeScene -> { enableSingleShade() whenTransitioning(from = Scenes.Lockscreen, to = Scenes.Shade) } preconditions.isTransitioningToShadeOverlay -> { enableDualShade() whenTransitioning(from = Scenes.Lockscreen, to = Overlays.NotificationsShade) } preconditions.isTransitioningAwayFromKeyguard -> whenTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) preconditions.isCurrentSceneShade -> whenIdle(on = Scenes.Shade) preconditions.isIdleOnShadeScene -> { enableSingleShade() whenIdle(on = Scenes.Shade) } preconditions.isIdleOnShadeOverlay -> { enableDualShade() whenIdle( on = if (preconditions.isDeviceEntered) Scenes.Gone else Scenes.Lockscreen, overlays = setOf(Overlays.NotificationsShade), ) } preconditions.isIdleOnBouncer -> whenIdle(on = Scenes.Lockscreen, overlays = setOf(Overlays.Bouncer)) preconditions.isIdleOnCommunal -> whenIdle(on = Scenes.Communal) } kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( showWhenLockedActivityOnTop = preconditions.isOccluded, taskInfo = if (preconditions.isOccluded) mock() else null, ) if (preconditions.isBiometricWakeAndUnlock) { kosmos.biometricUnlockInteractor.setBiometricUnlockState( biometricUnlockInteractor.setBiometricUnlockState( BiometricUnlockController.MODE_WAKE_AND_UNLOCK, BiometricUnlockSource.FINGERPRINT_SENSOR, ) } kosmos.brightnessMirrorShowingInteractor.setMirrorShowing( preconditions.isBrightnessMirrorVisible ) brightnessMirrorShowingInteractor.setMirrorShowing(preconditions.isBrightnessMirrorVisible) if (preconditions.hasPendingScreenOffCallback) { kosmos.dozeServiceHost.prepareForGentleSleep {} dozeServiceHost.prepareForGentleSleep {} } else { kosmos.dozeServiceHost.cancelGentleSleep() dozeServiceHost.cancelGentleSleep() } kosmos.fakeKeyguardRepository.setIsDozing(preconditions.isDozing) fakeKeyguardRepository.setIsDozing(preconditions.isDozing) if (preconditions.isPulsing) { kosmos.fakeKeyguardRepository.setDozeTransitionModel( fakeKeyguardRepository.setDozeTransitionModel( DozeTransitionModel(to = DozeStateModel.DOZE_PULSING) ) } kosmos.fakeKeyguardRepository.setDreaming(preconditions.isDreaming) whenever(kosmos.statusBarKeyguardViewManager.primaryBouncerNeedsScrimming()) .thenReturn(preconditions.isBouncerScrimmingNeeded) runCurrent() fakeKeyguardRepository.setDreaming(preconditions.isDreaming) } /** Sets up an idle state on the given [on] scene. */ private fun whenIdle(on: SceneKey, overlays: Set<OverlayKey> = emptySet()) { kosmos.setSceneTransition(ObservableTransitionState.Idle(on, overlays)) kosmos.sceneInteractor.changeScene(on, "") private fun Kosmos.whenIdle(on: SceneKey, overlays: Set<OverlayKey> = emptySet()) { setSceneTransition(ObservableTransitionState.Idle(on, overlays)) sceneInteractor.changeScene(on, "") for (overlay in overlays) { kosmos.sceneInteractor.showOverlay(overlay, "") sceneInteractor.showOverlay(overlay, "") } } /** Sets up a transitioning state between the [given] and [to] scenes. */ private fun whenTransitioning(from: SceneKey, to: SceneKey, progress: Float = 0.5f) { /** Sets up a transitioning state between the given [from] and [to] scenes. */ private fun Kosmos.whenTransitioning(from: SceneKey, to: SceneKey, progress: Float = 0.5f) { val currentScene = if (progress > 0.5f) to else from kosmos.setSceneTransition( setSceneTransition( ObservableTransitionState.Transition( fromScene = from, toScene = to, Loading @@ -302,15 +325,31 @@ class ScrimStartableTest : SysuiTestCase() { isUserInputOngoing = flowOf(false), ) ) kosmos.sceneInteractor.changeScene(currentScene, "") sceneInteractor.changeScene(currentScene, "") } /** Sets up a transitioning state between the [from] scene and [to] overlay. */ private fun Kosmos.whenTransitioning(from: SceneKey, to: OverlayKey, progress: Float = 0.5f) { val currentOverlays = if (progress > 0.5f) setOf(to) else emptySet() setSceneTransition( ObservableTransitionState.Transition.showOverlay( overlay = to, fromScene = from, progress = flowOf(progress), currentOverlays = flowOf(currentOverlays), isInitiatedByUserInput = true, isUserInputOngoing = flowOf(false), ) ) sceneInteractor.showOverlay(to, "") } data class Preconditions( /** Whether bouncer or lockscreen scene is in the nav stack. */ val isOnKeyguard: Boolean = false, val isAlternateBouncerVisible: Boolean = false, /** Whether any non-shade nor QS scene is transitioning to a shade or QS scene. */ val isTransitioningToShade: Boolean = false, val isTransitioningToShadeScene: Boolean = false, /** Whether any non-shade nor QS scene is transitioning to a shade or QS overlay. */ val isTransitioningToShadeOverlay: Boolean = false, val isOccluded: Boolean = false, val isIdleOnBouncer: Boolean = false, val isBiometricWakeAndUnlock: Boolean = false, Loading @@ -318,7 +357,9 @@ class ScrimStartableTest : SysuiTestCase() { val isTransitioningAwayFromKeyguard: Boolean = false, val isBrightnessMirrorVisible: Boolean = false, /** Whether the current scene is a shade or QS scene. */ val isCurrentSceneShade: Boolean = false, val isIdleOnShadeScene: Boolean = false, /** Whether the notifications shade or QS shade overlay is in the current overlays. */ val isIdleOnShadeOverlay: Boolean = false, val isDeviceEntered: Boolean = false, val isPulsing: Boolean = false, val hasPendingScreenOffCallback: Boolean = false, Loading @@ -342,47 +383,58 @@ class ScrimStartableTest : SysuiTestCase() { } fun assertValid() { assertWithMessage("isOccluded cannot be true without isOnKeyguard also being true") .that(!isOccluded || isOnKeyguard) assertWithMessage("isOccluded cannot be true at the same time as isDeviceEntered") .that(!isOccluded || !isDeviceEntered) .isTrue() assertWithMessage( "isCurrentSceneBouncer cannot be true without isOnKeyguard also being true" ) .that(!isIdleOnBouncer || isOnKeyguard) assertWithMessage("isIdleOnBouncer cannot be true at the same time as isDeviceEntered") .that(!isIdleOnBouncer || !isDeviceEntered) .isTrue() assertWithMessage("isIdleOnBouncer cannot be true at the same time as isIdleOnCommunal") .that(!isIdleOnBouncer || !isIdleOnCommunal) .isTrue() assertWithMessage( "isTransitioningAwayFromKeyguard cannot be true without isOnKeyguard being true" "isIdleOnShadeScene cannot be true at the same time as isIdleOnCommunal" ) .that(!isTransitioningAwayFromKeyguard || isOnKeyguard) .that(!isIdleOnShadeScene || !isIdleOnCommunal) .isTrue() assertWithMessage( "isCurrentSceneBouncer cannot be true at the same time as isCurrentSceneShade" "isIdleOnShadeOverlay cannot be true at the same time as isIdleOnCommunal" ) .that(!isIdleOnBouncer || !isCurrentSceneShade) .that(!isIdleOnShadeOverlay || !isIdleOnCommunal) .isTrue() assertWithMessage( "isCurrentSceneBouncer cannot be true at the same time as isIdleOnCommunal" "isIdleOnShadeScene cannot be true at the same time as isIdleOnShadeOverlay" ) .that(!isIdleOnBouncer || !isIdleOnCommunal) .that(!isIdleOnShadeScene || !isIdleOnShadeOverlay) .isTrue() assertWithMessage( "isCurrentSceneShade cannot be true at the same time as isIdleOnCommunal" "isTransitioningToShadeScene cannot be true at the same time as " + "isTransitioningToShadeOverlay" ) .that(!isCurrentSceneShade || !isIdleOnCommunal) .that(!isTransitioningToShadeScene || !isTransitioningToShadeOverlay) .isTrue() assertWithMessage("isDeviceEntered cannot be true at the same time as isOnKeyguard") .that(!isDeviceEntered || !isOnKeyguard) assertWithMessage( "isTransitioningToShadeScene cannot be true at the same time as " + "isIdleOnShadeOverlay" ) .that(!isTransitioningToShadeScene || !isIdleOnShadeOverlay) .isTrue() assertWithMessage( "isDeviceEntered cannot be true at the same time as isCurrentSceneBouncer" "isTransitioningToShadeOverlay cannot be true at the same time as " + "isIdleOnShadeScene" ) .that(!isTransitioningToShadeOverlay || !isIdleOnShadeScene) .isTrue() assertWithMessage("isDeviceEntered cannot be true at the same time as isIdleOnBouncer") .that(!isDeviceEntered || !isIdleOnBouncer) .isTrue() Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt +143 −91 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneKey import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository Loading @@ -31,12 +30,17 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockSource import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeTransitionModel import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.shade.domain.interactor.enableSingleShade import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.ScrimState Loading @@ -47,10 +51,8 @@ import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlin.reflect.full.memberProperties import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.BeforeClass import org.junit.Test Loading @@ -63,6 +65,7 @@ import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(ParameterizedAndroidJunit4::class) @OptIn(ExperimentalCoroutinesApi::class) @EnableSceneContainer class ScrimStartableTest : SysuiTestCase() { Loading @@ -75,7 +78,7 @@ class ScrimStartableTest : SysuiTestCase() { id = 0, expectedState = ScrimState.KEYGUARD, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isAlternateBouncerVisible = true, isTransitioningAwayFromKeyguard = true, ), Loading @@ -84,90 +87,104 @@ class ScrimStartableTest : SysuiTestCase() { id = 1, expectedState = null, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isAlternateBouncerVisible = true, isTransitioningToShade = true, isTransitioningToShadeScene = true, ), ), TestSpec( id = 2, expectedState = ScrimState.BOUNCER, Preconditions(isOnKeyguard = true, isIdleOnBouncer = true), expectedState = null, Preconditions( isDeviceEntered = false, isAlternateBouncerVisible = true, isTransitioningToShadeOverlay = true, ), ), TestSpec( id = 3, expectedState = ScrimState.BOUNCER, Preconditions(isDeviceEntered = false, isIdleOnBouncer = true), ), TestSpec( id = 4, expectedState = ScrimState.BOUNCER_SCRIMMED, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isIdleOnBouncer = true, isBouncerScrimmingNeeded = true, ), ), TestSpec( id = 4, id = 5, expectedState = ScrimState.BRIGHTNESS_MIRROR, Preconditions(isOnKeyguard = true, isBrightnessMirrorVisible = true), Preconditions(isDeviceEntered = false, isBrightnessMirrorVisible = true), ), TestSpec( id = 5, id = 6, expectedState = ScrimState.BRIGHTNESS_MIRROR, Preconditions( isOnKeyguard = true, isDeviceEntered = false, isIdleOnBouncer = true, isBiometricWakeAndUnlock = true, isBrightnessMirrorVisible = true, ), ), TestSpec( id = 6, id = 7, expectedState = ScrimState.SHADE_LOCKED, Preconditions(isOnKeyguard = true, isCurrentSceneShade = true), Preconditions(isDeviceEntered = false, isIdleOnShadeScene = true), ), TestSpec( id = 7, id = 8, expectedState = ScrimState.SHADE_LOCKED, Preconditions(isDeviceEntered = false, isIdleOnShadeOverlay = true), ), TestSpec( id = 9, expectedState = ScrimState.PULSING, Preconditions(isOnKeyguard = true, isDozing = true, isPulsing = true), Preconditions(isDeviceEntered = false, isDozing = true, isPulsing = true), ), TestSpec( id = 8, id = 10, expectedState = ScrimState.OFF, Preconditions(isOnKeyguard = true, hasPendingScreenOffCallback = true), Preconditions(isDeviceEntered = false, hasPendingScreenOffCallback = true), ), TestSpec( id = 9, id = 11, expectedState = ScrimState.AOD, Preconditions(isOnKeyguard = true, isDozing = true), Preconditions(isDeviceEntered = false, isDozing = true), ), TestSpec( id = 10, id = 12, expectedState = ScrimState.GLANCEABLE_HUB, Preconditions(isIdleOnCommunal = true), ), TestSpec( id = 11, id = 13, expectedState = ScrimState.GLANCEABLE_HUB_OVER_DREAM, Preconditions(isIdleOnCommunal = true, isDreaming = true), ), TestSpec( id = 12, id = 14, expectedState = ScrimState.UNLOCKED, Preconditions(isDeviceEntered = true), ), TestSpec( id = 13, id = 15, expectedState = ScrimState.UNLOCKED, Preconditions(isOnKeyguard = true, isBiometricWakeAndUnlock = true), Preconditions(isBiometricWakeAndUnlock = true), ), TestSpec(id = 14, expectedState = ScrimState.KEYGUARD, Preconditions()), TestSpec(id = 16, expectedState = ScrimState.KEYGUARD, Preconditions()), TestSpec( id = 15, id = 17, expectedState = ScrimState.DREAMING, Preconditions(isOnKeyguard = true, isOccluded = true, isDreaming = true), Preconditions(isOccluded = true, isDreaming = true), ), TestSpec( id = 16, id = 18, expectedState = ScrimState.UNLOCKED, Preconditions(isOnKeyguard = true, isOccluded = true), Preconditions(isOccluded = true), ), ) } Loading @@ -185,10 +202,9 @@ class ScrimStartableTest : SysuiTestCase() { } } private val kosmos = testKosmos() private val testScope = kosmos.testScope private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val underTest = kosmos.scrimStartable private val underTest: ScrimStartable by lazy { kosmos.scrimStartable } @JvmField @Parameter(0) var testSpec: TestSpec? = null Loading @@ -205,94 +221,101 @@ class ScrimStartableTest : SysuiTestCase() { @Test fun test() = testScope.runTest { kosmos.runTest { val observedState by collectLastValue(underTest.scrimState) val preconditions = checkNotNull(testSpec).preconditions preconditions.assertValid() setUpWith(preconditions) runCurrent() assertThat(observedState).isEqualTo(checkNotNull(testSpec).expectedState) } /** Sets up the state to match what's specified in the given [preconditions]. */ private fun TestScope.setUpWith(preconditions: Preconditions) { kosmos.fakeKeyguardBouncerRepository.setAlternateVisible( preconditions.isAlternateBouncerVisible ) private fun Kosmos.setUpWith(preconditions: Preconditions) { whenever(statusBarKeyguardViewManager.primaryBouncerNeedsScrimming()) .thenReturn(preconditions.isBouncerScrimmingNeeded) fakeKeyguardBouncerRepository.setAlternateVisible(preconditions.isAlternateBouncerVisible) if (preconditions.isDeviceEntered) { kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) whenIdle(on = Scenes.Gone) } else { whenIdle(on = Scenes.Lockscreen) } runCurrent() when { preconditions.isTransitioningToShade -> preconditions.isTransitioningToShadeScene -> { enableSingleShade() whenTransitioning(from = Scenes.Lockscreen, to = Scenes.Shade) } preconditions.isTransitioningToShadeOverlay -> { enableDualShade() whenTransitioning(from = Scenes.Lockscreen, to = Overlays.NotificationsShade) } preconditions.isTransitioningAwayFromKeyguard -> whenTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) preconditions.isCurrentSceneShade -> whenIdle(on = Scenes.Shade) preconditions.isIdleOnShadeScene -> { enableSingleShade() whenIdle(on = Scenes.Shade) } preconditions.isIdleOnShadeOverlay -> { enableDualShade() whenIdle( on = if (preconditions.isDeviceEntered) Scenes.Gone else Scenes.Lockscreen, overlays = setOf(Overlays.NotificationsShade), ) } preconditions.isIdleOnBouncer -> whenIdle(on = Scenes.Lockscreen, overlays = setOf(Overlays.Bouncer)) preconditions.isIdleOnCommunal -> whenIdle(on = Scenes.Communal) } kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( showWhenLockedActivityOnTop = preconditions.isOccluded, taskInfo = if (preconditions.isOccluded) mock() else null, ) if (preconditions.isBiometricWakeAndUnlock) { kosmos.biometricUnlockInteractor.setBiometricUnlockState( biometricUnlockInteractor.setBiometricUnlockState( BiometricUnlockController.MODE_WAKE_AND_UNLOCK, BiometricUnlockSource.FINGERPRINT_SENSOR, ) } kosmos.brightnessMirrorShowingInteractor.setMirrorShowing( preconditions.isBrightnessMirrorVisible ) brightnessMirrorShowingInteractor.setMirrorShowing(preconditions.isBrightnessMirrorVisible) if (preconditions.hasPendingScreenOffCallback) { kosmos.dozeServiceHost.prepareForGentleSleep {} dozeServiceHost.prepareForGentleSleep {} } else { kosmos.dozeServiceHost.cancelGentleSleep() dozeServiceHost.cancelGentleSleep() } kosmos.fakeKeyguardRepository.setIsDozing(preconditions.isDozing) fakeKeyguardRepository.setIsDozing(preconditions.isDozing) if (preconditions.isPulsing) { kosmos.fakeKeyguardRepository.setDozeTransitionModel( fakeKeyguardRepository.setDozeTransitionModel( DozeTransitionModel(to = DozeStateModel.DOZE_PULSING) ) } kosmos.fakeKeyguardRepository.setDreaming(preconditions.isDreaming) whenever(kosmos.statusBarKeyguardViewManager.primaryBouncerNeedsScrimming()) .thenReturn(preconditions.isBouncerScrimmingNeeded) runCurrent() fakeKeyguardRepository.setDreaming(preconditions.isDreaming) } /** Sets up an idle state on the given [on] scene. */ private fun whenIdle(on: SceneKey, overlays: Set<OverlayKey> = emptySet()) { kosmos.setSceneTransition(ObservableTransitionState.Idle(on, overlays)) kosmos.sceneInteractor.changeScene(on, "") private fun Kosmos.whenIdle(on: SceneKey, overlays: Set<OverlayKey> = emptySet()) { setSceneTransition(ObservableTransitionState.Idle(on, overlays)) sceneInteractor.changeScene(on, "") for (overlay in overlays) { kosmos.sceneInteractor.showOverlay(overlay, "") sceneInteractor.showOverlay(overlay, "") } } /** Sets up a transitioning state between the [given] and [to] scenes. */ private fun whenTransitioning(from: SceneKey, to: SceneKey, progress: Float = 0.5f) { /** Sets up a transitioning state between the given [from] and [to] scenes. */ private fun Kosmos.whenTransitioning(from: SceneKey, to: SceneKey, progress: Float = 0.5f) { val currentScene = if (progress > 0.5f) to else from kosmos.setSceneTransition( setSceneTransition( ObservableTransitionState.Transition( fromScene = from, toScene = to, Loading @@ -302,15 +325,31 @@ class ScrimStartableTest : SysuiTestCase() { isUserInputOngoing = flowOf(false), ) ) kosmos.sceneInteractor.changeScene(currentScene, "") sceneInteractor.changeScene(currentScene, "") } /** Sets up a transitioning state between the [from] scene and [to] overlay. */ private fun Kosmos.whenTransitioning(from: SceneKey, to: OverlayKey, progress: Float = 0.5f) { val currentOverlays = if (progress > 0.5f) setOf(to) else emptySet() setSceneTransition( ObservableTransitionState.Transition.showOverlay( overlay = to, fromScene = from, progress = flowOf(progress), currentOverlays = flowOf(currentOverlays), isInitiatedByUserInput = true, isUserInputOngoing = flowOf(false), ) ) sceneInteractor.showOverlay(to, "") } data class Preconditions( /** Whether bouncer or lockscreen scene is in the nav stack. */ val isOnKeyguard: Boolean = false, val isAlternateBouncerVisible: Boolean = false, /** Whether any non-shade nor QS scene is transitioning to a shade or QS scene. */ val isTransitioningToShade: Boolean = false, val isTransitioningToShadeScene: Boolean = false, /** Whether any non-shade nor QS scene is transitioning to a shade or QS overlay. */ val isTransitioningToShadeOverlay: Boolean = false, val isOccluded: Boolean = false, val isIdleOnBouncer: Boolean = false, val isBiometricWakeAndUnlock: Boolean = false, Loading @@ -318,7 +357,9 @@ class ScrimStartableTest : SysuiTestCase() { val isTransitioningAwayFromKeyguard: Boolean = false, val isBrightnessMirrorVisible: Boolean = false, /** Whether the current scene is a shade or QS scene. */ val isCurrentSceneShade: Boolean = false, val isIdleOnShadeScene: Boolean = false, /** Whether the notifications shade or QS shade overlay is in the current overlays. */ val isIdleOnShadeOverlay: Boolean = false, val isDeviceEntered: Boolean = false, val isPulsing: Boolean = false, val hasPendingScreenOffCallback: Boolean = false, Loading @@ -342,47 +383,58 @@ class ScrimStartableTest : SysuiTestCase() { } fun assertValid() { assertWithMessage("isOccluded cannot be true without isOnKeyguard also being true") .that(!isOccluded || isOnKeyguard) assertWithMessage("isOccluded cannot be true at the same time as isDeviceEntered") .that(!isOccluded || !isDeviceEntered) .isTrue() assertWithMessage( "isCurrentSceneBouncer cannot be true without isOnKeyguard also being true" ) .that(!isIdleOnBouncer || isOnKeyguard) assertWithMessage("isIdleOnBouncer cannot be true at the same time as isDeviceEntered") .that(!isIdleOnBouncer || !isDeviceEntered) .isTrue() assertWithMessage("isIdleOnBouncer cannot be true at the same time as isIdleOnCommunal") .that(!isIdleOnBouncer || !isIdleOnCommunal) .isTrue() assertWithMessage( "isTransitioningAwayFromKeyguard cannot be true without isOnKeyguard being true" "isIdleOnShadeScene cannot be true at the same time as isIdleOnCommunal" ) .that(!isTransitioningAwayFromKeyguard || isOnKeyguard) .that(!isIdleOnShadeScene || !isIdleOnCommunal) .isTrue() assertWithMessage( "isCurrentSceneBouncer cannot be true at the same time as isCurrentSceneShade" "isIdleOnShadeOverlay cannot be true at the same time as isIdleOnCommunal" ) .that(!isIdleOnBouncer || !isCurrentSceneShade) .that(!isIdleOnShadeOverlay || !isIdleOnCommunal) .isTrue() assertWithMessage( "isCurrentSceneBouncer cannot be true at the same time as isIdleOnCommunal" "isIdleOnShadeScene cannot be true at the same time as isIdleOnShadeOverlay" ) .that(!isIdleOnBouncer || !isIdleOnCommunal) .that(!isIdleOnShadeScene || !isIdleOnShadeOverlay) .isTrue() assertWithMessage( "isCurrentSceneShade cannot be true at the same time as isIdleOnCommunal" "isTransitioningToShadeScene cannot be true at the same time as " + "isTransitioningToShadeOverlay" ) .that(!isCurrentSceneShade || !isIdleOnCommunal) .that(!isTransitioningToShadeScene || !isTransitioningToShadeOverlay) .isTrue() assertWithMessage("isDeviceEntered cannot be true at the same time as isOnKeyguard") .that(!isDeviceEntered || !isOnKeyguard) assertWithMessage( "isTransitioningToShadeScene cannot be true at the same time as " + "isIdleOnShadeOverlay" ) .that(!isTransitioningToShadeScene || !isIdleOnShadeOverlay) .isTrue() assertWithMessage( "isDeviceEntered cannot be true at the same time as isCurrentSceneBouncer" "isTransitioningToShadeOverlay cannot be true at the same time as " + "isIdleOnShadeScene" ) .that(!isTransitioningToShadeOverlay || !isIdleOnShadeScene) .isTrue() assertWithMessage("isDeviceEntered cannot be true at the same time as isIdleOnBouncer") .that(!isDeviceEntered || !isIdleOnBouncer) .isTrue() Loading