Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/MediaCarouselElement.kt +45 −13 Original line number Diff line number Diff line Loading @@ -22,12 +22,18 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onLayoutRectChanged import androidx.compose.ui.res.dimensionResource import com.android.compose.animation.scene.ContentScope import com.android.systemui.Flags.mediaControlsInCompose import com.android.systemui.keyguard.ui.viewmodel.MediaCarouselElementViewModel import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.dagger.MediaModule import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.res.R import javax.inject.Inject import javax.inject.Named Loading @@ -37,6 +43,7 @@ class MediaCarouselElement constructor( private val mediaCarouselController: MediaCarouselController, @param:Named(MediaModule.KEYGUARD) private val mediaHost: MediaHost, private val mediaCarouselElementViewModelFactory: MediaCarouselElementViewModel.Factory, ) { @Composable Loading @@ -52,6 +59,30 @@ constructor( dimensionResource(id = R.dimen.notification_side_paddings) + dimensionResource(id = R.dimen.notification_panel_margin_horizontal) } if (mediaControlsInCompose()) { val viewModel = rememberViewModel("MediaCarouselElement") { mediaCarouselElementViewModelFactory.create() } Element( key = Media.Elements.mediaCarousel, modifier = modifier .fillMaxWidth() .padding(horizontal = horizontalPadding) .onLayoutRectChanged { onBottomChanged?.invoke(it.boundsInWindow.bottom.toFloat()) }, ) { Media( viewModelFactory = viewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Default, behavior = viewModel.mediaUiBehavior, onDismissed = viewModel::onSwipeToDismiss, ) } } else { MediaCarousel( isVisible = true, mediaHost = mediaHost, Loading @@ -67,3 +98,4 @@ constructor( ) } } } packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt +20 −28 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.res.dimensionResource import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey Loading @@ -34,13 +33,8 @@ import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn import com.android.systemui.keyguard.ui.composable.element.SmallClockElement import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.composable.isLandscape import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.COLLAPSED import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.EXPANDED import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel import com.android.systemui.res.R Loading @@ -54,7 +48,6 @@ import com.android.systemui.shade.ui.composable.isFullWidthShade import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import dagger.Lazy import javax.inject.Inject import javax.inject.Named import kotlinx.coroutines.flow.Flow @SysUISingleton Loading @@ -67,8 +60,6 @@ constructor( private val stackScrollView: Lazy<NotificationScrollView>, private val smallClockElement: SmallClockElement, private val keyguardClockViewModel: KeyguardClockViewModel, private val mediaCarouselController: MediaCarouselController, @Named(QUICK_QS_PANEL) private val mediaHost: Lazy<MediaHost>, private val jankMonitor: InteractionJankMonitor, ) : Overlay { override val key = Overlays.NotificationsShade Loading Loading @@ -98,11 +89,6 @@ constructor( viewModel.notificationsPlaceholderViewModelFactory.create() } val usingCollapsedLandscapeMedia = LocalResources.current.getBoolean(R.bool.config_quickSettingsMediaLandscapeCollapsed) mediaHost.get().expansion = if (usingCollapsedLandscapeMedia && isLandscape()) COLLAPSED else EXPANDED val isFullWidth = isFullWidthShade() OverlayShade( Loading Loading @@ -139,18 +125,24 @@ constructor( } } MediaCarousel( isVisible = viewModel.showMedia, mediaHost = mediaHost.get(), carouselController = mediaCarouselController, usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia, if (viewModel.showMedia) { Element( key = Media.Elements.mediaCarousel, modifier = Modifier.padding( top = notificationStackPadding, start = notificationStackPadding, end = notificationStackPadding, ), ) { Media( viewModelFactory = viewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Default, behavior = viewModel.mediaUiBehavior, onDismissed = viewModel::onMediaSwipeToDismiss, ) } } NotificationScrollingStack( shadeSession = shadeSession, Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +14 −38 Original line number Diff line number Diff line Loading @@ -58,7 +58,6 @@ import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateContentFloatAsState import com.android.compose.animation.scene.animateSceneDpAsState import com.android.compose.animation.scene.content.state.TransitionState import com.android.compose.modifiers.thenIf import com.android.compose.windowsizeclass.LocalWindowSizeClass Loading @@ -71,21 +70,16 @@ import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.composable.isLandscape import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.EXPANDED import com.android.systemui.media.dagger.MediaModule import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.notifications.ui.composable.NotificationScrollingStack import com.android.systemui.qs.composefragment.ui.GridAnchor import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.shared.ui.ElementKeys import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.InQS import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneContentViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsUserActionsViewModel import com.android.systemui.res.R Loading @@ -100,7 +94,6 @@ import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScr import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import dagger.Lazy import javax.inject.Inject import javax.inject.Named import kotlin.math.roundToInt import kotlinx.coroutines.flow.Flow Loading @@ -114,8 +107,6 @@ constructor( private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory, private val actionsViewModelFactory: QuickSettingsUserActionsViewModel.Factory, private val contentViewModelFactory: QuickSettingsSceneContentViewModel.Factory, private val mediaCarouselController: MediaCarouselController, @Named(MediaModule.QS_PANEL) private val mediaHost: MediaHost, private val jankMonitor: InteractionJankMonitor, ) : ExclusiveActivatable(), Scene { override val key = Scenes.QuickSettings Loading Loading @@ -145,19 +136,11 @@ constructor( viewModel = viewModel, headerViewModel = viewModel.qsContainerViewModel.shadeHeaderViewModel, notificationsPlaceholderViewModel = notificationsPlaceholderViewModel, mediaCarouselController = mediaCarouselController, mediaHost = mediaHost, modifier = modifier, shadeSession = shadeSession, jankMonitor = jankMonitor, ) } init { mediaHost.expansion = EXPANDED mediaHost.showsOnlyActiveMedia = false mediaHost.init(MediaHierarchyManager.LOCATION_QS) } } @Composable Loading @@ -166,8 +149,6 @@ private fun ContentScope.QuickSettingsScene( viewModel: QuickSettingsSceneContentViewModel, headerViewModel: ShadeHeaderViewModel, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, mediaCarouselController: MediaCarouselController, mediaHost: MediaHost, modifier: Modifier = Modifier, shadeSession: SaveableSession, jankMonitor: InteractionJankMonitor, Loading Loading @@ -233,10 +214,8 @@ private fun ContentScope.QuickSettingsScene( WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() // ############# Media ############### val isMediaVisible = viewModel.isMediaVisible val isMediaVisible = viewModel.qsContainerViewModel.showMedia val mediaInRow = isMediaVisible && isLandscape() val mediaOffset by animateSceneDpAsState(value = InQS, key = MediaLandscapeTopOffset, canOverflow = false) // This is the background for the whole scene, as the elements don't necessarily provide // a background that extends to the edges. Loading Loading @@ -301,19 +280,16 @@ private fun ContentScope.QuickSettingsScene( }, media = @Composable { MediaCarousel( isVisible = isMediaVisible, mediaHost = mediaHost, modifier = Modifier.fillMaxWidth() .padding( horizontal = dimensionResource( id = R.dimen.qs_horizontal_margin ) ), carouselController = mediaCarouselController, Element(key = Media.Elements.mediaCarousel, modifier = Modifier) { Media( viewModelFactory = viewModel.qsContainerViewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Default, behavior = QuickSettingsContainerViewModel.mediaUiBehavior, onDismissed = viewModel.qsContainerViewModel::onMediaSwipeToDismiss, ) } }, mediaInRow = mediaInRow, modifier = Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +52 −36 Original line number Diff line number Diff line Loading @@ -65,8 +65,8 @@ import com.android.systemui.brightness.ui.compose.ContainerColors import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.COLLAPSED import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace import com.android.systemui.qs.composefragment.ui.GridAnchor import com.android.systemui.qs.flags.QsDetailedView Loading @@ -74,6 +74,8 @@ import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.TileDetails import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.panels.ui.compose.toolbar.Toolbar import com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel import com.android.systemui.qs.tiles.dialog.AudioDetailsViewModel import com.android.systemui.qs.ui.composable.QuickSettingsShade.systemGestureExclusionInShade import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayActionsViewModel Loading @@ -90,6 +92,7 @@ import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrim import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.AudioStreamSliderViewModel import com.android.systemui.volume.panel.component.volume.ui.composable.VolumeSlider import dagger.Lazy import javax.inject.Inject Loading Loading @@ -125,16 +128,12 @@ constructor( override fun ContentScope.Content(modifier: Modifier) { val coroutineScope = rememberCoroutineScope() val contentViewModel = rememberViewModel("QuickSettingsShadeOverlayContent") { contentViewModelFactory.create() rememberViewModel("QuickSettingsShadeOverlayContent", key = coroutineScope) { contentViewModelFactory.create(coroutineScope) } val quickSettingsContainerViewModel = rememberViewModel("QuickSettingsShadeOverlayContainer") { quickSettingsContainerViewModelFactory.create( supportsBrightnessMirroring = true, expansion = COLLAPSED, volumeSliderCoroutineScope = coroutineScope, ) quickSettingsContainerViewModelFactory.create(supportsBrightnessMirroring = true) } val hunPlaceholderViewModel = rememberViewModel("QuickSettingsShadeOverlayPlaceholder") { Loading @@ -153,7 +152,7 @@ constructor( OverlayShade( panelElement = QuickSettingsShade.Elements.Panel, alignmentOnWideScreens = Alignment.TopEnd, enableTransparency = quickSettingsContainerViewModel.isTransparencyEnabled, enableTransparency = contentViewModel.isTransparencyEnabled, onScrimClicked = contentViewModel::onScrimClicked, onBackgroundPlaced = { bounds, topCornerRadius, bottomCornerRadius -> contentViewModel.onPanelShapeInWindowChanged( Loading @@ -176,7 +175,10 @@ constructor( } }, ) { QuickSettingsContainer(viewModel = quickSettingsContainerViewModel) QuickSettingsContainer( contentViewModel = contentViewModel, containerViewModel = quickSettingsContainerViewModel, ) } SnoozeableHeadsUpNotificationSpace( stackScrollView = notificationStackScrollView.get(), Loading @@ -196,13 +198,15 @@ private sealed interface ShadeBodyState { } @Composable fun ContentScope.QuickSettingsContainer( viewModel: QuickSettingsContainerViewModel, private fun ContentScope.QuickSettingsContainer( contentViewModel: QuickSettingsShadeOverlayContentViewModel, containerViewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() val isEditing by containerViewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() val tileDetails = if (QsDetailedView.isEnabled) viewModel.detailsViewModel.activeTileDetails else null if (QsDetailedView.isEnabled) containerViewModel.detailsViewModel.activeTileDetails else null AnimatedContent( modifier = Modifier.sysuiResTag("quick_settings_container"), Loading @@ -217,19 +221,23 @@ fun ContentScope.QuickSettingsContainer( when (state) { ShadeBodyState.Editing -> { EditMode( viewModel = viewModel.editModeViewModel, viewModel = containerViewModel.editModeViewModel, modifier = modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding), ) } ShadeBodyState.TileDetails -> { TileDetails(modifier = modifier, viewModel.detailsViewModel) TileDetails(modifier = modifier, containerViewModel.detailsViewModel) } ShadeBodyState.Default -> { QuickSettingsLayout( viewModel = viewModel, qsContainerViewModel = containerViewModel, toolbarViewModelFactory = contentViewModel.toolbarViewModelFactory, isTransparencyEnabled = contentViewModel.isTransparencyEnabled, volumeSliderViewModel = contentViewModel.volumeSliderViewModel, audioDetailsViewModelFactory = contentViewModel.audioDetailsViewModelFactory, modifier = modifier.sysuiResTag("quick_settings_panel"), ) } Loading @@ -239,8 +247,12 @@ fun ContentScope.QuickSettingsContainer( /** Column containing Brightness and QS tiles. */ @Composable fun ContentScope.QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, private fun ContentScope.QuickSettingsLayout( qsContainerViewModel: QuickSettingsContainerViewModel, toolbarViewModelFactory: ToolbarViewModel.Factory, isTransparencyEnabled: Boolean, volumeSliderViewModel: AudioStreamSliderViewModel?, audioDetailsViewModelFactory: AudioDetailsViewModel.Factory, modifier: Modifier = Modifier, ) { Column( Loading @@ -254,32 +266,35 @@ fun ContentScope.QuickSettingsLayout( if (isFullWidthShade()) { VerticalSeparator() QuickSettingsOverlayHeader( viewModel = viewModel.shadeHeaderViewModel, viewModel = qsContainerViewModel.shadeHeaderViewModel, modifier = Modifier.element(QuickSettingsShade.Elements.Header), ) VerticalSeparator() } val toolbarViewModel = rememberViewModel("QuickSettingsLayout") { toolbarViewModelFactory.create() } Toolbar( modifier = Modifier.fillMaxWidth().requiredHeight(QuickSettingsShade.Dimensions.ToolbarHeight), viewModel = viewModel.toolbarViewModel, viewModel = toolbarViewModel, ) // TODO(b/428805936): Double check this padding. VerticalSeparator() Column(modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { MediaCarousel( isVisible = viewModel.showMedia, mediaHost = viewModel.mediaHost, carouselController = viewModel.mediaCarouselController, usingCollapsedLandscapeMedia = true, modifier = Modifier.padding(horizontal = QuickSettingsShade.Dimensions.Padding), Media( viewModelFactory = qsContainerViewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Compact, behavior = QuickSettingsContainerViewModel.mediaUiBehavior, onDismissed = qsContainerViewModel::onMediaSwipeToDismiss, modifier = Modifier, ) if (viewModel.showMedia) { if (qsContainerViewModel.showMedia) { VerticalSeparator() } Loading @@ -289,12 +304,11 @@ fun ContentScope.QuickSettingsLayout( ) ) { BrightnessSliderContainer( viewModel = viewModel.brightnessSliderViewModel, viewModel = qsContainerViewModel.brightnessSliderViewModel, containerColors = ContainerColors( idleColor = Color.Transparent, mirrorColor = OverlayShade.Colors.panelBackground(viewModel.isTransparencyEnabled), mirrorColor = OverlayShade.Colors.panelBackground(isTransparencyEnabled), ), modifier = Modifier.fillMaxWidth(), ) Loading @@ -302,7 +316,6 @@ fun ContentScope.QuickSettingsLayout( VerticalSeparator() val volumeSliderViewModel = viewModel.volumeSliderViewModel if (volumeSliderViewModel != null) { val volumeSliderState by volumeSliderViewModel.slider.collectAsStateWithLifecycle() Loading Loading @@ -337,8 +350,8 @@ fun ContentScope.QuickSettingsLayout( contentColor = MaterialTheme.colorScheme.onPrimary, ), onClick = { viewModel.detailsViewModel.onVolumeSettingsButtonClicked( viewModel.audioDetailsViewModelFactory.create() qsContainerViewModel.detailsViewModel.onVolumeSettingsButtonClicked( audioDetailsViewModelFactory.create() ) }, ) { Loading @@ -359,7 +372,10 @@ fun ContentScope.QuickSettingsLayout( // TODO(b/428805936): Double check this padding. VerticalSeparator(QuickSettingsShade.Dimensions.Padding) TileGrid(viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth()) TileGrid( viewModel = qsContainerViewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth(), ) // TODO(b/428805936): Double check this padding. VerticalSeparator(QuickSettingsShade.Dimensions.Padding * 2) Loading packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt +2 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder import com.android.compose.animation.scene.UserActionDistance import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.scene.shared.model.Scenes Loading @@ -47,7 +47,7 @@ fun TransitionBuilder.toShadeTransition(durationScale: Double = 1.0) { val qsTranslation = -ShadeHeader.Dimensions.CollapsedHeightForTransitions * 0.66f translate(QuickSettings.Elements.QuickQuickSettings, y = qsTranslation) translate(MediaCarousel.Elements.Content, y = qsTranslation) translate(Media.Elements.mediaCarousel, y = qsTranslation) translate(Notifications.Elements.NotificationScrim, Edge.Top, false) } Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/MediaCarouselElement.kt +45 −13 Original line number Diff line number Diff line Loading @@ -22,12 +22,18 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onLayoutRectChanged import androidx.compose.ui.res.dimensionResource import com.android.compose.animation.scene.ContentScope import com.android.systemui.Flags.mediaControlsInCompose import com.android.systemui.keyguard.ui.viewmodel.MediaCarouselElementViewModel import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.dagger.MediaModule import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.res.R import javax.inject.Inject import javax.inject.Named Loading @@ -37,6 +43,7 @@ class MediaCarouselElement constructor( private val mediaCarouselController: MediaCarouselController, @param:Named(MediaModule.KEYGUARD) private val mediaHost: MediaHost, private val mediaCarouselElementViewModelFactory: MediaCarouselElementViewModel.Factory, ) { @Composable Loading @@ -52,6 +59,30 @@ constructor( dimensionResource(id = R.dimen.notification_side_paddings) + dimensionResource(id = R.dimen.notification_panel_margin_horizontal) } if (mediaControlsInCompose()) { val viewModel = rememberViewModel("MediaCarouselElement") { mediaCarouselElementViewModelFactory.create() } Element( key = Media.Elements.mediaCarousel, modifier = modifier .fillMaxWidth() .padding(horizontal = horizontalPadding) .onLayoutRectChanged { onBottomChanged?.invoke(it.boundsInWindow.bottom.toFloat()) }, ) { Media( viewModelFactory = viewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Default, behavior = viewModel.mediaUiBehavior, onDismissed = viewModel::onSwipeToDismiss, ) } } else { MediaCarousel( isVisible = true, mediaHost = mediaHost, Loading @@ -67,3 +98,4 @@ constructor( ) } } }
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt +20 −28 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.res.dimensionResource import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey Loading @@ -34,13 +33,8 @@ import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn import com.android.systemui.keyguard.ui.composable.element.SmallClockElement import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.composable.isLandscape import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.COLLAPSED import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.EXPANDED import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel import com.android.systemui.res.R Loading @@ -54,7 +48,6 @@ import com.android.systemui.shade.ui.composable.isFullWidthShade import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import dagger.Lazy import javax.inject.Inject import javax.inject.Named import kotlinx.coroutines.flow.Flow @SysUISingleton Loading @@ -67,8 +60,6 @@ constructor( private val stackScrollView: Lazy<NotificationScrollView>, private val smallClockElement: SmallClockElement, private val keyguardClockViewModel: KeyguardClockViewModel, private val mediaCarouselController: MediaCarouselController, @Named(QUICK_QS_PANEL) private val mediaHost: Lazy<MediaHost>, private val jankMonitor: InteractionJankMonitor, ) : Overlay { override val key = Overlays.NotificationsShade Loading Loading @@ -98,11 +89,6 @@ constructor( viewModel.notificationsPlaceholderViewModelFactory.create() } val usingCollapsedLandscapeMedia = LocalResources.current.getBoolean(R.bool.config_quickSettingsMediaLandscapeCollapsed) mediaHost.get().expansion = if (usingCollapsedLandscapeMedia && isLandscape()) COLLAPSED else EXPANDED val isFullWidth = isFullWidthShade() OverlayShade( Loading Loading @@ -139,18 +125,24 @@ constructor( } } MediaCarousel( isVisible = viewModel.showMedia, mediaHost = mediaHost.get(), carouselController = mediaCarouselController, usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia, if (viewModel.showMedia) { Element( key = Media.Elements.mediaCarousel, modifier = Modifier.padding( top = notificationStackPadding, start = notificationStackPadding, end = notificationStackPadding, ), ) { Media( viewModelFactory = viewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Default, behavior = viewModel.mediaUiBehavior, onDismissed = viewModel::onMediaSwipeToDismiss, ) } } NotificationScrollingStack( shadeSession = shadeSession, Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +14 −38 Original line number Diff line number Diff line Loading @@ -58,7 +58,6 @@ import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateContentFloatAsState import com.android.compose.animation.scene.animateSceneDpAsState import com.android.compose.animation.scene.content.state.TransitionState import com.android.compose.modifiers.thenIf import com.android.compose.windowsizeclass.LocalWindowSizeClass Loading @@ -71,21 +70,16 @@ import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.composable.isLandscape import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.EXPANDED import com.android.systemui.media.dagger.MediaModule import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.notifications.ui.composable.NotificationScrollingStack import com.android.systemui.qs.composefragment.ui.GridAnchor import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.shared.ui.ElementKeys import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.InQS import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneContentViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsUserActionsViewModel import com.android.systemui.res.R Loading @@ -100,7 +94,6 @@ import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScr import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import dagger.Lazy import javax.inject.Inject import javax.inject.Named import kotlin.math.roundToInt import kotlinx.coroutines.flow.Flow Loading @@ -114,8 +107,6 @@ constructor( private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory, private val actionsViewModelFactory: QuickSettingsUserActionsViewModel.Factory, private val contentViewModelFactory: QuickSettingsSceneContentViewModel.Factory, private val mediaCarouselController: MediaCarouselController, @Named(MediaModule.QS_PANEL) private val mediaHost: MediaHost, private val jankMonitor: InteractionJankMonitor, ) : ExclusiveActivatable(), Scene { override val key = Scenes.QuickSettings Loading Loading @@ -145,19 +136,11 @@ constructor( viewModel = viewModel, headerViewModel = viewModel.qsContainerViewModel.shadeHeaderViewModel, notificationsPlaceholderViewModel = notificationsPlaceholderViewModel, mediaCarouselController = mediaCarouselController, mediaHost = mediaHost, modifier = modifier, shadeSession = shadeSession, jankMonitor = jankMonitor, ) } init { mediaHost.expansion = EXPANDED mediaHost.showsOnlyActiveMedia = false mediaHost.init(MediaHierarchyManager.LOCATION_QS) } } @Composable Loading @@ -166,8 +149,6 @@ private fun ContentScope.QuickSettingsScene( viewModel: QuickSettingsSceneContentViewModel, headerViewModel: ShadeHeaderViewModel, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, mediaCarouselController: MediaCarouselController, mediaHost: MediaHost, modifier: Modifier = Modifier, shadeSession: SaveableSession, jankMonitor: InteractionJankMonitor, Loading Loading @@ -233,10 +214,8 @@ private fun ContentScope.QuickSettingsScene( WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() // ############# Media ############### val isMediaVisible = viewModel.isMediaVisible val isMediaVisible = viewModel.qsContainerViewModel.showMedia val mediaInRow = isMediaVisible && isLandscape() val mediaOffset by animateSceneDpAsState(value = InQS, key = MediaLandscapeTopOffset, canOverflow = false) // This is the background for the whole scene, as the elements don't necessarily provide // a background that extends to the edges. Loading Loading @@ -301,19 +280,16 @@ private fun ContentScope.QuickSettingsScene( }, media = @Composable { MediaCarousel( isVisible = isMediaVisible, mediaHost = mediaHost, modifier = Modifier.fillMaxWidth() .padding( horizontal = dimensionResource( id = R.dimen.qs_horizontal_margin ) ), carouselController = mediaCarouselController, Element(key = Media.Elements.mediaCarousel, modifier = Modifier) { Media( viewModelFactory = viewModel.qsContainerViewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Default, behavior = QuickSettingsContainerViewModel.mediaUiBehavior, onDismissed = viewModel.qsContainerViewModel::onMediaSwipeToDismiss, ) } }, mediaInRow = mediaInRow, modifier = Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +52 −36 Original line number Diff line number Diff line Loading @@ -65,8 +65,8 @@ import com.android.systemui.brightness.ui.compose.ContainerColors import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.COLLAPSED import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace import com.android.systemui.qs.composefragment.ui.GridAnchor import com.android.systemui.qs.flags.QsDetailedView Loading @@ -74,6 +74,8 @@ import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.TileDetails import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.panels.ui.compose.toolbar.Toolbar import com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel import com.android.systemui.qs.tiles.dialog.AudioDetailsViewModel import com.android.systemui.qs.ui.composable.QuickSettingsShade.systemGestureExclusionInShade import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayActionsViewModel Loading @@ -90,6 +92,7 @@ import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrim import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.AudioStreamSliderViewModel import com.android.systemui.volume.panel.component.volume.ui.composable.VolumeSlider import dagger.Lazy import javax.inject.Inject Loading Loading @@ -125,16 +128,12 @@ constructor( override fun ContentScope.Content(modifier: Modifier) { val coroutineScope = rememberCoroutineScope() val contentViewModel = rememberViewModel("QuickSettingsShadeOverlayContent") { contentViewModelFactory.create() rememberViewModel("QuickSettingsShadeOverlayContent", key = coroutineScope) { contentViewModelFactory.create(coroutineScope) } val quickSettingsContainerViewModel = rememberViewModel("QuickSettingsShadeOverlayContainer") { quickSettingsContainerViewModelFactory.create( supportsBrightnessMirroring = true, expansion = COLLAPSED, volumeSliderCoroutineScope = coroutineScope, ) quickSettingsContainerViewModelFactory.create(supportsBrightnessMirroring = true) } val hunPlaceholderViewModel = rememberViewModel("QuickSettingsShadeOverlayPlaceholder") { Loading @@ -153,7 +152,7 @@ constructor( OverlayShade( panelElement = QuickSettingsShade.Elements.Panel, alignmentOnWideScreens = Alignment.TopEnd, enableTransparency = quickSettingsContainerViewModel.isTransparencyEnabled, enableTransparency = contentViewModel.isTransparencyEnabled, onScrimClicked = contentViewModel::onScrimClicked, onBackgroundPlaced = { bounds, topCornerRadius, bottomCornerRadius -> contentViewModel.onPanelShapeInWindowChanged( Loading @@ -176,7 +175,10 @@ constructor( } }, ) { QuickSettingsContainer(viewModel = quickSettingsContainerViewModel) QuickSettingsContainer( contentViewModel = contentViewModel, containerViewModel = quickSettingsContainerViewModel, ) } SnoozeableHeadsUpNotificationSpace( stackScrollView = notificationStackScrollView.get(), Loading @@ -196,13 +198,15 @@ private sealed interface ShadeBodyState { } @Composable fun ContentScope.QuickSettingsContainer( viewModel: QuickSettingsContainerViewModel, private fun ContentScope.QuickSettingsContainer( contentViewModel: QuickSettingsShadeOverlayContentViewModel, containerViewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() val isEditing by containerViewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() val tileDetails = if (QsDetailedView.isEnabled) viewModel.detailsViewModel.activeTileDetails else null if (QsDetailedView.isEnabled) containerViewModel.detailsViewModel.activeTileDetails else null AnimatedContent( modifier = Modifier.sysuiResTag("quick_settings_container"), Loading @@ -217,19 +221,23 @@ fun ContentScope.QuickSettingsContainer( when (state) { ShadeBodyState.Editing -> { EditMode( viewModel = viewModel.editModeViewModel, viewModel = containerViewModel.editModeViewModel, modifier = modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding), ) } ShadeBodyState.TileDetails -> { TileDetails(modifier = modifier, viewModel.detailsViewModel) TileDetails(modifier = modifier, containerViewModel.detailsViewModel) } ShadeBodyState.Default -> { QuickSettingsLayout( viewModel = viewModel, qsContainerViewModel = containerViewModel, toolbarViewModelFactory = contentViewModel.toolbarViewModelFactory, isTransparencyEnabled = contentViewModel.isTransparencyEnabled, volumeSliderViewModel = contentViewModel.volumeSliderViewModel, audioDetailsViewModelFactory = contentViewModel.audioDetailsViewModelFactory, modifier = modifier.sysuiResTag("quick_settings_panel"), ) } Loading @@ -239,8 +247,12 @@ fun ContentScope.QuickSettingsContainer( /** Column containing Brightness and QS tiles. */ @Composable fun ContentScope.QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, private fun ContentScope.QuickSettingsLayout( qsContainerViewModel: QuickSettingsContainerViewModel, toolbarViewModelFactory: ToolbarViewModel.Factory, isTransparencyEnabled: Boolean, volumeSliderViewModel: AudioStreamSliderViewModel?, audioDetailsViewModelFactory: AudioDetailsViewModel.Factory, modifier: Modifier = Modifier, ) { Column( Loading @@ -254,32 +266,35 @@ fun ContentScope.QuickSettingsLayout( if (isFullWidthShade()) { VerticalSeparator() QuickSettingsOverlayHeader( viewModel = viewModel.shadeHeaderViewModel, viewModel = qsContainerViewModel.shadeHeaderViewModel, modifier = Modifier.element(QuickSettingsShade.Elements.Header), ) VerticalSeparator() } val toolbarViewModel = rememberViewModel("QuickSettingsLayout") { toolbarViewModelFactory.create() } Toolbar( modifier = Modifier.fillMaxWidth().requiredHeight(QuickSettingsShade.Dimensions.ToolbarHeight), viewModel = viewModel.toolbarViewModel, viewModel = toolbarViewModel, ) // TODO(b/428805936): Double check this padding. VerticalSeparator() Column(modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { MediaCarousel( isVisible = viewModel.showMedia, mediaHost = viewModel.mediaHost, carouselController = viewModel.mediaCarouselController, usingCollapsedLandscapeMedia = true, modifier = Modifier.padding(horizontal = QuickSettingsShade.Dimensions.Padding), Media( viewModelFactory = qsContainerViewModel.mediaViewModelFactory, presentationStyle = MediaPresentationStyle.Compact, behavior = QuickSettingsContainerViewModel.mediaUiBehavior, onDismissed = qsContainerViewModel::onMediaSwipeToDismiss, modifier = Modifier, ) if (viewModel.showMedia) { if (qsContainerViewModel.showMedia) { VerticalSeparator() } Loading @@ -289,12 +304,11 @@ fun ContentScope.QuickSettingsLayout( ) ) { BrightnessSliderContainer( viewModel = viewModel.brightnessSliderViewModel, viewModel = qsContainerViewModel.brightnessSliderViewModel, containerColors = ContainerColors( idleColor = Color.Transparent, mirrorColor = OverlayShade.Colors.panelBackground(viewModel.isTransparencyEnabled), mirrorColor = OverlayShade.Colors.panelBackground(isTransparencyEnabled), ), modifier = Modifier.fillMaxWidth(), ) Loading @@ -302,7 +316,6 @@ fun ContentScope.QuickSettingsLayout( VerticalSeparator() val volumeSliderViewModel = viewModel.volumeSliderViewModel if (volumeSliderViewModel != null) { val volumeSliderState by volumeSliderViewModel.slider.collectAsStateWithLifecycle() Loading Loading @@ -337,8 +350,8 @@ fun ContentScope.QuickSettingsLayout( contentColor = MaterialTheme.colorScheme.onPrimary, ), onClick = { viewModel.detailsViewModel.onVolumeSettingsButtonClicked( viewModel.audioDetailsViewModelFactory.create() qsContainerViewModel.detailsViewModel.onVolumeSettingsButtonClicked( audioDetailsViewModelFactory.create() ) }, ) { Loading @@ -359,7 +372,10 @@ fun ContentScope.QuickSettingsLayout( // TODO(b/428805936): Double check this padding. VerticalSeparator(QuickSettingsShade.Dimensions.Padding) TileGrid(viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth()) TileGrid( viewModel = qsContainerViewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth(), ) // TODO(b/428805936): Double check this padding. VerticalSeparator(QuickSettingsShade.Dimensions.Padding * 2) Loading
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt +2 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder import com.android.compose.animation.scene.UserActionDistance import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.remedia.ui.compose.Media import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.scene.shared.model.Scenes Loading @@ -47,7 +47,7 @@ fun TransitionBuilder.toShadeTransition(durationScale: Double = 1.0) { val qsTranslation = -ShadeHeader.Dimensions.CollapsedHeightForTransitions * 0.66f translate(QuickSettings.Elements.QuickQuickSettings, y = qsTranslation) translate(MediaCarousel.Elements.Content, y = qsTranslation) translate(Media.Elements.mediaCarousel, y = qsTranslation) translate(Notifications.Elements.NotificationScrim, Edge.Top, false) } Loading