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

Commit 268abc74 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge "Group media and QQS in SingleShade" into main

parents 26a69a45 ae92c329
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.systemui.scene.ui.composable.transitions
import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.TransitionBuilder
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.qs.shared.ui.QuickSettings
import com.android.systemui.shade.ui.composable.Shade
@@ -41,8 +40,7 @@ fun TransitionBuilder.toShadeSceneTransition(durationScale: Double = 1.0) {
    fade(Shade.Elements.BackgroundScrim)

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

+66 −46
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.shade.ui.composable
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -255,10 +256,9 @@ private fun ContentScope.SingleShade(
    val shadeHorizontalPadding =
        dimensionResource(id = R.dimen.notification_panel_margin_horizontal)
    val shadeMeasurePolicy =
        remember(mediaInRow, cutout, cutoutInsets) {
        remember(cutout, cutoutInsets) {
            val cutoutLocation = cutout().location
            SingleShadeMeasurePolicy(
                isMediaInRow = mediaInRow,
                onNotificationsTopChanged = { maxNotifScrimTop = it },
                cutoutInsetsProvider = {
                    if (cutoutLocation == CutoutLocation.CENTER) {
@@ -296,12 +296,14 @@ private fun ContentScope.SingleShade(
                val qqsLayoutPaddingBottom = 16.dp
                val qsHorizontalMargin =
                    shadeHorizontalPadding + dimensionResource(id = R.dimen.qs_horizontal_margin)
                Box(
                    Modifier.element(QuickSettings.Elements.QuickQuickSettings)
                        .layoutId(SingleShadeMeasurePolicy.LayoutId.QuickSettings)
                        .padding(horizontal = qsHorizontalMargin)
                MediaAndQqsLayout(
                    modifier =
                        Modifier.element(QuickSettings.Elements.QuickQuickSettingsAndMedia)
                            .layoutId(SingleShadeMeasurePolicy.LayoutId.MediaAndQqs)
                            .padding(bottom = qqsLayoutPaddingBottom)
                ) {
                            .padding(horizontal = qsHorizontalMargin),
                    tiles = {
                        Box {
                            val qqsViewModel =
                                rememberViewModel(traceName = "shade_scene_qqs") {
                                    viewModel.quickQuickSettingsViewModel.create()
@@ -314,20 +316,11 @@ private fun ContentScope.SingleShade(
                                )
                            }
                        }
                    },
                    media =
                        @Composable {
                            if (viewModel.isQsEnabled && viewModel.showMedia) {
                    Element(
                        key = Media.Elements.mediaCarousel,
                        modifier =
                            Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Media)
                                .padding(
                                    end = qsHorizontalMargin,
                                    // Only apply padding at the start if not in row, if in row, we
                                    // have
                                    // the end padding of qs.
                                    start = if (mediaInRow) 0.dp else qsHorizontalMargin,
                                )
                                .padding(bottom = qqsLayoutPaddingBottom),
                    ) {
                                Element(key = Media.Elements.mediaCarousel, modifier = Modifier) {
                                    Media(
                                        viewModelFactory = viewModel.mediaViewModelFactory,
                                        presentationStyle =
@@ -341,6 +334,9 @@ private fun ContentScope.SingleShade(
                                    )
                                }
                            }
                        },
                    mediaInRow = mediaInRow,
                )

                NotificationScrollingStack(
                    shadeSession = shadeSession,
@@ -371,6 +367,30 @@ private fun ContentScope.SingleShade(
    }
}

@Composable
private fun MediaAndQqsLayout(
    tiles: @Composable () -> Unit,
    media: @Composable () -> Unit,
    mediaInRow: Boolean,
    modifier: Modifier = Modifier,
) {
    if (mediaInRow) {
        Row(
            modifier = modifier,
            horizontalArrangement = spacedBy(dimensionResource(R.dimen.qs_tile_margin_vertical)),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Box(modifier = Modifier.weight(1f)) { tiles() }
            Box(modifier = Modifier.weight(1f)) { media() }
        }
    } else {
        Column(modifier = modifier, verticalArrangement = spacedBy(16.dp)) {
            tiles()
            media()
        }
    }
}

@Composable
private fun ContentScope.SplitShade(
    notificationStackScrollView: NotificationScrollView,
+10 −74
Original line number Diff line number Diff line
@@ -27,21 +27,18 @@ import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.offset
import androidx.compose.ui.util.fastFirstOrNull
import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy.LayoutId
import kotlin.math.max

/**
 * Lays out elements from the [LayoutId] in the shade. This policy supports the case when the QS and
 * UMO share the same row and when they should be one below another.
 */
class SingleShadeMeasurePolicy(
    private val isMediaInRow: Boolean,
    private val onNotificationsTopChanged: (Int) -> Unit,
    private val cutoutInsetsProvider: () -> WindowInsets?,
) : MeasurePolicy {

    enum class LayoutId {
        QuickSettings,
        Media,
        MediaAndQqs,
        Notifications,
        ShadeHeader,
    }
@@ -59,14 +56,10 @@ class SingleShadeMeasurePolicy(
            measurables
                .fastFirstOrNull { it.layoutId == LayoutId.ShadeHeader }
                ?.measure(constraintsWithCutout)
        val mediaPlaceable =
        val mediaAndQqsPlaceable =
            measurables
                .fastFirstOrNull { it.layoutId == LayoutId.Media }
                ?.measure(constraintsWithCutout.mediaConstraints(isMediaInRow))
        val quickSettingsPlaceable =
            measurables
                .fastFirstOrNull { it.layoutId == LayoutId.QuickSettings }
                ?.measure(constraintsWithCutout.qsTilesConstraints(isMediaInRow))
                .fastFirstOrNull { it.layoutId == LayoutId.MediaAndQqs }
                ?.measure(constraintsWithCutout)
        val notificationsPlaceable =
            measurables
                .fastFirstOrNull { it.layoutId == LayoutId.Notifications }
@@ -75,10 +68,8 @@ class SingleShadeMeasurePolicy(
        val notificationsTop =
            calculateNotificationsTop(
                statusBarHeaderPlaceable = shadeHeaderPlaceable,
                quickSettingsPlaceable = quickSettingsPlaceable,
                mediaPlaceable = mediaPlaceable,
                mediaAndQqsPlaceable = mediaAndQqsPlaceable,
                insetsTop = insetsTop,
                isMediaInRow = isMediaInRow,
            )
        onNotificationsTopChanged(notificationsTop)

@@ -86,36 +77,10 @@ class SingleShadeMeasurePolicy(
            shadeHeaderPlaceable?.placeRelative(x = insetsLeft, y = insetsTop)
            val statusBarHeaderHeight = shadeHeaderPlaceable?.height ?: 0

            val quickSettingsHeight = quickSettingsPlaceable?.height ?: 0
            val quickSettingsOffset =
                if (isMediaInRow && mediaPlaceable != null) {
                    max((mediaPlaceable.height - quickSettingsHeight) / 2, 0)
                } else {
                    0
                }

            quickSettingsPlaceable?.placeRelative(
                x = insetsLeft,
                y = insetsTop + statusBarHeaderHeight + quickSettingsOffset,
            )

            if (mediaPlaceable != null) {
                if (isMediaInRow) {
                    // mediaPlaceable height ranges from 0 to qsHeight. We want it to be centered
                    // vertically when it's smaller than the QS
                    val mediaCenteringOffset =
                        max((quickSettingsHeight - mediaPlaceable.height) / 2, 0)
                    mediaPlaceable.placeRelative(
                        x = insetsLeft + constraintsWithCutout.maxWidth / 2,
                        y = insetsTop + statusBarHeaderHeight + mediaCenteringOffset,
                    )
                } else {
                    mediaPlaceable.placeRelative(
            mediaAndQqsPlaceable?.placeRelative(
                x = insetsLeft,
                        y = insetsTop + statusBarHeaderHeight + quickSettingsHeight,
                y = insetsTop + statusBarHeaderHeight,
            )
                }
            }

            // Notifications don't need to accommodate for horizontal insets
            notificationsPlaceable?.placeRelative(x = 0, y = notificationsTop)
@@ -124,42 +89,13 @@ class SingleShadeMeasurePolicy(

    private fun calculateNotificationsTop(
        statusBarHeaderPlaceable: Placeable?,
        quickSettingsPlaceable: Placeable?,
        mediaPlaceable: Placeable?,
        mediaAndQqsPlaceable: Placeable?,
        insetsTop: Int,
        isMediaInRow: Boolean,
    ): Int {
        val mediaHeight = mediaPlaceable?.height ?: 0
        val statusBarHeaderHeight = statusBarHeaderPlaceable?.height ?: 0
        val quickSettingsHeight = quickSettingsPlaceable?.height ?: 0
        val mediaAndQqsHeight = mediaAndQqsPlaceable?.height ?: 0

        return insetsTop +
            statusBarHeaderHeight +
            if (isMediaInRow) {
                max(quickSettingsHeight, mediaHeight)
            } else {
                quickSettingsHeight + mediaHeight
            }
    }

    private fun Constraints.halfWidthConstraints(): Constraints {
        return copy(maxWidth = maxWidth / 2)
    }

    private fun Constraints.mediaConstraints(isMediaInRow: Boolean): Constraints {
        return if (isMediaInRow) {
            halfWidthConstraints()
        } else {
            this
        }
    }

    private fun Constraints.qsTilesConstraints(isMediaInRow: Boolean): Constraints {
        return if (isMediaInRow) {
            halfWidthConstraints()
        } else {
            this
        }
        return insetsTop + statusBarHeaderHeight + mediaAndQqsHeight
    }

    private fun MeasureScope.applyCutout(
+2 −1
Original line number Diff line number Diff line
@@ -1541,7 +1541,8 @@ object Media {
        val mediaCarousel = ElementKey("media_carousel")

        fun additionalActionButton(index: Int): ElementKey {
            return ElementKey("additional_action_$index")
            val name = "additional_action_$index"
            return ElementKey(debugName = name, identity = name)
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ object QuickSettings {

        val TileElementMatcher = ElementKey.withIdentity { it is TileIdentity }

        val QuickQuickSettings = ElementKey("QuickQuickSettings")
        val QuickQuickSettingsAndMedia = ElementKey("QuickQuickSettingsAndMedia")
        val SplitShadeQuickSettings = ElementKey("SplitShadeQuickSettings")
    }