diff options
author | 2025-02-04 13:18:31 -0500 | |
---|---|---|
committer | 2025-02-04 13:20:32 -0500 | |
commit | d1c5bd78967598379fedcfc7d67d308841fd54c3 (patch) | |
tree | c6dc7084cf4170ad4a00f1d582c62563204d7b4b | |
parent | 72acca4e4f01c107bee80db5a1b1d27ffc282a3d (diff) |
Fix dozing/dreaming->hub transitions for hub v2
When the glanceable hub v2 is enabled, new logic is used for deciding
whether to transition to the hub - instead of needing to do an IPC to
DreamManagerService
Bug: 392893049
Test: atest FromDozingTransitionInteractorTest
Test: atest FromDreamingTransitionInteractorTest
Flag: com.android.systemui.glanceable_hub_v2
Change-Id: I830e96a8fc4dfa6915fc63bc98536d79bc1ced51
5 files changed, 197 insertions, 157 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt index c7f9edff6060..72cf63749284 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt @@ -20,21 +20,26 @@ import android.os.PowerManager import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization +import android.provider.Settings import android.service.dream.dreamManager import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR +import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.Flags.FLAG_SCENE_CONTAINER +import com.android.systemui.Flags.glanceableHubV2 import com.android.systemui.SysuiTestCase +import com.android.systemui.common.data.repository.batteryRepository +import com.android.systemui.common.data.repository.fake import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository import com.android.systemui.communal.data.repository.communalSceneRepository import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.domain.interactor.setCommunalAvailable +import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository @@ -45,20 +50,24 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat +import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.kosmos.collectLastValue +import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope -import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos +import com.android.systemui.user.data.repository.fakeUserRepository +import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth import junit.framework.Assert.assertEquals import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.advanceTimeBy -import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -77,24 +86,25 @@ import platform.test.runner.parameterized.Parameters @EnableFlags(FLAG_COMMUNAL_HUB) class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiTestCase() { private val kosmos = - testKosmos().apply { + testKosmos().useUnconfinedTestDispatcher().apply { this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy this.fakeCommunalSceneRepository = spy(FakeCommunalSceneRepository(applicationScope = applicationCoroutineScope)) } - private val testScope = kosmos.testScope - private lateinit var underTest: FromDozingTransitionInteractor + private val Kosmos.underTest by Kosmos.Fixture { fromDozingTransitionInteractor } - private lateinit var powerInteractor: PowerInteractor - private lateinit var transitionRepository: FakeKeyguardTransitionRepository - private lateinit var keyguardInteractor: KeyguardInteractor + private val Kosmos.transitionRepository by + Kosmos.Fixture { fakeKeyguardTransitionRepositorySpy } companion object { @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { - return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_SCENE_KTF_REFACTOR) + return FlagsParameterization.allCombinationsOf( + FLAG_COMMUNAL_SCENE_KTF_REFACTOR, + FLAG_GLANCEABLE_HUB_V2, + ) } } @@ -104,32 +114,27 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Before fun setup() { - powerInteractor = kosmos.powerInteractor - keyguardInteractor = kosmos.keyguardInteractor - transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy - underTest = kosmos.fromDozingTransitionInteractor - - underTest.start() + kosmos.underTest.start() // Transition to DOZING and set the power interactor asleep. - powerInteractor.setAsleepForTest() + kosmos.powerInteractor.setAsleepForTest() + kosmos.setCommunalV2ConfigEnabled(true) runBlocking { - transitionRepository.sendTransitionSteps( + kosmos.transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.DOZING, - testScope, + kosmos.testScope, ) kosmos.fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE) - reset(transitionRepository) + reset(kosmos.transitionRepository) } } @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToLockscreen_onWakeup() = - testScope.runTest { + kosmos.runTest { powerInteractor.setAwakeForTest() - runCurrent() // Under default conditions, we should transition to LOCKSCREEN when waking up. assertThat(transitionRepository) @@ -139,12 +144,11 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGone_onWakeup_whenGoingAway() = - testScope.runTest { + kosmos.runTest { keyguardInteractor.setIsKeyguardGoingAway(true) - runCurrent() powerInteractor.setAwakeForTest() - advanceTimeBy(60L) + testScope.advanceTimeBy(60L) assertThat(transitionRepository) .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.GONE) @@ -152,15 +156,13 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) - @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR) + @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_GLANCEABLE_HUB_V2) fun testTransitionToLockscreen_onWake_canDream_glanceableHubAvailable() = - testScope.runTest { - whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) - kosmos.setCommunalAvailable(true) - runCurrent() + kosmos.runTest { + whenever(dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) + setCommunalAvailable(true) powerInteractor.setAwakeForTest() - runCurrent() // If dreaming is possible and communal is available, then we should transition to // GLANCEABLE_HUB when waking up due to power button press. @@ -171,30 +173,35 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR, FLAG_COMMUNAL_SCENE_KTF_REFACTOR) fun testTransitionToLockscreen_onWake_canDream_ktfRefactor() = - testScope.runTest { - whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) - kosmos.setCommunalAvailable(true) - runCurrent() - clearInvocations(kosmos.fakeCommunalSceneRepository) + kosmos.runTest { + setCommunalAvailable(true) + if (glanceableHubV2()) { + val user = fakeUserRepository.asMainUser() + fakeSettings.putIntForUser( + Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, + 1, + user.id, + ) + batteryRepository.fake.setDevicePluggedIn(true) + } else { + whenever(dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) + } + clearInvocations(fakeCommunalSceneRepository) powerInteractor.setAwakeForTest() - runCurrent() // If dreaming is possible and communal is available, then we should transition to // GLANCEABLE_HUB when waking up due to power button press. - verify(kosmos.fakeCommunalSceneRepository).snapToScene(CommunalScenes.Communal) + verify(fakeCommunalSceneRepository).snapToScene(CommunalScenes.Communal) } @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToLockscreen_onWake_canNotDream_glanceableHubAvailable() = - testScope.runTest { - whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(false) - kosmos.setCommunalAvailable(true) - runCurrent() - + kosmos.runTest { + whenever(dreamManager.canStartDreaming(anyBoolean())).thenReturn(false) + setCommunalAvailable(true) powerInteractor.setAwakeForTest() - runCurrent() // If dreaming is NOT possible but communal is available, then we should transition to // LOCKSCREEN when waking up due to power button press. @@ -205,13 +212,11 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToLockscreen_onWake_canNDream_glanceableHubNotAvailable() = - testScope.runTest { - whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) - kosmos.setCommunalAvailable(false) - runCurrent() + kosmos.runTest { + whenever(dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) + setCommunalAvailable(false) powerInteractor.setAwakeForTest() - runCurrent() // If dreaming is possible but communal is NOT available, then we should transition to // LOCKSCREEN when waking up due to power button press. @@ -223,14 +228,12 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR) fun testTransitionToGlanceableHub_onWakeup_ifIdleOnCommunal_noOccludingActivity() = - testScope.runTest { - kosmos.fakeCommunalSceneRepository.setTransitionState( + kosmos.runTest { + fakeCommunalSceneRepository.setTransitionState( flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal)) ) - runCurrent() powerInteractor.setAwakeForTest() - runCurrent() // Under default conditions, we should transition to LOCKSCREEN when waking up. assertThat(transitionRepository) @@ -241,19 +244,26 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR, FLAG_SCENE_CONTAINER) @EnableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR) fun testTransitionToGlanceableHub_onWakeup_ifAvailable() = - testScope.runTest { - // Hub is available. - whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) - kosmos.setCommunalAvailable(true) - runCurrent() + kosmos.runTest { + setCommunalAvailable(true) + if (glanceableHubV2()) { + val user = fakeUserRepository.asMainUser() + fakeSettings.putIntForUser( + Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, + 1, + user.id, + ) + batteryRepository.fake.setDevicePluggedIn(true) + } else { + whenever(dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) + } // Device turns on. powerInteractor.setAwakeForTest() - advanceTimeBy(50L) - runCurrent() + testScope.advanceTimeBy(51L) // We transition to the hub when waking up. - Truth.assertThat(kosmos.communalSceneRepository.currentScene.value) + Truth.assertThat(communalSceneRepository.currentScene.value) .isEqualTo(CommunalScenes.Communal) // No transitions are directly started by this interactor. assertThat(transitionRepository).noTransitionsStarted() @@ -262,10 +272,9 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToOccluded_onWakeup_whenOccludingActivityOnTop() = - testScope.runTest { - kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true) + kosmos.runTest { + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true) powerInteractor.setAwakeForTest() - runCurrent() // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED. assertThat(transitionRepository) @@ -275,15 +284,13 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToOccluded_onWakeup_whenOccludingActivityOnTop_evenIfIdleOnCommunal() = - testScope.runTest { - kosmos.fakeCommunalSceneRepository.setTransitionState( + kosmos.runTest { + fakeCommunalSceneRepository.setTransitionState( flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal)) ) - runCurrent() - kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true) + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true) powerInteractor.setAwakeForTest() - runCurrent() // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED. assertThat(transitionRepository) @@ -294,10 +301,9 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @Suppress("ktlint:standard:max-line-length") fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetected_fromAod_nonDismissableKeyguard() = - testScope.runTest { + kosmos.runTest { powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() - runCurrent() // We should head back to GONE since we started there. assertThat(transitionRepository) @@ -307,11 +313,10 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGone_onWakeUp_ifPowerButtonGestureDetected_fromAod_dismissableKeyguard() = - testScope.runTest { - kosmos.fakeKeyguardRepository.setKeyguardDismissible(true) + kosmos.runTest { + fakeKeyguardRepository.setKeyguardDismissible(true) powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() - runCurrent() // We should head back to GONE since we started there. assertThat(transitionRepository) @@ -321,25 +326,21 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGone_onWakeUp_ifPowerButtonGestureDetected_fromGone() = - testScope.runTest { + kosmos.runTest { val isGone by - collectLastValue( - kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) - ) + collectLastValue(keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE)) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.DOZING, to = KeyguardState.GONE, testScope, ) - runCurrent() // Make sure we're GONE. assertEquals(true, isGone) // Get part way to AOD. powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) - runCurrent() transitionRepository.sendTransitionSteps( from = KeyguardState.GONE, @@ -349,11 +350,10 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT ) // Detect a power gesture and then wake up. - kosmos.fakeKeyguardRepository.setKeyguardDismissible(true) + fakeKeyguardRepository.setKeyguardDismissible(true) reset(transitionRepository) powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() - runCurrent() // We should head back to GONE since we started there. assertThat(transitionRepository) @@ -364,7 +364,7 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @Suppress("ktlint:standard:max-line-length") fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetectedAfterFinishedInAod_fromGone() = - testScope.runTest { + kosmos.runTest { val isGone by collectLastValue( kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) @@ -375,7 +375,6 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT to = KeyguardState.GONE, testScope, ) - runCurrent() // Make sure we're GONE. assertEquals(true, isGone) @@ -392,7 +391,6 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT reset(transitionRepository) powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() - runCurrent() // We should go to OCCLUDED - we came from GONE, but we finished in AOD, so this is no // longer an insecure camera launch and it would be bad if we unlocked now. @@ -403,7 +401,7 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetected_fromLockscreen() = - testScope.runTest { + kosmos.runTest { val isLockscreen by collectLastValue( kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Lockscreen, LOCKSCREEN) @@ -414,14 +412,12 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT to = KeyguardState.LOCKSCREEN, testScope, ) - runCurrent() // Make sure we're in LOCKSCREEN. assertEquals(true, isLockscreen) // Get part way to AOD. powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) - runCurrent() transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, @@ -434,7 +430,6 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT reset(transitionRepository) powerInteractor.onCameraLaunchGestureDetected() powerInteractor.setAwakeForTest() - runCurrent() // We should head back to GONE since we started there. assertThat(transitionRepository) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt index dcfa298e99ff..5882cff74eb6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt @@ -19,14 +19,20 @@ package com.android.systemui.keyguard.domain.interactor import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization +import android.provider.Settings import android.service.dream.dreamManager import androidx.test.filters.SmallTest import com.android.systemui.Flags import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR +import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 +import com.android.systemui.Flags.glanceableHubV2 import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository +import com.android.systemui.common.data.repository.batteryRepository +import com.android.systemui.common.data.repository.fake import com.android.systemui.communal.data.repository.communalSceneRepository import com.android.systemui.communal.domain.interactor.setCommunalAvailable +import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.flags.andSceneContainer import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository @@ -38,16 +44,19 @@ import com.android.systemui.keyguard.data.repository.keyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope +import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.testKosmos +import com.android.systemui.user.data.repository.fakeUserRepository +import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.advanceTimeBy -import kotlinx.coroutines.test.runCurrent -import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Ignore import org.junit.Test @@ -65,7 +74,10 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { - return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_SCENE_KTF_REFACTOR) + return FlagsParameterization.allCombinationsOf( + FLAG_COMMUNAL_SCENE_KTF_REFACTOR, + FLAG_GLANCEABLE_HUB_V2, + ) .andSceneContainer() } } @@ -75,7 +87,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu } private val kosmos = - testKosmos().apply { + testKosmos().useUnconfinedTestDispatcher().apply { this.fakeKeyguardTransitionRepository = FakeKeyguardTransitionRepository( // This test sends transition steps manually in the test cases. @@ -86,44 +98,41 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } - private val testScope = kosmos.testScope - private val underTest by lazy { kosmos.fromDreamingTransitionInteractor } - - private val powerInteractor = kosmos.powerInteractor - private val transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy + private val Kosmos.underTest by Kosmos.Fixture { fromDreamingTransitionInteractor } + private val Kosmos.transitionRepository by + Kosmos.Fixture { fakeKeyguardTransitionRepositorySpy } @Before fun setup() { runBlocking { - transitionRepository.sendTransitionSteps( + kosmos.transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.DREAMING, - testScope, + kosmos.testScope, ) - reset(transitionRepository) + reset(kosmos.transitionRepository) kosmos.setCommunalAvailable(true) + kosmos.setCommunalV2ConfigEnabled(true) } - underTest.start() + kosmos.underTest.start() } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @Ignore("Until b/349837588 is fixed") fun testTransitionToOccluded_ifDreamEnds_occludingActivityOnTop() = - testScope.runTest { - kosmos.fakeKeyguardRepository.setDreaming(true) + kosmos.runTest { + fakeKeyguardRepository.setDreaming(true) transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.DREAMING, - testScope, + kosmos.testScope, ) - runCurrent() reset(transitionRepository) - kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true) - kosmos.fakeKeyguardRepository.setDreaming(false) - runCurrent() + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true) + fakeKeyguardRepository.setDreaming(false) assertThat(transitionRepository) .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.OCCLUDED) @@ -132,19 +141,15 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testDoesNotTransitionToOccluded_occludingActivityOnTop_whileStillDreaming() = - testScope.runTest { - kosmos.fakeKeyguardRepository.setDreaming(true) + kosmos.runTest { + fakeKeyguardRepository.setDreaming(true) transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.DREAMING, testScope, ) - runCurrent() - reset(transitionRepository) - - kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true) - runCurrent() + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true) assertThat(transitionRepository).noTransitionsStarted() } @@ -152,11 +157,9 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_whenOccludingActivityEnds() = - testScope.runTest { - runCurrent() - - kosmos.fakeKeyguardRepository.setDreaming(true) - kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(true) + kosmos.runTest { + fakeKeyguardRepository.setDreaming(true) + keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(true) // Transition to DREAMING and set the power interactor awake powerInteractor.setAwakeForTest() @@ -165,15 +168,15 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu to = KeyguardState.DREAMING, testScope, ) - kosmos.fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE) + fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE) // Get past initial setup - advanceTimeBy(600L) + testScope.advanceTimeBy(600L) reset(transitionRepository) - kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = false) - kosmos.fakeKeyguardRepository.setDreaming(false) - advanceTimeBy(60L) + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = false) + fakeKeyguardRepository.setDreaming(false) + testScope.advanceTimeBy(60L) assertThat(transitionRepository) .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.LOCKSCREEN) @@ -181,7 +184,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu @Test fun testTransitionToAlternateBouncer() = - testScope.runTest { + kosmos.runTest { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.DREAMING, @@ -189,8 +192,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu ) reset(transitionRepository) - kosmos.fakeKeyguardBouncerRepository.setAlternateVisible(true) - runCurrent() + fakeKeyguardBouncerRepository.setAlternateVisible(true) assertThat(transitionRepository) .startedTransition( @@ -203,7 +205,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu @EnableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR) @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun testTransitionToGlanceableHubOnWake() = - testScope.runTest { + kosmos.runTest { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.DREAMING, @@ -211,17 +213,25 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu ) reset(transitionRepository) - whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) - kosmos.setCommunalAvailable(true) - runCurrent() + setCommunalAvailable(true) + if (glanceableHubV2()) { + val user = fakeUserRepository.asMainUser() + fakeSettings.putIntForUser( + Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, + 1, + user.id, + ) + batteryRepository.fake.setDevicePluggedIn(true) + } else { + whenever(dreamManager.canStartDreaming(anyBoolean())).thenReturn(true) + } // Device wakes up. powerInteractor.setAwakeForTest() - advanceTimeBy(150L) - runCurrent() + testScope.advanceTimeBy(150L) // We transition to the hub when waking up. - assertThat(kosmos.communalSceneRepository.currentScene.value) + assertThat(communalSceneRepository.currentScene.value) .isEqualTo(CommunalScenes.Communal) // No transitions are directly started by this interactor. assertThat(transitionRepository).noTransitionsStarted() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt index 4291181d8336..090cdcc23936 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt @@ -24,6 +24,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.Flags.communalSceneKtfRefactor import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor +import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -57,6 +58,7 @@ constructor( keyguardInteractor: KeyguardInteractor, powerInteractor: PowerInteractor, private val communalInteractor: CommunalInteractor, + private val communalSettingsInteractor: CommunalSettingsInteractor, private val communalSceneInteractor: CommunalSceneInteractor, keyguardOcclusionInteractor: KeyguardOcclusionInteractor, val deviceEntryInteractor: DeviceEntryInteractor, @@ -115,6 +117,17 @@ constructor( } } + @SuppressLint("MissingPermission") + private fun shouldTransitionToCommunal( + shouldShowCommunal: Boolean, + isCommunalAvailable: Boolean, + ) = + if (communalSettingsInteractor.isV2FlagEnabled()) { + shouldShowCommunal + } else { + isCommunalAvailable && dreamManager.canStartDreaming(false) + } + @OptIn(FlowPreview::class) @SuppressLint("MissingPermission") private fun listenForDozingToAny() { @@ -128,9 +141,10 @@ constructor( .filterRelevantKeyguardStateAnd { isAwake -> isAwake } .sample( communalInteractor.isCommunalAvailable, + communalInteractor.shouldShowCommunal, communalSceneInteractor.isIdleOnCommunal, ) - .collect { (_, isCommunalAvailable, isIdleOnCommunal) -> + .collect { (_, isCommunalAvailable, shouldShowCommunal, isIdleOnCommunal) -> val isKeyguardOccludedLegacy = keyguardInteractor.isKeyguardOccluded.value val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value val isKeyguardGoingAway = keyguardInteractor.isKeyguardGoingAway.value @@ -164,11 +178,9 @@ constructor( if (!SceneContainerFlag.isEnabled) { startTransitionTo(KeyguardState.GLANCEABLE_HUB) } - } else if (isCommunalAvailable && dreamManager.canStartDreaming(false)) { - // Using false for isScreenOn as canStartDreaming returns false if any - // dream, including doze, is active. - // This case handles tapping the power button to transition through - // dream -> off -> hub. + } else if ( + shouldTransitionToCommunal(shouldShowCommunal, isCommunalAvailable) + ) { if (!SceneContainerFlag.isEnabled) { transitionToGlanceableHub() } @@ -190,6 +202,7 @@ constructor( powerInteractor.detailedWakefulness .filterRelevantKeyguardStateAnd { it.isAwake() } .sample( + communalInteractor.shouldShowCommunal, communalInteractor.isCommunalAvailable, communalSceneInteractor.isIdleOnCommunal, keyguardInteractor.biometricUnlockState, @@ -199,6 +212,7 @@ constructor( .collect { ( _, + shouldShowCommunal, isCommunalAvailable, isIdleOnCommunal, biometricUnlockState, @@ -232,7 +246,9 @@ constructor( ownerReason = "waking from dozing", ) } - } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) { + } else if ( + shouldTransitionToCommunal(shouldShowCommunal, isCommunalAvailable) + ) { if (!SceneContainerFlag.isEnabled) { transitionToGlanceableHub() } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt index 251af11f7fe6..c1c509b8fd57 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt @@ -129,20 +129,37 @@ constructor( if (!communalSettingsInteractor.isCommunalFlagEnabled()) return if (SceneContainerFlag.isEnabled) return scope.launch { - powerInteractor.isAwake - .debounce(50L) - .filterRelevantKeyguardStateAnd { isAwake -> isAwake } - .sample(communalInteractor.isCommunalAvailable) - .collect { isCommunalAvailable -> - if (isCommunalAvailable && dreamManager.canStartDreaming(false)) { - // This case handles tapping the power button to transition through - // dream -> off -> hub. - communalSceneInteractor.snapToScene( - newScene = CommunalScenes.Communal, - loggingReason = "from dreaming to hub", - ) + if (communalSettingsInteractor.isV2FlagEnabled()) { + powerInteractor.isAwake + .debounce(50L) + .filterRelevantKeyguardStateAnd { isAwake -> isAwake } + .sample(communalInteractor.shouldShowCommunal) + .collect { shouldShowCommunal -> + if (shouldShowCommunal) { + // This case handles tapping the power button to transition through + // dream -> off -> hub. + communalSceneInteractor.snapToScene( + newScene = CommunalScenes.Communal, + loggingReason = "from dreaming to hub", + ) + } } - } + } else { + powerInteractor.isAwake + .debounce(50L) + .filterRelevantKeyguardStateAnd { isAwake -> isAwake } + .sample(communalInteractor.isCommunalAvailable) + .collect { isCommunalAvailable -> + if (isCommunalAvailable && dreamManager.canStartDreaming(false)) { + // This case handles tapping the power button to transition through + // dream -> off -> hub. + communalSceneInteractor.snapToScene( + newScene = CommunalScenes.Communal, + loggingReason = "from dreaming to hub", + ) + } + } + } } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt index 4634a7fd009f..9da8e80283b6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor import android.service.dream.dreamManager import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.communalSceneInteractor +import com.android.systemui.communal.domain.interactor.communalSettingsInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.kosmos.Kosmos @@ -43,6 +44,7 @@ var Kosmos.fromDozingTransitionInteractor by keyguardOcclusionInteractor = keyguardOcclusionInteractor, deviceEntryInteractor = deviceEntryInteractor, wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor, - dreamManager = dreamManager + dreamManager = dreamManager, + communalSettingsInteractor = communalSettingsInteractor, ) } |