diff options
| author | 2024-06-11 15:28:44 -0400 | |
|---|---|---|
| committer | 2024-06-12 10:38:56 -0400 | |
| commit | c455fb1dd76be44aa2bb2ee5d3816e4398938c14 (patch) | |
| tree | 2437ead92b89538e628ebd0d2832372e8e6be25b | |
| parent | 20da94603f11a4e33f49cd6e5b39269c7df128d9 (diff) | |
[flexiglass] Switch to Gone during LS transition
WindowManagerLockscreenVisibilityInteractor determines when the surface
underneath lockscreen is made visible; SceneContainerStartable now
tracks this and forces the scene to Gone when true so that Lockscreen
isn't rendered above the surface.
Flag: com.android.systemui.scene_container DEVELOPMENT
Fixes: 344844978
Test: manual
0. Enable flexiglass
1. Swipe up slightly on lockscreen, do *not* fling
2. Lift finger
Observe: Lockscreen is not visible over launcher
Change-Id: I9a6645c74c128373966b62e6aab08f8ef86ea16b
4 files changed, 75 insertions, 4 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 ac66e6657a75..e40c8eecca0f 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,7 +14,7 @@ * limitations under the License. */ -@file:OptIn(ExperimentalCoroutinesApi::class, ExperimentalCoroutinesApi::class) +@file:OptIn(ExperimentalCoroutinesApi::class) package com.android.systemui.scene.domain.startable @@ -395,6 +395,7 @@ class SceneContainerStartableTest : SysuiTestCase() { ) assertThat(currentSceneKey).isEqualTo(Scenes.Gone) underTest.start() + runCurrent() kosmos.fakePowerRepository.updateWakefulness( rawState = WakefulnessState.STARTING_TO_SLEEP, @@ -1285,6 +1286,42 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test + fun switchToGone_whenSurfaceBehindLockscreenVisibleMidTransition() = + testScope.runTest { + val currentScene by collectLastValue(sceneInteractor.currentScene) + val transitionStateFlow = + prepareState( + authenticationMethod = AuthenticationMethodModel.None, + ) + underTest.start() + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + // Swipe to Gone, more than halfway + transitionStateFlow.value = + ObservableTransitionState.Transition( + fromScene = Scenes.Lockscreen, + toScene = Scenes.Gone, + currentScene = flowOf(Scenes.Gone), + progress = flowOf(0.51f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(true), + ) + runCurrent() + // Lift finger + transitionStateFlow.value = + ObservableTransitionState.Transition( + fromScene = Scenes.Lockscreen, + toScene = Scenes.Gone, + currentScene = flowOf(Scenes.Gone), + progress = flowOf(0.51f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), + ) + runCurrent() + + assertThat(currentScene).isEqualTo(Scenes.Gone) + } + + @Test fun switchToGone_extendUnlock() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt index 9d110e665ebe..10d6881e4f93 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt @@ -29,6 +29,7 @@ import com.android.systemui.keyguard.domain.interactor.TrustInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.util.kotlin.Quad +import com.android.systemui.utils.coroutines.flow.mapLatestConflated import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -37,6 +38,7 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -96,7 +98,16 @@ constructor( .filter { currentScene -> currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen } - .map { it == Scenes.Gone } + .mapLatestConflated { scene -> + if (scene == Scenes.Gone) { + // Make sure device unlock status is definitely unlocked before we consider the + // device "entered". + deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked } + true + } else { + false + } + } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, 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 0304e730cb68..1e689bd11fa3 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 @@ -39,6 +39,7 @@ import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor import com.android.systemui.model.SceneContainerPlugin import com.android.systemui.model.SysUiState import com.android.systemui.model.updateFlags @@ -81,6 +82,7 @@ import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.filterNot +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -120,6 +122,7 @@ constructor( private val uiEventLogger: UiEventLogger, private val sceneBackInteractor: SceneBackInteractor, private val shadeSessionStorage: SessionStorage, + private val windowMgrLockscreenVisInteractor: WindowManagerLockscreenVisibilityInteractor, ) : CoreStartable { private val centralSurfaces: CentralSurfaces? get() = centralSurfacesOptLazy.get().getOrNull() @@ -227,6 +230,25 @@ constructor( handleDeviceUnlockStatus() handlePowerState() handleShadeTouchability() + handleSurfaceBehindKeyguardVisibility() + } + + private fun handleSurfaceBehindKeyguardVisibility() { + applicationScope.launch { + sceneInteractor.currentScene.collectLatest { currentScene -> + if (currentScene == Scenes.Lockscreen) { + // Wait for surface to become visible + windowMgrLockscreenVisInteractor.surfaceBehindVisibility.first { it } + // Make sure the device is actually unlocked before force-changing the scene + deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked } + // Override the current transition, if any, by forcing the scene to Gone + sceneInteractor.changeScene( + toScene = Scenes.Gone, + loggingReason = "surface behind keyguard is visible", + ) + } + } + } } private fun handleBouncerImeVisibility() { @@ -329,8 +351,7 @@ constructor( Scenes.Gone to "device was unlocked in Bouncer scene" } else { val prevScene = previousScene.value - (prevScene - ?: Scenes.Gone) to + (prevScene ?: Scenes.Gone) to "device was unlocked in Bouncer scene, from sceneKey=$prevScene" } isOnLockscreen -> diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt index d82286fd3569..cf18c0e295ea 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt @@ -26,6 +26,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInt import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.keyguard.domain.interactor.keyguardInteractor +import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testScope @@ -67,5 +68,6 @@ val Kosmos.sceneContainerStartable by Fixture { uiEventLogger = uiEventLogger, sceneBackInteractor = sceneBackInteractor, shadeSessionStorage = shadeSessionStorage, + windowMgrLockscreenVisInteractor = windowManagerLockscreenVisibilityInteractor, ) } |