Merge "Flexiglass: include alternate bouncer in status bar state calculation" into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 0e9ef06..0454317 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -22,6 +22,10 @@
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.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.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.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 @@
() -> 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 @@
() -> mKosmos.getSceneInteractor(),
() -> mKosmos.getSceneContainerOcclusionInteractor(),
() -> mKosmos.getKeyguardClockInteractor(),
- () -> mKosmos.getSceneBackInteractor()),
+ () -> mKosmos.getSceneBackInteractor(),
+ () -> mKosmos.getAlternateBouncerInteractor()),
mKeyguardBypassController,
mDozeParameters,
mScreenOffAnimationController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index db274cc..f8720b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -28,6 +28,8 @@
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 @@
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 @@
{ kosmos.sceneContainerOcclusionInteractor },
{ kosmos.keyguardClockInteractor },
{ kosmos.sceneBackInteractor },
+ { kosmos.alternateBouncerInteractor },
) {
override fun createDarkAnimator(): ObjectAnimator {
return mockDarkAnimator
@@ -299,6 +303,52 @@
@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)
fun start_hydratesStatusBarState_dualShade_whileLocked() =
testScope.runTest {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 73ad0e5..da04f6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -46,6 +46,7 @@
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 @@
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 @@
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 @@
mSceneContainerOcclusionInteractorLazy = sceneContainerOcclusionInteractor;
mKeyguardClockInteractorLazy = keyguardClockInteractorLazy;
mSceneBackInteractorLazy = sceneBackInteractorLazy;
+ mAlternateBouncerInteractorLazy = alternateBouncerInteractorLazy;
for (int i = 0; i < HISTORY_SIZE; i++) {
mHistoricalRecords[i] = new HistoricalState();
}
@@ -233,6 +237,7 @@
mSceneInteractorLazy.get().getCurrentOverlays(),
mSceneBackInteractorLazy.get().getBackStack(),
mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(),
+ mAlternateBouncerInteractorLazy.get().isVisible(),
this::calculateStateFromSceneFramework),
this::onStatusBarStateChanged);
@@ -693,7 +698,8 @@
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 @@
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 @@
// 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 @@
// 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 @@
// 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.
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index f97f303..522c387 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -23,6 +23,7 @@
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 @@
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 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
index cfc31c7..10b073e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
@@ -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 @@
{ sceneContainerOcclusionInteractor },
{ keyguardClockInteractor },
{ sceneBackInteractor },
+ { alternateBouncerInteractor },
)
}