Merge "[flexiglass] Resets the scene when the device goes to sleep." into udc-qpr-dev

This commit is contained in:
Danny Burakov
2023-07-12 12:10:14 +00:00
committed by Android (Google) Code Review
6 changed files with 178 additions and 17 deletions

View File

@@ -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) {

View File

@@ -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>
@@ -299,7 +299,7 @@ constructor(
}
.distinctUntilChanged()
override val isKeyguardUnlocked: Flow<Boolean> =
override val isKeyguardUnlocked: StateFlow<Boolean> =
conflatedCallbackFlow {
val callback =
object : KeyguardStateController.Callback {
@@ -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 =

View File

@@ -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
@@ -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 {
@@ -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.
@@ -101,15 +104,30 @@ constructor(
}
}
.filterNotNull()
.collect { targetSceneKey ->
sceneInteractor.setCurrentScene(
containerName = CONTAINER_NAME,
scene = SceneModel(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
}

View File

@@ -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
@@ -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,
)
@@ -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,
@@ -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
)
}
}

View File

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

View File

@@ -22,11 +22,20 @@ import com.android.systemui.authentication.data.repository.AuthenticationReposit
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.bouncer.data.repository.BouncerRepository
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
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.data.repository.SceneContainerRepository
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneContainerConfig
@@ -53,7 +62,11 @@ class SceneTestUtils(
) {
val testDispatcher = StandardTestDispatcher()
val testScope = TestScope(testDispatcher)
val featureFlags = FakeFeatureFlags().apply { set(Flags.SCENE_CONTAINER, true) }
val featureFlags =
FakeFeatureFlags().apply {
set(Flags.SCENE_CONTAINER, true)
set(Flags.FACE_AUTH_REFACTOR, false)
}
private val userRepository: UserRepository by lazy {
FakeUserRepository().apply {
val users = listOf(UserInfo(/* id= */ 0, "name", /* flags= */ 0))
@@ -67,6 +80,17 @@ class SceneTestUtils(
currentTime = { testScope.currentTime },
)
}
val keyguardRepository: FakeKeyguardRepository by lazy {
FakeKeyguardRepository().apply {
setWakefulnessModel(
WakefulnessModel(
WakefulnessState.AWAKE,
WakeSleepReason.OTHER,
WakeSleepReason.OTHER,
)
)
}
}
private val context = test.context
fun fakeSceneContainerRepository(
@@ -122,6 +146,20 @@ class SceneTestUtils(
)
}
fun keyguardRepository(): FakeKeyguardRepository {
return keyguardRepository
}
fun keyguardInteractor(repository: KeyguardRepository): KeyguardInteractor {
return KeyguardInteractor(
repository = repository,
commandQueue = FakeCommandQueue(),
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
configurationRepository = FakeConfigurationRepository()
)
}
fun bouncerInteractor(
authenticationInteractor: AuthenticationInteractor,
sceneInteractor: SceneInteractor,