Merge "[flexiglass] hide and cancel AlternateBouncer when device sleeps" into main
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 bbb467f..64a13de 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
@@ -28,9 +28,7 @@
import com.android.internal.logging.uiEventLoggerFake
import com.android.internal.policy.IKeyguardDismissCallback
import com.android.systemui.SysuiTestCase
-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.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
@@ -357,6 +355,7 @@
kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
SuccessFingerprintAuthenticationStatus(0, true)
)
+ runCurrent()
assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
assertThat(alternateBouncerVisible).isFalse()
@@ -507,6 +506,33 @@
}
@Test
+ fun hideAlternateBouncerAndNotifyDismissCancelledWhenDeviceSleeps() =
+ testScope.runTest {
+ val alternateBouncerVisible by
+ collectLastValue(bouncerRepository.alternateBouncerVisible)
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Shade,
+ )
+ assertThat(currentSceneKey).isEqualTo(Scenes.Shade)
+ bouncerRepository.setAlternateVisible(true)
+ underTest.start()
+
+ // run all pending dismiss succeeded/cancelled calls from setup:
+ kosmos.fakeExecutor.runAllReady()
+
+ val dismissCallback: IKeyguardDismissCallback = mock()
+ kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
+ powerInteractor.setAsleepForTest()
+ runCurrent()
+ kosmos.fakeExecutor.runAllReady()
+
+ assertThat(alternateBouncerVisible).isFalse()
+ verify(dismissCallback).onDismissCancelled()
+ }
+
+ @Test
fun switchToLockscreenWhenDeviceSleepsLocked() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
@@ -1644,19 +1670,27 @@
}
@Test
- fun notifyKeyguardDismissCallbacks_whenUnlocking_onDismissSucceeded() =
+ fun notifyKeyguardDismissCallbacks_whenUnlockingFromBouncer_onDismissSucceeded() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- prepareState()
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ prepareState(
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Bouncer,
+ )
+ assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
underTest.start()
+
+ // run all pending dismiss succeeded/cancelled calls from setup:
+ kosmos.fakeExecutor.runAllReady()
+
val dismissCallback: IKeyguardDismissCallback = mock()
kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
- // Switch to bouncer and unlock device:
- sceneInteractor.changeScene(Scenes.Bouncer, "")
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
- kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
- assertThat(currentScene).isEqualTo(Scenes.Gone)
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
kosmos.fakeExecutor.runAllReady()
verify(dismissCallback).onDismissSucceeded()
@@ -1665,19 +1699,26 @@
@Test
fun notifyKeyguardDismissCallbacks_whenLeavingBouncer_onDismissCancelled() =
testScope.runTest {
+ val isUnlocked by collectLastValue(kosmos.deviceEntryInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene)
prepareState()
underTest.start()
+
+ // run all pending dismiss succeeded/cancelled calls from setup:
+ kosmos.fakeExecutor.runAllReady()
+
val dismissCallback: IKeyguardDismissCallback = mock()
kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
// Switch to bouncer:
sceneInteractor.changeScene(Scenes.Bouncer, "")
assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ runCurrent()
- // Return to lockscreen:
+ // Return to lockscreen when isUnlocked=false:
sceneInteractor.changeScene(Scenes.Lockscreen, "")
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(isUnlocked).isFalse()
runCurrent()
kosmos.fakeExecutor.runAllReady()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
index 1c445a7..7801c00 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
@@ -17,15 +17,16 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.DismissAction
import com.android.systemui.keyguard.shared.model.KeyguardDone
-import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
+import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.domain.resolver.NotifShadeSceneFamilyResolver
import com.android.systemui.scene.domain.resolver.QuickSettingsSceneFamilyResolver
@@ -61,6 +62,8 @@
deviceEntryInteractor: DeviceEntryInteractor,
quickSettingsSceneFamilyResolver: QuickSettingsSceneFamilyResolver,
notifShadeSceneFamilyResolver: NotifShadeSceneFamilyResolver,
+ powerInteractor: PowerInteractor,
+ alternateBouncerInteractor: AlternateBouncerInteractor,
) {
val dismissAction: Flow<DismissAction> = repository.dismissAction
@@ -124,10 +127,12 @@
scene = Scenes.Bouncer,
stateWithoutSceneContainer = PRIMARY_BOUNCER
),
- transitionInteractor.isFinishedIn(state = ALTERNATE_BOUNCER),
+ alternateBouncerInteractor.isVisible,
isOnShadeWhileUnlocked,
- ) { isOnGone, isOnBouncer, isOnAltBouncer, isOnShadeWhileUnlocked ->
- !isOnGone && !isOnBouncer && !isOnAltBouncer && !isOnShadeWhileUnlocked
+ powerInteractor.isAsleep,
+ ) { isOnGone, isOnBouncer, isOnAltBouncer, isOnShadeWhileUnlocked, isAsleep ->
+ (!isOnGone && !isOnBouncer && !isOnAltBouncer && !isOnShadeWhileUnlocked) ||
+ isAsleep
}
.filter { it }
.sampleFilter(dismissAction) { it !is DismissAction.None }
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 e73664d..cc46216 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
@@ -152,7 +152,7 @@
hydrateBackStack()
resetShadeSessions()
handleKeyguardEnabledness()
- notifyKeyguardDismissCallbacks()
+ notifyKeyguardDismissCancelledCallbacks()
refreshLockscreenEnabled()
} else {
sceneLogger.logFrameworkEnabled(
@@ -379,8 +379,10 @@
when {
isAlternateBouncerVisible -> {
// When the device becomes unlocked when the alternate bouncer is
- // showing, always hide the alternate bouncer...
+ // showing, always hide the alternate bouncer and notify dismiss
+ // succeeded
alternateBouncerInteractor.hide()
+ dismissCallbackRegistry.notifyDismissSucceeded()
// ... and go to Gone or stay on the current scene
if (
@@ -394,9 +396,11 @@
null
}
}
- isOnPrimaryBouncer ->
+ isOnPrimaryBouncer -> {
// When the device becomes unlocked in primary Bouncer,
+ // notify dismiss succeeded and
// go to previous scene or Gone.
+ dismissCallbackRegistry.notifyDismissSucceeded()
if (
previousScene.value == Scenes.Lockscreen ||
!statusBarStateController.leaveOpenOnKeyguardHide()
@@ -410,6 +414,7 @@
"device was unlocked with primary bouncer showing," +
" from sceneKey=$prevScene"
}
+ }
isOnLockscreen ->
// The lockscreen should be dismissed automatically in 2 scenarios:
// 1. When face auth bypass is enabled and authentication happens while
@@ -468,6 +473,9 @@
applicationScope.launch {
powerInteractor.isAsleep.collect { isAsleep ->
if (isAsleep) {
+ alternateBouncerInteractor.hide()
+ dismissCallbackRegistry.notifyDismissCancelled()
+
switchToScene(
targetSceneKey = Scenes.Lockscreen,
loggingReason = "device is starting to sleep",
@@ -771,15 +779,23 @@
}
}
- private fun notifyKeyguardDismissCallbacks() {
+ private fun notifyKeyguardDismissCancelledCallbacks() {
applicationScope.launch {
- sceneInteractor.currentScene.pairwise().collect { (from, to) ->
- when {
- from != Scenes.Bouncer -> Unit
- to == Scenes.Gone -> dismissCallbackRegistry.notifyDismissSucceeded()
- else -> dismissCallbackRegistry.notifyDismissCancelled()
+ combine(
+ deviceEntryInteractor.isUnlocked,
+ sceneInteractor.currentScene.pairwise(),
+ ) { isUnlocked, (from, to) ->
+ when {
+ from != Scenes.Bouncer -> false
+ to != Scenes.Gone && !isUnlocked -> true
+ else -> false
+ }
}
- }
+ .collect { notifyKeyguardDismissCancelled ->
+ if (notifyKeyguardDismissCancelled) {
+ dismissCallbackRegistry.notifyDismissCancelled()
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index de4d14d..0f93ff2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -545,6 +545,7 @@
@VisibleForTesting
void consumeFromAlternateBouncerTransitionSteps(TransitionStep step) {
+ SceneContainerFlag.assertInLegacyMode();
hideAlternateBouncer(false);
}
@@ -554,6 +555,7 @@
*/
@VisibleForTesting
void consumeKeyguardAuthenticatedBiometricsHandled(Unit handled) {
+ SceneContainerFlag.assertInLegacyMode();
if (mAlternateBouncerInteractor.isVisibleState()) {
hideAlternateBouncer(false);
}
@@ -981,7 +983,7 @@
} else {
showBouncerOrKeyguard(hideBouncerWhenShowing, isFalsingReset);
}
- if (hideBouncerWhenShowing) {
+ if (!SceneContainerFlag.isEnabled() && hideBouncerWhenShowing) {
hideAlternateBouncer(true);
}
mKeyguardUpdateManager.sendKeyguardReset();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index 32d059b..a0fe538b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -22,6 +22,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
@@ -29,6 +30,10 @@
import com.android.systemui.keyguard.shared.model.DismissAction
import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.data.repository.fakePowerRepository
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
@@ -82,6 +87,8 @@
deviceEntryInteractor = kosmos.deviceEntryInteractor,
quickSettingsSceneFamilyResolver = kosmos.quickSettingsSceneFamilyResolver,
notifShadeSceneFamilyResolver = kosmos.notifShadeSceneFamilyResolver,
+ powerInteractor = kosmos.powerInteractor,
+ alternateBouncerInteractor = kosmos.alternateBouncerInteractor,
)
}
@@ -234,6 +241,32 @@
}
@Test
+ fun resetDismissAction_onBouncer_OnAsleep() =
+ testScope.runTest {
+ kosmos.setSceneTransition(Idle(Scenes.Bouncer))
+ kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+ AuthenticationMethodModel.None
+ )
+ val resetDismissAction by collectLastValue(underTest.resetDismissAction)
+ keyguardRepository.setDismissAction(
+ DismissAction.RunAfterKeyguardGone(
+ dismissAction = {},
+ onCancelAction = {},
+ message = "message",
+ willAnimateOnLockscreen = true,
+ )
+ )
+ assertThat(resetDismissAction).isNull()
+ kosmos.fakePowerRepository.updateWakefulness(
+ rawState = WakefulnessState.ASLEEP,
+ lastWakeReason = WakeSleepReason.POWER_BUTTON,
+ lastSleepReason = WakeSleepReason.TIMEOUT,
+ powerButtonLaunchGestureTriggered = false,
+ )
+ assertThat(resetDismissAction).isEqualTo(Unit)
+ }
+
+ @Test
fun setDismissAction_callsCancelRunnableOnPreviousDismissAction() =
testScope.runTest {
val dismissAction by collectLastValue(underTest.dismissAction)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
index 957f092..27eadb1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
@@ -16,10 +16,12 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.notifShadeSceneFamilyResolver
import com.android.systemui.scene.domain.resolver.quickSettingsSceneFamilyResolver
@@ -37,5 +39,7 @@
deviceEntryInteractor = deviceEntryInteractor,
quickSettingsSceneFamilyResolver = quickSettingsSceneFamilyResolver,
notifShadeSceneFamilyResolver = notifShadeSceneFamilyResolver,
+ powerInteractor = powerInteractor,
+ alternateBouncerInteractor = alternateBouncerInteractor,
)
}