Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 509f7ad9 authored by Coco Duan's avatar Coco Duan
Browse files

Keep home status bar hidden when transitioning from launcher to dream

In HomeStatusBarViewModel, re-implements the behavior in the legacy
CollapsedStatusBarFragment from change-id:
b11171ee.

With the status_bar_root_modernization, ensure home status bar is
hidden while transitioning from GONE to DREAMING.

Bug: 372563526
Flag: com.android.systemui.status_bar_root_modernization
Test: atest HomeStatusBarViewModelImplTest
Test: lockscreen->dream, no home status bar flickering
Test: launcher->dream, no home status bar flickering
Change-Id: I9fcffe50d204c01ec69e032df22670ba6e36fada
parent 7c66d275
Loading
Loading
Loading
Loading
+128 −0
Original line number Diff line number Diff line
@@ -1746,6 +1746,134 @@ class HomeStatusBarViewModelImplTest(flags: FlagsParameterization) : SysuiTestCa
            assertThat(latest).containsExactly("icon1", "icon2")
        }

    @Test
    @DisableSceneContainer
    fun launcherToDream_sceneFlagOff_noStatusBarViewsShown() =
        kosmos.runTest {
            val clockVisible by collectLastValue(underTest.isClockVisible)
            val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
            val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)

            // Gone to dreaming transition starts
            keyguardInteractor.setDreaming(true)
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.GONE,
                to = KeyguardState.DREAMING,
                throughTransitionState = TransitionState.STARTED,
                testScope = testScope,
            )

            assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
        }

    @Test
    @EnableSceneContainer
    fun launcherToDream_sceneFlagOn_noStatusBarViewsShown() =
        kosmos.runTest {
            val clockVisible by collectLastValue(underTest.isClockVisible)
            val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
            val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)

            sceneContainerRepository.instantlyTransitionTo(Scenes.Gone)

            assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)

            sceneContainerRepository.instantlyTransitionTo(Scenes.Dream)

            assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
        }

    @Test
    @DisableSceneContainer
    fun dreamingToLauncher_sceneFlagOff_statusBarViewsShown() =
        kosmos.runTest {
            val clockVisible by collectLastValue(underTest.isClockVisible)
            val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
            val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)

            // Dream stops and returns to launcher
            keyguardInteractor.setDreaming(false)
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.DREAMING,
                to = KeyguardState.GONE,
                testScope = testScope,
            )

            assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
        }

    @Test
    @DisableSceneContainer
    fun finishedInDreaming_noStatusBarViewsShown() =
        kosmos.runTest {
            val clockVisible by collectLastValue(underTest.isClockVisible)
            val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
            val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)

            // Transition from gone to dreaming finishes.
            keyguardInteractor.setDreaming(true)
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.GONE,
                to = KeyguardState.DREAMING,
                testScope = testScope,
            )

            assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
        }

    @Test
    @EnableSceneContainer
    fun dreamingToLauncher_sceneFlagOn_statusBarViewsShown() =
        kosmos.runTest {
            val clockVisible by collectLastValue(underTest.isClockVisible)
            val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
            val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)

            sceneContainerRepository.instantlyTransitionTo(Scenes.Dream)

            assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)

            sceneContainerRepository.instantlyTransitionTo(Scenes.Gone)

            assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
        }

    @Test
    @DisableSceneContainer
    fun startsDreaming_fromLockscreen_noStatusBarViewsShown() =
        kosmos.runTest {
            val clockVisible by collectLastValue(underTest.isClockVisible)
            val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
            val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)

            // Starts transitioning to dream from any state other than launcher (lock screen)
            keyguardInteractor.setDreaming(true)
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
                throughTransitionState = TransitionState.STARTED,
                testScope = testScope,
            )
            // home status bar should remain hidden
            assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
            assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
            assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
        }

    private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
        ActiveNotificationsStore.Builder()
            .apply { notifications.forEach(::addIndividualNotif) }
+23 −2
Original line number Diff line number Diff line
@@ -331,6 +331,21 @@ constructor(
            hasShade && isShadeVisibleOnAnyDisplay
        }

    /** Whether keyguard is transitioning from Gone to Dreaming. */
    private val isTransitioningFromGoneToDream: Flow<Boolean> =
        keyguardTransitionInteractor
            .isInTransition(
                Edge.create(from = Scenes.Gone, to = DREAMING),
                edgeWithoutSceneContainer = Edge.create(from = GONE, to = DREAMING),
            )
            .distinctUntilChanged()
            .logDiffsForTable(
                tableLogBuffer = tableLogger,
                columnName = COL_GONE_TO_DREAM,
                initialValue = false,
            )
            .flowOn(bgDispatcher)

    private val isHomeStatusBarAllowedByScene: Flow<Boolean> =
        combine(
                sceneInteractor.currentScene,
@@ -433,7 +448,8 @@ constructor(
                isHomeStatusBarAllowed,
                keyguardInteractor.isSecureCameraActive,
                headsUpNotificationInteractor.statusBarHeadsUpStatus,
            ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState ->
                isTransitioningFromGoneToDream,
            ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState, isGoneToDream ->
                val showForHeadsUp =
                    if (StatusBarNoHunBehavior.isEnabled) {
                        false
@@ -449,7 +465,11 @@ constructor(
                // the icons and tells us to hide them. To ensure that this high-visibility
                // animation is smooth, keep the icons hidden during a camera launch. See
                // b/257292822.
                showForHeadsUp || (isHomeStatusBarAllowed && !isSecureCameraActive)
                // Similar to launching the camera: when dream is launched, the icons are
                // momentarily visible because the dream animation has finished, but SysUI has not
                // been informed that the dream is full-screen. See b/273314977.
                showForHeadsUp ||
                    (isHomeStatusBarAllowed && !isSecureCameraActive && !isGoneToDream)
            }
            .distinctUntilChanged()
            .logDiffsForTable(
@@ -653,6 +673,7 @@ constructor(

    companion object {
        private const val COL_LOCK_TO_OCCLUDED = "Lock->Occluded"
        private const val COL_GONE_TO_DREAM = "Gone->Dreaming"
        private const val COL_ALLOWED_LEGACY = "allowedLegacy"
        private const val COL_ALLOWED_BY_SCENE = "allowedByScene"
        private const val COL_SHADE_EXPANDED_ENOUGH = "shadeExpandedEnough"