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

Commit df6291ab authored by Darrell Shi's avatar Darrell Shi
Browse files

Fix UMO does not show in GH

This change fixes the issue of UMO not showing in the Glanceable Hub
when scene container is enabled by:
- igoring legacy transition view models if scene container is enabled
- use the Composable UMO in the CommunalScene

Test: atest CommunalTransitionViewModelTest
Test: manually verified that UMO shows in the hub
Fix: 339450630
Flag: com.android.systemui.scene_container
Change-Id: I20f0ea1d9aab6d28fdc11a402f2716dbb09adf8e
parent 3a74114a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ constructor(
                            dialogFactory = dialogFactory,
                            widgetSection = widgetSection,
                            modifier = Modifier.element(Communal.Elements.Grid),
                            sceneScope = this@Content,
                        )
                    }
                    with(lockSection) {
+28 −2
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ import androidx.compose.ui.zIndex
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.window.layout.WindowMetricsCalculator
import com.android.compose.animation.Easings.Emphasized
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.internal.R.dimen.system_app_widget_background_radius
@@ -186,7 +187,9 @@ import com.android.systemui.communal.util.DensityUtils.Companion.adjustedDp
import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.phone.SystemUIDialogFactory
import kotlin.math.max
import kotlin.math.min
@@ -205,6 +208,7 @@ fun CommunalHub(
    widgetConfigurator: WidgetConfigurator? = null,
    onOpenWidgetPicker: (() -> Unit)? = null,
    onEditDone: (() -> Unit)? = null,
    sceneScope: SceneScope? = null,
) {
    val communalContent by
        viewModel.communalContent.collectAsStateWithLifecycle(initialValue = emptyList())
@@ -414,6 +418,7 @@ fun CommunalHub(
                            widgetConfigurator = widgetConfigurator,
                            interactionHandler = interactionHandler,
                            widgetSection = widgetSection,
                            sceneScope = sceneScope,
                        )
                    }
                }
@@ -735,6 +740,7 @@ private fun BoxScope.CommunalHubLazyGrid(
    widgetConfigurator: WidgetConfigurator?,
    interactionHandler: RemoteViews.InteractionHandler?,
    widgetSection: CommunalAppWidgetSection,
    sceneScope: SceneScope?,
) {
    var gridModifier =
        Modifier.align(Alignment.TopStart).onGloballyPositioned { setGridCoordinates(it) }
@@ -871,6 +877,7 @@ private fun BoxScope.CommunalHubLazyGrid(
                    interactionHandler = interactionHandler,
                    widgetSection = widgetSection,
                    resizeableItemFrameViewModel = resizeableItemFrameViewModel,
                    sceneScope = sceneScope,
                )
            }
        }
@@ -1095,6 +1102,7 @@ private fun CommunalContent(
    interactionHandler: RemoteViews.InteractionHandler?,
    widgetSection: CommunalAppWidgetSection,
    resizeableItemFrameViewModel: ResizeableItemFrameViewModel,
    sceneScope: SceneScope? = null,
) {
    when (model) {
        is CommunalContentModel.WidgetContent.Widget ->
@@ -1118,7 +1126,7 @@ private fun CommunalContent(
        is CommunalContentModel.CtaTileInViewMode -> CtaTileInViewModeContent(viewModel, modifier)
        is CommunalContentModel.Smartspace -> SmartspaceContent(interactionHandler, model, modifier)
        is CommunalContentModel.Tutorial -> TutorialContent(modifier)
        is CommunalContentModel.Umo -> Umo(viewModel, modifier)
        is CommunalContentModel.Umo -> Umo(viewModel, sceneScope, modifier)
    }
}

@@ -1529,7 +1537,25 @@ private fun TutorialContent(modifier: Modifier = Modifier) {
}

@Composable
private fun Umo(viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier) {
private fun Umo(
    viewModel: BaseCommunalViewModel,
    sceneScope: SceneScope?,
    modifier: Modifier = Modifier,
) {
    if (SceneContainerFlag.isEnabled && sceneScope != null) {
        sceneScope.MediaCarousel(
            modifier = modifier.fillMaxSize(),
            isVisible = true,
            mediaHost = viewModel.mediaHost,
            carouselController = viewModel.mediaCarouselController,
        )
    } else {
        UmoLegacy(viewModel, modifier)
    }
}

@Composable
private fun UmoLegacy(viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier) {
    AndroidView(
        modifier =
            modifier.pointerInput(Unit) {
+57 −5
Original line number Diff line number Diff line
@@ -16,38 +16,64 @@

package com.android.systemui.communal.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class CommunalTransitionViewModelTest : SysuiTestCase() {
@RunWith(ParameterizedAndroidJunit4::class)
class CommunalTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {

    companion object {
        @JvmStatic
        @Parameters(name = "{0}")
        fun getParams(): List<FlagsParameterization> {
            return FlagsParameterization.allCombinationsOf().andSceneContainer()
        }
    }

    init {
        mSetFlagsRule.setFlagsParameterization(flags)
    }

    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
    private val communalSceneRepository = kosmos.fakeCommunalSceneRepository
    private val sceneInteractor = kosmos.sceneInteractor

    private val underTest: CommunalTransitionViewModel by lazy {
        kosmos.communalTransitionViewModel
    }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun testIsUmoOnCommunalDuringTransitionBetweenLockscreenAndGlanceableHub() =
        testScope.runTest {
@@ -61,6 +87,7 @@ class CommunalTransitionViewModelTest : SysuiTestCase() {
            assertThat(isUmoOnCommunal).isFalse()
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun testIsUmoOnCommunalDuringTransitionBetweenDreamingAndGlanceableHub() =
        testScope.runTest {
@@ -74,6 +101,7 @@ class CommunalTransitionViewModelTest : SysuiTestCase() {
            assertThat(isUmoOnCommunal).isFalse()
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun testIsUmoOnCommunalDuringTransitionBetweenOccludedAndGlanceableHub() =
        testScope.runTest {
@@ -87,6 +115,7 @@ class CommunalTransitionViewModelTest : SysuiTestCase() {
            assertThat(isUmoOnCommunal).isFalse()
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun isUmoOnCommunal_noLongerVisible_returnsFalse() =
        testScope.runTest {
@@ -103,6 +132,7 @@ class CommunalTransitionViewModelTest : SysuiTestCase() {
            assertThat(isUmoOnCommunal).isFalse()
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun isUmoOnCommunal_idleOnCommunal_returnsTrue() =
        testScope.runTest {
@@ -116,11 +146,25 @@ class CommunalTransitionViewModelTest : SysuiTestCase() {
            assertThat(isUmoOnCommunal).isTrue()
        }

    @EnableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun isUmoOnCommunal_sceneContainerEnabled_idleOnCommunal_returnsTrue() =
        testScope.runTest {
            val isUmoOnCommunal by collectLastValue(underTest.isUmoOnCommunal)
            assertThat(isUmoOnCommunal).isFalse()

            // Change to communal scene.
            setIdleScene(Scenes.Communal)

            // isUmoOnCommunal returns true, even without any keyguard transition.
            assertThat(isUmoOnCommunal).isTrue()
        }

    private suspend fun TestScope.enterCommunal(from: KeyguardState) {
        keyguardTransitionRepository.sendTransitionSteps(
            from = from,
            to = KeyguardState.GLANCEABLE_HUB,
            testScope
            testScope,
        )
        communalSceneRepository.changeScene(CommunalScenes.Communal)
        runCurrent()
@@ -130,9 +174,17 @@ class CommunalTransitionViewModelTest : SysuiTestCase() {
        keyguardTransitionRepository.sendTransitionSteps(
            from = KeyguardState.GLANCEABLE_HUB,
            to = to,
            testScope
            testScope,
        )
        communalSceneRepository.changeScene(CommunalScenes.Blank)
        runCurrent()
    }

    private fun setIdleScene(scene: SceneKey) {
        sceneInteractor.changeScene(scene, "test")
        val transitionState =
            MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(scene))
        sceneInteractor.setTransitionState(transitionState)
        testScope.runCurrent()
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInterac
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.mediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.testKosmos
@@ -133,6 +134,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
                accessibilityManager,
                packageManager,
                WIDGET_PICKER_PACKAGE_NAME,
                kosmos.mediaCarouselController,
            )
    }

+5 −12
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ 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
import com.android.systemui.media.controls.ui.controller.mediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
@@ -178,6 +179,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            mediaHost,
            logcatLogBuffer("CommunalViewModelTest"),
            metricsLogger,
            kosmos.mediaCarouselController,
        )
    }

@@ -627,10 +629,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            kosmos.setTransition(
                sceneTransition = Idle(Scenes.Communal),
                stateTransition =
                    TransitionStep(
                        from = KeyguardState.DREAMING,
                        to = KeyguardState.GLANCEABLE_HUB
                    ),
                    TransitionStep(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB),
            )

            // Then flow is not frozen
@@ -647,10 +646,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            kosmos.setTransition(
                sceneTransition = Idle(Scenes.Lockscreen),
                stateTransition =
                    TransitionStep(
                        from = KeyguardState.GLANCEABLE_HUB,
                        to = KeyguardState.OCCLUDED
                    ),
                    TransitionStep(from = KeyguardState.GLANCEABLE_HUB, to = KeyguardState.OCCLUDED),
            )

            // Then flow is not frozen
@@ -735,10 +731,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            kosmos.setTransition(
                sceneTransition = Idle(Scenes.Communal),
                stateTransition =
                    TransitionStep(
                        from = KeyguardState.DREAMING,
                        to = KeyguardState.GLANCEABLE_HUB
                    ),
                    TransitionStep(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB),
            )

            // Widgets available
Loading