Merge "[flexiglass] Resets the scene when the device goes to sleep." into udc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f0ba4ff127
@@ -144,12 +144,7 @@ constructor(
|
|||||||
private val lockPatternUtils: LockPatternUtils,
|
private val lockPatternUtils: LockPatternUtils,
|
||||||
) : AuthenticationRepository {
|
) : AuthenticationRepository {
|
||||||
|
|
||||||
override val isUnlocked: StateFlow<Boolean> =
|
override val isUnlocked: StateFlow<Boolean> = keyguardRepository.isKeyguardUnlocked
|
||||||
keyguardRepository.isKeyguardUnlocked.stateIn(
|
|
||||||
scope = applicationScope,
|
|
||||||
started = SharingStarted.WhileSubscribed(),
|
|
||||||
initialValue = false,
|
|
||||||
)
|
|
||||||
|
|
||||||
override suspend fun isLockscreenEnabled(): Boolean {
|
override suspend fun isLockscreenEnabled(): Boolean {
|
||||||
return withContext(backgroundDispatcher) {
|
return withContext(backgroundDispatcher) {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ interface KeyguardRepository {
|
|||||||
val isKeyguardShowing: Flow<Boolean>
|
val isKeyguardShowing: Flow<Boolean>
|
||||||
|
|
||||||
/** Is the keyguard in a unlocked state? */
|
/** Is the keyguard in a unlocked state? */
|
||||||
val isKeyguardUnlocked: Flow<Boolean>
|
val isKeyguardUnlocked: StateFlow<Boolean>
|
||||||
|
|
||||||
/** Is an activity showing over the keyguard? */
|
/** Is an activity showing over the keyguard? */
|
||||||
val isKeyguardOccluded: Flow<Boolean>
|
val isKeyguardOccluded: Flow<Boolean>
|
||||||
@@ -299,7 +299,7 @@ constructor(
|
|||||||
}
|
}
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
|
||||||
override val isKeyguardUnlocked: Flow<Boolean> =
|
override val isKeyguardUnlocked: StateFlow<Boolean> =
|
||||||
conflatedCallbackFlow {
|
conflatedCallbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
object : KeyguardStateController.Callback {
|
object : KeyguardStateController.Callback {
|
||||||
@@ -330,7 +330,11 @@ constructor(
|
|||||||
|
|
||||||
awaitClose { keyguardStateController.removeCallback(callback) }
|
awaitClose { keyguardStateController.removeCallback(callback) }
|
||||||
}
|
}
|
||||||
.distinctUntilChanged()
|
.stateIn(
|
||||||
|
scope = scope,
|
||||||
|
started = SharingStarted.WhileSubscribed(),
|
||||||
|
initialValue = keyguardStateController.isUnlocked,
|
||||||
|
)
|
||||||
|
|
||||||
override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
|
override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import com.android.systemui.dagger.SysUISingleton
|
|||||||
import com.android.systemui.dagger.qualifiers.Application
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
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.domain.interactor.SceneInteractor
|
||||||
import com.android.systemui.scene.shared.model.SceneContainerNames
|
import com.android.systemui.scene.shared.model.SceneContainerNames
|
||||||
import com.android.systemui.scene.shared.model.SceneKey
|
import com.android.systemui.scene.shared.model.SceneKey
|
||||||
@@ -45,6 +47,7 @@ constructor(
|
|||||||
@Application private val applicationScope: CoroutineScope,
|
@Application private val applicationScope: CoroutineScope,
|
||||||
private val sceneInteractor: SceneInteractor,
|
private val sceneInteractor: SceneInteractor,
|
||||||
private val authenticationInteractor: AuthenticationInteractor,
|
private val authenticationInteractor: AuthenticationInteractor,
|
||||||
|
private val keyguardInteractor: KeyguardInteractor,
|
||||||
private val featureFlags: FeatureFlags,
|
private val featureFlags: FeatureFlags,
|
||||||
) : CoreStartable {
|
) : CoreStartable {
|
||||||
|
|
||||||
@@ -78,7 +81,7 @@ constructor(
|
|||||||
when {
|
when {
|
||||||
isUnlocked ->
|
isUnlocked ->
|
||||||
when (currentSceneKey) {
|
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
|
is SceneKey.Bouncer -> SceneKey.Gone
|
||||||
// When the device becomes unlocked in Lockscreen, go to Gone if
|
// When the device becomes unlocked in Lockscreen, go to Gone if
|
||||||
// bypass is enabled.
|
// bypass is enabled.
|
||||||
@@ -101,14 +104,29 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.filterNotNull()
|
.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(
|
sceneInteractor.setCurrentScene(
|
||||||
containerName = CONTAINER_NAME,
|
containerName = CONTAINER_NAME,
|
||||||
scene = SceneModel(targetSceneKey),
|
scene = SceneModel(targetSceneKey),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT
|
private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import androidx.test.filters.SmallTest
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.coroutines.collectLastValue
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
import com.android.systemui.flags.Flags
|
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.SceneTestUtils
|
||||||
import com.android.systemui.scene.shared.model.SceneContainerNames
|
import com.android.systemui.scene.shared.model.SceneContainerNames
|
||||||
import com.android.systemui.scene.shared.model.SceneKey
|
import com.android.systemui.scene.shared.model.SceneKey
|
||||||
@@ -47,12 +50,18 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
|
|||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
repository = authenticationRepository,
|
repository = authenticationRepository,
|
||||||
)
|
)
|
||||||
|
private val keyguardRepository = utils.keyguardRepository()
|
||||||
|
private val keyguardInteractor =
|
||||||
|
utils.keyguardInteractor(
|
||||||
|
repository = keyguardRepository,
|
||||||
|
)
|
||||||
|
|
||||||
private val underTest =
|
private val underTest =
|
||||||
SystemUiDefaultSceneContainerStartable(
|
SystemUiDefaultSceneContainerStartable(
|
||||||
applicationScope = testScope.backgroundScope,
|
applicationScope = testScope.backgroundScope,
|
||||||
sceneInteractor = sceneInteractor,
|
sceneInteractor = sceneInteractor,
|
||||||
authenticationInteractor = authenticationInteractor,
|
authenticationInteractor = authenticationInteractor,
|
||||||
|
keyguardInteractor = keyguardInteractor,
|
||||||
featureFlags = featureFlags,
|
featureFlags = featureFlags,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -280,6 +289,94 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
|
|||||||
assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
|
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(
|
private fun prepareState(
|
||||||
isFeatureEnabled: Boolean = true,
|
isFeatureEnabled: Boolean = true,
|
||||||
isDeviceUnlocked: Boolean = false,
|
isDeviceUnlocked: Boolean = false,
|
||||||
@@ -293,4 +390,13 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
|
|||||||
sceneInteractor.setCurrentScene(SceneContainerNames.SYSTEM_UI_DEFAULT, SceneModel(it))
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class FakeKeyguardRepository : KeyguardRepository {
|
|||||||
override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
|
override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
|
||||||
|
|
||||||
private val _isKeyguardUnlocked = MutableStateFlow(false)
|
private val _isKeyguardUnlocked = MutableStateFlow(false)
|
||||||
override val isKeyguardUnlocked: Flow<Boolean> = _isKeyguardUnlocked
|
override val isKeyguardUnlocked: StateFlow<Boolean> = _isKeyguardUnlocked.asStateFlow()
|
||||||
|
|
||||||
private val _isKeyguardOccluded = MutableStateFlow(false)
|
private val _isKeyguardOccluded = MutableStateFlow(false)
|
||||||
override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded
|
override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded
|
||||||
|
|||||||
@@ -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.data.repository.FakeAuthenticationRepository
|
||||||
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
|
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
|
||||||
import com.android.systemui.bouncer.data.repository.BouncerRepository
|
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.domain.interactor.BouncerInteractor
|
||||||
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
|
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.FakeFeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
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.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.data.repository.SceneContainerRepository
|
||||||
import com.android.systemui.scene.domain.interactor.SceneInteractor
|
import com.android.systemui.scene.domain.interactor.SceneInteractor
|
||||||
import com.android.systemui.scene.shared.model.SceneContainerConfig
|
import com.android.systemui.scene.shared.model.SceneContainerConfig
|
||||||
@@ -53,7 +62,11 @@ class SceneTestUtils(
|
|||||||
) {
|
) {
|
||||||
val testDispatcher = StandardTestDispatcher()
|
val testDispatcher = StandardTestDispatcher()
|
||||||
val testScope = TestScope(testDispatcher)
|
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 {
|
private val userRepository: UserRepository by lazy {
|
||||||
FakeUserRepository().apply {
|
FakeUserRepository().apply {
|
||||||
val users = listOf(UserInfo(/* id= */ 0, "name", /* flags= */ 0))
|
val users = listOf(UserInfo(/* id= */ 0, "name", /* flags= */ 0))
|
||||||
@@ -67,6 +80,17 @@ class SceneTestUtils(
|
|||||||
currentTime = { testScope.currentTime },
|
currentTime = { testScope.currentTime },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val keyguardRepository: FakeKeyguardRepository by lazy {
|
||||||
|
FakeKeyguardRepository().apply {
|
||||||
|
setWakefulnessModel(
|
||||||
|
WakefulnessModel(
|
||||||
|
WakefulnessState.AWAKE,
|
||||||
|
WakeSleepReason.OTHER,
|
||||||
|
WakeSleepReason.OTHER,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
private val context = test.context
|
private val context = test.context
|
||||||
|
|
||||||
fun fakeSceneContainerRepository(
|
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(
|
fun bouncerInteractor(
|
||||||
authenticationInteractor: AuthenticationInteractor,
|
authenticationInteractor: AuthenticationInteractor,
|
||||||
sceneInteractor: SceneInteractor,
|
sceneInteractor: SceneInteractor,
|
||||||
|
|||||||
Reference in New Issue
Block a user