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

Commit df4dbc58 authored by Fabián Kozynski's avatar Fabián Kozynski
Browse files

[Flexiglass] Replace media with new implementation

Test: atest com.android.systemui.qs.ui.viewmodel
Test: atest PlatformScenarioTests
Bug: 397989775
Flag: com.android.systemui.scene_container
Flag: com.android.systemui.media_controls_in_compose

Change-Id: I7eab7d9d824e576051df35e732c9bff74674249b
parent 2c1ad46d
Loading
Loading
Loading
Loading
+45 −13
Original line number Diff line number Diff line
@@ -22,12 +22,18 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.onLayoutRectChanged
import androidx.compose.ui.res.dimensionResource
import com.android.compose.animation.scene.ContentScope
import com.android.systemui.Flags.mediaControlsInCompose
import com.android.systemui.keyguard.ui.viewmodel.MediaCarouselElementViewModel
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
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 javax.inject.Inject
import javax.inject.Named
@@ -37,6 +43,7 @@ class MediaCarouselElement
constructor(
    private val mediaCarouselController: MediaCarouselController,
    @param:Named(MediaModule.KEYGUARD) private val mediaHost: MediaHost,
    private val mediaCarouselElementViewModelFactory: MediaCarouselElementViewModel.Factory,
) {

    @Composable
@@ -52,6 +59,30 @@ constructor(
                dimensionResource(id = R.dimen.notification_side_paddings) +
                    dimensionResource(id = R.dimen.notification_panel_margin_horizontal)
            }
        if (mediaControlsInCompose()) {
            val viewModel =
                rememberViewModel("MediaCarouselElement") {
                    mediaCarouselElementViewModelFactory.create()
                }

            Element(
                key = Media.Elements.mediaCarousel,
                modifier =
                    modifier
                        .fillMaxWidth()
                        .padding(horizontal = horizontalPadding)
                        .onLayoutRectChanged {
                            onBottomChanged?.invoke(it.boundsInWindow.bottom.toFloat())
                        },
            ) {
                Media(
                    viewModelFactory = viewModel.mediaViewModelFactory,
                    presentationStyle = MediaPresentationStyle.Default,
                    behavior = viewModel.mediaUiBehavior,
                    onDismissed = viewModel::onSwipeToDismiss,
                )
            }
        } else {
            MediaCarousel(
                isVisible = true,
                mediaHost = mediaHost,
@@ -67,3 +98,4 @@ constructor(
            )
        }
    }
}
+20 −28
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.dimensionResource
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
@@ -34,13 +33,8 @@ import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn
import com.android.systemui.keyguard.ui.composable.element.SmallClockElement
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.composable.isLandscape
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.COLLAPSED
import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.EXPANDED
import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel
import com.android.systemui.res.R
@@ -54,7 +48,6 @@ import com.android.systemui.shade.ui.composable.isFullWidthShade
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
import dagger.Lazy
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.flow.Flow

@SysUISingleton
@@ -67,8 +60,6 @@ constructor(
    private val stackScrollView: Lazy<NotificationScrollView>,
    private val smallClockElement: SmallClockElement,
    private val keyguardClockViewModel: KeyguardClockViewModel,
    private val mediaCarouselController: MediaCarouselController,
    @Named(QUICK_QS_PANEL) private val mediaHost: Lazy<MediaHost>,
    private val jankMonitor: InteractionJankMonitor,
) : Overlay {
    override val key = Overlays.NotificationsShade
@@ -98,11 +89,6 @@ constructor(
                viewModel.notificationsPlaceholderViewModelFactory.create()
            }

        val usingCollapsedLandscapeMedia =
            LocalResources.current.getBoolean(R.bool.config_quickSettingsMediaLandscapeCollapsed)
        mediaHost.get().expansion =
            if (usingCollapsedLandscapeMedia && isLandscape()) COLLAPSED else EXPANDED

        val isFullWidth = isFullWidthShade()

        OverlayShade(
@@ -139,18 +125,24 @@ constructor(
                    }
                }

                MediaCarousel(
                    isVisible = viewModel.showMedia,
                    mediaHost = mediaHost.get(),
                    carouselController = mediaCarouselController,
                    usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
                if (viewModel.showMedia) {
                    Element(
                        key = Media.Elements.mediaCarousel,
                        modifier =
                            Modifier.padding(
                                top = notificationStackPadding,
                                start = notificationStackPadding,
                                end = notificationStackPadding,
                            ),
                    ) {
                        Media(
                            viewModelFactory = viewModel.mediaViewModelFactory,
                            presentationStyle = MediaPresentationStyle.Default,
                            behavior = viewModel.mediaUiBehavior,
                            onDismissed = viewModel::onMediaSwipeToDismiss,
                        )
                    }
                }

                NotificationScrollingStack(
                    shadeSession = shadeSession,
+14 −38
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.animateContentFloatAsState
import com.android.compose.animation.scene.animateSceneDpAsState
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.modifiers.thenIf
import com.android.compose.windowsizeclass.LocalWindowSizeClass
@@ -71,21 +70,16 @@ import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.composable.isLandscape
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
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.Companion.EXPANDED
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle
import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
import com.android.systemui.notifications.ui.composable.NotificationScrollingStack
import com.android.systemui.qs.composefragment.ui.GridAnchor
import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
import com.android.systemui.qs.panels.ui.compose.TileGrid
import com.android.systemui.qs.shared.ui.ElementKeys
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.InQS
import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneContentViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsUserActionsViewModel
import com.android.systemui.res.R
@@ -100,7 +94,6 @@ import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScr
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import dagger.Lazy
import javax.inject.Inject
import javax.inject.Named
import kotlin.math.roundToInt
import kotlinx.coroutines.flow.Flow

@@ -114,8 +107,6 @@ constructor(
    private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
    private val actionsViewModelFactory: QuickSettingsUserActionsViewModel.Factory,
    private val contentViewModelFactory: QuickSettingsSceneContentViewModel.Factory,
    private val mediaCarouselController: MediaCarouselController,
    @Named(MediaModule.QS_PANEL) private val mediaHost: MediaHost,
    private val jankMonitor: InteractionJankMonitor,
) : ExclusiveActivatable(), Scene {
    override val key = Scenes.QuickSettings
@@ -145,19 +136,11 @@ constructor(
            viewModel = viewModel,
            headerViewModel = viewModel.qsContainerViewModel.shadeHeaderViewModel,
            notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
            mediaCarouselController = mediaCarouselController,
            mediaHost = mediaHost,
            modifier = modifier,
            shadeSession = shadeSession,
            jankMonitor = jankMonitor,
        )
    }

    init {
        mediaHost.expansion = EXPANDED
        mediaHost.showsOnlyActiveMedia = false
        mediaHost.init(MediaHierarchyManager.LOCATION_QS)
    }
}

@Composable
@@ -166,8 +149,6 @@ private fun ContentScope.QuickSettingsScene(
    viewModel: QuickSettingsSceneContentViewModel,
    headerViewModel: ShadeHeaderViewModel,
    notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
    mediaCarouselController: MediaCarouselController,
    mediaHost: MediaHost,
    modifier: Modifier = Modifier,
    shadeSession: SaveableSession,
    jankMonitor: InteractionJankMonitor,
@@ -233,10 +214,8 @@ private fun ContentScope.QuickSettingsScene(
            WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()

        // ############# Media ###############
        val isMediaVisible = viewModel.isMediaVisible
        val isMediaVisible = viewModel.qsContainerViewModel.showMedia
        val mediaInRow = isMediaVisible && isLandscape()
        val mediaOffset by
            animateSceneDpAsState(value = InQS, key = MediaLandscapeTopOffset, canOverflow = false)

        // This is the background for the whole scene, as the elements don't necessarily provide
        // a background that extends to the edges.
@@ -301,19 +280,16 @@ private fun ContentScope.QuickSettingsScene(
                            },
                        media =
                            @Composable {
                                MediaCarousel(
                                    isVisible = isMediaVisible,
                                    mediaHost = mediaHost,
                                    modifier =
                                        Modifier.fillMaxWidth()
                                            .padding(
                                                horizontal =
                                                    dimensionResource(
                                                        id = R.dimen.qs_horizontal_margin
                                                    )
                                            ),
                                    carouselController = mediaCarouselController,
                                Element(key = Media.Elements.mediaCarousel, modifier = Modifier) {
                                    Media(
                                        viewModelFactory =
                                            viewModel.qsContainerViewModel.mediaViewModelFactory,
                                        presentationStyle = MediaPresentationStyle.Default,
                                        behavior = QuickSettingsContainerViewModel.mediaUiBehavior,
                                        onDismissed =
                                            viewModel.qsContainerViewModel::onMediaSwipeToDismiss,
                                    )
                                }
                            },
                        mediaInRow = mediaInRow,
                        modifier =
+9 −16
Original line number Diff line number Diff line
@@ -65,9 +65,8 @@ import com.android.systemui.brightness.ui.compose.ContainerColors
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle
import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
import com.android.systemui.qs.composefragment.ui.GridAnchor
import com.android.systemui.qs.flags.QsDetailedView
@@ -236,9 +235,6 @@ private fun ContentScope.QuickSettingsContainer(
                QuickSettingsLayout(
                    qsContainerViewModel = containerViewModel,
                    toolbarViewModelFactory = contentViewModel.toolbarViewModelFactory,
                    showMedia = contentViewModel.showMedia,
                    mediaHost = contentViewModel.mediaHost,
                    mediaCarouselController = contentViewModel.mediaCarouselController,
                    isTransparencyEnabled = contentViewModel.isTransparencyEnabled,
                    volumeSliderViewModel = contentViewModel.volumeSliderViewModel,
                    audioDetailsViewModelFactory = contentViewModel.audioDetailsViewModelFactory,
@@ -254,9 +250,6 @@ private fun ContentScope.QuickSettingsContainer(
private fun ContentScope.QuickSettingsLayout(
    qsContainerViewModel: QuickSettingsContainerViewModel,
    toolbarViewModelFactory: ToolbarViewModel.Factory,
    showMedia: Boolean,
    mediaHost: MediaHost,
    mediaCarouselController: MediaCarouselController,
    isTransparencyEnabled: Boolean,
    volumeSliderViewModel: AudioStreamSliderViewModel?,
    audioDetailsViewModelFactory: AudioDetailsViewModel.Factory,
@@ -293,15 +286,15 @@ private fun ContentScope.QuickSettingsLayout(
        VerticalSeparator()

        Column(modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
            MediaCarousel(
                isVisible = showMedia,
                mediaHost = mediaHost,
                carouselController = mediaCarouselController,
                usingCollapsedLandscapeMedia = true,
                modifier = Modifier.padding(horizontal = QuickSettingsShade.Dimensions.Padding),
            Media(
                viewModelFactory = qsContainerViewModel.mediaViewModelFactory,
                presentationStyle = MediaPresentationStyle.Compact,
                behavior = QuickSettingsContainerViewModel.mediaUiBehavior,
                onDismissed = qsContainerViewModel::onMediaSwipeToDismiss,
                modifier = Modifier,
            )

            if (showMedia) {
            if (qsContainerViewModel.showMedia) {
                VerticalSeparator()
            }

+2 −2
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.UserActionDistance
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.scene.shared.model.Scenes
@@ -47,7 +47,7 @@ fun TransitionBuilder.toShadeTransition(durationScale: Double = 1.0) {

    val qsTranslation = -ShadeHeader.Dimensions.CollapsedHeightForTransitions * 0.66f
    translate(QuickSettings.Elements.QuickQuickSettings, y = qsTranslation)
    translate(MediaCarousel.Elements.Content, y = qsTranslation)
    translate(Media.Elements.mediaCarousel, y = qsTranslation)
    translate(Notifications.Elements.NotificationScrim, Edge.Top, false)
}

Loading