Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +67 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ import com.android.systemui.kosmos.collectValues import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.data.model.asIterable import com.android.systemui.scene.data.model.sceneStackOf import com.android.systemui.scene.data.repository.HideOverlay Loading Loading @@ -1106,6 +1109,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { assertThat(currentScene).isEqualTo(Scenes.Gone) assertThat(lockscreenVisibility).isFalse() powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) // Lockscreen remains not visible during the transition so that the unlocked app content // is visible under the light reveal screen off animation. Loading Loading @@ -1297,6 +1301,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { // Lockscreen vis remains false during Gone -> LS so the unlocked app content is visible // during the screen off animation. powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) assertThat(lockscreenVisibility).isFalse() Loading @@ -1305,6 +1310,68 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun lockscreenVisibility_becomesVisible_ifAwakeDuringGoneLs() = kosmos.runTest { enableSingleShade() runCurrent() powerInteractor.setAwakeForTest() kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) setSceneTransition(Idle(Scenes.Gone)) sceneInteractor.changeScene(Scenes.Gone, "") val lockscreenVisibility by collectLastValue(underTest.lockscreenVisibility) assertThat(lockscreenVisibility).isFalse() // Lockscreen vis remains false during Gone -> LS so the unlocked app content is visible // during the screen off animation. powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) assertThat(lockscreenVisibility).isFalse() powerInteractor.setAwakeForTest() runCurrent() assertThat(lockscreenVisibility).isTrue() setSceneTransition(Idle(Scenes.Lockscreen)) sceneInteractor.changeScene(Scenes.Lockscreen, "") assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun lockscreenVisibility_remainsNotVisible_ifCameraLaunch() = kosmos.runTest { enableSingleShade() runCurrent() kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) setSceneTransition(Idle(Scenes.Gone)) sceneInteractor.changeScene(Scenes.Gone, "") val lockscreenVisibility by collectLastValue(underTest.lockscreenVisibility) assertThat(lockscreenVisibility).isFalse() // Lockscreen vis remains false during Gone -> LS so the unlocked app content is visible // during the screen off animation. powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) assertThat(lockscreenVisibility).isFalse() powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() runCurrent() assertThat(lockscreenVisibility).isFalse() setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone)) setSceneTransition(Idle(Scenes.Gone)) sceneInteractor.changeScene(Scenes.Gone, "") assertThat(lockscreenVisibility).isFalse() } companion object { private val progress = MutableStateFlow(0f) Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +30 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAsleepInState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Overlays Loading @@ -34,14 +35,15 @@ import com.android.systemui.statusbar.notification.domain.interactor.Notificatio import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import dagger.Lazy import javax.inject.Inject @SysUISingleton class WindowManagerLockscreenVisibilityInteractor Loading @@ -59,6 +61,7 @@ constructor( deviceEntryInteractor: Lazy<DeviceEntryInteractor>, wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor, deviceProvisioningInteractor: Lazy<DeviceProvisioningInteractor>, powerInteractor: PowerInteractor, ) { private val defaultSurfaceBehindVisibility = combine( Loading Loading @@ -198,6 +201,26 @@ constructor( .distinctUntilChanged() } /** * WM lockscreen visibility during Gone -> Lockscreen. * * Lockscreen only needs to remain non-visible (unlocked app content visible) in order to play * the screen off animation. If we become awake during the transition, that means the animation * was cancelled and we should hide the unlocked content so it's not visible behind the * lockscreen during Gone -> Lockscreen. * * This also covers the Lockdown case, where Gone -> Lockscreen starts while awake. There is no * lockdown animation, so we should immediately hide the unlocked content. * * We also need Lockscreen to remain non-visible at all times if the unlocked power button * gesture is triggered, since we'll be returning to Gone as if we never tried to lock in the * first place. */ private val goneToLockscreenLsVisibility = powerInteractor.detailedWakefulness .distinctUntilChangedBy { it.isAwake() } .map { it.isAwake() && !it.powerButtonLaunchGestureTriggered } private val lockscreenVisibilityWithScenes: Flow<Boolean> = deviceProvisioningInteractor.get().isDeviceProvisioned.flatMapLatestConflated { isProvisioned -> Loading Loading @@ -232,6 +255,11 @@ constructor( // visible. it.currentOverlays.contains(Overlays.Bouncer) -> flowOf(true) // If we're transitioning to Lockscreen from Gone, special // cases apply. it.fromScene == Scenes.Gone && it.toScene == Scenes.Lockscreen -> goneToLockscreenLsVisibility // Otherwise, default to showing the lockscreen if the // device is not yet entered, or leaving it not showing if // the device was entered. This covers two requirements: Loading packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor Loading @@ -38,5 +39,6 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by deviceEntryInteractor = { deviceEntryInteractor }, wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor, deviceProvisioningInteractor = { deviceProvisioningInteractor }, powerInteractor = powerInteractor, ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +67 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ import com.android.systemui.kosmos.collectValues import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.data.model.asIterable import com.android.systemui.scene.data.model.sceneStackOf import com.android.systemui.scene.data.repository.HideOverlay Loading Loading @@ -1106,6 +1109,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { assertThat(currentScene).isEqualTo(Scenes.Gone) assertThat(lockscreenVisibility).isFalse() powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) // Lockscreen remains not visible during the transition so that the unlocked app content // is visible under the light reveal screen off animation. Loading Loading @@ -1297,6 +1301,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { // Lockscreen vis remains false during Gone -> LS so the unlocked app content is visible // during the screen off animation. powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) assertThat(lockscreenVisibility).isFalse() Loading @@ -1305,6 +1310,68 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun lockscreenVisibility_becomesVisible_ifAwakeDuringGoneLs() = kosmos.runTest { enableSingleShade() runCurrent() powerInteractor.setAwakeForTest() kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) setSceneTransition(Idle(Scenes.Gone)) sceneInteractor.changeScene(Scenes.Gone, "") val lockscreenVisibility by collectLastValue(underTest.lockscreenVisibility) assertThat(lockscreenVisibility).isFalse() // Lockscreen vis remains false during Gone -> LS so the unlocked app content is visible // during the screen off animation. powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) assertThat(lockscreenVisibility).isFalse() powerInteractor.setAwakeForTest() runCurrent() assertThat(lockscreenVisibility).isTrue() setSceneTransition(Idle(Scenes.Lockscreen)) sceneInteractor.changeScene(Scenes.Lockscreen, "") assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun lockscreenVisibility_remainsNotVisible_ifCameraLaunch() = kosmos.runTest { enableSingleShade() runCurrent() kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) setSceneTransition(Idle(Scenes.Gone)) sceneInteractor.changeScene(Scenes.Gone, "") val lockscreenVisibility by collectLastValue(underTest.lockscreenVisibility) assertThat(lockscreenVisibility).isFalse() // Lockscreen vis remains false during Gone -> LS so the unlocked app content is visible // during the screen off animation. powerInteractor.setAsleepForTest() setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen)) assertThat(lockscreenVisibility).isFalse() powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() runCurrent() assertThat(lockscreenVisibility).isFalse() setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone)) setSceneTransition(Idle(Scenes.Gone)) sceneInteractor.changeScene(Scenes.Gone, "") assertThat(lockscreenVisibility).isFalse() } companion object { private val progress = MutableStateFlow(0f) Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +30 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAsleepInState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Overlays Loading @@ -34,14 +35,15 @@ import com.android.systemui.statusbar.notification.domain.interactor.Notificatio import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import dagger.Lazy import javax.inject.Inject @SysUISingleton class WindowManagerLockscreenVisibilityInteractor Loading @@ -59,6 +61,7 @@ constructor( deviceEntryInteractor: Lazy<DeviceEntryInteractor>, wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor, deviceProvisioningInteractor: Lazy<DeviceProvisioningInteractor>, powerInteractor: PowerInteractor, ) { private val defaultSurfaceBehindVisibility = combine( Loading Loading @@ -198,6 +201,26 @@ constructor( .distinctUntilChanged() } /** * WM lockscreen visibility during Gone -> Lockscreen. * * Lockscreen only needs to remain non-visible (unlocked app content visible) in order to play * the screen off animation. If we become awake during the transition, that means the animation * was cancelled and we should hide the unlocked content so it's not visible behind the * lockscreen during Gone -> Lockscreen. * * This also covers the Lockdown case, where Gone -> Lockscreen starts while awake. There is no * lockdown animation, so we should immediately hide the unlocked content. * * We also need Lockscreen to remain non-visible at all times if the unlocked power button * gesture is triggered, since we'll be returning to Gone as if we never tried to lock in the * first place. */ private val goneToLockscreenLsVisibility = powerInteractor.detailedWakefulness .distinctUntilChangedBy { it.isAwake() } .map { it.isAwake() && !it.powerButtonLaunchGestureTriggered } private val lockscreenVisibilityWithScenes: Flow<Boolean> = deviceProvisioningInteractor.get().isDeviceProvisioned.flatMapLatestConflated { isProvisioned -> Loading Loading @@ -232,6 +255,11 @@ constructor( // visible. it.currentOverlays.contains(Overlays.Bouncer) -> flowOf(true) // If we're transitioning to Lockscreen from Gone, special // cases apply. it.fromScene == Scenes.Gone && it.toScene == Scenes.Lockscreen -> goneToLockscreenLsVisibility // Otherwise, default to showing the lockscreen if the // device is not yet entered, or leaving it not showing if // the device was entered. This covers two requirements: Loading
packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor Loading @@ -38,5 +39,6 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by deviceEntryInteractor = { deviceEntryInteractor }, wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor, deviceProvisioningInteractor = { deviceProvisioningInteractor }, powerInteractor = powerInteractor, ) }