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 Original line Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.systemui.scene.ui.composable.transitions
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.TransitionBuilder
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.notifications.ui.composable.Notifications
import com.android.systemui.qs.shared.ui.QuickSettings
import com.android.systemui.qs.shared.ui.QuickSettings
import com.android.systemui.shade.ui.composable.Shade
import com.android.systemui.shade.ui.composable.Shade
@@ -41,8 +40,7 @@ fun TransitionBuilder.toShadeSceneTransition(durationScale: Double = 1.0) {
    fade(Shade.Elements.BackgroundScrim)
    fade(Shade.Elements.BackgroundScrim)


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


+66 −46
Original line number Original line 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.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Row
@@ -255,10 +256,9 @@ private fun ContentScope.SingleShade(
    val shadeHorizontalPadding =
    val shadeHorizontalPadding =
        dimensionResource(id = R.dimen.notification_panel_margin_horizontal)
        dimensionResource(id = R.dimen.notification_panel_margin_horizontal)
    val shadeMeasurePolicy =
    val shadeMeasurePolicy =
        remember(mediaInRow, cutout, cutoutInsets) {
        remember(cutout, cutoutInsets) {
            val cutoutLocation = cutout().location
            val cutoutLocation = cutout().location
            SingleShadeMeasurePolicy(
            SingleShadeMeasurePolicy(
                isMediaInRow = mediaInRow,
                onNotificationsTopChanged = { maxNotifScrimTop = it },
                onNotificationsTopChanged = { maxNotifScrimTop = it },
                cutoutInsetsProvider = {
                cutoutInsetsProvider = {
                    if (cutoutLocation == CutoutLocation.CENTER) {
                    if (cutoutLocation == CutoutLocation.CENTER) {
@@ -296,12 +296,14 @@ private fun ContentScope.SingleShade(
                val qqsLayoutPaddingBottom = 16.dp
                val qqsLayoutPaddingBottom = 16.dp
                val qsHorizontalMargin =
                val qsHorizontalMargin =
                    shadeHorizontalPadding + dimensionResource(id = R.dimen.qs_horizontal_margin)
                    shadeHorizontalPadding + dimensionResource(id = R.dimen.qs_horizontal_margin)
                Box(
                MediaAndQqsLayout(
                    Modifier.element(QuickSettings.Elements.QuickQuickSettings)
                    modifier =
                        .layoutId(SingleShadeMeasurePolicy.LayoutId.QuickSettings)
                        Modifier.element(QuickSettings.Elements.QuickQuickSettingsAndMedia)
                        .padding(horizontal = qsHorizontalMargin)
                            .layoutId(SingleShadeMeasurePolicy.LayoutId.MediaAndQqs)
                            .padding(bottom = qqsLayoutPaddingBottom)
                            .padding(bottom = qqsLayoutPaddingBottom)
                ) {
                            .padding(horizontal = qsHorizontalMargin),
                    tiles = {
                        Box {
                            val qqsViewModel =
                            val qqsViewModel =
                                rememberViewModel(traceName = "shade_scene_qqs") {
                                rememberViewModel(traceName = "shade_scene_qqs") {
                                    viewModel.quickQuickSettingsViewModel.create()
                                    viewModel.quickQuickSettingsViewModel.create()
@@ -314,20 +316,11 @@ private fun ContentScope.SingleShade(
                                )
                                )
                            }
                            }
                        }
                        }
                    },
                    media =
                        @Composable {
                            if (viewModel.isQsEnabled && viewModel.showMedia) {
                            if (viewModel.isQsEnabled && viewModel.showMedia) {
                    Element(
                                Element(key = Media.Elements.mediaCarousel, modifier = Modifier) {
                        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),
                    ) {
                                    Media(
                                    Media(
                                        viewModelFactory = viewModel.mediaViewModelFactory,
                                        viewModelFactory = viewModel.mediaViewModelFactory,
                                        presentationStyle =
                                        presentationStyle =
@@ -341,6 +334,9 @@ private fun ContentScope.SingleShade(
                                    )
                                    )
                                }
                                }
                            }
                            }
                        },
                    mediaInRow = mediaInRow,
                )


                NotificationScrollingStack(
                NotificationScrollingStack(
                    shadeSession = shadeSession,
                    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
@Composable
private fun ContentScope.SplitShade(
private fun ContentScope.SplitShade(
    notificationStackScrollView: NotificationScrollView,
    notificationStackScrollView: NotificationScrollView,
+10 −74
Original line number Original line 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.unit.offset
import androidx.compose.ui.util.fastFirstOrNull
import androidx.compose.ui.util.fastFirstOrNull
import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy.LayoutId
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
 * 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.
 * UMO share the same row and when they should be one below another.
 */
 */
class SingleShadeMeasurePolicy(
class SingleShadeMeasurePolicy(
    private val isMediaInRow: Boolean,
    private val onNotificationsTopChanged: (Int) -> Unit,
    private val onNotificationsTopChanged: (Int) -> Unit,
    private val cutoutInsetsProvider: () -> WindowInsets?,
    private val cutoutInsetsProvider: () -> WindowInsets?,
) : MeasurePolicy {
) : MeasurePolicy {


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


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


            val quickSettingsHeight = quickSettingsPlaceable?.height ?: 0
            mediaAndQqsPlaceable?.placeRelative(
            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(
                x = insetsLeft,
                x = insetsLeft,
                        y = insetsTop + statusBarHeaderHeight + quickSettingsHeight,
                y = insetsTop + statusBarHeaderHeight,
            )
            )
                }
            }


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


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


        return insetsTop +
        return insetsTop + statusBarHeaderHeight + mediaAndQqsHeight
            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
        }
    }
    }


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


        fun additionalActionButton(index: Int): ElementKey {
        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 Original line Diff line number Diff line
@@ -31,7 +31,7 @@ object QuickSettings {


        val TileElementMatcher = ElementKey.withIdentity { it is TileIdentity }
        val TileElementMatcher = ElementKey.withIdentity { it is TileIdentity }


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