diff options
2 files changed, 53 insertions, 10 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt index d624bf7165f3..43266bfcbc55 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt @@ -256,7 +256,7 @@ class CommunalSceneStartableTest : SysuiTestCase() { } @Test - fun hubTimeout_whenDreaming() = + fun hubTimeout_whenDreaming_goesToBlank() = with(kosmos) { testScope.runTest { // Device is dreaming and on communal. @@ -273,7 +273,22 @@ class CommunalSceneStartableTest : SysuiTestCase() { } @Test - fun hubTimeout_dreamStopped() = + fun hubTimeout_notDreaming_staysOnCommunal() = + with(kosmos) { + testScope.runTest { + // Device is not dreaming and on communal. + fakeKeyguardRepository.setDreaming(false) + communalInteractor.onSceneChanged(CommunalScenes.Communal) + + // Scene stays as Communal + advanceTimeBy(SCREEN_TIMEOUT.milliseconds) + val scene by collectLastValue(communalInteractor.desiredScene) + assertThat(scene).isEqualTo(CommunalScenes.Communal) + } + } + + @Test + fun hubTimeout_dreamStopped_staysOnCommunal() = with(kosmos) { testScope.runTest { // Device is dreaming and on communal. @@ -296,6 +311,28 @@ class CommunalSceneStartableTest : SysuiTestCase() { } @Test + fun hubTimeout_dreamStartedHalfway_goesToCommunal() = + with(kosmos) { + testScope.runTest { + // Device is on communal, but not dreaming. + fakeKeyguardRepository.setDreaming(false) + communalInteractor.onSceneChanged(CommunalScenes.Communal) + + val scene by collectLastValue(communalInteractor.desiredScene) + assertThat(scene).isEqualTo(CommunalScenes.Communal) + + // Wait a bit, but not long enough to timeout, then start dreaming. + advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds) + fakeKeyguardRepository.setDreaming(true) + assertThat(scene).isEqualTo(CommunalScenes.Communal) + + // Device times out after one screen timeout interval, dream doesn't reset timeout. + advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds) + assertThat(scene).isEqualTo(CommunalScenes.Blank) + } + } + + @Test fun hubTimeout_userActivityTriggered_resetsTimeout() = with(kosmos) { testScope.runTest { diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt index 98c8205abbb3..ef686f91b36a 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt @@ -30,6 +30,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.util.kotlin.emitOnStart +import com.android.systemui.util.kotlin.sample import com.android.systemui.util.settings.SettingsProxyExt.observerFlow import com.android.systemui.util.settings.SystemSettings import javax.inject.Inject @@ -38,7 +39,6 @@ import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn @@ -108,23 +108,29 @@ constructor( bgScope.launch { combine( communalInteractor.desiredScene, - keyguardInteractor.isDreaming, // Emit a value on start so the combine starts. communalInteractor.userActivity.emitOnStart() - ) { scene, isDreaming, _ -> + ) { scene, _ -> // Time out should run whenever we're dreaming and the hub is open, even if not // docked. - scene == CommunalScenes.Communal && isDreaming + scene == CommunalScenes.Communal } - // collectLatest cancels the previous action block when new values arrive, so any + // mapLatest cancels the previous action block when new values arrive, so any // already running timeout gets cancelled when conditions change or user interaction // is detected. - .collectLatest { shouldTimeout -> + .mapLatest { shouldTimeout -> if (!shouldTimeout) { - return@collectLatest + return@mapLatest false } + delay(screenTimeout.milliseconds) - communalInteractor.onSceneChanged(CommunalScenes.Blank) + true + } + .sample(keyguardInteractor.isDreaming, ::Pair) + .collect { (shouldTimeout, isDreaming) -> + if (isDreaming && shouldTimeout) { + communalInteractor.onSceneChanged(CommunalScenes.Blank) + } } } } |