Loading packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt +1 −6 Original line number Diff line number Diff line Loading @@ -144,12 +144,7 @@ constructor( private val lockPatternUtils: LockPatternUtils, ) : AuthenticationRepository { override val isUnlocked: StateFlow<Boolean> = keyguardRepository.isKeyguardUnlocked.stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = false, ) override val isUnlocked: StateFlow<Boolean> = keyguardRepository.isKeyguardUnlocked override suspend fun isLockscreenEnabled(): Boolean { return withContext(backgroundDispatcher) { Loading packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +7 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ interface KeyguardRepository { val isKeyguardShowing: Flow<Boolean> /** Is the keyguard in a unlocked state? */ val isKeyguardUnlocked: Flow<Boolean> val isKeyguardUnlocked: StateFlow<Boolean> /** Is an activity showing over the keyguard? */ val isKeyguardOccluded: Flow<Boolean> Loading Loading @@ -299,7 +299,7 @@ constructor( } .distinctUntilChanged() override val isKeyguardUnlocked: Flow<Boolean> = override val isKeyguardUnlocked: StateFlow<Boolean> = conflatedCallbackFlow { val callback = object : KeyguardStateController.Callback { Loading Loading @@ -330,7 +330,11 @@ constructor( awaitClose { keyguardStateController.removeCallback(callback) } } .distinctUntilChanged() .stateIn( scope = scope, started = SharingStarted.WhileSubscribed(), initialValue = keyguardStateController.isUnlocked, ) override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow { val callback = Loading packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt +24 −6 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneKey Loading @@ -45,6 +47,7 @@ constructor( @Application private val applicationScope: CoroutineScope, private val sceneInteractor: SceneInteractor, private val authenticationInteractor: AuthenticationInteractor, private val keyguardInteractor: KeyguardInteractor, private val featureFlags: FeatureFlags, ) : CoreStartable { Loading Loading @@ -78,7 +81,7 @@ constructor( when { isUnlocked -> when (currentSceneKey) { // When the device becomes unlocked in Bouncer, go to the Gone. // When the device becomes unlocked in Bouncer, go to Gone. is SceneKey.Bouncer -> SceneKey.Gone // When the device becomes unlocked in Lockscreen, go to Gone if // bypass is enabled. Loading @@ -101,14 +104,29 @@ constructor( } } .filterNotNull() .collect { targetSceneKey -> .collect { targetSceneKey -> switchToScene(targetSceneKey) } } applicationScope.launch { keyguardInteractor.wakefulnessModel .map { it.state == WakefulnessState.ASLEEP } .distinctUntilChanged() .collect { isAsleep -> if (isAsleep) { // When the device goes to sleep, reset the current scene. val isUnlocked = authenticationInteractor.isUnlocked.value switchToScene(if (isUnlocked) SceneKey.Gone else SceneKey.Lockscreen) } } } } private fun switchToScene(targetSceneKey: SceneKey) { sceneInteractor.setCurrentScene( containerName = CONTAINER_NAME, scene = SceneModel(targetSceneKey), ) } } } companion object { private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT Loading packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt +106 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneKey Loading Loading @@ -47,12 +50,18 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { utils.authenticationInteractor( repository = authenticationRepository, ) private val keyguardRepository = utils.keyguardRepository() private val keyguardInteractor = utils.keyguardInteractor( repository = keyguardRepository, ) private val underTest = SystemUiDefaultSceneContainerStartable( applicationScope = testScope.backgroundScope, sceneInteractor = sceneInteractor, authenticationInteractor = authenticationInteractor, keyguardInteractor = keyguardInteractor, featureFlags = featureFlags, ) Loading Loading @@ -280,6 +289,94 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen) } @Test fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = true, isDeviceUnlocked = true, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Gone) } @Test fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = false, isDeviceUnlocked = true, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) } @Test fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = true, isDeviceUnlocked = false, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen) } @Test fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = false, isDeviceUnlocked = false, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) } private fun prepareState( isFeatureEnabled: Boolean = true, isDeviceUnlocked: Boolean = false, Loading @@ -293,4 +390,13 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { sceneInteractor.setCurrentScene(SceneContainerNames.SYSTEM_UI_DEFAULT, SceneModel(it)) } } companion object { private val ASLEEP = WakefulnessModel( state = WakefulnessState.ASLEEP, lastWakeReason = WakeSleepReason.POWER_BUTTON, lastSleepReason = WakeSleepReason.POWER_BUTTON ) } } packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ class FakeKeyguardRepository : KeyguardRepository { override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing private val _isKeyguardUnlocked = MutableStateFlow(false) override val isKeyguardUnlocked: Flow<Boolean> = _isKeyguardUnlocked override val isKeyguardUnlocked: StateFlow<Boolean> = _isKeyguardUnlocked.asStateFlow() private val _isKeyguardOccluded = MutableStateFlow(false) override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded Loading Loading
packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt +1 −6 Original line number Diff line number Diff line Loading @@ -144,12 +144,7 @@ constructor( private val lockPatternUtils: LockPatternUtils, ) : AuthenticationRepository { override val isUnlocked: StateFlow<Boolean> = keyguardRepository.isKeyguardUnlocked.stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = false, ) override val isUnlocked: StateFlow<Boolean> = keyguardRepository.isKeyguardUnlocked override suspend fun isLockscreenEnabled(): Boolean { return withContext(backgroundDispatcher) { Loading
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +7 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ interface KeyguardRepository { val isKeyguardShowing: Flow<Boolean> /** Is the keyguard in a unlocked state? */ val isKeyguardUnlocked: Flow<Boolean> val isKeyguardUnlocked: StateFlow<Boolean> /** Is an activity showing over the keyguard? */ val isKeyguardOccluded: Flow<Boolean> Loading Loading @@ -299,7 +299,7 @@ constructor( } .distinctUntilChanged() override val isKeyguardUnlocked: Flow<Boolean> = override val isKeyguardUnlocked: StateFlow<Boolean> = conflatedCallbackFlow { val callback = object : KeyguardStateController.Callback { Loading Loading @@ -330,7 +330,11 @@ constructor( awaitClose { keyguardStateController.removeCallback(callback) } } .distinctUntilChanged() .stateIn( scope = scope, started = SharingStarted.WhileSubscribed(), initialValue = keyguardStateController.isUnlocked, ) override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow { val callback = Loading
packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt +24 −6 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneKey Loading @@ -45,6 +47,7 @@ constructor( @Application private val applicationScope: CoroutineScope, private val sceneInteractor: SceneInteractor, private val authenticationInteractor: AuthenticationInteractor, private val keyguardInteractor: KeyguardInteractor, private val featureFlags: FeatureFlags, ) : CoreStartable { Loading Loading @@ -78,7 +81,7 @@ constructor( when { isUnlocked -> when (currentSceneKey) { // When the device becomes unlocked in Bouncer, go to the Gone. // When the device becomes unlocked in Bouncer, go to Gone. is SceneKey.Bouncer -> SceneKey.Gone // When the device becomes unlocked in Lockscreen, go to Gone if // bypass is enabled. Loading @@ -101,14 +104,29 @@ constructor( } } .filterNotNull() .collect { targetSceneKey -> .collect { targetSceneKey -> switchToScene(targetSceneKey) } } applicationScope.launch { keyguardInteractor.wakefulnessModel .map { it.state == WakefulnessState.ASLEEP } .distinctUntilChanged() .collect { isAsleep -> if (isAsleep) { // When the device goes to sleep, reset the current scene. val isUnlocked = authenticationInteractor.isUnlocked.value switchToScene(if (isUnlocked) SceneKey.Gone else SceneKey.Lockscreen) } } } } private fun switchToScene(targetSceneKey: SceneKey) { sceneInteractor.setCurrentScene( containerName = CONTAINER_NAME, scene = SceneModel(targetSceneKey), ) } } } companion object { private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT Loading
packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt +106 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneKey Loading Loading @@ -47,12 +50,18 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { utils.authenticationInteractor( repository = authenticationRepository, ) private val keyguardRepository = utils.keyguardRepository() private val keyguardInteractor = utils.keyguardInteractor( repository = keyguardRepository, ) private val underTest = SystemUiDefaultSceneContainerStartable( applicationScope = testScope.backgroundScope, sceneInteractor = sceneInteractor, authenticationInteractor = authenticationInteractor, keyguardInteractor = keyguardInteractor, featureFlags = featureFlags, ) Loading Loading @@ -280,6 +289,94 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen) } @Test fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = true, isDeviceUnlocked = true, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Gone) } @Test fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = false, isDeviceUnlocked = true, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) } @Test fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = true, isDeviceUnlocked = false, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen) } @Test fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() = testScope.runTest { val currentSceneKey by collectLastValue( sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map { it.key } ) prepareState( isFeatureEnabled = false, isDeviceUnlocked = false, initialSceneKey = SceneKey.Shade, ) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) underTest.start() keyguardRepository.setWakefulnessModel(ASLEEP) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) } private fun prepareState( isFeatureEnabled: Boolean = true, isDeviceUnlocked: Boolean = false, Loading @@ -293,4 +390,13 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { sceneInteractor.setCurrentScene(SceneContainerNames.SYSTEM_UI_DEFAULT, SceneModel(it)) } } companion object { private val ASLEEP = WakefulnessModel( state = WakefulnessState.ASLEEP, lastWakeReason = WakeSleepReason.POWER_BUTTON, lastSleepReason = WakeSleepReason.POWER_BUTTON ) } }
packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ class FakeKeyguardRepository : KeyguardRepository { override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing private val _isKeyguardUnlocked = MutableStateFlow(false) override val isKeyguardUnlocked: Flow<Boolean> = _isKeyguardUnlocked override val isKeyguardUnlocked: StateFlow<Boolean> = _isKeyguardUnlocked.asStateFlow() private val _isKeyguardOccluded = MutableStateFlow(false) override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded Loading