Loading packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +22 −15 Original line number Diff line number Diff line Loading @@ -96,9 +96,7 @@ import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadi import com.android.systemui.res.R import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.session.ui.composable.rememberSession import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds Loading @@ -124,12 +122,6 @@ object Notifications { } } private val notificationsShadeContentKey: ContentKey get() = if (DualShade.isEnabled) Overlays.NotificationsShade else Scenes.Shade private val quickSettingsShadeContentKey: ContentKey get() = if (DualShade.isEnabled) Overlays.QuickSettingsShade else Scenes.QuickSettings /** * Adds the space where heads up notifications can appear in the scene. This should generally be the * entire size of the scene. Loading Loading @@ -270,7 +262,12 @@ fun ContentScope.ConstrainedNotificationStack( HeadsUpNotificationSpace( stackScrollView = stackScrollView, viewModel = viewModel, useHunBounds = { shouldUseLockscreenHunBounds(layoutState.transitionState) }, useHunBounds = { shouldUseLockscreenHunBounds( layoutState.transitionState, viewModel.quickSettingsShadeContentKey, ) }, modifier = Modifier.align(Alignment.TopCenter), ) NotificationStackCutoffGuideline( Loading Loading @@ -494,11 +491,11 @@ fun ContentScope.NotificationScrollingStack( if ( scrimOffset.value < 0 && (layoutState.isTransitioning( from = notificationsShadeContentKey, from = viewModel.notificationsShadeContentKey, to = Scenes.Gone, ) || layoutState.isTransitioning( from = notificationsShadeContentKey, from = viewModel.notificationsShadeContentKey, to = Scenes.Lockscreen, )) ) { Loading Loading @@ -527,6 +524,7 @@ fun ContentScope.NotificationScrollingStack( shouldAnimateScrimCornerRadius( layoutState, shouldPunchHoleBehindScrim, viewModel.notificationsShadeContentKey, ), ) .let { scrimRounding.value.toRoundedCornerShape(it) } Loading Loading @@ -613,7 +611,12 @@ fun ContentScope.NotificationScrollingStack( HeadsUpNotificationSpace( stackScrollView = stackScrollView, viewModel = viewModel, useHunBounds = { !shouldUseLockscreenHunBounds(layoutState.transitionState) }, useHunBounds = { !shouldUseLockscreenHunBounds( layoutState.transitionState, viewModel.quickSettingsShadeContentKey, ) }, modifier = Modifier.padding(top = stackTopPadding), ) } Loading Loading @@ -720,20 +723,24 @@ private fun shouldUseLockscreenStackBounds(state: TransitionState): Boolean { return state is TransitionState.Idle && state.isOnLockscreen() } private fun shouldUseLockscreenHunBounds(state: TransitionState): Boolean { private fun shouldUseLockscreenHunBounds( state: TransitionState, quickSettingsShade: ContentKey, ): Boolean { return when (state) { is TransitionState.Idle -> state.isOnLockscreen() is TransitionState.Transition -> state.isTransitioning(from = quickSettingsShadeContentKey, to = Scenes.Lockscreen) state.isTransitioning(from = quickSettingsShade, to = Scenes.Lockscreen) } } private fun shouldAnimateScrimCornerRadius( state: SceneTransitionLayoutState, shouldPunchHoleBehindScrim: Boolean, notificationsShade: ContentKey, ): Boolean { return shouldPunchHoleBehindScrim || state.isTransitioning(from = notificationsShadeContentKey, to = Scenes.Lockscreen) state.isTransitioning(from = notificationsShade, to = Scenes.Lockscreen) } private fun calculateCornerRadius( Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt +39 −2 Original line number Diff line number Diff line Loading @@ -16,15 +16,21 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import androidx.compose.runtime.getValue import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor Loading Loading @@ -63,6 +69,24 @@ constructor( tag = "NotificationsPlaceholderViewModel", ) { private val hydrator = Hydrator("NotificationsPlaceholderViewModel") /** The content key to use for the notification shade. */ val notificationsShadeContentKey: ContentKey by hydrator.hydratedStateOf( traceName = "notificationsShadeContentKey", initialValue = getNotificationsShadeContentKey(shadeInteractor.shadeMode.value), source = shadeInteractor.shadeMode.map { getNotificationsShadeContentKey(it) }, ) /** The content key to use for the quick settings shade. */ val quickSettingsShadeContentKey: ContentKey by hydrator.hydratedStateOf( traceName = "quickSettingsShadeContentKey", initialValue = getQuickSettingsShadeContentKey(shadeInteractor.shadeMode.value), source = shadeInteractor.shadeMode.map { getQuickSettingsShadeContentKey(it) }, ) /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */ val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES) Loading @@ -71,6 +95,8 @@ constructor( override suspend fun onActivated(): Nothing { coroutineScope { launch { hydrator.activate() } launch { shadeInteractor.isAnyExpanded .filter { it } Loading @@ -79,8 +105,7 @@ constructor( launch { sceneInteractor.transitionState .map { state -> state is ObservableTransitionState.Idle } .filter { it } .filter { it is ObservableTransitionState.Idle } .collect { headsUpNotificationInteractor.onTransitionIdle() } } } Loading Loading @@ -163,6 +188,18 @@ constructor( interactor.setAccessibilityScrollEventConsumer(consumer) } private fun getNotificationsShadeContentKey(shadeMode: ShadeMode): ContentKey { return if (shadeMode is ShadeMode.Dual) Overlays.NotificationsShade else Scenes.Shade } private fun getQuickSettingsShadeContentKey(shadeMode: ShadeMode): ContentKey { return when (shadeMode) { is ShadeMode.Single -> Scenes.QuickSettings is ShadeMode.Split -> Scenes.Shade is ShadeMode.Dual -> Overlays.QuickSettingsShade } } @AssistedFactory interface Factory { fun create(): NotificationsPlaceholderViewModel Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +22 −15 Original line number Diff line number Diff line Loading @@ -96,9 +96,7 @@ import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadi import com.android.systemui.res.R import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.session.ui.composable.rememberSession import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds Loading @@ -124,12 +122,6 @@ object Notifications { } } private val notificationsShadeContentKey: ContentKey get() = if (DualShade.isEnabled) Overlays.NotificationsShade else Scenes.Shade private val quickSettingsShadeContentKey: ContentKey get() = if (DualShade.isEnabled) Overlays.QuickSettingsShade else Scenes.QuickSettings /** * Adds the space where heads up notifications can appear in the scene. This should generally be the * entire size of the scene. Loading Loading @@ -270,7 +262,12 @@ fun ContentScope.ConstrainedNotificationStack( HeadsUpNotificationSpace( stackScrollView = stackScrollView, viewModel = viewModel, useHunBounds = { shouldUseLockscreenHunBounds(layoutState.transitionState) }, useHunBounds = { shouldUseLockscreenHunBounds( layoutState.transitionState, viewModel.quickSettingsShadeContentKey, ) }, modifier = Modifier.align(Alignment.TopCenter), ) NotificationStackCutoffGuideline( Loading Loading @@ -494,11 +491,11 @@ fun ContentScope.NotificationScrollingStack( if ( scrimOffset.value < 0 && (layoutState.isTransitioning( from = notificationsShadeContentKey, from = viewModel.notificationsShadeContentKey, to = Scenes.Gone, ) || layoutState.isTransitioning( from = notificationsShadeContentKey, from = viewModel.notificationsShadeContentKey, to = Scenes.Lockscreen, )) ) { Loading Loading @@ -527,6 +524,7 @@ fun ContentScope.NotificationScrollingStack( shouldAnimateScrimCornerRadius( layoutState, shouldPunchHoleBehindScrim, viewModel.notificationsShadeContentKey, ), ) .let { scrimRounding.value.toRoundedCornerShape(it) } Loading Loading @@ -613,7 +611,12 @@ fun ContentScope.NotificationScrollingStack( HeadsUpNotificationSpace( stackScrollView = stackScrollView, viewModel = viewModel, useHunBounds = { !shouldUseLockscreenHunBounds(layoutState.transitionState) }, useHunBounds = { !shouldUseLockscreenHunBounds( layoutState.transitionState, viewModel.quickSettingsShadeContentKey, ) }, modifier = Modifier.padding(top = stackTopPadding), ) } Loading Loading @@ -720,20 +723,24 @@ private fun shouldUseLockscreenStackBounds(state: TransitionState): Boolean { return state is TransitionState.Idle && state.isOnLockscreen() } private fun shouldUseLockscreenHunBounds(state: TransitionState): Boolean { private fun shouldUseLockscreenHunBounds( state: TransitionState, quickSettingsShade: ContentKey, ): Boolean { return when (state) { is TransitionState.Idle -> state.isOnLockscreen() is TransitionState.Transition -> state.isTransitioning(from = quickSettingsShadeContentKey, to = Scenes.Lockscreen) state.isTransitioning(from = quickSettingsShade, to = Scenes.Lockscreen) } } private fun shouldAnimateScrimCornerRadius( state: SceneTransitionLayoutState, shouldPunchHoleBehindScrim: Boolean, notificationsShade: ContentKey, ): Boolean { return shouldPunchHoleBehindScrim || state.isTransitioning(from = notificationsShadeContentKey, to = Scenes.Lockscreen) state.isTransitioning(from = notificationsShade, to = Scenes.Lockscreen) } private fun calculateCornerRadius( Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt +39 −2 Original line number Diff line number Diff line Loading @@ -16,15 +16,21 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import androidx.compose.runtime.getValue import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor Loading Loading @@ -63,6 +69,24 @@ constructor( tag = "NotificationsPlaceholderViewModel", ) { private val hydrator = Hydrator("NotificationsPlaceholderViewModel") /** The content key to use for the notification shade. */ val notificationsShadeContentKey: ContentKey by hydrator.hydratedStateOf( traceName = "notificationsShadeContentKey", initialValue = getNotificationsShadeContentKey(shadeInteractor.shadeMode.value), source = shadeInteractor.shadeMode.map { getNotificationsShadeContentKey(it) }, ) /** The content key to use for the quick settings shade. */ val quickSettingsShadeContentKey: ContentKey by hydrator.hydratedStateOf( traceName = "quickSettingsShadeContentKey", initialValue = getQuickSettingsShadeContentKey(shadeInteractor.shadeMode.value), source = shadeInteractor.shadeMode.map { getQuickSettingsShadeContentKey(it) }, ) /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */ val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES) Loading @@ -71,6 +95,8 @@ constructor( override suspend fun onActivated(): Nothing { coroutineScope { launch { hydrator.activate() } launch { shadeInteractor.isAnyExpanded .filter { it } Loading @@ -79,8 +105,7 @@ constructor( launch { sceneInteractor.transitionState .map { state -> state is ObservableTransitionState.Idle } .filter { it } .filter { it is ObservableTransitionState.Idle } .collect { headsUpNotificationInteractor.onTransitionIdle() } } } Loading Loading @@ -163,6 +188,18 @@ constructor( interactor.setAccessibilityScrollEventConsumer(consumer) } private fun getNotificationsShadeContentKey(shadeMode: ShadeMode): ContentKey { return if (shadeMode is ShadeMode.Dual) Overlays.NotificationsShade else Scenes.Shade } private fun getQuickSettingsShadeContentKey(shadeMode: ShadeMode): ContentKey { return when (shadeMode) { is ShadeMode.Single -> Scenes.QuickSettings is ShadeMode.Split -> Scenes.Shade is ShadeMode.Dual -> Overlays.QuickSettingsShade } } @AssistedFactory interface Factory { fun create(): NotificationsPlaceholderViewModel Loading