Loading packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.compose import android.content.Context import android.view.View import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.lifecycle.LifecycleOwner import com.android.systemui.people.ui.viewmodel.PeopleViewModel Loading @@ -26,6 +27,8 @@ import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow /** The Compose facade, when Compose is *not* available. */ object ComposeFacade : BaseComposeFacade { Loading @@ -52,8 +55,10 @@ object ComposeFacade : BaseComposeFacade { } override fun createSceneContainerView( scope: CoroutineScope, context: Context, viewModel: SceneContainerViewModel, windowInsets: StateFlow<WindowInsets?>, sceneByKey: Map<SceneKey, Scene>, ): View { throwComposeUnavailableError() Loading packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt +66 −5 Original line number Diff line number Diff line Loading @@ -17,12 +17,19 @@ package com.android.systemui.compose import android.content.Context import android.graphics.Point import android.view.View import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.LifecycleOwner import com.android.compose.theme.PlatformTheme import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation import com.android.systemui.common.ui.compose.windowinsets.DisplayCutout import com.android.systemui.common.ui.compose.windowinsets.DisplayCutoutProvider import com.android.systemui.people.ui.compose.PeopleScreen import com.android.systemui.people.ui.viewmodel.PeopleViewModel import com.android.systemui.qs.footer.ui.compose.FooterActions Loading @@ -32,6 +39,11 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.SceneContainer import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** The Compose facade, when Compose is available. */ object ComposeFacade : BaseComposeFacade { Loading @@ -58,13 +70,18 @@ object ComposeFacade : BaseComposeFacade { } override fun createSceneContainerView( scope: CoroutineScope, context: Context, viewModel: SceneContainerViewModel, windowInsets: StateFlow<WindowInsets?>, sceneByKey: Map<SceneKey, Scene>, ): View { return ComposeView(context).apply { setContent { PlatformTheme { DisplayCutoutProvider( displayCutout = displayCutoutFromWindowInsets(scope, context, windowInsets) ) { SceneContainer( viewModel = viewModel, sceneByKey = Loading @@ -75,3 +92,47 @@ object ComposeFacade : BaseComposeFacade { } } } // TODO(b/298525212): remove once Compose exposes window inset bounds. private fun displayCutoutFromWindowInsets( scope: CoroutineScope, context: Context, windowInsets: StateFlow<WindowInsets?>, ): StateFlow<DisplayCutout> = windowInsets .map { val boundingRect = it?.displayCutout?.boundingRectTop val width = boundingRect?.let { boundingRect.right - boundingRect.left } ?: 0 val left = boundingRect?.left?.toDp(context) ?: 0.dp val top = boundingRect?.top?.toDp(context) ?: 0.dp val right = boundingRect?.right?.toDp(context) ?: 0.dp val bottom = boundingRect?.bottom?.toDp(context) ?: 0.dp val location = when { width <= 0f -> CutoutLocation.NONE left <= 0.dp -> CutoutLocation.LEFT right >= getDisplayWidth(context) -> CutoutLocation.RIGHT else -> CutoutLocation.CENTER } DisplayCutout( left, top, right, bottom, location, ) } .stateIn(scope, SharingStarted.WhileSubscribed(), DisplayCutout()) // TODO(b/298525212): remove once Compose exposes window inset bounds. private fun getDisplayWidth(context: Context): Dp { val point = Point() checkNotNull(context.display).getRealSize(point) return point.x.dp } // TODO(b/298525212): remove once Compose exposes window inset bounds. private fun Int.toDp(context: Context): Dp { return (this.toFloat() / context.resources.displayMetrics.density).dp } } packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/windowinsets/DisplayCutout.kt 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright 2023 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.common.ui.compose.windowinsets import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import kotlin.math.abs /** Represents the global position of the bounds for the display cutout for this display */ data class DisplayCutout( val left: Dp = 0.dp, val top: Dp = 0.dp, val right: Dp = 0.dp, val bottom: Dp = 0.dp, val location: CutoutLocation = CutoutLocation.NONE, ) { fun width() = abs(right.value - left.value).dp } enum class CutoutLocation { NONE, CENTER, LEFT, RIGHT, } packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/windowinsets/DisplayCutoutProvider.kt 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.common.ui.compose.windowinsets import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.staticCompositionLocalOf import kotlinx.coroutines.flow.StateFlow /** The bounds and [CutoutLocation] of the current display. */ val LocalDisplayCutout = staticCompositionLocalOf { DisplayCutout() } @Composable fun DisplayCutoutProvider( displayCutout: StateFlow<DisplayCutout>, content: @Composable () -> Unit, ) { val cutout by displayCutout.collectAsState() CompositionLocalProvider(LocalDisplayCutout provides cutout) { content() } } packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +103 −34 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalLayoutDirection 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.viewinterop.AndroidView Loading @@ -49,9 +51,11 @@ import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.ValueKey import com.android.compose.animation.scene.animateSharedFloatAsState import com.android.settingslib.Utils import com.android.systemui.res.R 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.res.R import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager Loading Loading @@ -97,32 +101,45 @@ fun SceneScope.CollapsedShadeHeader( val useExpandedFormat by remember(formatProgress) { derivedStateOf { formatProgress.value > 0.5f } } Row( modifier = modifier .element(ShadeHeader.Elements.CollapsedContent) .fillMaxWidth() .defaultMinSize(minHeight = ShadeHeader.Dimensions.CollapsedHeight), ) { val cutoutWidth = LocalDisplayCutout.current.width() val cutoutLocation = LocalDisplayCutout.current.location // This layout assumes it is globally positioned at (0, 0) and is the // same size as the screen. Layout( modifier = modifier.element(ShadeHeader.Elements.CollapsedContent), contents = listOf( { Row { AndroidView( factory = { context -> Clock(ContextThemeWrapper(context, R.style.TextAppearance_QS_Status), null) Clock( ContextThemeWrapper(context, R.style.TextAppearance_QS_Status), null ) }, modifier = Modifier.align(Alignment.CenterVertically), ) Spacer(modifier = Modifier.width(5.dp)) VariableDayDate( viewModel = viewModel, modifier = Modifier.widthIn(max = 90.dp).align(Alignment.CenterVertically), modifier = Modifier.align(Alignment.CenterVertically), ) Spacer(modifier = Modifier.weight(1f)) } }, { Row(horizontalArrangement = Arrangement.End) { SystemIconContainer { StatusIcons( viewModel = viewModel, createTintedIconManager = createTintedIconManager, statusBarIconController = statusBarIconController, useExpandedFormat = useExpandedFormat, modifier = Modifier.align(Alignment.CenterVertically).padding(end = 6.dp), modifier = Modifier.align(Alignment.CenterVertically) .padding(end = 6.dp) .weight(1f, fill = false) ) BatteryIcon( createBatteryMeterViewController = createBatteryMeterViewController, Loading @@ -131,6 +148,55 @@ fun SceneScope.CollapsedShadeHeader( ) } } }, ), ) { measurables, constraints -> check(constraints.hasBoundedWidth) check(measurables.size == 2) check(measurables[0].size == 1) check(measurables[1].size == 1) val screenWidth = constraints.maxWidth val cutoutWidthPx = cutoutWidth.roundToPx() val height = ShadeHeader.Dimensions.CollapsedHeight.roundToPx() val childConstraints = Constraints.fixed((screenWidth - cutoutWidthPx) / 2, height) val startMeasurable = measurables[0][0] val endMeasurable = measurables[1][0] val startPlaceable = startMeasurable.measure(childConstraints) val endPlaceable = endMeasurable.measure(childConstraints) layout(screenWidth, height) { when (cutoutLocation) { CutoutLocation.NONE, CutoutLocation.RIGHT -> { startPlaceable.placeRelative(x = 0, y = 0) endPlaceable.placeRelative( x = startPlaceable.width, y = 0, ) } CutoutLocation.CENTER -> { startPlaceable.placeRelative(x = 0, y = 0) endPlaceable.placeRelative( x = startPlaceable.width + cutoutWidthPx, y = 0, ) } CutoutLocation.LEFT -> { startPlaceable.placeRelative( x = cutoutWidthPx, y = 0, ) endPlaceable.placeRelative( x = startPlaceable.width + cutoutWidthPx, y = 0, ) } } } } } @Composable Loading Loading @@ -201,7 +267,10 @@ fun SceneScope.ExpandedShadeHeader( createTintedIconManager = createTintedIconManager, statusBarIconController = statusBarIconController, useExpandedFormat = useExpandedFormat, modifier = Modifier.align(Alignment.CenterVertically).padding(end = 6.dp), modifier = Modifier.align(Alignment.CenterVertically) .padding(end = 6.dp) .weight(1f, fill = false), ) BatteryIcon( useExpandedFormat = useExpandedFormat, Loading Loading
packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.compose import android.content.Context import android.view.View import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.lifecycle.LifecycleOwner import com.android.systemui.people.ui.viewmodel.PeopleViewModel Loading @@ -26,6 +27,8 @@ import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow /** The Compose facade, when Compose is *not* available. */ object ComposeFacade : BaseComposeFacade { Loading @@ -52,8 +55,10 @@ object ComposeFacade : BaseComposeFacade { } override fun createSceneContainerView( scope: CoroutineScope, context: Context, viewModel: SceneContainerViewModel, windowInsets: StateFlow<WindowInsets?>, sceneByKey: Map<SceneKey, Scene>, ): View { throwComposeUnavailableError() Loading
packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt +66 −5 Original line number Diff line number Diff line Loading @@ -17,12 +17,19 @@ package com.android.systemui.compose import android.content.Context import android.graphics.Point import android.view.View import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.LifecycleOwner import com.android.compose.theme.PlatformTheme import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation import com.android.systemui.common.ui.compose.windowinsets.DisplayCutout import com.android.systemui.common.ui.compose.windowinsets.DisplayCutoutProvider import com.android.systemui.people.ui.compose.PeopleScreen import com.android.systemui.people.ui.viewmodel.PeopleViewModel import com.android.systemui.qs.footer.ui.compose.FooterActions Loading @@ -32,6 +39,11 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.SceneContainer import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** The Compose facade, when Compose is available. */ object ComposeFacade : BaseComposeFacade { Loading @@ -58,13 +70,18 @@ object ComposeFacade : BaseComposeFacade { } override fun createSceneContainerView( scope: CoroutineScope, context: Context, viewModel: SceneContainerViewModel, windowInsets: StateFlow<WindowInsets?>, sceneByKey: Map<SceneKey, Scene>, ): View { return ComposeView(context).apply { setContent { PlatformTheme { DisplayCutoutProvider( displayCutout = displayCutoutFromWindowInsets(scope, context, windowInsets) ) { SceneContainer( viewModel = viewModel, sceneByKey = Loading @@ -75,3 +92,47 @@ object ComposeFacade : BaseComposeFacade { } } } // TODO(b/298525212): remove once Compose exposes window inset bounds. private fun displayCutoutFromWindowInsets( scope: CoroutineScope, context: Context, windowInsets: StateFlow<WindowInsets?>, ): StateFlow<DisplayCutout> = windowInsets .map { val boundingRect = it?.displayCutout?.boundingRectTop val width = boundingRect?.let { boundingRect.right - boundingRect.left } ?: 0 val left = boundingRect?.left?.toDp(context) ?: 0.dp val top = boundingRect?.top?.toDp(context) ?: 0.dp val right = boundingRect?.right?.toDp(context) ?: 0.dp val bottom = boundingRect?.bottom?.toDp(context) ?: 0.dp val location = when { width <= 0f -> CutoutLocation.NONE left <= 0.dp -> CutoutLocation.LEFT right >= getDisplayWidth(context) -> CutoutLocation.RIGHT else -> CutoutLocation.CENTER } DisplayCutout( left, top, right, bottom, location, ) } .stateIn(scope, SharingStarted.WhileSubscribed(), DisplayCutout()) // TODO(b/298525212): remove once Compose exposes window inset bounds. private fun getDisplayWidth(context: Context): Dp { val point = Point() checkNotNull(context.display).getRealSize(point) return point.x.dp } // TODO(b/298525212): remove once Compose exposes window inset bounds. private fun Int.toDp(context: Context): Dp { return (this.toFloat() / context.resources.displayMetrics.density).dp } }
packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/windowinsets/DisplayCutout.kt 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright 2023 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.common.ui.compose.windowinsets import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import kotlin.math.abs /** Represents the global position of the bounds for the display cutout for this display */ data class DisplayCutout( val left: Dp = 0.dp, val top: Dp = 0.dp, val right: Dp = 0.dp, val bottom: Dp = 0.dp, val location: CutoutLocation = CutoutLocation.NONE, ) { fun width() = abs(right.value - left.value).dp } enum class CutoutLocation { NONE, CENTER, LEFT, RIGHT, }
packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/windowinsets/DisplayCutoutProvider.kt 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.common.ui.compose.windowinsets import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.staticCompositionLocalOf import kotlinx.coroutines.flow.StateFlow /** The bounds and [CutoutLocation] of the current display. */ val LocalDisplayCutout = staticCompositionLocalOf { DisplayCutout() } @Composable fun DisplayCutoutProvider( displayCutout: StateFlow<DisplayCutout>, content: @Composable () -> Unit, ) { val cutout by displayCutout.collectAsState() CompositionLocalProvider(LocalDisplayCutout provides cutout) { content() } }
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +103 −34 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalLayoutDirection 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.viewinterop.AndroidView Loading @@ -49,9 +51,11 @@ import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.ValueKey import com.android.compose.animation.scene.animateSharedFloatAsState import com.android.settingslib.Utils import com.android.systemui.res.R 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.res.R import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager Loading Loading @@ -97,32 +101,45 @@ fun SceneScope.CollapsedShadeHeader( val useExpandedFormat by remember(formatProgress) { derivedStateOf { formatProgress.value > 0.5f } } Row( modifier = modifier .element(ShadeHeader.Elements.CollapsedContent) .fillMaxWidth() .defaultMinSize(minHeight = ShadeHeader.Dimensions.CollapsedHeight), ) { val cutoutWidth = LocalDisplayCutout.current.width() val cutoutLocation = LocalDisplayCutout.current.location // This layout assumes it is globally positioned at (0, 0) and is the // same size as the screen. Layout( modifier = modifier.element(ShadeHeader.Elements.CollapsedContent), contents = listOf( { Row { AndroidView( factory = { context -> Clock(ContextThemeWrapper(context, R.style.TextAppearance_QS_Status), null) Clock( ContextThemeWrapper(context, R.style.TextAppearance_QS_Status), null ) }, modifier = Modifier.align(Alignment.CenterVertically), ) Spacer(modifier = Modifier.width(5.dp)) VariableDayDate( viewModel = viewModel, modifier = Modifier.widthIn(max = 90.dp).align(Alignment.CenterVertically), modifier = Modifier.align(Alignment.CenterVertically), ) Spacer(modifier = Modifier.weight(1f)) } }, { Row(horizontalArrangement = Arrangement.End) { SystemIconContainer { StatusIcons( viewModel = viewModel, createTintedIconManager = createTintedIconManager, statusBarIconController = statusBarIconController, useExpandedFormat = useExpandedFormat, modifier = Modifier.align(Alignment.CenterVertically).padding(end = 6.dp), modifier = Modifier.align(Alignment.CenterVertically) .padding(end = 6.dp) .weight(1f, fill = false) ) BatteryIcon( createBatteryMeterViewController = createBatteryMeterViewController, Loading @@ -131,6 +148,55 @@ fun SceneScope.CollapsedShadeHeader( ) } } }, ), ) { measurables, constraints -> check(constraints.hasBoundedWidth) check(measurables.size == 2) check(measurables[0].size == 1) check(measurables[1].size == 1) val screenWidth = constraints.maxWidth val cutoutWidthPx = cutoutWidth.roundToPx() val height = ShadeHeader.Dimensions.CollapsedHeight.roundToPx() val childConstraints = Constraints.fixed((screenWidth - cutoutWidthPx) / 2, height) val startMeasurable = measurables[0][0] val endMeasurable = measurables[1][0] val startPlaceable = startMeasurable.measure(childConstraints) val endPlaceable = endMeasurable.measure(childConstraints) layout(screenWidth, height) { when (cutoutLocation) { CutoutLocation.NONE, CutoutLocation.RIGHT -> { startPlaceable.placeRelative(x = 0, y = 0) endPlaceable.placeRelative( x = startPlaceable.width, y = 0, ) } CutoutLocation.CENTER -> { startPlaceable.placeRelative(x = 0, y = 0) endPlaceable.placeRelative( x = startPlaceable.width + cutoutWidthPx, y = 0, ) } CutoutLocation.LEFT -> { startPlaceable.placeRelative( x = cutoutWidthPx, y = 0, ) endPlaceable.placeRelative( x = startPlaceable.width + cutoutWidthPx, y = 0, ) } } } } } @Composable Loading Loading @@ -201,7 +267,10 @@ fun SceneScope.ExpandedShadeHeader( createTintedIconManager = createTintedIconManager, statusBarIconController = statusBarIconController, useExpandedFormat = useExpandedFormat, modifier = Modifier.align(Alignment.CenterVertically).padding(end = 6.dp), modifier = Modifier.align(Alignment.CenterVertically) .padding(end = 6.dp) .weight(1f, fill = false), ) BatteryIcon( useExpandedFormat = useExpandedFormat, Loading