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

Commit dca9276e authored by Julia Tuttle's avatar Julia Tuttle Committed by Justin Weir
Browse files

Flexiglass: include alternate bouncer in status bar state calculation

Just like when the primary bouncer is visible, we need to keep the
status bar state on SHADE_LOCKED while the alternate bouncer is visible,
so plumb that into calculateStateFromSceneFramework too.

Bug: 359530769
Test: presubmit
Flag: com.android.systemui.scene_container
Change-Id: Ib15c95bdf7a996d08b7a7648833934d04e49bfcb
parent bdd0d83e
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ import static com.android.systemui.log.LogBufferHelperKt.logcatLogBuffer;

import static com.google.common.truth.Truth.assertThat;

import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
import static kotlinx.coroutines.flow.SharedFlowKt.MutableSharedFlow;
import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
@@ -36,10 +40,6 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
import static kotlinx.coroutines.flow.SharedFlowKt.MutableSharedFlow;
import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;

import android.animation.Animator;
import android.annotation.IdRes;
import android.content.ContentResolver;
@@ -201,6 +201,12 @@ import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;

import dagger.Lazy;

import kotlinx.coroutines.CoroutineDispatcher;
import kotlinx.coroutines.channels.BufferOverflow;
import kotlinx.coroutines.test.TestScope;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -215,11 +221,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;

import dagger.Lazy;
import kotlinx.coroutines.CoroutineDispatcher;
import kotlinx.coroutines.channels.BufferOverflow;
import kotlinx.coroutines.test.TestScope;

public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {

    protected static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
@@ -461,7 +462,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
                () -> mKosmos.getSceneInteractor(),
                () -> mKosmos.getSceneContainerOcclusionInteractor(),
                () -> mKosmos.getKeyguardClockInteractor(),
                () -> mKosmos.getSceneBackInteractor());
                () -> mKosmos.getSceneBackInteractor(),
                () -> mKosmos.getAlternateBouncerInteractor());

        KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
        keyguardStatusView.setId(R.id.keyguard_status_view);
@@ -622,7 +624,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
                                () -> mKosmos.getSceneInteractor(),
                                () -> mKosmos.getSceneContainerOcclusionInteractor(),
                                () -> mKosmos.getKeyguardClockInteractor(),
                                () -> mKosmos.getSceneBackInteractor()),
                                () -> mKosmos.getSceneBackInteractor(),
                                () -> mKosmos.getAlternateBouncerInteractor()),
                        mKeyguardBypassController,
                        mDozeParameters,
                        mScreenOffAnimationController,
+52 −2
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.givenCanShowAlternateBouncer
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.DisableSceneContainer
@@ -83,8 +85,9 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest

    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val sceneInteractor = kosmos.sceneInteractor
    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
    private val sceneInteractor by lazy { kosmos.sceneInteractor }
    private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
    private val alternateBouncerInteractor by lazy { kosmos.alternateBouncerInteractor }
    private val mockDarkAnimator = mock<ObjectAnimator>()

    private lateinit var underTest: StatusBarStateControllerImpl
@@ -121,6 +124,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
                    { kosmos.sceneContainerOcclusionInteractor },
                    { kosmos.keyguardClockInteractor },
                    { kosmos.sceneBackInteractor },
                    { kosmos.alternateBouncerInteractor },
                ) {
                override fun createDarkAnimator(): ObjectAnimator {
                    return mockDarkAnimator
@@ -297,6 +301,52 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
            assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD)
        }

    @Test
    @EnableSceneContainer
    @DisableFlags(DualShade.FLAG_NAME)
    fun start_hydratesStatusBarState_withAlternateBouncer() =
        testScope.runTest {
            var statusBarState = underTest.state
            val listener =
                object : StatusBarStateController.StateListener {
                    override fun onStateChanged(newState: Int) {
                        statusBarState = newState
                    }
                }
            underTest.addCallback(listener)

            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val deviceUnlockStatus by
                collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus)
            val alternateBouncerIsVisible by collectLastValue(alternateBouncerInteractor.isVisible)

            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.Password
            )
            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )
            runCurrent()
            assertThat(deviceUnlockStatus!!.isUnlocked).isTrue()

            sceneInteractor.changeScene(toScene = Scenes.Lockscreen, loggingReason = "reason")
            runCurrent()
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)

            kosmos.givenCanShowAlternateBouncer()
            alternateBouncerInteractor.forceShow()
            runCurrent()
            assertThat(alternateBouncerIsVisible).isTrue()

            // Call start to begin hydrating based on the scene framework:
            underTest.start()

            sceneInteractor.changeScene(toScene = Scenes.Gone, loggingReason = "reason")
            runCurrent()
            assertThat(currentScene).isEqualTo(Scenes.Gone)
            assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD)
        }

    @Test
    @EnableSceneContainer
    @EnableFlags(DualShade.FLAG_NAME)
+13 −4
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.internal.jank.InteractionJankMonitor.Configuration;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardClockSwitch;
import com.android.systemui.DejankUtils;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor;
import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus;
@@ -123,6 +124,7 @@ public class StatusBarStateControllerImpl implements
    private final Lazy<SceneContainerOcclusionInteractor> mSceneContainerOcclusionInteractorLazy;
    private final Lazy<KeyguardClockInteractor> mKeyguardClockInteractorLazy;
    private final Lazy<SceneBackInteractor> mSceneBackInteractorLazy;
    private final Lazy<AlternateBouncerInteractor> mAlternateBouncerInteractorLazy;
    private int mState;
    private int mLastState;
    private int mUpcomingState;
@@ -193,7 +195,8 @@ public class StatusBarStateControllerImpl implements
            Lazy<SceneInteractor> sceneInteractorLazy,
            Lazy<SceneContainerOcclusionInteractor> sceneContainerOcclusionInteractor,
            Lazy<KeyguardClockInteractor> keyguardClockInteractorLazy,
            Lazy<SceneBackInteractor> sceneBackInteractorLazy) {
            Lazy<SceneBackInteractor> sceneBackInteractorLazy,
            Lazy<AlternateBouncerInteractor> alternateBouncerInteractorLazy) {
        mUiEventLogger = uiEventLogger;
        mInteractionJankMonitorLazy = interactionJankMonitorLazy;
        mJavaAdapter = javaAdapter;
@@ -205,6 +208,7 @@ public class StatusBarStateControllerImpl implements
        mSceneContainerOcclusionInteractorLazy = sceneContainerOcclusionInteractor;
        mKeyguardClockInteractorLazy = keyguardClockInteractorLazy;
        mSceneBackInteractorLazy = sceneBackInteractorLazy;
        mAlternateBouncerInteractorLazy = alternateBouncerInteractorLazy;
        for (int i = 0; i < HISTORY_SIZE; i++) {
            mHistoricalRecords[i] = new HistoricalState();
        }
@@ -233,6 +237,7 @@ public class StatusBarStateControllerImpl implements
                        mSceneInteractorLazy.get().getCurrentOverlays(),
                        mSceneBackInteractorLazy.get().getBackStack(),
                        mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(),
                        mAlternateBouncerInteractorLazy.get().isVisible(),
                        this::calculateStateFromSceneFramework),
                    this::onStatusBarStateChanged);

@@ -693,7 +698,8 @@ public class StatusBarStateControllerImpl implements
            SceneKey currentScene,
            Set<OverlayKey> currentOverlays,
            SceneStack backStack,
            boolean isOccluded) {
            boolean isOccluded,
            boolean alternateBouncerIsVisible) {
        SceneContainerFlag.isUnexpectedlyInLegacyMode();

        final boolean onBouncer = currentScene.equals(Scenes.Bouncer);
@@ -714,7 +720,8 @@ public class StatusBarStateControllerImpl implements

        final String inputLogString = "currentScene=" + currentScene.getTestTag()
                + " currentOverlays=" + currentOverlays + " backStack=" + backStack
                + " isUnlocked=" + isUnlocked + " isOccluded=" + isOccluded;
                + " isUnlocked=" + isUnlocked + " isOccluded=" + isOccluded
                + " alternateBouncerIsVisible=" + alternateBouncerIsVisible;

        int newState;

@@ -722,6 +729,7 @@ public class StatusBarStateControllerImpl implements
        // 1. deviceUnlockStatus.isUnlocked changes from false to true.
        // 2. Lockscreen changes to Gone, either in currentScene or in backStack.
        // 3. Bouncer is removed from currentScene or backStack, if it was present.
        // 4. the alternate bouncer is hidden, if it was visible.
        //
        // From this function's perspective, though, deviceUnlockStatus, currentScene, and backStack
        // each update separately, and the relative order of those updates is not well-defined. This
@@ -733,6 +741,7 @@ public class StatusBarStateControllerImpl implements
        // 1. deviceUnlockStatus.isUnlocked is false.
        // 2. currentScene is a keyguardish scene (Lockscreen, Bouncer, or Communal).
        // 3. backStack contains a keyguardish scene (Lockscreen or Communal).
        // 4. the alternate bouncer is visible.

        final boolean onKeyguardish = onLockscreen || onBouncer || onCommunal;
        final boolean overKeyguardish = overLockscreen || overCommunal;
@@ -741,7 +750,7 @@ public class StatusBarStateControllerImpl implements
            // Occlusion is special; even though the device is still technically on the lockscreen,
            // the UI behaves as if it is unlocked.
            newState = StatusBarState.SHADE;
        } else if (onKeyguardish || overKeyguardish) {
        } else if (onKeyguardish || overKeyguardish || alternateBouncerIsVisible) {
            // We get here if we are on or over a keyguardish scene, even if isUnlocked is true; we
            // want to return SHADE_LOCKED or KEYGUARD until we are also neither on nor over a
            // keyguardish scene.
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.fakeExecutorHandler
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.bouncerRepository
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
import com.android.systemui.classifier.falsingCollector
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
@@ -152,6 +153,7 @@ class KosmosJavaAdapter() {
    val wifiInteractor by lazy { kosmos.wifiInteractor }
    val fakeWifiRepository by lazy { kosmos.fakeWifiRepository }
    val volumeDialogInteractor by lazy { kosmos.volumeDialogInteractor }
    val alternateBouncerInteractor by lazy { kosmos.alternateBouncerInteractor }

    val ongoingActivityChipsViewModel by lazy { kosmos.ongoingActivityChipsViewModel }
    val scrimController by lazy { kosmos.scrimController }
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.plugins.statusbar

import com.android.internal.logging.uiEventLogger
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.jank.interactionJankMonitor
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
@@ -45,5 +46,6 @@ var Kosmos.statusBarStateController: SysuiStatusBarStateController by
            { sceneContainerOcclusionInteractor },
            { keyguardClockInteractor },
            { sceneBackInteractor },
            { alternateBouncerInteractor },
        )
    }