Loading packages/SystemUI/AndroidManifest.xml +0 −8 Original line number Diff line number Diff line Loading @@ -906,14 +906,6 @@ android:exported="true" /> <activity android:name=".volume.panel.ui.activity.VolumePanelActivity" android:label="@string/accessibility_volume_settings" android:excludeFromRecents="true" android:exported="false" android:launchMode="singleInstance" android:theme="@style/Theme.VolumePanelActivity" /> <activity android:name=".wallet.ui.WalletActivity" android:label="@string/wallet_title" android:theme="@style/Wallet.Theme" Loading packages/SystemUI/src/com/android/systemui/volume/panel/dagger/CoroutineModule.kt→packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/EdgeToEdgeDialogDelegate.kt +43 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * 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. Loading @@ -14,30 +14,30 @@ * limitations under the License. */ package com.android.systemui.volume.panel.dagger package com.android.systemui.statusbar.phone import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope import dagger.Module import dagger.Provides import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import android.os.Bundle import android.view.Gravity import android.view.WindowManager /** Provides Volume Panel coroutine tools. */ @Module interface CoroutineModule { /** [DialogDelegate] that configures a dialog to be an edge-to-edge one. */ class EdgeToEdgeDialogDelegate : DialogDelegate<SystemUIDialog> { companion object { /** * Provides a coroutine scope to use inside [VolumePanelScope]. * [com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel] manages the * lifecycle of this scope. It's cancelled when the View Model is destroyed. This helps to * free occupied resources when volume panel is not shown. */ @VolumePanelScope @Provides fun provideCoroutineScope(@Application applicationScope: CoroutineScope): CoroutineScope = CoroutineScope(applicationScope.coroutineContext + SupervisorJob()) override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) { dialog.window?.apply { setGravity(Gravity.BOTTOM or Gravity.CENTER) attributes = attributes.apply { fitInsetsSides = 0 attributes.apply { layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS } } } } override fun getWidth(dialog: SystemUIDialog): Int = WindowManager.LayoutParams.MATCH_PARENT override fun getHeight(dialog: SystemUIDialog): Int = WindowManager.LayoutParams.MATCH_PARENT } packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt +113 −1 Original line number Diff line number Diff line Loading @@ -17,13 +17,33 @@ package com.android.systemui.statusbar.phone import android.content.Context import android.content.res.Configuration import android.os.Bundle import androidx.annotation.GravityInt import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.compose.theme.PlatformTheme import com.android.systemui.res.R /** * Create a [SystemUIDialog] with the given [content]. Loading Loading @@ -56,7 +76,73 @@ fun SystemUIDialogFactory.create( @GravityInt dialogGravity: Int? = null, content: @Composable (SystemUIDialog) -> Unit, ): ComponentSystemUIDialog { val dialog = create(context, theme, dismissOnDeviceLock, dialogGravity) return create( context = context, theme = theme, dismissOnDeviceLock = dismissOnDeviceLock, delegate = object : DialogDelegate<SystemUIDialog> { override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) { super.onCreate(dialog, savedInstanceState) dialogGravity?.let { dialog.window?.setGravity(it) } } }, content = content, ) } /** Same as [create] but creates a bottom sheet dialog. */ fun SystemUIDialogFactory.createBottomSheet( context: Context = this.applicationContext, theme: Int = R.style.Theme_SystemUI_BottomSheet, dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK, content: @Composable (SystemUIDialog) -> Unit, ): ComponentSystemUIDialog { return create( context = context, theme = theme, dismissOnDeviceLock = dismissOnDeviceLock, delegate = EdgeToEdgeDialogDelegate(), content = { dialog -> Box( modifier = Modifier.bottomSheetClickable { dialog.dismiss() }, contentAlignment = Alignment.BottomCenter ) { val radius = dimensionResource(R.dimen.bottom_sheet_corner_radius) Surface( modifier = Modifier.bottomSheetPaddings() // consume input so it doesn't get to the parent Composable .bottomSheetClickable {} // TODO(b/337205027) change width .widthIn(max = 800.dp), shape = RoundedCornerShape(topStart = radius, topEnd = radius), color = MaterialTheme.colorScheme.surfaceContainer, ) { Box( Modifier.padding( bottom = with(LocalDensity.current) { WindowInsets.safeDrawing.getBottom(this).toDp() } ) ) { content(dialog) } } } }, ) } private fun SystemUIDialogFactory.create( context: Context, theme: Int, dismissOnDeviceLock: Boolean, delegate: DialogDelegate<SystemUIDialog>, content: @Composable (SystemUIDialog) -> Unit, ): ComponentSystemUIDialog { val dialog = create(context, theme, dismissOnDeviceLock, delegate) // Create the dialog so that it is properly constructed before we set the Compose content. // Otherwise, the ComposeView won't render properly. Loading @@ -79,3 +165,29 @@ fun SystemUIDialogFactory.create( return dialog } /** Adds paddings for the bottom sheet surface. */ @Composable private fun Modifier.bottomSheetPaddings(): Modifier { val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT return with(LocalDensity.current) { val insets = WindowInsets.safeDrawing // TODO(b/337205027) change paddings val horizontalPadding: Dp = if (isPortrait) 0.dp else 48.dp padding( start = insets.getLeft(this, LocalLayoutDirection.current).toDp() + horizontalPadding, top = insets.getTop(this).toDp(), end = insets.getRight(this, LocalLayoutDirection.current).toDp() + horizontalPadding ) } } /** * For some reason adding clickable modifier onto the VolumePanel affects the traversal order: * b/331155283. * * TODO(b/334870995) revert this to Modifier.clickable */ @Composable private fun Modifier.bottomSheetClickable(onClick: () -> Unit) = pointerInput(onClick) { detectTapGestures { onClick() } } packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ constructor( ) { val dialog = dialogFactory.create( theme = R.style.Theme_VolumePanelActivity_Popup, theme = R.style.Theme_VolumePanel_Popup, dialogGravity = Gravity.BOTTOM, ) { PopupComposable(it, title, content) Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt +14 −86 Original line number Diff line number Diff line Loading @@ -16,40 +16,22 @@ package com.android.systemui.volume.panel.ui.composable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.displayCutout import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.max import com.android.compose.theme.PlatformTheme import com.android.systemui.res.R import com.android.systemui.volume.panel.ui.layout.ComponentsLayout import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import kotlin.math.max private val padding = 24.dp Loading @@ -67,42 +49,23 @@ fun VolumePanelRoot( } } PlatformTheme(isSystemInDarkTheme()) { val state: VolumePanelState by viewModel.volumePanelState.collectAsState() val components by viewModel.componentsLayout.collectAsState(null) with(VolumePanelComposeScope(state)) { Box( modifier = modifier .fillMaxSize() .volumePanelClick(onDismiss) .volumePanelPaddings(isPortrait = isPortrait), contentAlignment = Alignment.BottomCenter, ) { val radius = dimensionResource(R.dimen.volume_panel_corner_radius) Surface( modifier = Modifier.volumePanelClick {}, shape = RoundedCornerShape(topStart = radius, topEnd = radius), color = MaterialTheme.colorScheme.surfaceContainer, ) { components?.let { componentsState -> Components( componentsState, Modifier.padding( modifier.padding( start = padding, top = padding, end = padding, bottom = 20.dp, ) .navigationBarsPadding() ) } } } } } } @Composable private fun VolumePanelComposeScope.Components( Loading @@ -116,7 +79,7 @@ private fun VolumePanelComposeScope.Components( if (isPortrait) Arrangement.spacedBy(padding) else Arrangement.spacedBy(4.dp) } Column( modifier = modifier.widthIn(max = 800.dp), modifier = modifier, verticalArrangement = arrangement, ) { if (isPortrait || isLargeScreen) { Loading Loading @@ -153,38 +116,3 @@ private fun VolumePanelComposeScope.BottomBar( } } } /** * Makes sure volume panel stays symmetrically in the middle of the screen while still avoiding * being under the cutouts. */ @Composable private fun Modifier.volumePanelPaddings(isPortrait: Boolean): Modifier { val cutout = WindowInsets.displayCutout return with(LocalDensity.current) { val horizontalCutout = max( cutout.getLeft(density = this, layoutDirection = LocalLayoutDirection.current), cutout.getRight(density = this, layoutDirection = LocalLayoutDirection.current) ) val minHorizontalPadding = if (isPortrait) 0.dp else 48.dp val horizontalPadding = max(horizontalCutout.toDp(), minHorizontalPadding) padding( start = horizontalPadding, top = cutout.getTop(this).toDp(), end = horizontalPadding, bottom = cutout.getBottom(this).toDp(), ) } } /** * For some reason adding clickable modifier onto the VolumePanel affects the traversal order: * b/331155283. * * TODO(b/334870995) revert this to Modifier.clickable */ @Composable private fun Modifier.volumePanelClick(onClick: () -> Unit) = pointerInput(onClick) { detectTapGestures { onClick() } } Loading
packages/SystemUI/AndroidManifest.xml +0 −8 Original line number Diff line number Diff line Loading @@ -906,14 +906,6 @@ android:exported="true" /> <activity android:name=".volume.panel.ui.activity.VolumePanelActivity" android:label="@string/accessibility_volume_settings" android:excludeFromRecents="true" android:exported="false" android:launchMode="singleInstance" android:theme="@style/Theme.VolumePanelActivity" /> <activity android:name=".wallet.ui.WalletActivity" android:label="@string/wallet_title" android:theme="@style/Wallet.Theme" Loading
packages/SystemUI/src/com/android/systemui/volume/panel/dagger/CoroutineModule.kt→packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/EdgeToEdgeDialogDelegate.kt +43 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * 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. Loading @@ -14,30 +14,30 @@ * limitations under the License. */ package com.android.systemui.volume.panel.dagger package com.android.systemui.statusbar.phone import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope import dagger.Module import dagger.Provides import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import android.os.Bundle import android.view.Gravity import android.view.WindowManager /** Provides Volume Panel coroutine tools. */ @Module interface CoroutineModule { /** [DialogDelegate] that configures a dialog to be an edge-to-edge one. */ class EdgeToEdgeDialogDelegate : DialogDelegate<SystemUIDialog> { companion object { /** * Provides a coroutine scope to use inside [VolumePanelScope]. * [com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel] manages the * lifecycle of this scope. It's cancelled when the View Model is destroyed. This helps to * free occupied resources when volume panel is not shown. */ @VolumePanelScope @Provides fun provideCoroutineScope(@Application applicationScope: CoroutineScope): CoroutineScope = CoroutineScope(applicationScope.coroutineContext + SupervisorJob()) override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) { dialog.window?.apply { setGravity(Gravity.BOTTOM or Gravity.CENTER) attributes = attributes.apply { fitInsetsSides = 0 attributes.apply { layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS } } } } override fun getWidth(dialog: SystemUIDialog): Int = WindowManager.LayoutParams.MATCH_PARENT override fun getHeight(dialog: SystemUIDialog): Int = WindowManager.LayoutParams.MATCH_PARENT }
packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt +113 −1 Original line number Diff line number Diff line Loading @@ -17,13 +17,33 @@ package com.android.systemui.statusbar.phone import android.content.Context import android.content.res.Configuration import android.os.Bundle import androidx.annotation.GravityInt import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.compose.theme.PlatformTheme import com.android.systemui.res.R /** * Create a [SystemUIDialog] with the given [content]. Loading Loading @@ -56,7 +76,73 @@ fun SystemUIDialogFactory.create( @GravityInt dialogGravity: Int? = null, content: @Composable (SystemUIDialog) -> Unit, ): ComponentSystemUIDialog { val dialog = create(context, theme, dismissOnDeviceLock, dialogGravity) return create( context = context, theme = theme, dismissOnDeviceLock = dismissOnDeviceLock, delegate = object : DialogDelegate<SystemUIDialog> { override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) { super.onCreate(dialog, savedInstanceState) dialogGravity?.let { dialog.window?.setGravity(it) } } }, content = content, ) } /** Same as [create] but creates a bottom sheet dialog. */ fun SystemUIDialogFactory.createBottomSheet( context: Context = this.applicationContext, theme: Int = R.style.Theme_SystemUI_BottomSheet, dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK, content: @Composable (SystemUIDialog) -> Unit, ): ComponentSystemUIDialog { return create( context = context, theme = theme, dismissOnDeviceLock = dismissOnDeviceLock, delegate = EdgeToEdgeDialogDelegate(), content = { dialog -> Box( modifier = Modifier.bottomSheetClickable { dialog.dismiss() }, contentAlignment = Alignment.BottomCenter ) { val radius = dimensionResource(R.dimen.bottom_sheet_corner_radius) Surface( modifier = Modifier.bottomSheetPaddings() // consume input so it doesn't get to the parent Composable .bottomSheetClickable {} // TODO(b/337205027) change width .widthIn(max = 800.dp), shape = RoundedCornerShape(topStart = radius, topEnd = radius), color = MaterialTheme.colorScheme.surfaceContainer, ) { Box( Modifier.padding( bottom = with(LocalDensity.current) { WindowInsets.safeDrawing.getBottom(this).toDp() } ) ) { content(dialog) } } } }, ) } private fun SystemUIDialogFactory.create( context: Context, theme: Int, dismissOnDeviceLock: Boolean, delegate: DialogDelegate<SystemUIDialog>, content: @Composable (SystemUIDialog) -> Unit, ): ComponentSystemUIDialog { val dialog = create(context, theme, dismissOnDeviceLock, delegate) // Create the dialog so that it is properly constructed before we set the Compose content. // Otherwise, the ComposeView won't render properly. Loading @@ -79,3 +165,29 @@ fun SystemUIDialogFactory.create( return dialog } /** Adds paddings for the bottom sheet surface. */ @Composable private fun Modifier.bottomSheetPaddings(): Modifier { val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT return with(LocalDensity.current) { val insets = WindowInsets.safeDrawing // TODO(b/337205027) change paddings val horizontalPadding: Dp = if (isPortrait) 0.dp else 48.dp padding( start = insets.getLeft(this, LocalLayoutDirection.current).toDp() + horizontalPadding, top = insets.getTop(this).toDp(), end = insets.getRight(this, LocalLayoutDirection.current).toDp() + horizontalPadding ) } } /** * For some reason adding clickable modifier onto the VolumePanel affects the traversal order: * b/331155283. * * TODO(b/334870995) revert this to Modifier.clickable */ @Composable private fun Modifier.bottomSheetClickable(onClick: () -> Unit) = pointerInput(onClick) { detectTapGestures { onClick() } }
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ constructor( ) { val dialog = dialogFactory.create( theme = R.style.Theme_VolumePanelActivity_Popup, theme = R.style.Theme_VolumePanel_Popup, dialogGravity = Gravity.BOTTOM, ) { PopupComposable(it, title, content) Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt +14 −86 Original line number Diff line number Diff line Loading @@ -16,40 +16,22 @@ package com.android.systemui.volume.panel.ui.composable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.displayCutout import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.max import com.android.compose.theme.PlatformTheme import com.android.systemui.res.R import com.android.systemui.volume.panel.ui.layout.ComponentsLayout import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import kotlin.math.max private val padding = 24.dp Loading @@ -67,42 +49,23 @@ fun VolumePanelRoot( } } PlatformTheme(isSystemInDarkTheme()) { val state: VolumePanelState by viewModel.volumePanelState.collectAsState() val components by viewModel.componentsLayout.collectAsState(null) with(VolumePanelComposeScope(state)) { Box( modifier = modifier .fillMaxSize() .volumePanelClick(onDismiss) .volumePanelPaddings(isPortrait = isPortrait), contentAlignment = Alignment.BottomCenter, ) { val radius = dimensionResource(R.dimen.volume_panel_corner_radius) Surface( modifier = Modifier.volumePanelClick {}, shape = RoundedCornerShape(topStart = radius, topEnd = radius), color = MaterialTheme.colorScheme.surfaceContainer, ) { components?.let { componentsState -> Components( componentsState, Modifier.padding( modifier.padding( start = padding, top = padding, end = padding, bottom = 20.dp, ) .navigationBarsPadding() ) } } } } } } @Composable private fun VolumePanelComposeScope.Components( Loading @@ -116,7 +79,7 @@ private fun VolumePanelComposeScope.Components( if (isPortrait) Arrangement.spacedBy(padding) else Arrangement.spacedBy(4.dp) } Column( modifier = modifier.widthIn(max = 800.dp), modifier = modifier, verticalArrangement = arrangement, ) { if (isPortrait || isLargeScreen) { Loading Loading @@ -153,38 +116,3 @@ private fun VolumePanelComposeScope.BottomBar( } } } /** * Makes sure volume panel stays symmetrically in the middle of the screen while still avoiding * being under the cutouts. */ @Composable private fun Modifier.volumePanelPaddings(isPortrait: Boolean): Modifier { val cutout = WindowInsets.displayCutout return with(LocalDensity.current) { val horizontalCutout = max( cutout.getLeft(density = this, layoutDirection = LocalLayoutDirection.current), cutout.getRight(density = this, layoutDirection = LocalLayoutDirection.current) ) val minHorizontalPadding = if (isPortrait) 0.dp else 48.dp val horizontalPadding = max(horizontalCutout.toDp(), minHorizontalPadding) padding( start = horizontalPadding, top = cutout.getTop(this).toDp(), end = horizontalPadding, bottom = cutout.getBottom(this).toDp(), ) } } /** * For some reason adding clickable modifier onto the VolumePanel affects the traversal order: * b/331155283. * * TODO(b/334870995) revert this to Modifier.clickable */ @Composable private fun Modifier.volumePanelClick(onClick: () -> Unit) = pointerInput(onClick) { detectTapGestures { onClick() } }