summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt27
2 files changed, 102 insertions, 2 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 6d4fffdefb1b..00710dc037fa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.scene.domain.startable
import android.app.StatusBarManager
@@ -121,6 +123,7 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository
import com.google.android.msdl.data.model.MSDLToken
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -2608,6 +2611,75 @@ class SceneContainerStartableTest : SysuiTestCase() {
}
@Test
+ fun handleDeviceUnlockStatus_returnsToLsFromBouncer_whenGoesToSleep() =
+ testScope.runTest {
+ val authMethod by collectLastValue(kosmos.authenticationInteractor.authenticationMethod)
+ val isUnlocked by
+ collectLastValue(
+ kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+ )
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ val isAwake by collectLastValue(powerInteractor.isAwake)
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ startsAwake = true,
+ )
+ underTest.start()
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
+ assertThat(isAwake).isTrue()
+
+ sceneInteractor.showOverlay(Overlays.Bouncer, "")
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
+ assertThat(isAwake).isTrue()
+
+ powerInteractor.setAsleepForTest()
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
+ assertThat(isAwake).isFalse()
+ }
+
+ @Test
+ fun hidesBouncer_whenAuthMethodChangesToNonSecure() =
+ testScope.runTest {
+ val authMethod by collectLastValue(kosmos.authenticationInteractor.authenticationMethod)
+ val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(kosmos.sceneInteractor.currentOverlays)
+ prepareState(
+ authenticationMethod = AuthenticationMethodModel.Password,
+ initialSceneKey = Scenes.Lockscreen,
+ )
+ underTest.start()
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Password)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
+
+ sceneInteractor.showOverlay(Overlays.Bouncer, "")
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Password)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
+
+ kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+ AuthenticationMethodModel.None
+ )
+ runCurrent()
+
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.None)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
+ }
+
+ @Test
fun replacesLockscreenSceneOnBackStack_whenFaceUnlocked_fromShade_noAlternateBouncer() =
testScope.runTest {
val transitionState =
@@ -2898,7 +2970,10 @@ class SceneContainerStartableTest : SysuiTestCase() {
sceneInteractor.changeScene(it, "prepareState, initialSceneKey isn't null")
}
for (overlay in initialOverlays) {
- sceneInteractor.showOverlay(overlay, "prepareState, initialOverlays isn't empty")
+ sceneInteractor.instantlyShowOverlay(
+ overlay,
+ "prepareState, initialOverlays isn't empty",
+ )
}
if (startsAwake) {
powerInteractor.setAwakeForTest()
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 06fc8610c97b..daaa2db54775 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -332,6 +332,7 @@ constructor(
/** Switches between scenes based on ever-changing application state. */
private fun automaticallySwitchScenes() {
handleBouncerImeVisibility()
+ handleBouncerHiding()
handleSimUnlock()
handleDeviceUnlockStatus()
handlePowerState()
@@ -352,6 +353,24 @@ constructor(
}
}
+ private fun handleBouncerHiding() {
+ applicationScope.launch {
+ repeatWhen(
+ condition =
+ authenticationInteractor
+ .get()
+ .authenticationMethod
+ .map { !it.isSecure }
+ .distinctUntilChanged()
+ ) {
+ sceneInteractor.hideOverlay(
+ overlay = Overlays.Bouncer,
+ loggingReason = "Authentication method changed to a non-secure one.",
+ )
+ }
+ }
+ }
+
private fun handleSimUnlock() {
applicationScope.launch {
simBouncerInteractor
@@ -434,6 +453,12 @@ constructor(
}
}
+ if (powerInteractor.detailedWakefulness.value.isAsleep()) {
+ // The logic below is for when the device becomes unlocked. That must be a
+ // no-op if the device is not awake.
+ return@mapNotNull null
+ }
+
if (
isOnPrimaryBouncer &&
deviceUnlockStatus.deviceUnlockSource == DeviceUnlockSource.TrustAgent
@@ -833,7 +858,7 @@ constructor(
}
.collect {
val loggingReason = "Falsing detected."
- switchToScene(Scenes.Lockscreen, loggingReason)
+ switchToScene(targetSceneKey = Scenes.Lockscreen, loggingReason = loggingReason)
}
}
}