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

Commit 26724a4c authored by Shawn Lee's avatar Shawn Lee Committed by Android (Google) Code Review
Browse files

Merge "[Flexiglass] Fix split shade layout and transitions" into main

parents 379f37fa d41c9837
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ data class DisplayCutout(
    val viewDisplayCutoutKeyguardStatusBarView: ViewDisplayCutout? = null,
) {
    fun width() = abs(right.value - left.value).dp
    fun height() = abs(bottom.value - top.value).dp
}

enum class CutoutLocation {
+0 −1
Original line number Diff line number Diff line
@@ -320,7 +320,6 @@ private fun SceneScope.QuickSettingsScene(
                                createTintedIconManager = createTintedIconManager,
                                createBatteryMeterViewController = createBatteryMeterViewController,
                                statusBarIconController = statusBarIconController,
                                modifier = Modifier.padding(horizontal = 16.dp),
                            )
                    }
                    Spacer(modifier = Modifier.height(16.dp))
+14 −0
Original line number Diff line number Diff line
@@ -5,10 +5,13 @@ import com.android.compose.animation.scene.transitions
import com.android.systemui.bouncer.ui.composable.Bouncer
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.CollapseShadeInstantly
import com.android.systemui.scene.shared.model.TransitionKeys.GoneToSplitShade
import com.android.systemui.scene.shared.model.TransitionKeys.SlightlyFasterShadeCollapse
import com.android.systemui.scene.ui.composable.transitions.bouncerToGoneTransition
import com.android.systemui.scene.ui.composable.transitions.goneToQuickSettingsTransition
import com.android.systemui.scene.ui.composable.transitions.goneToShadeTransition
import com.android.systemui.scene.ui.composable.transitions.goneToSplitShadeTransition
import com.android.systemui.scene.ui.composable.transitions.lockscreenToBouncerTransition
import com.android.systemui.scene.ui.composable.transitions.lockscreenToCommunalTransition
import com.android.systemui.scene.ui.composable.transitions.lockscreenToGoneTransition
@@ -35,6 +38,13 @@ val SceneContainerTransitions = transitions {

    from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() }
    from(Scenes.Gone, to = Scenes.Shade) { goneToShadeTransition() }
    from(
        Scenes.Gone,
        to = Scenes.Shade,
        key = GoneToSplitShade,
    ) {
        goneToSplitShadeTransition()
    }
    from(
        Scenes.Gone,
        to = Scenes.Shade,
@@ -68,5 +78,9 @@ val SceneContainerTransitions = transitions {
            Notifications.Elements.NotificationScrim,
            y = { Shade.Dimensions.ScrimOverscrollLimit }
        )
        translate(
            Shade.Elements.SplitShadeStartColumn,
            y = { Shade.Dimensions.ScrimOverscrollLimit }
        )
    }
}
+65 −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.scene.ui.composable.transitions

import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.unit.IntSize
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.notifications.ui.composable.Notifications
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.shade.ui.composable.Shade
import com.android.systemui.shade.ui.composable.ShadeHeader
import kotlin.time.Duration.Companion.milliseconds

fun TransitionBuilder.goneToSplitShadeTransition(
    durationScale: Double = 1.0,
) {
    spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
    swipeSpec =
        spring(
            stiffness = Spring.StiffnessMediumLow,
            visibilityThreshold = Shade.Dimensions.ScrimVisibilityThreshold,
        )
    distance =
        object : UserActionDistance {
            override fun UserActionDistanceScope.absoluteDistance(
                fromSceneSize: IntSize,
                orientation: Orientation,
            ): Float {
                return fromSceneSize.height.toFloat() * 2 / 3f
            }
        }

    fractionRange(end = .33f) { fade(Shade.Elements.BackgroundScrim) }

    fractionRange(start = .33f) {
        fade(ShadeHeader.Elements.Clock)
        fade(ShadeHeader.Elements.CollapsedContentStart)
        fade(ShadeHeader.Elements.CollapsedContentEnd)
        fade(ShadeHeader.Elements.PrivacyChip)
        fade(QuickSettings.Elements.SplitShadeQuickSettings)
        fade(QuickSettings.Elements.FooterActions)
        fade(Notifications.Elements.NotificationScrim)
    }
}

private val DefaultDuration = 500.milliseconds
+21 −5
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.max
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexScenePicker
@@ -63,6 +64,7 @@ import com.android.systemui.battery.BatteryMeterView
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation
import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout
import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.privacy.OngoingPrivacyChip
import com.android.systemui.res.R
@@ -77,6 +79,7 @@ import com.android.systemui.statusbar.phone.ui.TintedIconManager
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel
import com.android.systemui.statusbar.policy.Clock
import kotlin.math.max

object ShadeHeader {
    object Elements {
@@ -121,7 +124,11 @@ fun SceneScope.CollapsedShadeHeader(
    }

    val cutoutWidth = LocalDisplayCutout.current.width()
    val cutoutHeight = LocalDisplayCutout.current.height()
    val cutoutTop = LocalDisplayCutout.current.top
    val cutoutLocation = LocalDisplayCutout.current.location
    val horizontalPadding =
        max(LocalScreenCornerRadius.current / 2f, Shade.Dimensions.HorizontalPadding)

    val useExpandedFormat by
        remember(cutoutLocation) {
@@ -140,7 +147,7 @@ fun SceneScope.CollapsedShadeHeader(
        contents =
            listOf(
                {
                    Row {
                    Row(modifier = Modifier.padding(horizontal = horizontalPadding)) {
                        Clock(
                            scale = 1f,
                            viewModel = viewModel,
@@ -157,7 +164,12 @@ fun SceneScope.CollapsedShadeHeader(
                },
                {
                    if (isPrivacyChipVisible) {
                        Box(modifier = Modifier.height(CollapsedHeight).fillMaxWidth()) {
                        Box(
                            modifier =
                                Modifier.height(CollapsedHeight)
                                    .fillMaxWidth()
                                    .padding(horizontal = horizontalPadding)
                        ) {
                            PrivacyChip(
                                viewModel = viewModel,
                                modifier = Modifier.align(Alignment.CenterEnd),
@@ -166,9 +178,13 @@ fun SceneScope.CollapsedShadeHeader(
                    } else {
                        Row(
                            horizontalArrangement = Arrangement.End,
                            modifier = Modifier.element(ShadeHeader.Elements.CollapsedContentEnd)
                            modifier =
                                Modifier.element(ShadeHeader.Elements.CollapsedContentEnd)
                                    .padding(horizontal = horizontalPadding)
                        ) {
                            SystemIconContainer(
                                modifier = Modifier.align(Alignment.CenterVertically)
                            ) {
                            SystemIconContainer {
                                when (LocalWindowSizeClass.current.widthSizeClass) {
                                    WindowWidthSizeClass.Medium,
                                    WindowWidthSizeClass.Expanded ->
@@ -206,7 +222,7 @@ fun SceneScope.CollapsedShadeHeader(

        val screenWidth = constraints.maxWidth
        val cutoutWidthPx = cutoutWidth.roundToPx()
        val height = CollapsedHeight.roundToPx()
        val height = max(cutoutHeight + (cutoutTop * 2), CollapsedHeight).roundToPx()
        val childConstraints = Constraints.fixed((screenWidth - cutoutWidthPx) / 2, height)

        val startMeasurable = measurables[0][0]
Loading