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

Commit b09e962d authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB][Flexi] Hide home status bar on lockscreen when flexiglass enabled.

Fixes: 342107016
Flag: com.android.systemui.scene_container

Test: Disable flexiglass -> status bar smoke test
Test: Enable flexiglass -> setup screen lock, unlock device, then
relock -> verify home status bar doesn't appear on lockscreen
Test: Enable flexiglass -> on lockscreen, trigger occluding activity ->
verify home status bar appears
Test: atest CollapsedStatusBarViewModelImplTest
CollapsedStatusBarFragmentTest

Change-Id: I3c1e21e6538e146ac4e0595e99b84b1b0f951f78
parent 72cd9a53
Loading
Loading
Loading
Loading
+35 −13
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@

package com.android.systemui.statusbar.phone.fragment;

import static com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.createHiddenModel;

import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.Fragment;
@@ -46,6 +48,7 @@ import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
import com.android.systemui.statusbar.CommandQueue;
@@ -204,6 +207,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
     */
    private boolean mTransitionFromLockscreenToDreamStarted = false;

    /**
     * True if the current scene allows the home status bar (aka this status bar) to be shown, and
     * false if the current scene should never show the home status bar. Only used if the scene
     * container is enabled.
     */
    private boolean mHomeStatusBarAllowedByScene = true;

    /**
     * True if there's an active ongoing activity that should be showing a chip and false otherwise.
     */
@@ -522,6 +532,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
                    mHasOngoingActivity = hasOngoingActivity;
                    updateStatusBarVisibilities(/* animate= */ true);
                }

                @Override
                public void onIsHomeStatusBarAllowedBySceneChanged(
                        boolean isHomeStatusBarAllowedByScene) {
                    mHomeStatusBarAllowedByScene = isHomeStatusBarAllowedByScene;
                    updateStatusBarVisibilities(/* animate= */ true);
                }
    };

    @Override
@@ -580,17 +597,22 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
        boolean headsUpVisible =
                mStatusBarFragmentComponent.getHeadsUpAppearanceController().shouldBeVisible();

        if (SceneContainerFlag.isEnabled()) {
            // With the scene container, only use the value calculated by the view model to
            // determine if the status bar needs hiding.
            if (!mHomeStatusBarAllowedByScene) {
                return createHiddenModel();
            }
        } else {
            // Without the scene container, use our old, mildly-hacky logic to determine if the
            // status bar needs hiding.
            if (!mKeyguardStateController.isLaunchTransitionFadingAway()
                    && !mKeyguardStateController.isKeyguardFadingAway()
                    && shouldHideStatusBar()
                    && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
                    && headsUpVisible)) {
            // Hide everything
            return new StatusBarVisibilityModel(
                    /* showClock= */ false,
                    /* showNotificationIcons= */ false,
                    /* showOngoingActivityChip= */ false,
                    /* showSystemInfo= */ false);
                return createHiddenModel();
            }
        }

        boolean showClock = externalModel.getShowClock() && !headsUpVisible;
@@ -698,7 +720,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
    }

    private void hideEndSideContent(boolean animate) {
        if (!animate) {
        if (!animate || !mAnimationsEnabled) {
            mEndSideAlphaController.setAlpha(/*alpha*/ 0f, SOURCE_OTHER);
        } else {
            mEndSideAlphaController.animateToAlpha(/*alpha*/ 0f, SOURCE_OTHER, FADE_OUT_DURATION,
@@ -707,7 +729,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
    }

    private void showEndSideContent(boolean animate) {
        if (!animate) {
        if (!animate || !mAnimationsEnabled) {
            mEndSideAlphaController.setAlpha(1f, SOURCE_OTHER);
            return;
        }
+11 −0
Original line number Diff line number Diff line
@@ -36,6 +36,17 @@ data class StatusBarVisibilityModel(
            return createModelFromFlags(DISABLE_NONE, DISABLE2_NONE)
        }

        /** Creates a model that hides every piece of the status bar. */
        @JvmStatic
        fun createHiddenModel(): StatusBarVisibilityModel {
            return StatusBarVisibilityModel(
                showClock = false,
                showNotificationIcons = false,
                showOngoingActivityChip = false,
                showSystemInfo = false,
            )
        }

        /**
         * Given a set of disabled flags, converts them into the correct visibility statuses.
         *
+15 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
@@ -136,6 +137,14 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
                        }
                    }
                }

                if (SceneContainerFlag.isEnabled) {
                    launch {
                        viewModel.isHomeStatusBarAllowedByScene.collect {
                            listener.onIsHomeStatusBarAllowedBySceneChanged(it)
                        }
                    }
                }
            }
        }
    }
@@ -259,4 +268,10 @@ interface StatusBarVisibilityChangeListener {

    /** Called when the status of the ongoing activity chip (active or not active) has changed. */
    fun onOngoingActivityStatusChanged(hasOngoingActivity: Boolean)

    /**
     * Called when the scene state has changed such that the home status bar is newly allowed or no
     * longer allowed. See [CollapsedStatusBarViewModel.isHomeStatusBarAllowedByScene].
     */
    fun onIsHomeStatusBarAllowedBySceneChanged(isHomeStatusBarAllowedByScene: Boolean)
}
+25 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -64,6 +67,12 @@ interface CollapsedStatusBarViewModel {
    /** The ongoing activity chip that should be shown on the left-hand side of the status bar. */
    val ongoingActivityChip: StateFlow<OngoingActivityChipModel>

    /**
     * True if the current scene can show the home status bar (aka this status bar), and false if
     * the current scene should never show the home status bar.
     */
    val isHomeStatusBarAllowedByScene: StateFlow<Boolean>

    /**
     * Apps can request a low profile mode [android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE] where
     * status bar and navigation icons dim. In this mode, a notification dot appears where the
@@ -83,6 +92,8 @@ constructor(
    private val lightsOutInteractor: LightsOutInteractor,
    private val notificationsInteractor: ActiveNotificationsInteractor,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
    sceneInteractor: SceneInteractor,
    sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor,
    ongoingActivityChipsViewModel: OngoingActivityChipsViewModel,
    @Application coroutineScope: CoroutineScope,
) : CollapsedStatusBarViewModel {
@@ -99,6 +110,20 @@ constructor(

    override val ongoingActivityChip = ongoingActivityChipsViewModel.chip

    override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
        combine(
                sceneInteractor.currentScene,
                sceneContainerOcclusionInteractor.invisibleDueToOcclusion,
            ) { currentScene, isOccluded ->
                // All scenes have their own status bars, so we should only show the home status bar
                // if we're not in a scene. The one exception: If the scene is occluded, then the
                // occluding app needs to show the status bar. (Fullscreen apps actually won't show
                // the status bar but that's handled with the rest of our fullscreen app logic,
                // which lives elsewhere.)
                currentScene == Scenes.Gone || isOccluded
            }
            .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)

    override fun areNotificationsLightsOut(displayId: Int): Flow<Boolean> =
        if (NotificationsLiveDataStoreRefactor.isUnexpectedlyInLegacyMode()) {
            emptyFlow()
+83 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.animation.AnimatorTestRule;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.DisableSceneContainer;
import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogcatEchoTracker;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -302,6 +304,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @DisableSceneContainer
    public void disable_shadeOpenAndShouldHide_everythingHidden() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

@@ -318,6 +321,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @DisableSceneContainer
    public void disable_shadeOpenButNotShouldHide_everythingShown() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

@@ -335,6 +339,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {

    /** Regression test for b/279790651. */
    @Test
    @DisableSceneContainer
    public void disable_shadeOpenAndShouldHide_thenShadeNotOpenAndDozingUpdate_everythingShown() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

@@ -376,6 +381,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @DisableSceneContainer
    public void disable_isTransitioningToOccluded_everythingHidden() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

@@ -390,6 +396,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @DisableSceneContainer
    public void disable_wasTransitioningToOccluded_transitionFinished_everythingShown() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

@@ -673,6 +680,80 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
    }

    @Test
    @EnableSceneContainer
    public void isHomeStatusBarAllowedByScene_false_everythingHidden() {
        resumeAndGetFragment();

        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);

        // THEN all views are hidden
        assertEquals(View.GONE, getClockView().getVisibility());
        assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
        assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
    }

    @Test
    @EnableSceneContainer
    public void isHomeStatusBarAllowedByScene_true_everythingShown() {
        resumeAndGetFragment();

        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);

        // THEN all views are shown
        assertEquals(View.VISIBLE, getClockView().getVisibility());
        assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
    }

    @Test
    @EnableSceneContainer
    public void disable_isHomeStatusBarAllowedBySceneFalse_disableValuesIgnored() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

        // WHEN the scene doesn't allow the status bar
        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);

        // BUT the disable flags want to show the status bar
        fragment.disable(DEFAULT_DISPLAY, 0, 0, false);

        // THEN all views are hidden (the disable flags aren't respected)
        assertEquals(View.GONE, getClockView().getVisibility());
        assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
        assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
    }

    @Test
    @EnableSceneContainer
    public void disable_isHomeStatusBarAllowedBySceneTrue_disableValuesUsed() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();

        // WHEN the scene does allow the status bar
        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);

        // AND the disable flags want to hide the clock
        fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_CLOCK, 0, false);

        // THEN all views are shown except the clock (the disable flags are used)
        assertEquals(View.GONE, getClockView().getVisibility());
        assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
    }

    @Test
    @DisableSceneContainer
    public void isHomeStatusBarAllowedByScene_sceneContainerDisabled_valueNotUsed() {
        resumeAndGetFragment();

        // Even if the scene says to hide the home status bar
        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);

        // The value isn't used because the scene container flag is disabled, so all views are shown
        assertEquals(View.VISIBLE, getClockView().getVisibility());
        assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
    }

    @Test
    public void disable_isDozing_clockAndSystemInfoVisible() {
        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -758,6 +839,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @DisableSceneContainer
    public void testStatusBarIcons_hiddenThroughoutCameraLaunch() {
        final CollapsedStatusBarFragment fragment = resumeAndGetFragment();

@@ -779,6 +861,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @DisableSceneContainer
    public void testStatusBarIcons_hiddenThroughoutLockscreenToDreamTransition() {
        final CollapsedStatusBarFragment fragment = resumeAndGetFragment();

Loading