Loading packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt +6 −5 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.scene.domain.interactor.sceneBackInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.sceneContainerStartable import com.android.systemui.scene.shared.model.Scenes Loading Loading @@ -72,7 +71,6 @@ class DeviceEntryInteractorTest : SysuiTestCase() { private val trustRepository by lazy { kosmos.fakeTrustRepository } private val sceneInteractor by lazy { kosmos.sceneInteractor } private val authenticationInteractor by lazy { kosmos.authenticationInteractor } private val sceneBackInteractor by lazy { kosmos.sceneBackInteractor } private val sceneContainerStartable by lazy { kosmos.sceneContainerStartable } private val sysuiStatusBarStateController by lazy { kosmos.sysuiStatusBarStateController } private lateinit var underTest: DeviceEntryInteractor Loading Loading @@ -437,7 +435,9 @@ class DeviceEntryInteractorTest : SysuiTestCase() { fun isDeviceEntered_unlockedWhileOnShade_emitsTrue() = testScope.runTest { val isDeviceEntered by collectLastValue(underTest.isDeviceEntered) val isDeviceEnteredDirectly by collectLastValue(underTest.isDeviceEnteredDirectly) assertThat(isDeviceEntered).isFalse() assertThat(isDeviceEnteredDirectly).isFalse() val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -445,19 +445,20 @@ class DeviceEntryInteractorTest : SysuiTestCase() { switchToScene(Scenes.Shade) assertThat(currentScene).isEqualTo(Scenes.Shade) // Simulating a "leave it open when the keyguard is hidden" which means the bouncer will // be // shown and successful authentication should take the user back to where they are, the // shade scene. // be shown and successful authentication should take the user back to where they are, // the shade scene. sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true) switchToScene(Scenes.Bouncer) assertThat(currentScene).isEqualTo(Scenes.Bouncer) assertThat(isDeviceEntered).isFalse() assertThat(isDeviceEnteredDirectly).isFalse() // Authenticate with PIN to unlock and dismiss the lockscreen: authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) runCurrent() assertThat(isDeviceEntered).isTrue() assertThat(isDeviceEnteredDirectly).isFalse() } private fun TestScope.switchToScene(sceneKey: SceneKey) { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +51 −12 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep import com.android.systemui.authentication.domain.interactor.authenticationInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer Loading @@ -34,10 +35,12 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.kosmos.testScope import com.android.systemui.scene.data.model.asIterable import com.android.systemui.scene.data.model.sceneStackOf import com.android.systemui.scene.data.repository.Idle import com.android.systemui.scene.data.repository.Transition import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.domain.interactor.sceneBackInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos Loading Loading @@ -85,7 +88,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { fun setUp() { // lazy value needs to be called here otherwise flow collection misbehaves underTest.value kosmos.sceneContainerRepository.setTransitionState(sceneTransitions) kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Lockscreen)) } @Test Loading Loading @@ -965,6 +968,47 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun lockscreenVisibilityWithScenes_staysTrue_despiteEnteringIndirectly() = testScope.runTest { val isDeviceUnlocked by collectLastValue( kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked } ) assertThat(isDeviceUnlocked).isFalse() val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility) assertThat(lockscreenVisibility).isTrue() kosmos.setSceneTransition(Idle(Scenes.Shade)) kosmos.sceneInteractor.changeScene(Scenes.Shade, "") kosmos.sceneBackInteractor.onSceneChange(from = Scenes.Lockscreen, to = Scenes.Shade) assertThat(currentScene).isEqualTo(Scenes.Shade) assertThat(lockscreenVisibility).isTrue() val sceneBackStack by collectLastValue(kosmos.sceneBackInteractor.backStack) assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Lockscreen)) val isDeviceEntered by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEntered) val isDeviceEnteredDirectly by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEnteredDirectly) runCurrent() assertThat(isDeviceEntered).isFalse() assertThat(isDeviceEnteredDirectly).isFalse() kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) kosmos.sceneBackInteractor.updateBackStack { sceneStackOf(Scenes.Gone) } assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Gone)) assertThat(isDeviceEntered).isTrue() assertThat(isDeviceEnteredDirectly).isFalse() assertThat(isDeviceUnlocked).isTrue() assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun sceneContainer_usingGoingAwayAnimation_duringTransitionToGone() = Loading @@ -972,10 +1016,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { val usingKeyguardGoingAwayAnimation by collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation) sceneTransitions.value = lsToGone kosmos.setSceneTransition(lsToGone) assertThat(usingKeyguardGoingAwayAnimation).isTrue() sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone)) assertThat(usingKeyguardGoingAwayAnimation).isFalse() } Loading @@ -986,14 +1030,14 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { val usingKeyguardGoingAwayAnimation by collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation) sceneTransitions.value = lsToGone kosmos.setSceneTransition(lsToGone) surfaceBehindIsAnimatingFlow.emit(true) assertThat(usingKeyguardGoingAwayAnimation).isTrue() sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone)) assertThat(usingKeyguardGoingAwayAnimation).isTrue() sceneTransitions.value = goneToLs kosmos.setSceneTransition(goneToLs) assertThat(usingKeyguardGoingAwayAnimation).isTrue() surfaceBehindIsAnimatingFlow.emit(false) Loading @@ -1003,11 +1047,6 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { companion object { private val progress = MutableStateFlow(0f) private val sceneTransitions = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Lockscreen) ) private val lsToGone = ObservableTransitionState.Transition( Scenes.Lockscreen, Loading packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt +37 −14 Original line number Diff line number Diff line Loading @@ -84,16 +84,16 @@ constructor( ) /** * Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method). * This can be `false` when the device is unlocked, e.g. when the user still needs to swipe away * the non-secure lockscreen, even though they've already authenticated. * Emits `true` when the current scene switches to [Scenes.Gone] for the first time after having * been on [Scenes.Lockscreen]. * * Note: This does not imply that the lockscreen is visible or not. * Different from [isDeviceEntered] such that the current scene must actually go through * [Scenes.Gone] to produce a `true`. [isDeviceEntered] also takes into account the navigation * back stack and will produce a `true` value even when the current scene is still not * [Scenes.Gone] but the bottommost entry of the navigation back stack switched from * [Scenes.Lockscreen] to [Scenes.Gone] while the user is staring at another scene. */ val isDeviceEntered: StateFlow<Boolean> = combine( // This flow emits true when the currentScene switches to Gone for the first time // after having been on Lockscreen. val isDeviceEnteredDirectly: StateFlow<Boolean> = sceneInteractor.currentScene .filter { currentScene -> currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen Loading @@ -107,7 +107,30 @@ constructor( } else { false } }, } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, initialValue = false, ) /** * Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method). * This can be `false` when the device is unlocked, e.g. when the user still needs to swipe away * the non-secure lockscreen, even though they've already authenticated. * * Note: This does not imply that the lockscreen is visible or not. * * Different from [isDeviceEnteredDirectly] such that the current scene doesn't actually have to * go through [Scenes.Gone] to produce a `true`. [isDeviceEnteredDirectly] doesn't take the * navigation back stack into account and will only produce a `true` value even when the current * scene is actually [Scenes.Gone]. */ val isDeviceEntered: StateFlow<Boolean> = combine( // This flow emits true when the currentScene switches to Gone for the first time // after having been on Lockscreen. isDeviceEnteredDirectly, // This flow emits true only if the bottom of the navigation back stack has been // switched from Lockscreen to Gone. In other words, only if the device was unlocked // while visiting at least one scene "above" the Lockscreen scene. Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +7 −5 Original line number Diff line number Diff line Loading @@ -112,8 +112,10 @@ constructor( } .distinctUntilChanged() private val isDeviceEntered by lazy { deviceEntryInteractor.get().isDeviceEntered } private val isDeviceNotEntered by lazy { isDeviceEntered.map { !it } } private val isDeviceEnteredDirectly by lazy { deviceEntryInteractor.get().isDeviceEnteredDirectly } private val isDeviceNotEnteredDirectly by lazy { isDeviceEnteredDirectly.map { !it } } /** * Surface visibility, which is either determined by the default visibility when not Loading @@ -126,7 +128,7 @@ constructor( sceneInteractor.get().transitionState.flatMapLatestConflated { state -> when { state.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) -> isDeviceEntered isDeviceEnteredDirectly state.isTransitioning(from = Scenes.Bouncer, to = Scenes.Gone) -> (state as Transition).progress.map { progress -> progress > Loading Loading @@ -210,7 +212,7 @@ constructor( when (it.currentScene) { in keyguardScenes -> flowOf(true) in nonKeyguardScenes -> flowOf(false) in keyguardAgnosticScenes -> isDeviceNotEntered in keyguardAgnosticScenes -> isDeviceNotEnteredDirectly else -> throw IllegalStateException("Unknown scene: ${it.currentScene}") } Loading @@ -220,7 +222,7 @@ constructor( it.isTransitioningSets(from = keyguardScenes) -> flowOf(true) it.isTransitioningSets(from = nonKeyguardScenes) -> flowOf(false) it.isTransitioningSets(from = keyguardAgnosticScenes) -> isDeviceNotEntered isDeviceNotEnteredDirectly else -> throw IllegalStateException("Unknown scene: ${it.fromContent}") } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt +6 −5 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.scene.domain.interactor.sceneBackInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.sceneContainerStartable import com.android.systemui.scene.shared.model.Scenes Loading Loading @@ -72,7 +71,6 @@ class DeviceEntryInteractorTest : SysuiTestCase() { private val trustRepository by lazy { kosmos.fakeTrustRepository } private val sceneInteractor by lazy { kosmos.sceneInteractor } private val authenticationInteractor by lazy { kosmos.authenticationInteractor } private val sceneBackInteractor by lazy { kosmos.sceneBackInteractor } private val sceneContainerStartable by lazy { kosmos.sceneContainerStartable } private val sysuiStatusBarStateController by lazy { kosmos.sysuiStatusBarStateController } private lateinit var underTest: DeviceEntryInteractor Loading Loading @@ -437,7 +435,9 @@ class DeviceEntryInteractorTest : SysuiTestCase() { fun isDeviceEntered_unlockedWhileOnShade_emitsTrue() = testScope.runTest { val isDeviceEntered by collectLastValue(underTest.isDeviceEntered) val isDeviceEnteredDirectly by collectLastValue(underTest.isDeviceEnteredDirectly) assertThat(isDeviceEntered).isFalse() assertThat(isDeviceEnteredDirectly).isFalse() val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -445,19 +445,20 @@ class DeviceEntryInteractorTest : SysuiTestCase() { switchToScene(Scenes.Shade) assertThat(currentScene).isEqualTo(Scenes.Shade) // Simulating a "leave it open when the keyguard is hidden" which means the bouncer will // be // shown and successful authentication should take the user back to where they are, the // shade scene. // be shown and successful authentication should take the user back to where they are, // the shade scene. sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true) switchToScene(Scenes.Bouncer) assertThat(currentScene).isEqualTo(Scenes.Bouncer) assertThat(isDeviceEntered).isFalse() assertThat(isDeviceEnteredDirectly).isFalse() // Authenticate with PIN to unlock and dismiss the lockscreen: authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) runCurrent() assertThat(isDeviceEntered).isTrue() assertThat(isDeviceEnteredDirectly).isFalse() } private fun TestScope.switchToScene(sceneKey: SceneKey) { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +51 −12 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep import com.android.systemui.authentication.domain.interactor.authenticationInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer Loading @@ -34,10 +35,12 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.kosmos.testScope import com.android.systemui.scene.data.model.asIterable import com.android.systemui.scene.data.model.sceneStackOf import com.android.systemui.scene.data.repository.Idle import com.android.systemui.scene.data.repository.Transition import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.domain.interactor.sceneBackInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos Loading Loading @@ -85,7 +88,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { fun setUp() { // lazy value needs to be called here otherwise flow collection misbehaves underTest.value kosmos.sceneContainerRepository.setTransitionState(sceneTransitions) kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Lockscreen)) } @Test Loading Loading @@ -965,6 +968,47 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun lockscreenVisibilityWithScenes_staysTrue_despiteEnteringIndirectly() = testScope.runTest { val isDeviceUnlocked by collectLastValue( kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked } ) assertThat(isDeviceUnlocked).isFalse() val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility) assertThat(lockscreenVisibility).isTrue() kosmos.setSceneTransition(Idle(Scenes.Shade)) kosmos.sceneInteractor.changeScene(Scenes.Shade, "") kosmos.sceneBackInteractor.onSceneChange(from = Scenes.Lockscreen, to = Scenes.Shade) assertThat(currentScene).isEqualTo(Scenes.Shade) assertThat(lockscreenVisibility).isTrue() val sceneBackStack by collectLastValue(kosmos.sceneBackInteractor.backStack) assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Lockscreen)) val isDeviceEntered by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEntered) val isDeviceEnteredDirectly by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEnteredDirectly) runCurrent() assertThat(isDeviceEntered).isFalse() assertThat(isDeviceEnteredDirectly).isFalse() kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) kosmos.sceneBackInteractor.updateBackStack { sceneStackOf(Scenes.Gone) } assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Gone)) assertThat(isDeviceEntered).isTrue() assertThat(isDeviceEnteredDirectly).isFalse() assertThat(isDeviceUnlocked).isTrue() assertThat(lockscreenVisibility).isTrue() } @Test @EnableSceneContainer fun sceneContainer_usingGoingAwayAnimation_duringTransitionToGone() = Loading @@ -972,10 +1016,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { val usingKeyguardGoingAwayAnimation by collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation) sceneTransitions.value = lsToGone kosmos.setSceneTransition(lsToGone) assertThat(usingKeyguardGoingAwayAnimation).isTrue() sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone)) assertThat(usingKeyguardGoingAwayAnimation).isFalse() } Loading @@ -986,14 +1030,14 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { val usingKeyguardGoingAwayAnimation by collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation) sceneTransitions.value = lsToGone kosmos.setSceneTransition(lsToGone) surfaceBehindIsAnimatingFlow.emit(true) assertThat(usingKeyguardGoingAwayAnimation).isTrue() sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone)) assertThat(usingKeyguardGoingAwayAnimation).isTrue() sceneTransitions.value = goneToLs kosmos.setSceneTransition(goneToLs) assertThat(usingKeyguardGoingAwayAnimation).isTrue() surfaceBehindIsAnimatingFlow.emit(false) Loading @@ -1003,11 +1047,6 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { companion object { private val progress = MutableStateFlow(0f) private val sceneTransitions = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Lockscreen) ) private val lsToGone = ObservableTransitionState.Transition( Scenes.Lockscreen, Loading
packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt +37 −14 Original line number Diff line number Diff line Loading @@ -84,16 +84,16 @@ constructor( ) /** * Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method). * This can be `false` when the device is unlocked, e.g. when the user still needs to swipe away * the non-secure lockscreen, even though they've already authenticated. * Emits `true` when the current scene switches to [Scenes.Gone] for the first time after having * been on [Scenes.Lockscreen]. * * Note: This does not imply that the lockscreen is visible or not. * Different from [isDeviceEntered] such that the current scene must actually go through * [Scenes.Gone] to produce a `true`. [isDeviceEntered] also takes into account the navigation * back stack and will produce a `true` value even when the current scene is still not * [Scenes.Gone] but the bottommost entry of the navigation back stack switched from * [Scenes.Lockscreen] to [Scenes.Gone] while the user is staring at another scene. */ val isDeviceEntered: StateFlow<Boolean> = combine( // This flow emits true when the currentScene switches to Gone for the first time // after having been on Lockscreen. val isDeviceEnteredDirectly: StateFlow<Boolean> = sceneInteractor.currentScene .filter { currentScene -> currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen Loading @@ -107,7 +107,30 @@ constructor( } else { false } }, } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, initialValue = false, ) /** * Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method). * This can be `false` when the device is unlocked, e.g. when the user still needs to swipe away * the non-secure lockscreen, even though they've already authenticated. * * Note: This does not imply that the lockscreen is visible or not. * * Different from [isDeviceEnteredDirectly] such that the current scene doesn't actually have to * go through [Scenes.Gone] to produce a `true`. [isDeviceEnteredDirectly] doesn't take the * navigation back stack into account and will only produce a `true` value even when the current * scene is actually [Scenes.Gone]. */ val isDeviceEntered: StateFlow<Boolean> = combine( // This flow emits true when the currentScene switches to Gone for the first time // after having been on Lockscreen. isDeviceEnteredDirectly, // This flow emits true only if the bottom of the navigation back stack has been // switched from Lockscreen to Gone. In other words, only if the device was unlocked // while visiting at least one scene "above" the Lockscreen scene. Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +7 −5 Original line number Diff line number Diff line Loading @@ -112,8 +112,10 @@ constructor( } .distinctUntilChanged() private val isDeviceEntered by lazy { deviceEntryInteractor.get().isDeviceEntered } private val isDeviceNotEntered by lazy { isDeviceEntered.map { !it } } private val isDeviceEnteredDirectly by lazy { deviceEntryInteractor.get().isDeviceEnteredDirectly } private val isDeviceNotEnteredDirectly by lazy { isDeviceEnteredDirectly.map { !it } } /** * Surface visibility, which is either determined by the default visibility when not Loading @@ -126,7 +128,7 @@ constructor( sceneInteractor.get().transitionState.flatMapLatestConflated { state -> when { state.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) -> isDeviceEntered isDeviceEnteredDirectly state.isTransitioning(from = Scenes.Bouncer, to = Scenes.Gone) -> (state as Transition).progress.map { progress -> progress > Loading Loading @@ -210,7 +212,7 @@ constructor( when (it.currentScene) { in keyguardScenes -> flowOf(true) in nonKeyguardScenes -> flowOf(false) in keyguardAgnosticScenes -> isDeviceNotEntered in keyguardAgnosticScenes -> isDeviceNotEnteredDirectly else -> throw IllegalStateException("Unknown scene: ${it.currentScene}") } Loading @@ -220,7 +222,7 @@ constructor( it.isTransitioningSets(from = keyguardScenes) -> flowOf(true) it.isTransitioningSets(from = nonKeyguardScenes) -> flowOf(false) it.isTransitioningSets(from = keyguardAgnosticScenes) -> isDeviceNotEntered isDeviceNotEnteredDirectly else -> throw IllegalStateException("Unknown scene: ${it.fromContent}") } Loading