Loading packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import com.android.systemui.scene.ui.composable.transitions.bouncerToLockscreenP import com.android.systemui.scene.ui.composable.transitions.communalToBouncerTransition import com.android.systemui.scene.ui.composable.transitions.communalToShadeTransition import com.android.systemui.scene.ui.composable.transitions.dreamToBouncerTransition import com.android.systemui.scene.ui.composable.transitions.dreamToCommunalTransition import com.android.systemui.scene.ui.composable.transitions.dreamToGoneTransition import com.android.systemui.scene.ui.composable.transitions.dreamToShadeTransition import com.android.systemui.scene.ui.composable.transitions.goneToQuickSettingsTransition Loading Loading @@ -58,6 +59,7 @@ val SceneContainerTransitions = transitions { from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() } from(Scenes.Dream, to = Scenes.Bouncer) { dreamToBouncerTransition() } from(Scenes.Dream, to = Scenes.Communal) { dreamToCommunalTransition() } from(Scenes.Dream, to = Scenes.Gone) { dreamToGoneTransition() } from(Scenes.Dream, to = Scenes.Shade) { dreamToShadeTransition() } from(Scenes.Gone, to = Scenes.Shade) { goneToShadeTransition() } Loading packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromDreamToCommunalTransition.kt 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.scene.ui.composable.transitions import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder import com.android.systemui.communal.ui.compose.AllElements import com.android.systemui.communal.ui.compose.Communal fun TransitionBuilder.dreamToCommunalTransition() { spec = tween(durationMillis = 1000) // Translate communal hub grid from the end direction. translate(Communal.Elements.Grid, Edge.End) // Fade all communal hub elements. timestampRange(startMillis = 167, endMillis = 334) { fade(AllElements) } } packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt +55 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ import android.app.WindowConfiguration import android.content.ComponentName import android.content.Intent import android.os.RemoteException import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.service.dreams.Flags import android.service.dreams.IDreamOverlay import android.service.dreams.IDreamOverlayCallback Loading @@ -33,7 +35,6 @@ import android.view.WindowManagerImpl import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.app.viewcapture.ViewCapture import com.android.app.viewcapture.ViewCaptureAwareWindowManager Loading @@ -43,6 +44,7 @@ import com.android.internal.logging.UiEventLogger import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase import com.android.systemui.ambient.touch.TouchMonitor import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent Loading @@ -62,12 +64,16 @@ import com.android.systemui.complication.ComplicationLayoutEngine import com.android.systemui.complication.dagger.ComplicationComponent import com.android.systemui.dreams.complication.HideComplicationTouchHandler import com.android.systemui.dreams.dagger.DreamOverlayComponent import com.android.systemui.flags.andSceneContainer import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.gesture.domain.gestureInteractor import com.android.systemui.kosmos.testScope import com.android.systemui.navigationbar.gestural.domain.GestureInteractor import com.android.systemui.navigationbar.gestural.domain.TaskInfo import com.android.systemui.navigationbar.gestural.domain.TaskMatcher import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos import com.android.systemui.touch.TouchInsetManager import com.android.systemui.util.concurrency.FakeExecutor Loading Loading @@ -98,12 +104,14 @@ import org.mockito.kotlin.spy import org.mockito.kotlin.times import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) @RunWith(AndroidJUnit4::class) class DreamOverlayServiceTest : SysuiTestCase() { @RunWith(ParameterizedAndroidJunit4::class) class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() { private val mFakeSystemClock = FakeSystemClock() private val mMainExecutor = FakeExecutor(mFakeSystemClock) private val kosmos = testKosmos() Loading Loading @@ -245,6 +253,10 @@ class DreamOverlayServiceTest : SysuiTestCase() { ) } init { mSetFlagsRule.setFlagsParameterization(flags!!) } @Before fun setup() { MockitoAnnotations.initMocks(this) Loading Loading @@ -287,6 +299,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { mKeyguardUpdateMonitor, mScrimManager, mCommunalInteractor, kosmos.sceneInteractor, mSystemDialogsCloser, mUiEventLogger, mTouchInsetManager, Loading Loading @@ -768,6 +781,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { @Test @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_COMMUNAL_HUB) @DisableFlags(FLAG_SCENE_CONTAINER) @kotlin.Throws(RemoteException::class) fun testTransitionToGlanceableHub() = testScope.runTest { Loading @@ -792,6 +806,35 @@ class DreamOverlayServiceTest : SysuiTestCase() { verify(mUiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START) } @Test @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_SCENE_CONTAINER, FLAG_COMMUNAL_HUB) @kotlin.Throws(RemoteException::class) fun testTransitionToGlanceableHub_sceneContainer() = testScope.runTest { // Inform the overlay service of dream starting. Do not show dream complications. client.startDream( mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*isPreview*/, false, /*shouldShowComplication*/ ) mMainExecutor.runAllReady() verify(mDreamOverlayCallback).onRedirectWake(false) clearInvocations(mDreamOverlayCallback) kosmos.setCommunalAvailable(true) mMainExecutor.runAllReady() runCurrent() verify(mDreamOverlayCallback).onRedirectWake(true) client.onWakeRequested() mMainExecutor.runAllReady() runCurrent() assertThat(kosmos.sceneContainerRepository.currentScene.value) .isEqualTo(Scenes.Communal) verify(mUiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START) } @Test @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_COMMUNAL_HUB) @Throws(RemoteException::class) Loading Loading @@ -911,6 +954,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { // Verifies that the touch handling lifecycle is STARTED even if the dream starts while not // focused. @Test @DisableFlags(FLAG_SCENE_CONTAINER) fun testLifecycle_dreamNotFocusedOnStart_isStarted() { val transitionState: MutableStateFlow<ObservableTransitionState> = MutableStateFlow(ObservableTransitionState.Idle(CommunalScenes.Blank)) Loading Loading @@ -1024,6 +1068,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) fun testCommunalVisible_setsLifecycleState() { val client = client Loading Loading @@ -1060,6 +1105,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { // Verifies the dream's lifecycle @Test @DisableFlags(FLAG_SCENE_CONTAINER) fun testLifecycleStarted_whenAnyOcclusion() { val client = client Loading Loading @@ -1256,5 +1302,11 @@ class DreamOverlayServiceTest : SysuiTestCase() { ComponentName("package", "homeControlPanel") private const val DREAM_COMPONENT = "package/dream" private const val WINDOW_NAME = "test" @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_HUB).andSceneContainer() } } } packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorTest.kt +19 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import com.android.compose.animation.scene.ObservableTransitionState.Transition. import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState Loading Loading @@ -194,6 +195,24 @@ class SceneContainerOcclusionInteractorTest : SysuiTestCase() { .isFalse() } @Test fun invisibleDueToOcclusion_isDreaming_emitsTrue() = testScope.runTest { val invisibleDueToOcclusion by collectLastValue(underTest.invisibleDueToOcclusion) // Verify that we start with unoccluded assertWithMessage("Should start unoccluded").that(invisibleDueToOcclusion).isFalse() // Start dreaming, which is an occluding activity showOccludingActivity() kosmos.keyguardInteractor.setDreaming(true) // Verify not invisible when dreaming assertWithMessage("Should be invisible when dreaming") .that(invisibleDueToOcclusion) .isTrue() } /** Simulates the appearance of a show-when-locked `Activity` in the foreground. */ private fun TestScope.showOccludingActivity() { keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( Loading packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +123 −2 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.dismissCallbackRegistry import com.android.systemui.keyguard.domain.interactor.dozeInteractor import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.scenetransition.lockscreenSceneTransitionInteractor Loading Loading @@ -143,6 +144,8 @@ class SceneContainerStartableTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val deviceEntryHapticsInteractor by lazy { kosmos.deviceEntryHapticsInteractor } private val dozeInteractor by lazy { kosmos.dozeInteractor } private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val sceneInteractor by lazy { kosmos.sceneInteractor } private val sceneBackInteractor by lazy { kosmos.sceneBackInteractor } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } Loading Loading @@ -372,6 +375,64 @@ class SceneContainerStartableTest : SysuiTestCase() { assertThat(isVisible).isTrue() } @Test fun hydrateVisibility_whileDreaming() = testScope.runTest { val isVisible by collectLastValue(sceneInteractor.isVisible) // GIVEN the device is dreaming val transitionState = prepareState(isDeviceUnlocked = false, initialSceneKey = Scenes.Dream) underTest.start() assertThat(isVisible).isFalse() } @Test fun hydrateVisibility_onCommunalWhileOccluded() = testScope.runTest { val isVisible by collectLastValue(sceneInteractor.isVisible) kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( true, mock(), ) prepareState(isDeviceUnlocked = false, initialSceneKey = Scenes.Communal) underTest.start() runCurrent() assertThat(isVisible).isTrue() } @Test fun hydrateVisibility_inCommunalTransition() = testScope.runTest { val isVisible by collectLastValue(sceneInteractor.isVisible) // GIVEN the device is dreaming val transitionState = prepareState( authenticationMethod = AuthenticationMethodModel.Pin, isDeviceUnlocked = false, initialSceneKey = Scenes.Dream, ) underTest.start() assertThat(isVisible).isFalse() // WHEN a transition starts to the communal hub sceneInteractor.changeScene(Scenes.Dream, "switching to dream for test") transitionState.value = ObservableTransitionState.Transition( fromScene = Scenes.Dream, toScene = Scenes.Communal, currentScene = flowOf(Scenes.Dream), progress = flowOf(0.5f), isInitiatedByUserInput = true, isUserInputOngoing = flowOf(false), ) runCurrent() // THEN scenes are visible assertThat(isVisible).isTrue() } @Test fun startsInLockscreenScene() = testScope.runTest { Loading Loading @@ -643,7 +704,7 @@ class SceneContainerStartableTest : SysuiTestCase() { fun switchToAOD_whenAvailable_whenDeviceSleepsLocked() = testScope.runTest { kosmos.lockscreenSceneTransitionInteractor.start() val asleepState by collectLastValue(kosmos.keyguardInteractor.asleepKeyguardState) val asleepState by collectLastValue(keyguardInteractor.asleepKeyguardState) val currentTransitionInfo by collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal) val transitionState = Loading Loading @@ -673,7 +734,7 @@ class SceneContainerStartableTest : SysuiTestCase() { fun switchToDozing_whenAodUnavailable_whenDeviceSleepsLocked() = testScope.runTest { kosmos.lockscreenSceneTransitionInteractor.start() val asleepState by collectLastValue(kosmos.keyguardInteractor.asleepKeyguardState) val asleepState by collectLastValue(keyguardInteractor.asleepKeyguardState) val currentTransitionInfo by collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal) val transitionState = Loading Loading @@ -2359,6 +2420,66 @@ class SceneContainerStartableTest : SysuiTestCase() { assertThat(isLockscreenEnabled).isTrue() } @Test fun stayOnLockscreen_whenDozingStarted() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) underTest.start() // Stay on Lockscreen when dozing and dreaming dozeInteractor.setIsDozing(true) keyguardInteractor.setDreaming(true) kosmos.fakeKeyguardRepository.setDreamingWithOverlay(false) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) } @Test fun switchFromLockscreenToDream_whenDreamStarted() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) underTest.start() powerInteractor.setAwakeForTest() keyguardInteractor.setDreaming(true) // Move past initial delay with [KeyguardInteractor#isAbleToDream] advanceTimeBy(600L) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Dream) } @Test fun switchFromDreamToLockscreen_whenLockedAndDreamStopped() = testScope.runTest { keyguardInteractor.setDreaming(true) val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState(initialSceneKey = Scenes.Dream) assertThat(currentScene).isEqualTo(Scenes.Dream) underTest.start() keyguardInteractor.setDreaming(false) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) } @Test fun switchFromDreamToGone_whenUnlockedAndDreamStopped() = testScope.runTest { keyguardInteractor.setDreaming(true) val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState(initialSceneKey = Scenes.Dream, isDeviceUnlocked = true) assertThat(currentScene).isEqualTo(Scenes.Dream) underTest.start() keyguardInteractor.setDreaming(false) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Gone) } @Test fun replacesLockscreenSceneOnBackStack_whenUnlockdViaAlternateBouncer_fromShade() = testScope.runTest { Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import com.android.systemui.scene.ui.composable.transitions.bouncerToLockscreenP import com.android.systemui.scene.ui.composable.transitions.communalToBouncerTransition import com.android.systemui.scene.ui.composable.transitions.communalToShadeTransition import com.android.systemui.scene.ui.composable.transitions.dreamToBouncerTransition import com.android.systemui.scene.ui.composable.transitions.dreamToCommunalTransition import com.android.systemui.scene.ui.composable.transitions.dreamToGoneTransition import com.android.systemui.scene.ui.composable.transitions.dreamToShadeTransition import com.android.systemui.scene.ui.composable.transitions.goneToQuickSettingsTransition Loading Loading @@ -58,6 +59,7 @@ val SceneContainerTransitions = transitions { from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() } from(Scenes.Dream, to = Scenes.Bouncer) { dreamToBouncerTransition() } from(Scenes.Dream, to = Scenes.Communal) { dreamToCommunalTransition() } from(Scenes.Dream, to = Scenes.Gone) { dreamToGoneTransition() } from(Scenes.Dream, to = Scenes.Shade) { dreamToShadeTransition() } from(Scenes.Gone, to = Scenes.Shade) { goneToShadeTransition() } Loading
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromDreamToCommunalTransition.kt 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.scene.ui.composable.transitions import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder import com.android.systemui.communal.ui.compose.AllElements import com.android.systemui.communal.ui.compose.Communal fun TransitionBuilder.dreamToCommunalTransition() { spec = tween(durationMillis = 1000) // Translate communal hub grid from the end direction. translate(Communal.Elements.Grid, Edge.End) // Fade all communal hub elements. timestampRange(startMillis = 167, endMillis = 334) { fade(AllElements) } }
packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt +55 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ import android.app.WindowConfiguration import android.content.ComponentName import android.content.Intent import android.os.RemoteException import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.service.dreams.Flags import android.service.dreams.IDreamOverlay import android.service.dreams.IDreamOverlayCallback Loading @@ -33,7 +35,6 @@ import android.view.WindowManagerImpl import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.app.viewcapture.ViewCapture import com.android.app.viewcapture.ViewCaptureAwareWindowManager Loading @@ -43,6 +44,7 @@ import com.android.internal.logging.UiEventLogger import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase import com.android.systemui.ambient.touch.TouchMonitor import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent Loading @@ -62,12 +64,16 @@ import com.android.systemui.complication.ComplicationLayoutEngine import com.android.systemui.complication.dagger.ComplicationComponent import com.android.systemui.dreams.complication.HideComplicationTouchHandler import com.android.systemui.dreams.dagger.DreamOverlayComponent import com.android.systemui.flags.andSceneContainer import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.gesture.domain.gestureInteractor import com.android.systemui.kosmos.testScope import com.android.systemui.navigationbar.gestural.domain.GestureInteractor import com.android.systemui.navigationbar.gestural.domain.TaskInfo import com.android.systemui.navigationbar.gestural.domain.TaskMatcher import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos import com.android.systemui.touch.TouchInsetManager import com.android.systemui.util.concurrency.FakeExecutor Loading Loading @@ -98,12 +104,14 @@ import org.mockito.kotlin.spy import org.mockito.kotlin.times import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) @RunWith(AndroidJUnit4::class) class DreamOverlayServiceTest : SysuiTestCase() { @RunWith(ParameterizedAndroidJunit4::class) class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() { private val mFakeSystemClock = FakeSystemClock() private val mMainExecutor = FakeExecutor(mFakeSystemClock) private val kosmos = testKosmos() Loading Loading @@ -245,6 +253,10 @@ class DreamOverlayServiceTest : SysuiTestCase() { ) } init { mSetFlagsRule.setFlagsParameterization(flags!!) } @Before fun setup() { MockitoAnnotations.initMocks(this) Loading Loading @@ -287,6 +299,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { mKeyguardUpdateMonitor, mScrimManager, mCommunalInteractor, kosmos.sceneInteractor, mSystemDialogsCloser, mUiEventLogger, mTouchInsetManager, Loading Loading @@ -768,6 +781,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { @Test @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_COMMUNAL_HUB) @DisableFlags(FLAG_SCENE_CONTAINER) @kotlin.Throws(RemoteException::class) fun testTransitionToGlanceableHub() = testScope.runTest { Loading @@ -792,6 +806,35 @@ class DreamOverlayServiceTest : SysuiTestCase() { verify(mUiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START) } @Test @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_SCENE_CONTAINER, FLAG_COMMUNAL_HUB) @kotlin.Throws(RemoteException::class) fun testTransitionToGlanceableHub_sceneContainer() = testScope.runTest { // Inform the overlay service of dream starting. Do not show dream complications. client.startDream( mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*isPreview*/, false, /*shouldShowComplication*/ ) mMainExecutor.runAllReady() verify(mDreamOverlayCallback).onRedirectWake(false) clearInvocations(mDreamOverlayCallback) kosmos.setCommunalAvailable(true) mMainExecutor.runAllReady() runCurrent() verify(mDreamOverlayCallback).onRedirectWake(true) client.onWakeRequested() mMainExecutor.runAllReady() runCurrent() assertThat(kosmos.sceneContainerRepository.currentScene.value) .isEqualTo(Scenes.Communal) verify(mUiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START) } @Test @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_COMMUNAL_HUB) @Throws(RemoteException::class) Loading Loading @@ -911,6 +954,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { // Verifies that the touch handling lifecycle is STARTED even if the dream starts while not // focused. @Test @DisableFlags(FLAG_SCENE_CONTAINER) fun testLifecycle_dreamNotFocusedOnStart_isStarted() { val transitionState: MutableStateFlow<ObservableTransitionState> = MutableStateFlow(ObservableTransitionState.Idle(CommunalScenes.Blank)) Loading Loading @@ -1024,6 +1068,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) fun testCommunalVisible_setsLifecycleState() { val client = client Loading Loading @@ -1060,6 +1105,7 @@ class DreamOverlayServiceTest : SysuiTestCase() { // Verifies the dream's lifecycle @Test @DisableFlags(FLAG_SCENE_CONTAINER) fun testLifecycleStarted_whenAnyOcclusion() { val client = client Loading Loading @@ -1256,5 +1302,11 @@ class DreamOverlayServiceTest : SysuiTestCase() { ComponentName("package", "homeControlPanel") private const val DREAM_COMPONENT = "package/dream" private const val WINDOW_NAME = "test" @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_HUB).andSceneContainer() } } }
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorTest.kt +19 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import com.android.compose.animation.scene.ObservableTransitionState.Transition. import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState Loading Loading @@ -194,6 +195,24 @@ class SceneContainerOcclusionInteractorTest : SysuiTestCase() { .isFalse() } @Test fun invisibleDueToOcclusion_isDreaming_emitsTrue() = testScope.runTest { val invisibleDueToOcclusion by collectLastValue(underTest.invisibleDueToOcclusion) // Verify that we start with unoccluded assertWithMessage("Should start unoccluded").that(invisibleDueToOcclusion).isFalse() // Start dreaming, which is an occluding activity showOccludingActivity() kosmos.keyguardInteractor.setDreaming(true) // Verify not invisible when dreaming assertWithMessage("Should be invisible when dreaming") .that(invisibleDueToOcclusion) .isTrue() } /** Simulates the appearance of a show-when-locked `Activity` in the foreground. */ private fun TestScope.showOccludingActivity() { keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +123 −2 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.dismissCallbackRegistry import com.android.systemui.keyguard.domain.interactor.dozeInteractor import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.scenetransition.lockscreenSceneTransitionInteractor Loading Loading @@ -143,6 +144,8 @@ class SceneContainerStartableTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val deviceEntryHapticsInteractor by lazy { kosmos.deviceEntryHapticsInteractor } private val dozeInteractor by lazy { kosmos.dozeInteractor } private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val sceneInteractor by lazy { kosmos.sceneInteractor } private val sceneBackInteractor by lazy { kosmos.sceneBackInteractor } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } Loading Loading @@ -372,6 +375,64 @@ class SceneContainerStartableTest : SysuiTestCase() { assertThat(isVisible).isTrue() } @Test fun hydrateVisibility_whileDreaming() = testScope.runTest { val isVisible by collectLastValue(sceneInteractor.isVisible) // GIVEN the device is dreaming val transitionState = prepareState(isDeviceUnlocked = false, initialSceneKey = Scenes.Dream) underTest.start() assertThat(isVisible).isFalse() } @Test fun hydrateVisibility_onCommunalWhileOccluded() = testScope.runTest { val isVisible by collectLastValue(sceneInteractor.isVisible) kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( true, mock(), ) prepareState(isDeviceUnlocked = false, initialSceneKey = Scenes.Communal) underTest.start() runCurrent() assertThat(isVisible).isTrue() } @Test fun hydrateVisibility_inCommunalTransition() = testScope.runTest { val isVisible by collectLastValue(sceneInteractor.isVisible) // GIVEN the device is dreaming val transitionState = prepareState( authenticationMethod = AuthenticationMethodModel.Pin, isDeviceUnlocked = false, initialSceneKey = Scenes.Dream, ) underTest.start() assertThat(isVisible).isFalse() // WHEN a transition starts to the communal hub sceneInteractor.changeScene(Scenes.Dream, "switching to dream for test") transitionState.value = ObservableTransitionState.Transition( fromScene = Scenes.Dream, toScene = Scenes.Communal, currentScene = flowOf(Scenes.Dream), progress = flowOf(0.5f), isInitiatedByUserInput = true, isUserInputOngoing = flowOf(false), ) runCurrent() // THEN scenes are visible assertThat(isVisible).isTrue() } @Test fun startsInLockscreenScene() = testScope.runTest { Loading Loading @@ -643,7 +704,7 @@ class SceneContainerStartableTest : SysuiTestCase() { fun switchToAOD_whenAvailable_whenDeviceSleepsLocked() = testScope.runTest { kosmos.lockscreenSceneTransitionInteractor.start() val asleepState by collectLastValue(kosmos.keyguardInteractor.asleepKeyguardState) val asleepState by collectLastValue(keyguardInteractor.asleepKeyguardState) val currentTransitionInfo by collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal) val transitionState = Loading Loading @@ -673,7 +734,7 @@ class SceneContainerStartableTest : SysuiTestCase() { fun switchToDozing_whenAodUnavailable_whenDeviceSleepsLocked() = testScope.runTest { kosmos.lockscreenSceneTransitionInteractor.start() val asleepState by collectLastValue(kosmos.keyguardInteractor.asleepKeyguardState) val asleepState by collectLastValue(keyguardInteractor.asleepKeyguardState) val currentTransitionInfo by collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal) val transitionState = Loading Loading @@ -2359,6 +2420,66 @@ class SceneContainerStartableTest : SysuiTestCase() { assertThat(isLockscreenEnabled).isTrue() } @Test fun stayOnLockscreen_whenDozingStarted() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) underTest.start() // Stay on Lockscreen when dozing and dreaming dozeInteractor.setIsDozing(true) keyguardInteractor.setDreaming(true) kosmos.fakeKeyguardRepository.setDreamingWithOverlay(false) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) } @Test fun switchFromLockscreenToDream_whenDreamStarted() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) underTest.start() powerInteractor.setAwakeForTest() keyguardInteractor.setDreaming(true) // Move past initial delay with [KeyguardInteractor#isAbleToDream] advanceTimeBy(600L) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Dream) } @Test fun switchFromDreamToLockscreen_whenLockedAndDreamStopped() = testScope.runTest { keyguardInteractor.setDreaming(true) val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState(initialSceneKey = Scenes.Dream) assertThat(currentScene).isEqualTo(Scenes.Dream) underTest.start() keyguardInteractor.setDreaming(false) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) } @Test fun switchFromDreamToGone_whenUnlockedAndDreamStopped() = testScope.runTest { keyguardInteractor.setDreaming(true) val currentScene by collectLastValue(sceneInteractor.currentScene) prepareState(initialSceneKey = Scenes.Dream, isDeviceUnlocked = true) assertThat(currentScene).isEqualTo(Scenes.Dream) underTest.start() keyguardInteractor.setDreaming(false) runCurrent() assertThat(currentScene).isEqualTo(Scenes.Gone) } @Test fun replacesLockscreenSceneOnBackStack_whenUnlockdViaAlternateBouncer_fromShade() = testScope.runTest { Loading