diff options
| author | 2024-09-30 17:28:21 +0000 | |
|---|---|---|
| committer | 2024-09-30 17:28:21 +0000 | |
| commit | 494976f3216f17f53e022735c158b3692174a65e (patch) | |
| tree | d9475bfa6debaa8bd4b7a343b97d7555e85d83bd | |
| parent | b51ff156db41d26c4fe10692b36d2a14cc11f1a9 (diff) | |
| parent | 8bff5c385a7a0a37fb842e85081fceb1a8debdda (diff) | |
Merge "[bc25] Take overlays into account when updating StatusBarState." into main
3 files changed, 124 insertions, 54 deletions
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 aefbc6b3b646..db274cc311dd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt @@ -19,6 +19,8 @@ package com.android.systemui.statusbar import android.animation.ObjectAnimator +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.testing.TestableLooper import androidx.test.filters.SmallTest @@ -47,8 +49,10 @@ import com.android.systemui.scene.data.repository.setTransition import com.android.systemui.scene.domain.interactor.sceneBackInteractor import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.shadeInteractor +import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.testKosmos import com.android.systemui.util.kotlin.JavaAdapter @@ -79,6 +83,7 @@ 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 mockDarkAnimator = mock<ObjectAnimator>() @@ -229,14 +234,15 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest @Test fun testSetDreamState_getterReturnsCurrentState() { underTest.setIsDreaming(true) - assertTrue(underTest.isDreaming()) + assertTrue(underTest.isDreaming) underTest.setIsDreaming(false) - assertFalse(underTest.isDreaming()) + assertFalse(underTest.isDreaming) } @Test @EnableSceneContainer + @DisableFlags(DualShade.FLAG_NAME) fun start_hydratesStatusBarState_whileLocked() = testScope.runTest { var statusBarState = underTest.state @@ -248,7 +254,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest } underTest.addCallback(listener) - val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) + val currentScene by collectLastValue(sceneInteractor.currentScene) val deviceUnlockStatus by collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus) @@ -258,45 +264,107 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest runCurrent() assertThat(deviceUnlockStatus!!.isUnlocked).isFalse() - kosmos.sceneInteractor.changeScene( - toScene = Scenes.Lockscreen, - loggingReason = "reason" - ) + sceneInteractor.changeScene(toScene = Scenes.Lockscreen, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) // Call start to begin hydrating based on the scene framework: underTest.start() - kosmos.sceneInteractor.changeScene(toScene = Scenes.Bouncer, loggingReason = "reason") + sceneInteractor.changeScene(toScene = Scenes.Bouncer, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Bouncer) assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) - kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason") + sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Shade) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE_LOCKED) - kosmos.sceneInteractor.changeScene( - toScene = Scenes.QuickSettings, - loggingReason = "reason" - ) + sceneInteractor.changeScene(toScene = Scenes.QuickSettings, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.QuickSettings) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE_LOCKED) - kosmos.sceneInteractor.changeScene(toScene = Scenes.Communal, loggingReason = "reason") + sceneInteractor.changeScene(toScene = Scenes.Communal, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Communal) assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) - kosmos.sceneInteractor.changeScene( - toScene = Scenes.Lockscreen, - loggingReason = "reason" + sceneInteractor.changeScene(toScene = Scenes.Lockscreen, loggingReason = "reason") + runCurrent() + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) + } + + @Test + @EnableSceneContainer + @EnableFlags(DualShade.FLAG_NAME) + fun start_hydratesStatusBarState_dualShade_whileLocked() = + 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 currentOverlays by collectLastValue(sceneInteractor.currentOverlays) + val deviceUnlockStatus by + collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus) + + kosmos.fakeAuthenticationRepository.setAuthenticationMethod( + AuthenticationMethodModel.Password ) runCurrent() + assertThat(deviceUnlockStatus!!.isUnlocked).isFalse() + + sceneInteractor.changeScene(Scenes.Lockscreen, loggingReason = "reason") + runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + + // Call start to begin hydrating based on the scene framework: + underTest.start() + + sceneInteractor.changeScene(Scenes.Bouncer, loggingReason = "reason") + runCurrent() + assertThat(currentScene).isEqualTo(Scenes.Bouncer) + assertThat(currentOverlays).isEmpty() + assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) + + sceneInteractor.changeScene(Scenes.Lockscreen, loggingReason = "reason") + runCurrent() + + sceneInteractor.showOverlay(Overlays.NotificationsShade, loggingReason = "reason") + runCurrent() + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + assertThat(currentOverlays).containsExactly(Overlays.NotificationsShade) + assertThat(statusBarState).isEqualTo(StatusBarState.SHADE_LOCKED) + + sceneInteractor.replaceOverlay( + from = Overlays.NotificationsShade, + to = Overlays.QuickSettingsShade, + loggingReason = "reason", + ) + runCurrent() + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + assertThat(currentOverlays).containsExactly(Overlays.QuickSettingsShade) + assertThat(statusBarState).isEqualTo(StatusBarState.SHADE_LOCKED) + + sceneInteractor.hideOverlay(Overlays.QuickSettingsShade, loggingReason = "reason") + sceneInteractor.changeScene(Scenes.Communal, loggingReason = "reason") + runCurrent() + assertThat(currentScene).isEqualTo(Scenes.Communal) + assertThat(currentOverlays).isEmpty() + assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) + + sceneInteractor.changeScene(Scenes.Lockscreen, loggingReason = "reason") + runCurrent() + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + assertThat(currentOverlays).isEmpty() assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) } @@ -313,7 +381,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest } underTest.addCallback(listener) - val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) + val currentScene by collectLastValue(sceneInteractor.currentScene) val deviceUnlockStatus by collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( @@ -326,10 +394,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest assertThat(deviceUnlockStatus!!.isUnlocked).isTrue() - kosmos.sceneInteractor.changeScene( - toScene = Scenes.Lockscreen, - loggingReason = "reason" - ) + sceneInteractor.changeScene(toScene = Scenes.Lockscreen, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Lockscreen) @@ -339,20 +404,17 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD) - kosmos.sceneInteractor.changeScene(toScene = Scenes.Gone, loggingReason = "reason") + sceneInteractor.changeScene(toScene = Scenes.Gone, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Gone) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE) - kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason") + sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Shade) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE) - kosmos.sceneInteractor.changeScene( - toScene = Scenes.QuickSettings, - loggingReason = "reason" - ) + sceneInteractor.changeScene(toScene = Scenes.QuickSettings, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.QuickSettings) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE) @@ -371,7 +433,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest } underTest.addCallback(listener) - val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) + val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) val isOccluded by collectLastValue(kosmos.sceneContainerOcclusionInteractor.invisibleDueToOcclusion) @@ -385,15 +447,12 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest // Call start to begin hydrating based on the scene framework: underTest.start() - kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason") + sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.Shade) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE) - kosmos.sceneInteractor.changeScene( - toScene = Scenes.QuickSettings, - loggingReason = "reason" - ) + sceneInteractor.changeScene(toScene = Scenes.QuickSettings, loggingReason = "reason") runCurrent() assertThat(currentScene).isEqualTo(Scenes.QuickSettings) assertThat(statusBarState).isEqualTo(StatusBarState.SHADE) @@ -415,10 +474,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest kosmos.setTransition( sceneTransition = Idle(Scenes.Gone), stateTransition = - TransitionStep( - from = KeyguardState.LOCKSCREEN, - to = KeyguardState.GONE, - ) + TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE), ) assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(false) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java index 8a6ec2aa27c9..eab2762edf96 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java @@ -37,6 +37,7 @@ import android.view.animation.Interpolator; import androidx.annotation.NonNull; import com.android.app.animation.Interpolators; +import com.android.compose.animation.scene.OverlayKey; import com.android.compose.animation.scene.SceneKey; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -60,6 +61,7 @@ import com.android.systemui.scene.domain.interactor.SceneBackInteractor; import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor; import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.flag.SceneContainerFlag; +import com.android.systemui.scene.shared.model.Overlays; import com.android.systemui.scene.shared.model.Scenes; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; @@ -75,6 +77,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.Map; +import java.util.Set; import javax.inject.Inject; @@ -230,6 +233,7 @@ public class StatusBarStateControllerImpl implements combineFlows( mDeviceUnlockedInteractorLazy.get().getDeviceUnlockStatus(), mSceneInteractorLazy.get().getCurrentScene(), + mSceneInteractorLazy.get().getCurrentOverlays(), mSceneBackInteractorLazy.get().getBackStack(), mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(), this::calculateStateFromSceneFramework), @@ -690,19 +694,25 @@ public class StatusBarStateControllerImpl implements private int calculateStateFromSceneFramework( DeviceUnlockStatus deviceUnlockStatus, SceneKey currentScene, + Set<OverlayKey> currentOverlays, SceneStack backStack, boolean isOccluded) { SceneContainerFlag.isUnexpectedlyInLegacyMode(); if (currentScene.equals(Scenes.Lockscreen)) { + if (currentOverlays.contains(Overlays.NotificationsShade) || currentOverlays.contains( + Overlays.QuickSettingsShade)) { + return StatusBarState.SHADE_LOCKED; + } return StatusBarState.KEYGUARD; - } else if (currentScene.equals(Scenes.Shade) + } + if (currentScene.equals(Scenes.Shade) && SceneStackKt.contains(backStack, Scenes.Lockscreen)) { return StatusBarState.SHADE_LOCKED; - } else if (deviceUnlockStatus.isUnlocked() || isOccluded) { + } + if (deviceUnlockStatus.isUnlocked() || isOccluded) { return StatusBarState.SHADE; - } else { - return Preconditions.checkNotNull(sStatusBarStateByLockedSceneKey.get(currentScene)); } + return Preconditions.checkNotNull(sStatusBarStateByLockedSceneKey.get(currentScene)); } /** Notifies that the {@link StatusBarState} has changed to the given new state. */ diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt index 64e056da97d4..7c055c8876ae 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt @@ -39,11 +39,7 @@ import kotlinx.coroutines.launch /** A class allowing Java classes to collect on Kotlin flows. */ @SysUISingleton -class JavaAdapter -@Inject -constructor( - @Application private val scope: CoroutineScope, -) { +class JavaAdapter @Inject constructor(@Application private val scope: CoroutineScope) { /** * Collect information for the given [flow], calling [consumer] for each emitted event. * @@ -55,10 +51,7 @@ constructor( * Do *not* call this method in a class's constructor. Instead, call it in * [com.android.systemui.CoreStartable.start] or similar method. */ - fun <T> alwaysCollectFlow( - flow: Flow<T>, - consumer: Consumer<T>, - ): Job { + fun <T> alwaysCollectFlow(flow: Flow<T>, consumer: Consumer<T>): Job { return scope.launch { flow.collect { consumer.accept(it) } } } @@ -66,7 +59,7 @@ constructor( fun <T> stateInApp( flow: Flow<T>, initialValue: T, - started: SharingStarted = SharingStarted.Eagerly + started: SharingStarted = SharingStarted.Eagerly, ): StateFlow<T> { return flow.stateIn(scope, started, initialValue) } @@ -117,7 +110,7 @@ fun <A, B, C, R> combineFlows( flow1: Flow<A>, flow2: Flow<B>, flow3: Flow<C>, - trifunction: (A, B, C) -> R + trifunction: (A, B, C) -> R, ): Flow<R> { return combine(flow1, flow2, flow3, trifunction) } @@ -127,7 +120,18 @@ fun <T1, T2, T3, T4, R> combineFlows( flow2: Flow<T2>, flow3: Flow<T3>, flow4: Flow<T4>, - transform: (T1, T2, T3, T4) -> R + transform: (T1, T2, T3, T4) -> R, ): Flow<R> { return combine(flow, flow2, flow3, flow4, transform) } + +fun <T1, T2, T3, T4, T5, R> combineFlows( + flow: Flow<T1>, + flow2: Flow<T2>, + flow3: Flow<T3>, + flow4: Flow<T4>, + flow5: Flow<T5>, + transform: (T1, T2, T3, T4, T5) -> R, +): Flow<R> { + return combine(flow, flow2, flow3, flow4, flow5, transform) +} |