diff options
2 files changed, 101 insertions, 1 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt index a9d2a541a241..38cea5b23f78 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt @@ -64,6 +64,7 @@ import com.android.systemui.util.settings.SecureSettings import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -431,6 +432,12 @@ constructor( /** Is the communal UI showing */ private var isCommunalShowing: Boolean = false + /** Is the primary bouncer showing */ + private var isPrimaryBouncerShowing: Boolean = false + + /** Is either shade or QS fully expanded */ + private var isAnyShadeFullyExpanded: Boolean = false + /** Is the communal UI showing and not dreaming */ private var onCommunalNotDreaming: Boolean = false @@ -587,6 +594,20 @@ constructor( } } + coroutineScope.launch { + shadeInteractor.isAnyFullyExpanded.collect { + isAnyShadeFullyExpanded = it + updateUserVisibility() + } + } + + coroutineScope.launch { + keyguardInteractor.primaryBouncerShowing.collect { + isPrimaryBouncerShowing = it + updateUserVisibility() + } + } + if (mediaControlsLockscreenShadeBugFix()) { coroutineScope.launch { shadeInteractor.shadeExpansion.collect { expansion -> @@ -638,6 +659,7 @@ constructor( communalShowing && isDreaming && isShadeExpanding onCommunalNotDreaming = communalShowing && !isDreaming updateDesiredLocation(forceNoAnimation = true) + updateUserVisibility() } } } @@ -1290,7 +1312,8 @@ constructor( val shadeVisible = isLockScreenVisibleToUser() || isLockScreenShadeVisibleToUser() || - isHomeScreenShadeVisibleToUser() + isHomeScreenShadeVisibleToUser() || + isGlanceableHubVisibleToUser() val mediaVisible = qsExpanded || hasActiveMediaOrRecommendation mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = shadeVisible && mediaVisible @@ -1318,6 +1341,10 @@ constructor( statusBarStateController.isExpanded } + private fun isGlanceableHubVisibleToUser(): Boolean { + return isCommunalShowing && !isPrimaryBouncerShowing && !isAnyShadeFullyExpanded + } + companion object { /** Attached in expanded quick settings */ const val LOCATION_QS = 0 diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt index 2370bca52951..0508c2cf0426 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt @@ -25,6 +25,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardViewController import com.android.systemui.SysuiTestCase +import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.ui.viewmodel.communalTransitionViewModel @@ -34,6 +35,7 @@ import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.kosmos.testScope @@ -80,6 +82,8 @@ import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.atLeastOnce +import org.mockito.kotlin.lastValue @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @@ -118,6 +122,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { private lateinit var mediaHierarchyManager: MediaHierarchyManager private lateinit var isQsBypassingShade: MutableStateFlow<Boolean> private lateinit var shadeExpansion: MutableStateFlow<Float> + private lateinit var anyShadeExpanded: MutableStateFlow<Boolean> private lateinit var mediaFrame: ViewGroup private val configurationController = FakeConfigurationController() private val settings = FakeSettings() @@ -137,8 +142,10 @@ class MediaHierarchyManagerTest : SysuiTestCase() { whenever(mediaCarouselController.mediaFrame).thenReturn(mediaFrame) isQsBypassingShade = MutableStateFlow(false) shadeExpansion = MutableStateFlow(0f) + anyShadeExpanded = MutableStateFlow(false) whenever(shadeInteractor.isQsBypassingShade).thenReturn(isQsBypassingShade) whenever(shadeInteractor.shadeExpansion).thenReturn(shadeExpansion) + whenever(shadeInteractor.isAnyFullyExpanded).thenReturn(anyShadeExpanded) mediaHierarchyManager = MediaHierarchyManager( context, @@ -574,6 +581,72 @@ class MediaHierarchyManagerTest : SysuiTestCase() { } @Test + fun testCommunalLocationVisibilityWithShadeShowing() = + testScope.runTest { + whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GLANCEABLE_HUB, + testScope = testScope, + ) + kosmos.fakeCommunalSceneRepository.changeScene(CommunalScenes.Communal) + runCurrent() + verify(mediaCarouselController) + .onDesiredLocationChanged( + eq(MediaHierarchyManager.LOCATION_COMMUNAL_HUB), + nullable(), + eq(false), + anyLong(), + anyLong() + ) + + val captor = ArgumentCaptor.forClass(Boolean::class.java) + verify(mediaCarouselScrollHandler, atLeastOnce()).visibleToUser = captor.capture() + + assertThat(captor.lastValue).isTrue() + + clearInvocations(mediaCarouselScrollHandler) + anyShadeExpanded.value = true + runCurrent() + verify(mediaCarouselScrollHandler, atLeastOnce()).visibleToUser = captor.capture() + + assertThat(captor.lastValue).isFalse() + } + + @Test + fun testCommunalLocationVisibilityWithPrimaryBouncerShowing() = + testScope.runTest { + whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GLANCEABLE_HUB, + testScope = testScope, + ) + kosmos.fakeCommunalSceneRepository.changeScene(CommunalScenes.Communal) + runCurrent() + verify(mediaCarouselController) + .onDesiredLocationChanged( + eq(MediaHierarchyManager.LOCATION_COMMUNAL_HUB), + nullable(), + eq(false), + anyLong(), + anyLong() + ) + + val captor = ArgumentCaptor.forClass(Boolean::class.java) + verify(mediaCarouselScrollHandler, atLeastOnce()).visibleToUser = captor.capture() + + assertThat(captor.lastValue).isTrue() + + clearInvocations(mediaCarouselScrollHandler) + kosmos.keyguardBouncerRepository.setPrimaryShow(true) + runCurrent() + verify(mediaCarouselScrollHandler, atLeastOnce()).visibleToUser = captor.capture() + + assertThat(captor.lastValue).isFalse() + } + + @Test fun testCommunalLocation_showsOverLockscreen() = testScope.runTest { // Device is on lock screen. |