Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +28 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.toComposeRect import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.Layout import androidx.compose.ui.viewinterop.AndroidView import androidx.core.view.isVisible import com.android.compose.animation.scene.SceneScope Loading @@ -41,6 +42,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.qualifiers.KeyguardRootView import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge Loading Loading @@ -88,7 +90,7 @@ constructor( ) { LockscreenScene( viewProvider = viewProvider, longPressViewModel = viewModel.longPress, viewModel = viewModel, modifier = modifier, ) } Loading @@ -108,9 +110,9 @@ constructor( } @Composable private fun LockscreenScene( private fun SceneScope.LockscreenScene( viewProvider: () -> View, longPressViewModel: KeyguardLongPressViewModel, viewModel: LockscreenSceneViewModel, modifier: Modifier = Modifier, ) { fun findSettingsMenu(): View { Loading @@ -121,7 +123,7 @@ private fun LockscreenScene( modifier = modifier, ) { LongPressSurface( viewModel = longPressViewModel, viewModel = viewModel.longPress, isSettingsMenuVisible = { findSettingsMenu().isVisible }, settingsMenuBounds = { val bounds = android.graphics.Rect() Loading @@ -141,6 +143,28 @@ private fun LockscreenScene( }, modifier = Modifier.fillMaxSize(), ) val notificationStackPosition by viewModel.keyguardRoot.notificationPositionOnLockscreen.collectAsState() Layout( modifier = Modifier.fillMaxSize(), content = { NotificationStack( viewModel = viewModel.notifications, isScrimVisible = false, ) } ) { measurables, constraints -> check(measurables.size == 1) val height = notificationStackPosition.height.toInt() val childConstraints = constraints.copy(minHeight = height, maxHeight = height) val placeable = measurables[0].measure(childConstraints) layout(constraints.maxWidth, constraints.maxHeight) { val start = (constraints.maxWidth - placeable.measuredWidth) / 2 placeable.placeRelative(x = start, y = notificationStackPosition.top.toInt()) } } } } Loading packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +167 −26 Original line number Diff line number Diff line Loading @@ -17,56 +17,197 @@ package com.android.systemui.notifications.ui.composable import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.positionInWindow 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.animation.scene.ValueKey import com.android.compose.animation.scene.animateSharedFloatAsState import com.android.systemui.notifications.ui.composable.Notifications.Form import com.android.systemui.notifications.ui.composable.Notifications.SharedValues.SharedExpansionValue import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel object Notifications { object Elements { val Notifications = ElementKey("Notifications") val NotificationScrim = ElementKey("NotificationScrim") val NotificationPlaceholder = ElementKey("NotificationPlaceholder") val ShelfSpace = ElementKey("ShelfSpace") } object SharedValues { val SharedExpansionValue = ValueKey("SharedExpansionValue") } enum class Form { HunFromTop, Stack, HunFromBottom, } } /** * Adds the space where heads up notifications can appear in the scene. This should generally be the * entire size of the scene. */ @Composable fun SceneScope.HeadsUpNotificationSpace( viewModel: NotificationsPlaceholderViewModel, isPeekFromBottom: Boolean = false, modifier: Modifier = Modifier, ) { NotificationPlaceholder( viewModel = viewModel, form = if (isPeekFromBottom) Form.HunFromBottom else Form.HunFromTop, modifier = modifier, ) } /** Adds the space where notification stack will appear in the scene. */ @Composable fun SceneScope.Notifications( fun SceneScope.NotificationStack( viewModel: NotificationsPlaceholderViewModel, isScrimVisible: Boolean, modifier: Modifier = Modifier, ) { // TODO(b/272779828): implement. Column( Box(modifier = modifier) { if (isScrimVisible) { Box( modifier = modifier .element(key = Notifications.Elements.Notifications) .fillMaxWidth() .defaultMinSize(minHeight = 300.dp) Modifier.element(Notifications.Elements.NotificationScrim) .fillMaxSize() .clip(RoundedCornerShape(32.dp)) .background(MaterialTheme.colorScheme.surface) .padding(16.dp), ) } NotificationPlaceholder( viewModel = viewModel, form = Form.Stack, modifier = Modifier.fillMaxSize(), ) } } /** * This may be added to the lockscreen to provide a space to the start of the lock icon where the * short shelf has room to flow vertically below the lock icon, but to its start, allowing more * notifications to fit in the stack itself. (see: b/213934746) * * NOTE: this is totally unused for now; it is here to clarify the future plan */ @Composable fun SceneScope.NotificationShelfSpace( viewModel: NotificationsPlaceholderViewModel, modifier: Modifier = Modifier, ) { Text( text = "Notifications", modifier = Modifier.align(Alignment.CenterHorizontally), text = "Shelf Space", modifier .element(key = Notifications.Elements.ShelfSpace) .fillMaxWidth() .onSizeChanged { size: IntSize -> debugLog(viewModel) { "SHELF onSizeChanged: size=$size" } } .onPlaced { coordinates: LayoutCoordinates -> debugLog(viewModel) { ("SHELF onPlaced:" + " size=${coordinates.size}" + " position=${coordinates.positionInWindow()}" + " bounds=${coordinates.boundsInWindow()}") } } .clip(RoundedCornerShape(24.dp)) .background(MaterialTheme.colorScheme.primaryContainer) .padding(16.dp), style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onPrimaryContainer, ) } @Composable private fun SceneScope.NotificationPlaceholder( viewModel: NotificationsPlaceholderViewModel, form: Form, modifier: Modifier = Modifier, ) { val key = Notifications.Elements.NotificationPlaceholder Box( modifier = modifier .element(key) .debugBackground(viewModel) .onSizeChanged { size: IntSize -> debugLog(viewModel) { "STACK onSizeChanged: size=$size" } } .onPlaced { coordinates: LayoutCoordinates -> debugLog(viewModel) { "STACK onPlaced:" + " size=${coordinates.size}" + " position=${coordinates.positionInWindow()}" + " bounds=${coordinates.boundsInWindow()}" } val boundsInWindow = coordinates.boundsInWindow() viewModel.setPlaceholderPositionInWindow( top = boundsInWindow.top, bottom = boundsInWindow.bottom, ) Spacer(modifier = Modifier.weight(1f)) } ) { val animatedExpansion by animateSharedFloatAsState( value = if (form == Form.HunFromTop) 0f else 1f, key = SharedExpansionValue, element = key ) debugLog(viewModel) { "STACK composed: expansion=$animatedExpansion" } if (viewModel.isPlaceholderTextVisible) { Text( text = "Shelf", modifier = Modifier.align(Alignment.CenterHorizontally), style = MaterialTheme.typography.titleSmall, text = "Notifications", style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.align(Alignment.Center), ) } } } private inline fun debugLog( viewModel: NotificationsPlaceholderViewModel, msg: () -> Any, ) { if (viewModel.isDebugLoggingEnabled) { Log.d(TAG, msg().toString()) } } private fun Modifier.debugBackground( viewModel: NotificationsPlaceholderViewModel, color: Color = DEBUG_COLOR, ): Modifier = if (viewModel.isVisualDebuggingEnabled) { background(color) } else { this } private const val TAG = "FlexiNotifs" private val DEBUG_COLOR = Color(1f, 0f, 0f, 0.2f) packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +49 −41 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically 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.fillMaxHeight Loading @@ -43,6 +44,7 @@ import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel import com.android.systemui.scene.shared.model.SceneKey Loading Loading @@ -101,14 +103,14 @@ private fun SceneScope.QuickSettingsScene( modifier: Modifier = Modifier, ) { // TODO(b/280887232): implement the real UI. Box(modifier = modifier.fillMaxSize()) { val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() val collapsedHeaderHeight = with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier .fillMaxSize() Modifier.fillMaxSize() .clickable(onClick = { viewModel.onContentClicked() }) .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) ) { Loading Loading @@ -150,4 +152,10 @@ private fun SceneScope.QuickSettingsScene( QSSceneAdapter.State.QS ) } HeadsUpNotificationSpace( viewModel = viewModel.notifications, isPeekFromBottom = true, modifier = Modifier.padding(16.dp).fillMaxSize(), ) } } packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt +16 −2 Original line number Diff line number Diff line Loading @@ -17,15 +17,20 @@ package com.android.systemui.scene.ui.composable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier 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.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow Loading @@ -36,7 +41,11 @@ import kotlinx.coroutines.flow.asStateFlow * content from the scene framework. */ @SysUISingleton class GoneScene @Inject constructor() : ComposableScene { class GoneScene @Inject constructor( private val notificationsViewModel: NotificationsPlaceholderViewModel, ) : ComposableScene { override val key = SceneKey.Gone override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> = Loading @@ -56,6 +65,11 @@ class GoneScene @Inject constructor() : ComposableScene { override fun SceneScope.Content( modifier: Modifier, ) { Box(modifier = modifier) Box(modifier = modifier) { HeadsUpNotificationSpace( viewModel = notificationsViewModel, modifier = Modifier.padding(16.dp).fillMaxSize(), ) } } } packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt +2 −0 Original line number Diff line number Diff line Loading @@ -3,10 +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 fun TransitionBuilder.goneToShadeTransition() { spec = tween(durationMillis = 500) translate(Shade.rootElementKey, Edge.Top, true) fade(Notifications.Elements.NotificationScrim) } Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +28 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.toComposeRect import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.Layout import androidx.compose.ui.viewinterop.AndroidView import androidx.core.view.isVisible import com.android.compose.animation.scene.SceneScope Loading @@ -41,6 +42,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.qualifiers.KeyguardRootView import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge Loading Loading @@ -88,7 +90,7 @@ constructor( ) { LockscreenScene( viewProvider = viewProvider, longPressViewModel = viewModel.longPress, viewModel = viewModel, modifier = modifier, ) } Loading @@ -108,9 +110,9 @@ constructor( } @Composable private fun LockscreenScene( private fun SceneScope.LockscreenScene( viewProvider: () -> View, longPressViewModel: KeyguardLongPressViewModel, viewModel: LockscreenSceneViewModel, modifier: Modifier = Modifier, ) { fun findSettingsMenu(): View { Loading @@ -121,7 +123,7 @@ private fun LockscreenScene( modifier = modifier, ) { LongPressSurface( viewModel = longPressViewModel, viewModel = viewModel.longPress, isSettingsMenuVisible = { findSettingsMenu().isVisible }, settingsMenuBounds = { val bounds = android.graphics.Rect() Loading @@ -141,6 +143,28 @@ private fun LockscreenScene( }, modifier = Modifier.fillMaxSize(), ) val notificationStackPosition by viewModel.keyguardRoot.notificationPositionOnLockscreen.collectAsState() Layout( modifier = Modifier.fillMaxSize(), content = { NotificationStack( viewModel = viewModel.notifications, isScrimVisible = false, ) } ) { measurables, constraints -> check(measurables.size == 1) val height = notificationStackPosition.height.toInt() val childConstraints = constraints.copy(minHeight = height, maxHeight = height) val placeable = measurables[0].measure(childConstraints) layout(constraints.maxWidth, constraints.maxHeight) { val start = (constraints.maxWidth - placeable.measuredWidth) / 2 placeable.placeRelative(x = start, y = notificationStackPosition.top.toInt()) } } } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +167 −26 Original line number Diff line number Diff line Loading @@ -17,56 +17,197 @@ package com.android.systemui.notifications.ui.composable import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.positionInWindow 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.animation.scene.ValueKey import com.android.compose.animation.scene.animateSharedFloatAsState import com.android.systemui.notifications.ui.composable.Notifications.Form import com.android.systemui.notifications.ui.composable.Notifications.SharedValues.SharedExpansionValue import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel object Notifications { object Elements { val Notifications = ElementKey("Notifications") val NotificationScrim = ElementKey("NotificationScrim") val NotificationPlaceholder = ElementKey("NotificationPlaceholder") val ShelfSpace = ElementKey("ShelfSpace") } object SharedValues { val SharedExpansionValue = ValueKey("SharedExpansionValue") } enum class Form { HunFromTop, Stack, HunFromBottom, } } /** * Adds the space where heads up notifications can appear in the scene. This should generally be the * entire size of the scene. */ @Composable fun SceneScope.HeadsUpNotificationSpace( viewModel: NotificationsPlaceholderViewModel, isPeekFromBottom: Boolean = false, modifier: Modifier = Modifier, ) { NotificationPlaceholder( viewModel = viewModel, form = if (isPeekFromBottom) Form.HunFromBottom else Form.HunFromTop, modifier = modifier, ) } /** Adds the space where notification stack will appear in the scene. */ @Composable fun SceneScope.Notifications( fun SceneScope.NotificationStack( viewModel: NotificationsPlaceholderViewModel, isScrimVisible: Boolean, modifier: Modifier = Modifier, ) { // TODO(b/272779828): implement. Column( Box(modifier = modifier) { if (isScrimVisible) { Box( modifier = modifier .element(key = Notifications.Elements.Notifications) .fillMaxWidth() .defaultMinSize(minHeight = 300.dp) Modifier.element(Notifications.Elements.NotificationScrim) .fillMaxSize() .clip(RoundedCornerShape(32.dp)) .background(MaterialTheme.colorScheme.surface) .padding(16.dp), ) } NotificationPlaceholder( viewModel = viewModel, form = Form.Stack, modifier = Modifier.fillMaxSize(), ) } } /** * This may be added to the lockscreen to provide a space to the start of the lock icon where the * short shelf has room to flow vertically below the lock icon, but to its start, allowing more * notifications to fit in the stack itself. (see: b/213934746) * * NOTE: this is totally unused for now; it is here to clarify the future plan */ @Composable fun SceneScope.NotificationShelfSpace( viewModel: NotificationsPlaceholderViewModel, modifier: Modifier = Modifier, ) { Text( text = "Notifications", modifier = Modifier.align(Alignment.CenterHorizontally), text = "Shelf Space", modifier .element(key = Notifications.Elements.ShelfSpace) .fillMaxWidth() .onSizeChanged { size: IntSize -> debugLog(viewModel) { "SHELF onSizeChanged: size=$size" } } .onPlaced { coordinates: LayoutCoordinates -> debugLog(viewModel) { ("SHELF onPlaced:" + " size=${coordinates.size}" + " position=${coordinates.positionInWindow()}" + " bounds=${coordinates.boundsInWindow()}") } } .clip(RoundedCornerShape(24.dp)) .background(MaterialTheme.colorScheme.primaryContainer) .padding(16.dp), style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onPrimaryContainer, ) } @Composable private fun SceneScope.NotificationPlaceholder( viewModel: NotificationsPlaceholderViewModel, form: Form, modifier: Modifier = Modifier, ) { val key = Notifications.Elements.NotificationPlaceholder Box( modifier = modifier .element(key) .debugBackground(viewModel) .onSizeChanged { size: IntSize -> debugLog(viewModel) { "STACK onSizeChanged: size=$size" } } .onPlaced { coordinates: LayoutCoordinates -> debugLog(viewModel) { "STACK onPlaced:" + " size=${coordinates.size}" + " position=${coordinates.positionInWindow()}" + " bounds=${coordinates.boundsInWindow()}" } val boundsInWindow = coordinates.boundsInWindow() viewModel.setPlaceholderPositionInWindow( top = boundsInWindow.top, bottom = boundsInWindow.bottom, ) Spacer(modifier = Modifier.weight(1f)) } ) { val animatedExpansion by animateSharedFloatAsState( value = if (form == Form.HunFromTop) 0f else 1f, key = SharedExpansionValue, element = key ) debugLog(viewModel) { "STACK composed: expansion=$animatedExpansion" } if (viewModel.isPlaceholderTextVisible) { Text( text = "Shelf", modifier = Modifier.align(Alignment.CenterHorizontally), style = MaterialTheme.typography.titleSmall, text = "Notifications", style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.align(Alignment.Center), ) } } } private inline fun debugLog( viewModel: NotificationsPlaceholderViewModel, msg: () -> Any, ) { if (viewModel.isDebugLoggingEnabled) { Log.d(TAG, msg().toString()) } } private fun Modifier.debugBackground( viewModel: NotificationsPlaceholderViewModel, color: Color = DEBUG_COLOR, ): Modifier = if (viewModel.isVisualDebuggingEnabled) { background(color) } else { this } private const val TAG = "FlexiNotifs" private val DEBUG_COLOR = Color(1f, 0f, 0f, 0.2f)
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +49 −41 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically 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.fillMaxHeight Loading @@ -43,6 +44,7 @@ import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel import com.android.systemui.scene.shared.model.SceneKey Loading Loading @@ -101,14 +103,14 @@ private fun SceneScope.QuickSettingsScene( modifier: Modifier = Modifier, ) { // TODO(b/280887232): implement the real UI. Box(modifier = modifier.fillMaxSize()) { val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() val collapsedHeaderHeight = with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier .fillMaxSize() Modifier.fillMaxSize() .clickable(onClick = { viewModel.onContentClicked() }) .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) ) { Loading Loading @@ -150,4 +152,10 @@ private fun SceneScope.QuickSettingsScene( QSSceneAdapter.State.QS ) } HeadsUpNotificationSpace( viewModel = viewModel.notifications, isPeekFromBottom = true, modifier = Modifier.padding(16.dp).fillMaxSize(), ) } }
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt +16 −2 Original line number Diff line number Diff line Loading @@ -17,15 +17,20 @@ package com.android.systemui.scene.ui.composable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier 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.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow Loading @@ -36,7 +41,11 @@ import kotlinx.coroutines.flow.asStateFlow * content from the scene framework. */ @SysUISingleton class GoneScene @Inject constructor() : ComposableScene { class GoneScene @Inject constructor( private val notificationsViewModel: NotificationsPlaceholderViewModel, ) : ComposableScene { override val key = SceneKey.Gone override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> = Loading @@ -56,6 +65,11 @@ class GoneScene @Inject constructor() : ComposableScene { override fun SceneScope.Content( modifier: Modifier, ) { Box(modifier = modifier) Box(modifier = modifier) { HeadsUpNotificationSpace( viewModel = notificationsViewModel, modifier = Modifier.padding(16.dp).fillMaxSize(), ) } } }
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt +2 −0 Original line number Diff line number Diff line Loading @@ -3,10 +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 fun TransitionBuilder.goneToShadeTransition() { spec = tween(durationMillis = 500) translate(Shade.rootElementKey, Edge.Top, true) fade(Notifications.Elements.NotificationScrim) }