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

Commit 07b38431 authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "Add media carousel to quick settings scene" into main

parents df245600 04cc957e
Loading
Loading
Loading
Loading
+8 −25
Original line number Diff line number Diff line
@@ -17,21 +17,14 @@
package com.android.systemui.keyguard.ui.composable.section

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.ui.viewmodel.MediaCarouselViewModel
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.res.R
import com.android.systemui.util.animation.MeasurementInput
import javax.inject.Inject
import javax.inject.Named

@@ -43,29 +36,19 @@ constructor(
    private val mediaCarouselViewModel: MediaCarouselViewModel,
) {

    @Composable
    fun SceneScope.MediaCarousel(modifier: Modifier = Modifier) {
        if (!mediaCarouselViewModel.isMediaVisible) {
            return
        }

    private fun isVisible(): Boolean {
        if (mediaCarouselController.mediaFrame == null) {
            return
            return false
        }
        return mediaCarouselViewModel.isMediaVisible
    }

        val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)
        // TODO(b/312714128): MediaPlayer background size is not as expected.
    @Composable
    fun SceneScope.KeyguardMediaCarousel() {
        MediaCarousel(
            modifier =
                modifier.height(mediaHeight).fillMaxWidth().onSizeChanged { size ->
                    // Notify controller to size the carousel for the
                    // current space
                    mediaHost.measurementInput = MeasurementInput(size.width, size.height)
                    mediaCarouselController.setSceneContainerSize(size.width, size.height)
                },
            isVisible = ::isVisible,
            mediaHost = mediaHost,
            layoutWidth = 0, // Layout width is not used.
            layoutHeight = with(LocalDensity.current) { mediaHeight.toPx() }.toInt(),
            modifier = Modifier.fillMaxWidth(),
            carouselController = mediaCarouselController,
        )
    }
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ constructor(
                    onTopChanged = burnIn.onSmartspaceTopChanged,
                )
            }
            with(mediaCarouselSection) { MediaCarousel() }
            with(mediaCarouselSection) { KeyguardMediaCarousel() }
        }
    }

+31 −3
Original line number Diff line number Diff line
@@ -18,14 +18,20 @@ package com.android.systemui.media.controls.ui.composable

import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.contains
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.res.R
import com.android.systemui.util.animation.MeasurementInput

private object MediaCarousel {
@@ -36,18 +42,40 @@ private object MediaCarousel {

@Composable
fun SceneScope.MediaCarousel(
    isVisible: () -> Boolean,
    mediaHost: MediaHost,
    modifier: Modifier = Modifier,
    layoutWidth: Int,
    layoutHeight: Int,
    carouselController: MediaCarouselController,
) {
    if (!isVisible()) {
        return
    }

    val density = LocalDensity.current
    val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)

    val layoutWidth = 0
    val layoutHeight = with(density) { mediaHeight.toPx() }.toInt()

    // Notify controller to size the carousel for the current space
    mediaHost.measurementInput = MeasurementInput(layoutWidth, layoutHeight)
    carouselController.setSceneContainerSize(layoutWidth, layoutHeight)

    AndroidView(
        modifier = modifier.element(MediaCarousel.Elements.Content),
        modifier =
            modifier
                .element(MediaCarousel.Elements.Content)
                .height(mediaHeight)
                .fillMaxWidth()
                .layout { measurable, constraints ->
                    val placeable = measurable.measure(constraints)

                    // Notify controller to size the carousel for the current space
                    mediaHost.measurementInput = MeasurementInput(placeable.width, placeable.height)
                    carouselController.setSceneContainerSize(placeable.width, placeable.height)

                    layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
                },
        factory = { context ->
            FrameLayout(context).apply {
                val mediaFrame = carouselController.mediaFrame
+18 −0
Original line number Diff line number Diff line
@@ -67,6 +67,10 @@ import com.android.systemui.common.ui.compose.windowinsets.LocalRawScreenHeight
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
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.notifications.ui.composable.NotificationScrollingStack
import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
@@ -82,6 +86,7 @@ import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
import com.android.systemui.statusbar.phone.ui.TintedIconManager
import javax.inject.Inject
import javax.inject.Named
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -98,6 +103,8 @@ constructor(
    private val tintedIconManagerFactory: TintedIconManager.Factory,
    private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
    private val statusBarIconController: StatusBarIconController,
    private val mediaCarouselController: MediaCarouselController,
    @Named(MediaModule.QS_PANEL) private val mediaHost: MediaHost,
) : ComposableScene {
    override val key = Scenes.QuickSettings

@@ -118,6 +125,8 @@ constructor(
            createTintedIconManager = tintedIconManagerFactory::create,
            createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
            statusBarIconController = statusBarIconController,
            mediaCarouselController = mediaCarouselController,
            mediaHost = mediaHost,
            modifier = modifier,
        )
    }
@@ -130,6 +139,8 @@ private fun SceneScope.QuickSettingsScene(
    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
    statusBarIconController: StatusBarIconController,
    mediaCarouselController: MediaCarouselController,
    mediaHost: MediaHost,
    modifier: Modifier = Modifier,
) {
    val brightnessMirrorShowing by viewModel.brightnessMirrorViewModel.isShowing.collectAsState()
@@ -282,6 +293,13 @@ private fun SceneScope.QuickSettingsScene(
                        isSplitShade = false,
                        modifier = Modifier.sysuiResTag("expanded_qs_scroll_view"),
                    )

                    MediaCarousel(
                        isVisible = viewModel::isMediaVisible,
                        mediaHost = mediaHost,
                        modifier = Modifier.fillMaxWidth(),
                        carouselController = mediaCarouselController,
                    )
                }
            }

+7 −40
Original line number Diff line number Diff line
@@ -50,11 +50,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexScenePicker
@@ -85,7 +83,6 @@ import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
import com.android.systemui.statusbar.phone.ui.TintedIconManager
import com.android.systemui.util.animation.MeasurementInput
import javax.inject.Inject
import javax.inject.Named
import kotlin.math.roundToInt
@@ -243,10 +240,11 @@ private fun SceneScope.SingleShade(
                                )
                            }

                            MediaIfVisible(
                                viewModel = viewModel,
                                mediaCarouselController = mediaCarouselController,
                            MediaCarousel(
                                isVisible = viewModel::isMediaVisible,
                                mediaHost = mediaHost,
                                modifier = Modifier.fillMaxWidth(),
                                carouselController = mediaCarouselController,
                            )

                            Spacer(modifier = Modifier.height(16.dp))
@@ -406,11 +404,11 @@ private fun SceneScope.SplitShade(
                                )
                            }

                            MediaIfVisible(
                                viewModel = viewModel,
                                mediaCarouselController = mediaCarouselController,
                            MediaCarousel(
                                isVisible = viewModel::isMediaVisible,
                                mediaHost = mediaHost,
                                modifier = Modifier.fillMaxWidth(),
                                carouselController = mediaCarouselController,
                            )
                        }
                        FooterActionsWithAnimatedVisibility(
@@ -437,34 +435,3 @@ private fun SceneScope.SplitShade(
        }
    }
}

@Composable
private fun SceneScope.MediaIfVisible(
    viewModel: ShadeSceneViewModel,
    mediaCarouselController: MediaCarouselController,
    mediaHost: MediaHost,
    modifier: Modifier = Modifier,
) {
    if (viewModel.isMediaVisible()) {
        val density = LocalDensity.current
        val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)

        MediaCarousel(
            modifier =
                modifier.height(mediaHeight).fillMaxWidth().layout { measurable, constraints ->
                    val placeable = measurable.measure(constraints)

                    // Notify controller to size the carousel for the
                    // current space
                    mediaHost.measurementInput = MeasurementInput(placeable.width, placeable.height)
                    mediaCarouselController.setSceneContainerSize(placeable.width, placeable.height)

                    layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
                },
            mediaHost = mediaHost,
            layoutWidth = 0,
            layoutHeight = with(density) { mediaHeight.toPx() }.toInt(),
            carouselController = mediaCarouselController,
        )
    }
}
Loading