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

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

[SB][Flexi] Show lockscreen status bar even when no auth required.

KeyguardStatusBarViewModel (the model that decides whether to show the
status bar on lockscreen when scenes are enabled) was only showing the
status bar if `statusBarState == KEYGUARD`. However,
StatusBarStateController sets the statusBarState to SHADE if there's no
authentication required, even if the user is currently seeing the
lockscreen.

This CL updates KeyguardStatusBarViewModel to listen to the current
scene instead of statusBarState, since the current scene better reflects
what the user is currently seeing.

Also updates KeyguardStatusBarViewControllerTest to use more Kosmos.

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

Test: Set device lock to just "swipe", lock device -> verify the
keyguard status bar shows when on lockscreen, but not when on AOD,
shade, or bouncer

Test: - Have face auth bypass enabled.
      - Go to the LS.
      - Receive a HUN.
      - Verify keyguard status bar hides, and status bar area just shows
	the name of the app sending a HUN
      (This verifies Ie168fe0171496d20c62057df46ce62669263e90a didn't
      regress)
Change-Id: Ia65928d16c598d9a10c22e5816abe07af6aceb37
parent b09e962d
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -20,7 +20,8 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.policy.BatteryController
@@ -48,6 +49,7 @@ class KeyguardStatusBarViewModel
constructor(
    @Application scope: CoroutineScope,
    headsUpNotificationInteractor: HeadsUpNotificationInteractor,
    sceneInteractor: SceneInteractor,
    keyguardInteractor: KeyguardInteractor,
    keyguardStatusBarInteractor: KeyguardStatusBarInteractor,
    batteryController: BatteryController,
@@ -55,11 +57,11 @@ constructor(
    /** True if this view should be visible and false otherwise. */
    val isVisible: StateFlow<Boolean> =
        combine(
                sceneInteractor.currentScene,
                keyguardInteractor.isDozing,
                keyguardInteractor.statusBarState,
                headsUpNotificationInteractor.showHeadsUpStatusBar,
            ) { isDozing, statusBarState, showHeadsUpStatusBar ->
                !isDozing && statusBarState == StatusBarState.KEYGUARD && !showHeadsUpStatusBar
            ) { currentScene, isDozing, showHeadsUpStatusBar ->
                currentScene == Scenes.Lockscreen && !isDozing && !showHeadsUpStatusBar
            }
            .stateIn(scope, SharingStarted.WhileSubscribed(), false)

+1 −41
Original line number Diff line number Diff line
@@ -52,28 +52,17 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.CarrierTextController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.TestScopeProvider;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
import com.android.systemui.flags.DisableSceneContainer;
import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeViewStateProvider;
import com.android.systemui.shade.data.repository.FakeShadeRepository;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository;
import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
import com.android.systemui.statusbar.phone.ui.TintedIconManager;
@@ -82,14 +71,11 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;

import kotlinx.coroutines.test.TestScope;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -150,11 +136,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
    private KeyguardStatusBarViewController mController;
    private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
    private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
    private final TestScope mTestScope = TestScopeProvider.getTestScope();
    private final FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
    private KeyguardInteractor mKeyguardInteractor;
    private KeyguardStatusBarViewModel mViewModel;

    @Before
    public void setup() throws Exception {
@@ -163,28 +145,6 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
        MockitoAnnotations.initMocks(this);

        when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
        KeyguardTransitionInteractor keyguardTransitionInteractor =
                mKosmos.getKeyguardTransitionInteractor();
        mKeyguardInteractor = new KeyguardInteractor(
                mKeyguardRepository,
                mCommandQueue,
                PowerInteractorFactory.create().getPowerInteractor(),
                new FakeKeyguardBouncerRepository(),
                new ConfigurationInteractor(new FakeConfigurationRepository()),
                new FakeShadeRepository(),
                keyguardTransitionInteractor,
                () -> mKosmos.getSceneInteractor(),
                () -> mKosmos.getFromGoneTransitionInteractor(),
                () -> mKosmos.getFromLockscreenTransitionInteractor(),
                () -> mKosmos.getSharedNotificationContainerInteractor(),
                mTestScope);
        mViewModel =
                new KeyguardStatusBarViewModel(
                        mTestScope.getBackgroundScope(),
                        mKosmos.getHeadsUpNotificationInteractor(),
                        mKeyguardInteractor,
                        new KeyguardStatusBarInteractor(new FakeKeyguardStatusBarRepository()),
                        mBatteryController);

        allowTestableLooperAsMainThread();
        TestableLooper.get(this).runWithLooper(() -> {
@@ -212,7 +172,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
                mKeyguardStateController,
                mKeyguardBypassController,
                mKeyguardUpdateMonitor,
                mViewModel,
                mKosmos.getKeyguardStatusBarViewModel(),
                mBiometricUnlockController,
                mStatusBarStateController,
                mStatusBarContentInsetsProvider,
+12 −9
Original line number Diff line number Diff line
@@ -26,8 +26,10 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.kosmos.testScope
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.statusbar.domain.interactor.keyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
@@ -85,6 +87,7 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
            KeyguardStatusBarViewModel(
                testScope.backgroundScope,
                headsUpNotificationInteractor,
                kosmos.sceneInteractor,
                keyguardInteractor,
                keyguardStatusBarInteractor,
                batteryController,
@@ -95,7 +98,7 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
    fun isVisible_dozing_false() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)
            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)

            keyguardRepository.setIsDozing(true)

@@ -103,21 +106,21 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
        }

    @Test
    fun isVisible_statusBarStateShade_false() =
    fun isVisible_sceneShade_false() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)

            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
            kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)

            assertThat(latest).isFalse()
        }

    @Test
    fun isVisible_statusBarStateShadeLocked_false() =
    fun isVisible_sceneBouncer_false() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)

            keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
            kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)

            assertThat(latest).isFalse()
        }
@@ -130,7 +133,7 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
            // WHEN HUN displayed on the bypass lock screen
            headsUpRepository.setNotifications(FakeHeadsUpRowRepository("key 0", isPinned = true))
            keyguardTransitionRepository.emitInitialStepsFromOff(KeyguardState.LOCKSCREEN)
            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
            faceAuthRepository.isBypassEnabled.value = true

            // THEN KeyguardStatusBar is NOT visible to make space for HeadsUpStatusBar
@@ -138,11 +141,11 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
        }

    @Test
    fun isVisible_statusBarStateKeyguard_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
    fun isVisible_sceneLockscreen_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)

            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
            keyguardRepository.setIsDozing(false)

            assertThat(latest).isTrue()
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.fakeWifiRepo
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.wifiInteractor
import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository
import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel
import com.android.systemui.util.time.systemClock
import com.android.systemui.volume.domain.interactor.volumeDialogInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -102,6 +103,7 @@ class KosmosJavaAdapter() {
    val keyguardInteractor by lazy { kosmos.keyguardInteractor }
    val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
    val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
    val keyguardStatusBarViewModel by lazy { kosmos.keyguardStatusBarViewModel }
    val powerRepository by lazy { kosmos.fakePowerRepository }
    val clock by lazy { kosmos.systemClock }
    val mobileConnectionsRepository by lazy { kosmos.fakeMobileConnectionsRepository }
+37 −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.statusbar.ui.viewmodel

import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.policy.batteryController

val Kosmos.keyguardStatusBarViewModel: KeyguardStatusBarViewModel by
    Kosmos.Fixture {
        KeyguardStatusBarViewModel(
            applicationCoroutineScope,
            headsUpNotificationInteractor,
            sceneInteractor,
            keyguardInteractor,
            keyguardStatusBarInteractor,
            batteryController,
        )
    }