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

Commit 1e17adc6 authored by Bryce Lee's avatar Bryce Lee
Browse files

Update media carousel visibility for glanceable hub.

This changelist accounts for the glanceable hub presence for determining
whether the media carousel is visible. The visibility state is
responsible for ensuring the carousel is properly configured when shown.

Test: atest testCommunalLocationVisibilityWithShadeShowing
Test: atest testCommunalLocationVisibilityWithPrimaryBouncerShowing
Flag: EXEMPT bugfix
Fixes: 364488347
Change-Id: I97a8e70bcdb68a8740eab15df2cb14f5a94b15f6
parent 36a651cb
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -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
+73 −0
Original line number Diff line number Diff line
@@ -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,
@@ -573,6 +580,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 {