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

Commit 05c802b2 authored by Prince's avatar Prince
Browse files

Removing UMO from glanceable hub if media on lock screen setting is off

Test: atest CommunalViewModelTest CommunalInteractorTest
Flag: com.android.systemui.communal_hub
Fixes: 339085881
Change-Id: Ib146901e0214e42dfce53ee0be51c1a7bb519886
parent 9f835c5f
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -295,7 +295,7 @@ class CommunalInteractorTest : SysuiTestCase() {
            val targets = listOf(target1, target2, target3)
            smartspaceRepository.setCommunalSmartspaceTargets(targets)

            val smartspaceContent by collectLastValue(underTest.ongoingContent)
            val smartspaceContent by collectLastValue(underTest.getOngoingContent(true))
            assertThat(smartspaceContent?.size).isEqualTo(1)
            assertThat(smartspaceContent?.get(0)?.key)
                .isEqualTo(CommunalContentModel.KEY.smartspace("target3"))
@@ -393,7 +393,7 @@ class CommunalInteractorTest : SysuiTestCase() {

            smartspaceRepository.setCommunalSmartspaceTargets(targets)

            val smartspaceContent by collectLastValue(underTest.ongoingContent)
            val smartspaceContent by collectLastValue(underTest.getOngoingContent(true))
            assertThat(smartspaceContent?.size).isEqualTo(totalTargets)
            for (index in 0 until totalTargets) {
                assertThat(smartspaceContent?.get(index)?.size).isEqualTo(expectedSizes[index])
@@ -409,13 +409,27 @@ class CommunalInteractorTest : SysuiTestCase() {
            // Media is playing.
            mediaRepository.mediaActive()

            val umoContent by collectLastValue(underTest.ongoingContent)
            val umoContent by collectLastValue(underTest.getOngoingContent(true))

            assertThat(umoContent?.size).isEqualTo(1)
            assertThat(umoContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java)
            assertThat(umoContent?.get(0)?.key).isEqualTo(CommunalContentModel.KEY.umo())
        }

    @Test
    fun umo_mediaPlaying_doNotShowUmo() =
        testScope.run {
            // Tutorial completed.
            tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)

            // Media is playing.
            mediaRepository.mediaActive()

            val umoContent by collectLastValue(underTest.getOngoingContent(false))

            assertThat(umoContent?.size).isEqualTo(0)
        }

    @Test
    fun ongoing_shouldOrderAndSizeByTimestamp() =
        testScope.runTest {
@@ -439,7 +453,7 @@ class CommunalInteractorTest : SysuiTestCase() {
            val timer3 = smartspaceTimer("timer3", timestamp = 4L)
            smartspaceRepository.setCommunalSmartspaceTargets(listOf(timer1, timer2, timer3))

            val ongoingContent by collectLastValue(underTest.ongoingContent)
            val ongoingContent by collectLastValue(underTest.getOngoingContent(true))
            assertThat(ongoingContent?.size).isEqualTo(4)
            assertThat(ongoingContent?.get(0)?.key)
                .isEqualTo(CommunalContentModel.KEY.smartspace("timer3"))
+43 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS
import com.android.systemui.communal.ui.viewmodel.PopupType
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
@@ -61,6 +62,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
@@ -142,11 +144,13 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            selectedUserIndex = 0,
        )
        whenever(providerInfo.profile).thenReturn(UserHandle(MAIN_USER_INFO.id))
        whenever(mediaHost.visible).thenReturn(true)

        kosmos.powerInteractor.setAwakeForTest()

        underTest =
            CommunalViewModel(
                kosmos.testDispatcher,
                testScope,
                context.resources,
                kosmos.keyguardTransitionInteractor,
@@ -234,6 +238,45 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
                .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java)
        }

    @Test
    fun communalContent_mediaHostVisible_umoIncluded() =
        testScope.runTest {
            // Media playing.
            mediaRepository.mediaActive()

            val communalContent by collectLastValue(underTest.communalContent)
            assertThat(communalContent?.size).isEqualTo(2)
            assertThat(communalContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java)
        }

    @Test
    fun communalContent_mediaHostVisible_umoExcluded() =
        testScope.runTest {
            whenever(mediaHost.visible).thenReturn(false)
            mediaHost.updateViewVisibility()
            // Media playing.
            mediaRepository.mediaActive()

            val communalContent by collectLastValue(underTest.communalContent)
            assertThat(communalContent?.size).isEqualTo(1)
            assertThat(communalContent?.get(0))
                .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java)
        }

    @Test
    fun communalContent_mediaHostVisible_umoToggle() =
        testScope.runTest {
            mediaHost.updateViewVisibility()
            mediaRepository.mediaActive()

            val communalContent by collectValues(underTest.communalContent)

            whenever(mediaHost.visible).thenReturn(false)
            mediaHost.updateViewVisibility()

            assertThat(communalContent.size).isEqualTo(1)
        }

    @Test
    fun isEmptyState_isTrue_noWidgetButActiveLiveContent() =
        testScope.runTest {
+29 −28
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ constructor(
    broadcastDispatcher: BroadcastDispatcher,
    private val widgetRepository: CommunalWidgetRepository,
    private val communalPrefsRepository: CommunalPrefsRepository,
    mediaRepository: CommunalMediaRepository,
    private val mediaRepository: CommunalMediaRepository,
    smartspaceRepository: SmartspaceRepository,
    keyguardInteractor: KeyguardInteractor,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -479,7 +479,7 @@ constructor(
     * A flow of ongoing content, including smartspace timers and umo, ordered by creation time and
     * sized dynamically.
     */
    val ongoingContent: Flow<List<CommunalContentModel.Ongoing>> =
    fun getOngoingContent(mediaHostVisible: Boolean): Flow<List<CommunalContentModel.Ongoing>> =
        combine(smartspaceTargets, mediaRepository.mediaModel) { smartspace, media ->
                val ongoingContent = mutableListOf<CommunalContentModel.Ongoing>()

@@ -495,7 +495,7 @@ constructor(
                )

                // Add UMO
            if (media.hasActiveMediaOrRecommendation) {
                if (mediaHostVisible && media.hasActiveMediaOrRecommendation) {
                    ongoingContent.add(
                        CommunalContentModel.Umo(
                            createdTimestampMillis = media.createdTimestampMillis,
@@ -511,8 +511,9 @@ constructor(
                    model.size = dynamicContentSize(ongoingContent.size, index)
                }

            return@combine ongoingContent
                ongoingContent
            }
            .flowOn(bgDispatcher)

    /**
     * Filter and retain widgets associated with an existing user, safeguarding against displaying
+21 −1
Original line number Diff line number Diff line
@@ -42,12 +42,15 @@ import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -56,8 +59,10 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch

/** The default view model used for showing the communal hub. */
@@ -66,6 +71,7 @@ import kotlinx.coroutines.launch
class CommunalViewModel
@Inject
constructor(
    @Main val mainDispatcher: CoroutineDispatcher,
    @Application private val scope: CoroutineScope,
    @Main private val resources: Resources,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -79,6 +85,18 @@ constructor(
    @CommunalLog logBuffer: LogBuffer,
) : BaseCommunalViewModel(communalSceneInteractor, communalInteractor, mediaHost) {

    private val _isMediaHostVisible =
        conflatedCallbackFlow<Boolean> {
                val callback = { visible: Boolean ->
                    trySend(visible)
                    Unit
                }
                mediaHost.addVisibilityChangeListener(callback)
                awaitClose { mediaHost.removeVisibilityChangeListener(callback) }
            }
            .onStart { emit(mediaHost.visible) }
            .flowOn(mainDispatcher)

    private val logger = Logger(logBuffer, "CommunalViewModel")

    /** Communal content saved from the previous emission when the flow is active (not "frozen"). */
@@ -91,8 +109,10 @@ constructor(
                if (isTutorialMode) {
                    return@flatMapLatest flowOf(communalInteractor.tutorialContent)
                }
                val ongoingContent =
                    _isMediaHostVisible.flatMapLatest { communalInteractor.getOngoingContent(it) }
                combine(
                    communalInteractor.ongoingContent,
                    ongoingContent,
                    communalInteractor.widgetContent,
                    communalInteractor.ctaTileContent,
                ) { ongoing, widgets, ctaTile,