diff options
author | 2024-08-19 21:02:09 +0000 | |
---|---|---|
committer | 2024-08-19 21:02:09 +0000 | |
commit | d3e5ab1f857a60ab007fd78823e3a6cfdb5c9568 (patch) | |
tree | 76067d9db6f3476d24921c3a7b28908bc77e5321 | |
parent | bf2fcba244ec171d9382e0c2e0311fa5730c8129 (diff) | |
parent | ddf249118d35308d0a137de4b018b99bc3c83b73 (diff) |
Merge "[flexiglass] hide and cancel AlternateBouncer when device sleeps" into main
6 files changed, 127 insertions, 26 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 bbb467f4f33d..64a13de2145f 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.compose.animation.scene.SceneKey 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 @@ class SceneContainerStartableTest : SysuiTestCase() { kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) + runCurrent() assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings) assertThat(alternateBouncerVisible).isFalse() @@ -507,6 +506,33 @@ class SceneContainerStartableTest : SysuiTestCase() { } @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 @@ class SceneContainerStartableTest : SysuiTestCase() { } @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 @@ class SceneContainerStartableTest : SysuiTestCase() { @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 1c445a703bc4..7801c00d83b8 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 @@ constructor( deviceEntryInteractor: DeviceEntryInteractor, quickSettingsSceneFamilyResolver: QuickSettingsSceneFamilyResolver, notifShadeSceneFamilyResolver: NotifShadeSceneFamilyResolver, + powerInteractor: PowerInteractor, + alternateBouncerInteractor: AlternateBouncerInteractor, ) { val dismissAction: Flow<DismissAction> = repository.dismissAction @@ -124,10 +127,12 @@ constructor( 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 e73664d43952..cc46216b6e43 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 @@ constructor( hydrateBackStack() resetShadeSessions() handleKeyguardEnabledness() - notifyKeyguardDismissCallbacks() + notifyKeyguardDismissCancelledCallbacks() refreshLockscreenEnabled() } else { sceneLogger.logFrameworkEnabled( @@ -379,8 +379,10 @@ constructor( 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 @@ constructor( 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 @@ constructor( "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 @@ constructor( 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 @@ constructor( } } - 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 de4d14d31da3..0f93ff2b70ed 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 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb @VisibleForTesting void consumeFromAlternateBouncerTransitionSteps(TransitionStep step) { + SceneContainerFlag.assertInLegacyMode(); hideAlternateBouncer(false); } @@ -554,6 +555,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb */ @VisibleForTesting void consumeKeyguardAuthenticatedBiometricsHandled(Unit handled) { + SceneContainerFlag.assertInLegacyMode(); if (mAlternateBouncerInteractor.isVisibleState()) { hideAlternateBouncer(false); } @@ -981,7 +983,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } 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 32d059b2f037..a0fe538bdd2b 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 androidx.test.filters.SmallTest 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.data.repository.fakeKeyguardRepository 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 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() { deviceEntryInteractor = kosmos.deviceEntryInteractor, quickSettingsSceneFamilyResolver = kosmos.quickSettingsSceneFamilyResolver, notifShadeSceneFamilyResolver = kosmos.notifShadeSceneFamilyResolver, + powerInteractor = kosmos.powerInteractor, + alternateBouncerInteractor = kosmos.alternateBouncerInteractor, ) } @@ -234,6 +241,32 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() { } @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 957f092c188a..27eadb147055 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 @@ val Kosmos.keyguardDismissActionInteractor by deviceEntryInteractor = deviceEntryInteractor, quickSettingsSceneFamilyResolver = quickSettingsSceneFamilyResolver, notifShadeSceneFamilyResolver = notifShadeSceneFamilyResolver, + powerInteractor = powerInteractor, + alternateBouncerInteractor = alternateBouncerInteractor, ) } |