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

Commit d7fb2f02 authored by Darrell Shi's avatar Darrell Shi Committed by Android (Google) Code Review
Browse files

Merge "Use new signal for mediaHostVisible" into main

parents 6f8d9243 55c7e006
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -213,7 +213,6 @@ import com.android.systemui.media.remedia.shared.flag.MediaControlsInComposeFlag
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle
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
@@ -1867,7 +1866,7 @@ private fun Umo(
                }
            }
    ) {
        if (SceneContainerFlag.isEnabled || MediaControlsInComposeFlag.isEnabled) {
        if (MediaControlsInComposeFlag.isEnabled) {
            Media(
                viewModelFactory = viewModel.mediaViewModelFactory,
                presentationStyle = MediaPresentationStyle.Large,
@@ -2205,7 +2204,8 @@ class Dimensions(val context: Context, val config: Configuration) {
    val emptyStatePadding: Dp
        get() {
            return if (
                WindowSizeUtils.getWindowSizeCategory(context) == WindowSizeUtils.WindowSizeCategory.MOBILE_PORTRAIT
                WindowSizeUtils.getWindowSizeCategory(context) ==
                    WindowSizeUtils.WindowSizeCategory.MOBILE_PORTRAIT
            ) {
                24.adjustedDp
            } else {
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.communal

import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.runTest
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.testKosmos
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
class CommunalMediaStartableTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    private val mediaHost = mock<MediaHost>()

    private val Kosmos.underTest by
        Kosmos.Fixture { CommunalMediaStartable(communalSettingsInteractor, mediaHost) }

    @DisableFlags(FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    @Test
    fun onStart_mediaControlsInComposeDisabled_initializeMediaHostForCommunal() =
        kosmos.runTest {
            underTest.start()
            verify(mediaHost).init(MediaHierarchyManager.LOCATION_COMMUNAL_HUB)
        }

    @EnableFlags(FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    @Test
    fun onStart_mediaControlsInComposeEnabled_doNotInitializeMediaHost() =
        kosmos.runTest {
            underTest.start()
            verify(mediaHost, never()).init(any())
        }
}
+41 −21
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ import com.android.systemui.Flags.FLAG_COMMUNAL_RESPONSIVE_GRID
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.Flags.FLAG_HUB_EDIT_MODE_TRANSITION
import com.android.systemui.Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE
import com.android.systemui.Flags.FLAG_NOTIFICATION_SHADE_BLUR
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.classifier.domain.interactor.falsingInteractor
@@ -74,6 +76,7 @@ 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.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.advanceTimeBy
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.backgroundScope
@@ -85,10 +88,11 @@ import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.ui.controller.mediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.remedia.data.repository.mediaPipelineRepository
import com.android.systemui.media.remedia.ui.viewmodel.factory.mediaViewModelFactory
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
@@ -135,7 +139,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {

    private val kosmos = testKosmos()

    private lateinit var underTest: CommunalViewModel
    private val Kosmos.underTest by Kosmos.Fixture { createViewModel() }

    init {
        mSetFlagsRule.setFlagsParameterization(flags)
@@ -152,8 +156,6 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            .thenReturn(mediaCarouselScrollHandler)

        kosmos.powerInteractor.setAwakeForTest()

        underTest = createViewModel()
    }

    private fun createViewModel(): CommunalViewModel {
@@ -182,13 +184,6 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
        )
    }

    @Test
    fun init_initsMediaHost() =
        kosmos.runTest {
            // MediaHost is initialized as soon as the class is created.
            verify(mediaHost).init(MediaHierarchyManager.LOCATION_COMMUNAL_HUB)
        }

    @Test
    fun tutorial_tutorialNotCompletedAndKeyguardVisible_showTutorialContent() =
        kosmos.runTest {
@@ -207,7 +202,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2, FLAG_MEDIA_CONTROLS_IN_COMPOSE, FLAG_SCENE_CONTAINER)
    fun ordering_smartspaceBeforeUmoBeforeWidgetsBeforeCtaTile() =
        kosmos.runTest {
            fakeCommunalTutorialRepository.setTutorialSettingState(
@@ -249,7 +244,12 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {

    /** TODO(b/378171351): Handle ongoing content in responsive grid. */
    @Test
    @DisableFlags(FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2)
    @DisableFlags(
        FLAG_COMMUNAL_RESPONSIVE_GRID,
        FLAG_GLANCEABLE_HUB_V2,
        FLAG_MEDIA_CONTROLS_IN_COMPOSE,
        FLAG_SCENE_CONTAINER,
    )
    fun ongoingContent_umoAndOneTimer_sizedAppropriately() =
        kosmos.runTest {
            // Widgets available.
@@ -287,7 +287,12 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {

    /** TODO(b/378171351): Handle ongoing content in responsive grid. */
    @Test
    @DisableFlags(FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2)
    @DisableFlags(
        FLAG_COMMUNAL_RESPONSIVE_GRID,
        FLAG_GLANCEABLE_HUB_V2,
        FLAG_MEDIA_CONTROLS_IN_COMPOSE,
        FLAG_SCENE_CONTAINER,
    )
    fun ongoingContent_umoAndTwoTimers_sizedAppropriately() =
        kosmos.runTest {
            // Widgets available.
@@ -334,6 +339,19 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {

    @Test
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    @EnableFlags(FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun communalContent_mediaHostVisible_mediaControlsInCompose_umoIncluded() =
        kosmos.runTest {
            mediaPipelineRepository.addCurrentUserMediaEntry(MediaData().copy(active = true))
            fakeCommunalMediaRepository.mediaActive()

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

    @Test
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2, FLAG_MEDIA_CONTROLS_IN_COMPOSE, FLAG_SCENE_CONTAINER)
    fun communalContent_mediaHostVisible_umoIncluded() =
        kosmos.runTest {
            // Media playing.
@@ -345,8 +363,8 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun communalContent_mediaHostVisible_umoExcluded() =
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2, FLAG_MEDIA_CONTROLS_IN_COMPOSE, FLAG_SCENE_CONTAINER)
    fun communalContent_mediaHostNotVisible_umoExcluded() =
        kosmos.runTest {
            whenever(mediaHost.visible).thenReturn(false)
            mediaHost.updateViewVisibility()
@@ -356,7 +374,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            val communalContent by collectLastValue(underTest.communalContent)
            assertThat(communalContent?.size).isEqualTo(1)
            assertThat(communalContent?.get(0))
                .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java)
                .isNotInstanceOf(CommunalContentModel.Umo::class.java)
        }

    @Test
@@ -873,6 +891,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_MEDIA_CONTROLS_IN_COMPOSE, FLAG_SCENE_CONTAINER)
    fun communalContent_readTriggersUmoVisibilityUpdate() =
        kosmos.runTest {
            verify(mediaHost, never()).updateViewVisibility()
@@ -897,7 +916,8 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
        }

    @Test
    fun onTapWidget_logEvent() {
    fun onTapWidget_logEvent() =
        kosmos.runTest {
            underTest.onTapWidget(ComponentName("test_pkg", "test_cls"), rank = 10)
            verify(metricsLogger).logTapWidget("test_pkg/test_cls", rank = 10)
        }
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.communal

import com.android.systemui.CoreStartable
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.media.remedia.shared.flag.MediaControlsInComposeFlag
import javax.inject.Inject
import javax.inject.Named

@SysUISingleton
class CommunalMediaStartable
@Inject
constructor(
    private val communalSettingsInteractor: CommunalSettingsInteractor,
    @Named(MediaModule.COMMUNAL_HUB) private val mediaHost: MediaHost,
) : CoreStartable {
    override fun start() {
        if (MediaControlsInComposeFlag.isEnabled) {
            return
        }

        // Initialize our media host for the UMO. This only needs to happen once and must be done
        // before the MediaHierarchyManager attempts to move the UMO to the hub.
        with(mediaHost) {
            expansion = MediaHostState.EXPANDED
            expandedMatchesParentHeight = true
            // When V2 is enabled, only show active media to match lock screen, non-resumable media,
            // which can persist for up to 2 days.
            showsOnlyActiveMedia = communalSettingsInteractor.isV2FlagEnabled()
            falsingProtectionNeeded = false
            disableScrolling = true
            init(MediaHierarchyManager.LOCATION_COMMUNAL_HUB)
        }
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.communal.dagger
import com.android.systemui.CoreStartable
import com.android.systemui.communal.CommunalBackupRestoreStartable
import com.android.systemui.communal.CommunalDreamStartable
import com.android.systemui.communal.CommunalMediaStartable
import com.android.systemui.communal.CommunalMetricsStartable
import com.android.systemui.communal.CommunalOngoingContentStartable
import com.android.systemui.communal.CommunalSceneStartable
@@ -49,6 +50,11 @@ interface CommunalStartableModule {
    @ClassKey(CommunalDreamStartable::class)
    fun bindCommunalDreamStartable(impl: CommunalDreamStartable): CoreStartable

    @Binds
    @IntoMap
    @ClassKey(CommunalMediaStartable::class)
    fun bindCommunalMediaStartable(impl: CommunalMediaStartable): CoreStartable

    @Binds
    @IntoMap
    @PerUser
Loading