summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt120
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt19
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt2
3 files changed, 121 insertions, 20 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
index 38ed22a1c410..f0d79bb83652 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
@@ -33,6 +33,7 @@ import com.android.systemui.flags.fakeSystemPropertiesHelper
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeTrustRepository
import com.android.systemui.keyguard.shared.model.AuthenticationFlags
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
@@ -40,6 +41,8 @@ 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.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.fakeUserRepository
@@ -47,6 +50,7 @@ import com.android.systemui.user.domain.interactor.selectedUserInteractor
import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
@@ -230,11 +234,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
@Test
fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep() =
testScope.runTest {
- kosmos.fakeSettings.putIntForUser(
- Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- 0,
- kosmos.selectedUserInteractor.getSelectedUserId(),
- )
+ setLockAfterScreenTimeout(0)
kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false
val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
@@ -254,11 +254,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_afterDelay() =
testScope.runTest {
val delay = 5000
- kosmos.fakeSettings.putIntForUser(
- Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- delay,
- kosmos.selectedUserInteractor.getSelectedUserId(),
- )
+ setLockAfterScreenTimeout(delay)
kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false
val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
@@ -279,11 +275,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
@Test
fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_powerButtonLocksInstantly() =
testScope.runTest {
- kosmos.fakeSettings.putIntForUser(
- Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- 5000,
- kosmos.selectedUserInteractor.getSelectedUserId(),
- )
+ setLockAfterScreenTimeout(5000)
kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = true
val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
@@ -304,11 +296,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
@Test
fun deviceUnlockStatus_becomesUnlocked_whenFingerprintUnlocked_whileDeviceAsleep() =
testScope.runTest {
- kosmos.fakeSettings.putIntForUser(
- Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- 0,
- kosmos.selectedUserInteractor.getSelectedUserId(),
- )
+ setLockAfterScreenTimeout(0)
val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
@@ -517,6 +505,98 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
.isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
}
+ @Test
+ fun deviceUnlockStatus_locksImmediately_whenDreamStarts_noTimeout() =
+ testScope.runTest {
+ setLockAfterScreenTimeout(0)
+ val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked })
+ unlockDevice()
+
+ startDreaming()
+
+ assertThat(isUnlocked).isFalse()
+ }
+
+ @Test
+ fun deviceUnlockStatus_locksWithDelay_afterDreamStarts_withTimeout() =
+ testScope.runTest {
+ val delay = 5000
+ setLockAfterScreenTimeout(delay)
+ val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked })
+ unlockDevice()
+
+ startDreaming()
+ assertThat(isUnlocked).isTrue()
+
+ advanceTimeBy(delay - 1L)
+ assertThat(isUnlocked).isTrue()
+
+ advanceTimeBy(1L)
+ assertThat(isUnlocked).isFalse()
+ }
+
+ @Test
+ fun deviceUnlockStatus_doesNotLockWithDelay_whenDreamStopsBeforeTimeout() =
+ testScope.runTest {
+ val delay = 5000
+ setLockAfterScreenTimeout(delay)
+ val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked })
+ unlockDevice()
+
+ startDreaming()
+ assertThat(isUnlocked).isTrue()
+
+ advanceTimeBy(delay - 1L)
+ assertThat(isUnlocked).isTrue()
+
+ stopDreaming()
+ assertThat(isUnlocked).isTrue()
+
+ advanceTimeBy(1L)
+ assertThat(isUnlocked).isTrue()
+ }
+
+ @Test
+ fun deviceUnlockStatus_doesNotLock_whenDreamStarts_ifNotInteractive() =
+ testScope.runTest {
+ setLockAfterScreenTimeout(0)
+ val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked })
+ unlockDevice()
+
+ startDreaming()
+
+ assertThat(isUnlocked).isFalse()
+ }
+
+ private fun TestScope.unlockDevice() {
+ val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason")
+ runCurrent()
+ }
+
+ private fun setLockAfterScreenTimeout(timeoutMs: Int) {
+ kosmos.fakeSettings.putIntForUser(
+ Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ timeoutMs,
+ kosmos.selectedUserInteractor.getSelectedUserId(),
+ )
+ }
+
+ private fun TestScope.startDreaming() {
+ kosmos.fakeKeyguardRepository.setDreaming(true)
+ runCurrent()
+ }
+
+ private fun TestScope.stopDreaming() {
+ kosmos.fakeKeyguardRepository.setDreaming(false)
+ runCurrent()
+ }
+
private fun TestScope.verifyRestrictionReasonsForAuthFlags(
vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?>
) {
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
index 67584a599e5c..b74ca035a229 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
@@ -30,11 +30,13 @@ import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus
import com.android.systemui.flags.SystemPropertiesHelper
import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.TrustInteractor
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
@@ -49,6 +51,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
@@ -69,6 +72,7 @@ constructor(
private val biometricSettingsInteractor: DeviceEntryBiometricSettingsInteractor,
private val systemPropertiesHelper: SystemPropertiesHelper,
private val userAwareSecureSettingsRepository: UserAwareSecureSettingsRepository,
+ private val keyguardInteractor: KeyguardInteractor,
) : ExclusiveActivatable() {
private val deviceUnlockSource =
@@ -236,6 +240,21 @@ constructor(
.distinctUntilChanged()
.filter { it }
.map { LockImmediately("lockdown") },
+ // Started dreaming
+ powerInteractor.isInteractive.flatMapLatestConflated { isInteractive ->
+ // Only respond to dream state changes while the device is interactive.
+ if (isInteractive) {
+ keyguardInteractor.isDreamingAny.distinctUntilChanged().map { isDreaming ->
+ if (isDreaming) {
+ LockWithDelay("started dreaming")
+ } else {
+ CancelDelayedLock("stopped dreaming")
+ }
+ }
+ } else {
+ emptyFlow()
+ }
+ },
)
.collectLatest(::onLockEvent)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
index b76fa356de33..e4c7df64fdc6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
import com.android.systemui.flags.fakeSystemPropertiesHelper
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.trustInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -38,6 +39,7 @@ val Kosmos.deviceUnlockedInteractor by Fixture {
biometricSettingsInteractor = deviceEntryBiometricSettingsInteractor,
systemPropertiesHelper = fakeSystemPropertiesHelper,
userAwareSecureSettingsRepository = userAwareSecureSettingsRepository,
+ keyguardInteractor = keyguardInteractor,
)
.apply { activateIn(testScope) }
}