Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt +33 −1 Original line number Diff line number Diff line Loading @@ -16,23 +16,55 @@ package com.android.systemui.keyguard.ui.composable.section import android.content.Context import android.view.ViewGroup import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.SceneScope import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationStackAppearanceViewBinder import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject class NotificationSection @Inject constructor( @Application context: Context, private val viewModel: NotificationsPlaceholderViewModel, controller: NotificationStackScrollLayoutController, sceneContainerFlags: SceneContainerFlags, sharedNotificationContainer: SharedNotificationContainer, stackScrollLayout: NotificationStackScrollLayout, notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel, ambientState: AmbientState, ) { init { if (sceneContainerFlags.flexiNotifsEnabled()) { (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout) sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout) NotificationStackAppearanceViewBinder.bind( context, sharedNotificationContainer, notificationStackAppearanceViewModel, ambientState, controller, ) } } @Composable fun SceneScope.Notifications(modifier: Modifier = Modifier) { NotificationStack( viewModel = viewModel, isScrimVisible = false, modifier = modifier, ) } Loading packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +40 −16 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme Loading @@ -43,8 +44,10 @@ import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope import com.android.compose.modifiers.height import com.android.systemui.notifications.ui.composable.Notifications.Form import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import kotlin.math.roundToInt object Notifications { object Elements { Loading Loading @@ -77,32 +80,52 @@ fun SceneScope.HeadsUpNotificationSpace( ) } /** Adds the space where notification stack will appear in the scene. */ /** Adds the space where notification stack should appear in the scene. */ @Composable fun SceneScope.NotificationStack( viewModel: NotificationsPlaceholderViewModel, isScrimVisible: Boolean, modifier: Modifier = Modifier, ) { NotificationPlaceholder( viewModel = viewModel, form = Form.Stack, modifier = modifier, ) } /** * Adds the space where notification stack should appear in the scene, with a scrim and nested * scrolling. */ @Composable fun SceneScope.NotificationScrollingStack( viewModel: NotificationsPlaceholderViewModel, modifier: Modifier = Modifier, ) { val cornerRadius by viewModel.cornerRadiusDp.collectAsState() Box(modifier = modifier) { if (isScrimVisible) { val contentHeight by viewModel.intrinsicContentHeight.collectAsState() val expansionFraction by viewModel.expandFraction.collectAsState(0f) Box( modifier = Modifier.element(Notifications.Elements.NotificationScrim) .fillMaxSize() modifier .verticalNestedScrollToScene() .fillMaxWidth() .element(Notifications.Elements.NotificationScrim) .graphicsLayer { shape = RoundedCornerShape(cornerRadius.dp) clip = true alpha = expansionFraction } .background(MaterialTheme.colorScheme.surface) ) } .debugBackground(viewModel, Color(0.5f, 0.5f, 0f, 0.2f)) ) { NotificationPlaceholder( viewModel = viewModel, form = Form.Stack, modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxWidth().height { contentHeight.roundToInt() } ) } } Loading Loading @@ -159,6 +182,7 @@ private fun SceneScope.NotificationPlaceholder( debugLog(viewModel) { "STACK onSizeChanged: size=$size" } } .onPlaced { coordinates: LayoutCoordinates -> viewModel.onContentTopChanged(coordinates.positionInWindow().y) debugLog(viewModel) { "STACK onPlaced:" + " size=${coordinates.size}" + Loading packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope import com.android.systemui.dagger.SysUISingleton import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge import com.android.systemui.scene.shared.model.SceneKey Loading Loading @@ -66,6 +67,7 @@ constructor( modifier: Modifier, ) { Box(modifier = modifier) { Box(modifier = Modifier.fillMaxSize().element(Notifications.Elements.NotificationScrim)) HeadsUpNotificationSpace( viewModel = notificationsViewModel, modifier = Modifier.padding(16.dp).fillMaxSize(), Loading packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt +4 −4 Original line number Diff line number Diff line Loading @@ -3,12 +3,12 @@ package com.android.systemui.scene.ui.composable.transitions import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.scene.ui.composable.Shade import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.shade.ui.composable.ShadeHeader fun TransitionBuilder.goneToShadeTransition() { spec = tween(durationMillis = 500) translate(Shade.rootElementKey, Edge.Top, true) fade(Notifications.Elements.NotificationScrim) fractionRange(start = .58f) { fade(ShadeHeader.Elements.CollapsedContent) } translate(QuickSettings.Elements.Content, Edge.Top, true) } packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +13 −24 Original line number Diff line number Diff line Loading @@ -22,11 +22,9 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable Loading @@ -47,7 +45,7 @@ import com.android.systemui.media.controls.ui.MediaCarouselController import com.android.systemui.media.controls.ui.MediaHost import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.notifications.ui.composable.NotificationScrollingStack import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Direction Loading Loading @@ -148,35 +146,27 @@ private fun SceneScope.ShadeScene( mediaHost: MediaHost, modifier: Modifier = Modifier, ) { val localDensity = LocalDensity.current val layoutWidth = remember { mutableStateOf(0) } Box(modifier.element(Shade.Elements.Scrim)) { Spacer( Box( modifier = Modifier.element(Shade.Elements.ScrimBackground) .fillMaxSize() .background(MaterialTheme.colorScheme.scrim, shape = Shade.Shapes.Scrim) modifier.element(Shade.Elements.Scrim).background(MaterialTheme.colorScheme.scrim), ) Box { Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxSize() .clickable(onClick = { viewModel.onContentClicked() }) .padding( start = Shade.Dimensions.HorizontalPadding, end = Shade.Dimensions.HorizontalPadding, bottom = 48.dp ) modifier = Modifier.fillMaxWidth().clickable(onClick = { viewModel.onContentClicked() }) ) { CollapsedShadeHeader( viewModel = viewModel.shadeHeaderViewModel, createTintedIconManager = createTintedIconManager, createBatteryMeterViewController = createBatteryMeterViewController, statusBarIconController = statusBarIconController, modifier = Modifier.padding(horizontal = Shade.Dimensions.HorizontalPadding) ) Spacer(modifier = Modifier.height(16.dp)) QuickSettings( modifier = Modifier.wrapContentHeight(), modifier = Modifier.height(130.dp), viewModel.qsSceneAdapter, ) Loading @@ -202,16 +192,15 @@ private fun SceneScope.ShadeScene( }, mediaHost = mediaHost, layoutWidth = layoutWidth.value, layoutHeight = with(LocalDensity.current) { mediaHeight.toPx() }.toInt(), layoutHeight = with(localDensity) { mediaHeight.toPx() }.toInt(), carouselController = mediaCarouselController, ) } Spacer(modifier = Modifier.height(16.dp)) NotificationStack( NotificationScrollingStack( viewModel = viewModel.notifications, isScrimVisible = true, modifier = Modifier.weight(1f), modifier = Modifier.fillMaxWidth().weight(1f), ) } } Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt +33 −1 Original line number Diff line number Diff line Loading @@ -16,23 +16,55 @@ package com.android.systemui.keyguard.ui.composable.section import android.content.Context import android.view.ViewGroup import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.SceneScope import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationStackAppearanceViewBinder import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject class NotificationSection @Inject constructor( @Application context: Context, private val viewModel: NotificationsPlaceholderViewModel, controller: NotificationStackScrollLayoutController, sceneContainerFlags: SceneContainerFlags, sharedNotificationContainer: SharedNotificationContainer, stackScrollLayout: NotificationStackScrollLayout, notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel, ambientState: AmbientState, ) { init { if (sceneContainerFlags.flexiNotifsEnabled()) { (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout) sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout) NotificationStackAppearanceViewBinder.bind( context, sharedNotificationContainer, notificationStackAppearanceViewModel, ambientState, controller, ) } } @Composable fun SceneScope.Notifications(modifier: Modifier = Modifier) { NotificationStack( viewModel = viewModel, isScrimVisible = false, modifier = modifier, ) } Loading
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +40 −16 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme Loading @@ -43,8 +44,10 @@ import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope import com.android.compose.modifiers.height import com.android.systemui.notifications.ui.composable.Notifications.Form import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import kotlin.math.roundToInt object Notifications { object Elements { Loading Loading @@ -77,32 +80,52 @@ fun SceneScope.HeadsUpNotificationSpace( ) } /** Adds the space where notification stack will appear in the scene. */ /** Adds the space where notification stack should appear in the scene. */ @Composable fun SceneScope.NotificationStack( viewModel: NotificationsPlaceholderViewModel, isScrimVisible: Boolean, modifier: Modifier = Modifier, ) { NotificationPlaceholder( viewModel = viewModel, form = Form.Stack, modifier = modifier, ) } /** * Adds the space where notification stack should appear in the scene, with a scrim and nested * scrolling. */ @Composable fun SceneScope.NotificationScrollingStack( viewModel: NotificationsPlaceholderViewModel, modifier: Modifier = Modifier, ) { val cornerRadius by viewModel.cornerRadiusDp.collectAsState() Box(modifier = modifier) { if (isScrimVisible) { val contentHeight by viewModel.intrinsicContentHeight.collectAsState() val expansionFraction by viewModel.expandFraction.collectAsState(0f) Box( modifier = Modifier.element(Notifications.Elements.NotificationScrim) .fillMaxSize() modifier .verticalNestedScrollToScene() .fillMaxWidth() .element(Notifications.Elements.NotificationScrim) .graphicsLayer { shape = RoundedCornerShape(cornerRadius.dp) clip = true alpha = expansionFraction } .background(MaterialTheme.colorScheme.surface) ) } .debugBackground(viewModel, Color(0.5f, 0.5f, 0f, 0.2f)) ) { NotificationPlaceholder( viewModel = viewModel, form = Form.Stack, modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxWidth().height { contentHeight.roundToInt() } ) } } Loading Loading @@ -159,6 +182,7 @@ private fun SceneScope.NotificationPlaceholder( debugLog(viewModel) { "STACK onSizeChanged: size=$size" } } .onPlaced { coordinates: LayoutCoordinates -> viewModel.onContentTopChanged(coordinates.positionInWindow().y) debugLog(viewModel) { "STACK onPlaced:" + " size=${coordinates.size}" + Loading
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope import com.android.systemui.dagger.SysUISingleton import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge import com.android.systemui.scene.shared.model.SceneKey Loading Loading @@ -66,6 +67,7 @@ constructor( modifier: Modifier, ) { Box(modifier = modifier) { Box(modifier = Modifier.fillMaxSize().element(Notifications.Elements.NotificationScrim)) HeadsUpNotificationSpace( viewModel = notificationsViewModel, modifier = Modifier.padding(16.dp).fillMaxSize(), Loading
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt +4 −4 Original line number Diff line number Diff line Loading @@ -3,12 +3,12 @@ package com.android.systemui.scene.ui.composable.transitions import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.scene.ui.composable.Shade import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.shade.ui.composable.ShadeHeader fun TransitionBuilder.goneToShadeTransition() { spec = tween(durationMillis = 500) translate(Shade.rootElementKey, Edge.Top, true) fade(Notifications.Elements.NotificationScrim) fractionRange(start = .58f) { fade(ShadeHeader.Elements.CollapsedContent) } translate(QuickSettings.Elements.Content, Edge.Top, true) }
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +13 −24 Original line number Diff line number Diff line Loading @@ -22,11 +22,9 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable Loading @@ -47,7 +45,7 @@ import com.android.systemui.media.controls.ui.MediaCarouselController import com.android.systemui.media.controls.ui.MediaHost import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.notifications.ui.composable.NotificationScrollingStack import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Direction Loading Loading @@ -148,35 +146,27 @@ private fun SceneScope.ShadeScene( mediaHost: MediaHost, modifier: Modifier = Modifier, ) { val localDensity = LocalDensity.current val layoutWidth = remember { mutableStateOf(0) } Box(modifier.element(Shade.Elements.Scrim)) { Spacer( Box( modifier = Modifier.element(Shade.Elements.ScrimBackground) .fillMaxSize() .background(MaterialTheme.colorScheme.scrim, shape = Shade.Shapes.Scrim) modifier.element(Shade.Elements.Scrim).background(MaterialTheme.colorScheme.scrim), ) Box { Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxSize() .clickable(onClick = { viewModel.onContentClicked() }) .padding( start = Shade.Dimensions.HorizontalPadding, end = Shade.Dimensions.HorizontalPadding, bottom = 48.dp ) modifier = Modifier.fillMaxWidth().clickable(onClick = { viewModel.onContentClicked() }) ) { CollapsedShadeHeader( viewModel = viewModel.shadeHeaderViewModel, createTintedIconManager = createTintedIconManager, createBatteryMeterViewController = createBatteryMeterViewController, statusBarIconController = statusBarIconController, modifier = Modifier.padding(horizontal = Shade.Dimensions.HorizontalPadding) ) Spacer(modifier = Modifier.height(16.dp)) QuickSettings( modifier = Modifier.wrapContentHeight(), modifier = Modifier.height(130.dp), viewModel.qsSceneAdapter, ) Loading @@ -202,16 +192,15 @@ private fun SceneScope.ShadeScene( }, mediaHost = mediaHost, layoutWidth = layoutWidth.value, layoutHeight = with(LocalDensity.current) { mediaHeight.toPx() }.toInt(), layoutHeight = with(localDensity) { mediaHeight.toPx() }.toInt(), carouselController = mediaCarouselController, ) } Spacer(modifier = Modifier.height(16.dp)) NotificationStack( NotificationScrollingStack( viewModel = viewModel.notifications, isScrimVisible = true, modifier = Modifier.weight(1f), modifier = Modifier.fillMaxWidth().weight(1f), ) } } Loading