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

Commit 0166970a authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Make UMO follow squishing QQS" into main

parents bcdad5b9 f9d829a7
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@ 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.approachLayout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.MovableElementKey
import com.android.compose.animation.scene.SceneScope
@@ -51,6 +53,7 @@ fun SceneScope.MediaCarousel(
    mediaHost: MediaHost,
    modifier: Modifier = Modifier,
    carouselController: MediaCarouselController,
    offsetProvider: (() -> IntOffset)? = null,
) {
    if (!isVisible) {
        return
@@ -68,20 +71,37 @@ fun SceneScope.MediaCarousel(

    MovableElement(
        key = MediaCarousel.Elements.Content,
        modifier = modifier.height(mediaHeight).fillMaxWidth()
        modifier = modifier.height(mediaHeight).fillMaxWidth(),
    ) {
        content {
            AndroidView(
                modifier =
                    Modifier.fillMaxSize().layout { measurable, constraints ->
                    Modifier.fillMaxSize()
                        .approachLayout(
                            isMeasurementApproachInProgress = { offsetProvider != null },
                            approachMeasure = { measurable, constraints ->
                                val placeable = measurable.measure(constraints)
                                layout(placeable.width, placeable.height) {
                                    placeable.placeRelative(
                                        offsetProvider?.invoke() ?: IntOffset.Zero
                                    )
                                }
                            }
                        )
                        .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)
                            carouselController.setSceneContainerSize(
                                placeable.width,
                                placeable.height
                            )

                        layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
                            layout(placeable.width, placeable.height) {
                                placeable.placeRelative(0, 0)
                            }
                        },
                factory = { context ->
                    FrameLayout(context).apply {
+0 −1
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.systemui.scene.shared.model.Scenes
/** [ElementContentPicker] implementation for the media carousel object. */
object MediaContentPicker : StaticElementContentPicker {

    const val SHADE_FRACTION = 0.66f
    override val contents =
        setOf(
            Scenes.Lockscreen,
+0 −7
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.UserActionDistance
import com.android.compose.animation.scene.UserActionDistanceScope
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.composable.MediaContentPicker
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.shade.ui.composable.Shade
@@ -54,13 +53,7 @@ fun TransitionBuilder.goneToSplitShadeTransition(
    fractionRange(end = .33f) { fade(Shade.Elements.BackgroundScrim) }

    fractionRange(start = .33f) {
        val qsTranslation =
            ShadeHeader.Dimensions.CollapsedHeight * MediaContentPicker.SHADE_FRACTION
        val qsExpansionDiff =
            ShadeHeader.Dimensions.ExpandedHeight - ShadeHeader.Dimensions.CollapsedHeight
        translate(MediaCarousel.Elements.Content, y = -(qsExpansionDiff + qsTranslation))
        fade(MediaCarousel.Elements.Content)

        fade(ShadeHeader.Elements.Clock)
        fade(ShadeHeader.Elements.CollapsedContentStart)
        fade(ShadeHeader.Elements.CollapsedContentEnd)
+3 −7
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.UserActionDistance
import com.android.compose.animation.scene.UserActionDistanceScope
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.composable.MediaContentPicker
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.scene.shared.model.Scenes
@@ -62,12 +61,9 @@ fun TransitionBuilder.toShadeTransition(
        fade(QuickSettings.Elements.FooterActions)
    }

    val qsTranslation = ShadeHeader.Dimensions.CollapsedHeight * MediaContentPicker.SHADE_FRACTION
    val qsExpansionDiff =
        ShadeHeader.Dimensions.ExpandedHeight - ShadeHeader.Dimensions.CollapsedHeight

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

+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.shade.ui.composable

import androidx.compose.ui.unit.IntOffset
import com.android.systemui.qs.ui.adapter.QSSceneAdapter

/**
 * Provider for the extra offset for the Media section in the shade to accommodate for the squishing
 * qs or qqs tiles.
 */
interface ShadeMediaOffsetProvider {

    /** Returns current offset to be applied to the Media Carousel */
    val offset: IntOffset

    /**
     * [ShadeMediaOffsetProvider] implementation for Quick Settings.
     *
     * [updateLayout] should represent an access to some state to trigger Compose to relayout to
     * track [QSSceneAdapter] internal state changes during the transition.
     */
    class Qs(private val updateLayout: () -> Unit, private val qsSceneAdapter: QSSceneAdapter) :
        ShadeMediaOffsetProvider {

        override val offset: IntOffset
            get() =
                calculateQsOffset(
                    updateLayout,
                    qsSceneAdapter.qsHeight,
                    qsSceneAdapter.squishedQsHeight
                )
    }

    /**
     * [ShadeMediaOffsetProvider] implementation for Quick Quick Settings.
     *
     * [updateLayout] should represent an access to some state to trigger Compose to relayout to
     * track [QSSceneAdapter] internal state changes during the transition.
     */
    class Qqs(private val updateLayout: () -> Unit, private val qsSceneAdapter: QSSceneAdapter) :
        ShadeMediaOffsetProvider {

        override val offset: IntOffset
            get() =
                calculateQsOffset(
                    updateLayout,
                    qsSceneAdapter.qqsHeight,
                    qsSceneAdapter.squishedQqsHeight
                )
    }

    companion object {

        protected fun calculateQsOffset(
            updateLayout: () -> Unit,
            qsHeight: Int,
            qsSquishedHeight: Int
        ): IntOffset {
            updateLayout()
            val distanceFromBottomToActualBottom = qsHeight - qsSquishedHeight
            return IntOffset(0, -distanceFromBottomToActualBottom)
        }
    }
}
Loading