diff options
6 files changed, 98 insertions, 32 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt index 99f7d0f902a6..887e3494b49e 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt @@ -28,7 +28,6 @@ import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.blueprint.ComposableLockscreenSceneBlueprint import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel -import javax.inject.Inject /** * Renders the content of the lockscreen. diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt index cf2e895b044b..e6132c6a2a59 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt @@ -169,6 +169,7 @@ fun SceneScope.NotificationScrollingStack( viewModel: NotificationsPlaceholderViewModel, maxScrimTop: () -> Float, shouldPunchHoleBehindScrim: Boolean, + shouldFillMaxSize: Boolean = true, shadeMode: ShadeMode, modifier: Modifier = Modifier, ) { @@ -327,14 +328,14 @@ fun SceneScope.NotificationScrollingStack( } Box( modifier = - Modifier.fillMaxSize() - .graphicsLayer { + Modifier.graphicsLayer { alpha = if (shouldPunchHoleBehindScrim) { (expansionFraction / EXPANSION_FOR_MAX_SCRIM_ALPHA).coerceAtMost(1f) } else 1f } .background(MaterialTheme.colorScheme.surface) + .thenIf(shouldFillMaxSize) { Modifier.fillMaxSize() } .debugBackground(viewModel, DEBUG_BOX_COLOR) ) { NotificationPlaceholder( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt index e17a1464a71a..ae53d56e331a 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt @@ -17,21 +17,31 @@ package com.android.systemui.notifications.ui.composable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text +import androidx.compose.foundation.layout.width 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.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult +import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneViewModel +import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.ComposableScene +import com.android.systemui.shade.shared.model.ShadeMode +import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel +import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel +import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel +import com.android.systemui.statusbar.phone.ui.StatusBarIconController +import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject @@ -41,36 +51,53 @@ import kotlinx.coroutines.flow.StateFlow class NotificationsShadeScene @Inject constructor( - viewModel: NotificationsShadeSceneViewModel, + sceneViewModel: NotificationsShadeSceneViewModel, private val overlayShadeViewModel: OverlayShadeViewModel, + private val shadeHeaderViewModel: ShadeHeaderViewModel, + private val notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, + private val tintedIconManagerFactory: TintedIconManager.Factory, + private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, + private val statusBarIconController: StatusBarIconController, + private val shadeSession: SaveableSession, + private val stackScrollView: Lazy<NotificationScrollView>, private val lockscreenContent: Lazy<Optional<LockscreenContent>>, ) : ComposableScene { override val key = Scenes.NotificationsShade override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = - viewModel.destinationScenes + sceneViewModel.destinationScenes @Composable override fun SceneScope.Content( modifier: Modifier, ) { OverlayShade( - viewModel = overlayShadeViewModel, modifier = modifier, + viewModel = overlayShadeViewModel, horizontalArrangement = Arrangement.Start, lockscreenContent = lockscreenContent, ) { - Text( - text = "Notifications list", - modifier = Modifier.padding(NotificationsShade.Dimensions.Padding) - ) - } - } -} + Column { + ExpandedShadeHeader( + viewModel = shadeHeaderViewModel, + createTintedIconManager = tintedIconManagerFactory::create, + createBatteryMeterViewController = batteryMeterViewControllerFactory::create, + statusBarIconController = statusBarIconController, + modifier = Modifier.padding(horizontal = 16.dp), + ) -object NotificationsShade { - object Dimensions { - val Padding = 16.dp + NotificationScrollingStack( + shadeSession = shadeSession, + stackScrollView = stackScrollView.get(), + viewModel = notificationsPlaceholderViewModel, + maxScrimTop = { 0f }, + shouldPunchHoleBehindScrim = false, + shouldFillMaxSize = false, + shadeMode = ShadeMode.Dual, + modifier = Modifier.width(416.dp), + ) + } + } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt index 04f76f5d58ab..4d946bff63ca 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt @@ -33,9 +33,9 @@ import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import dagger.Lazy +import java.util.Optional import javax.inject.Inject import kotlinx.coroutines.flow.StateFlow -import java.util.Optional @SysUISingleton class QuickSettingsShadeScene diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt index 53c10a370868..fe16fc03ce40 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt @@ -49,11 +49,13 @@ constructor( sharedNotificationContainerInteractor: SharedNotificationContainerInteractor, shadeRepository: ShadeRepository, ) : BaseShadeInteractor { + override val shadeMode: StateFlow<ShadeMode> = shadeRepository.shadeMode + override val shadeExpansion: StateFlow<Float> = - sceneBasedExpansion(sceneInteractor, Scenes.Shade) + sceneBasedExpansion(sceneInteractor, notificationsScene) .stateIn(scope, SharingStarted.Eagerly, 0f) - private val sceneBasedQsExpansion = sceneBasedExpansion(sceneInteractor, Scenes.QuickSettings) + private val sceneBasedQsExpansion = sceneBasedExpansion(sceneInteractor, quickSettingsScene) override val qsExpansion: StateFlow<Float> = combine( @@ -81,7 +83,7 @@ constructor( when (state) { is ObservableTransitionState.Idle -> false is ObservableTransitionState.Transition -> - state.toScene == Scenes.QuickSettings && state.fromScene != Scenes.Shade + state.toScene == quickSettingsScene && state.fromScene != notificationsScene } } .distinctUntilChanged() @@ -90,7 +92,7 @@ constructor( sceneInteractor.transitionState .map { state -> when (state) { - is ObservableTransitionState.Idle -> state.currentScene == Scenes.QuickSettings + is ObservableTransitionState.Idle -> state.currentScene == quickSettingsScene is ObservableTransitionState.Transition -> false } } @@ -106,12 +108,10 @@ constructor( .stateIn(scope, SharingStarted.Eagerly, false) override val isUserInteractingWithShade: Flow<Boolean> = - sceneBasedInteracting(sceneInteractor, Scenes.Shade) + sceneBasedInteracting(sceneInteractor, notificationsScene) override val isUserInteractingWithQs: Flow<Boolean> = - sceneBasedInteracting(sceneInteractor, Scenes.QuickSettings) - - override val shadeMode: StateFlow<ShadeMode> = shadeRepository.shadeMode + sceneBasedInteracting(sceneInteractor, quickSettingsScene) /** * Returns a flow that uses scene transition progress to and from a scene that is pulled down @@ -154,4 +154,20 @@ constructor( } } .distinctUntilChanged() + + private val notificationsScene: SceneKey + get() = + if (shadeMode.value is ShadeMode.Dual) { + Scenes.NotificationsShade + } else { + Scenes.Shade + } + + private val quickSettingsScene: SceneKey + get() = + if (shadeMode.value is ShadeMode.Dual) { + Scenes.QuickSettingsShade + } else { + Scenes.QuickSettings + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt index 61373815db1c..c2ce1144fe1b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import com.android.compose.animation.scene.ObservableTransitionState +import com.android.compose.animation.scene.SceneKey import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor @@ -25,6 +26,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag 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.notification.stack.domain.interactor.NotificationStackAppearanceInteractor import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimClipping import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape @@ -34,6 +36,7 @@ import com.android.systemui.util.kotlin.FlowDumperImpl import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf @@ -73,16 +76,16 @@ constructor( } is ObservableTransitionState.Transition -> { if ( - (transitionState.fromScene == Scenes.Shade && - transitionState.toScene == Scenes.QuickSettings) || - (transitionState.fromScene == Scenes.QuickSettings && - transitionState.toScene == Scenes.Shade) + (transitionState.fromScene == notificationsScene && + transitionState.toScene == quickSettingsScene) || + (transitionState.fromScene == quickSettingsScene && + transitionState.toScene == notificationsScene) ) { 1f } else if ( (transitionState.fromScene == Scenes.Gone || transitionState.fromScene == Scenes.Lockscreen) && - transitionState.toScene == Scenes.QuickSettings + transitionState.toScene == quickSettingsScene ) { // during QS expansion, increase fraction at same rate as scrim alpha, // but start when scrim alpha is at EXPANSION_FOR_DELAYED_STACK_FADE_IN. @@ -152,7 +155,9 @@ constructor( /** Whether the notification stack is scrollable or not. */ val isScrollable: Flow<Boolean> = - sceneInteractor.currentScene.map { it == Scenes.Shade }.dumpWhileCollecting("isScrollable") + sceneInteractor.currentScene + .map { it == notificationsScene } + .dumpWhileCollecting("isScrollable") /** Whether the notification stack is displayed in doze mode. */ val isDozing: Flow<Boolean> by lazy { @@ -162,4 +167,22 @@ constructor( keyguardInteractor.get().isDozing.dumpWhileCollecting("isDozing") } } + + private val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode + + private val notificationsScene: SceneKey + get() = + if (shadeMode.value is ShadeMode.Dual) { + Scenes.NotificationsShade + } else { + Scenes.Shade + } + + private val quickSettingsScene: SceneKey + get() = + if (shadeMode.value is ShadeMode.Dual) { + Scenes.QuickSettingsShade + } else { + Scenes.QuickSettings + } } |