Loading packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt +6 −8 Original line number Diff line number Diff line Loading @@ -35,15 +35,14 @@ import com.android.compose.animation.scene.ContentScope import com.android.systemui.Flags import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection import com.android.systemui.communal.ui.compose.section.CommunalLockSection import com.android.systemui.communal.ui.compose.section.CommunalPopupSection import com.android.systemui.communal.ui.compose.section.HubOnboardingSection import com.android.systemui.communal.ui.view.layout.sections.CommunalAppWidgetSection import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.keyguard.ui.composable.element.IndicationAreaElement import com.android.systemui.keyguard.ui.composable.element.LockElement import com.android.systemui.keyguard.ui.composable.layout.LockIconAlignmentLines import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialogFactory import javax.inject.Inject Loading @@ -58,10 +57,9 @@ constructor( private val interactionHandler: SmartspaceInteractionHandler, private val communalSettingsInteractor: CommunalSettingsInteractor, private val dialogFactory: SystemUIDialogFactory, private val lockSection: LockSection, private val lockElement: LockElement, private val communalLockSection: CommunalLockSection, private val bottomAreaSection: BottomAreaSection, private val ambientStatusBarSection: AmbientStatusBarSection, private val indicationAreaElement: IndicationAreaElement, private val communalPopupSection: CommunalPopupSection, private val widgetSection: CommunalAppWidgetSection, private val hubOnboardingSection: HubOnboardingSection, Loading Loading @@ -91,14 +89,14 @@ constructor( LockIcon(modifier = Modifier.element(Communal.Elements.LockIcon)) } } else { with(lockSection) { with(lockElement) { LockIcon( overrideColor = MaterialTheme.colorScheme.onPrimaryContainer, modifier = Modifier.element(Communal.Elements.LockIcon), ) } } with(bottomAreaSection) { with(indicationAreaElement) { IndicationArea( Modifier.element(Communal.Elements.IndicationArea) .fillMaxWidth() Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt +2 −8 Original line number Diff line number Diff line Loading @@ -17,14 +17,8 @@ package com.android.systemui.keyguard.ui.composable import com.android.systemui.keyguard.ui.composable.blueprint.CommunalBlueprintModule import com.android.systemui.keyguard.ui.composable.section.OptionalSectionModule import com.android.systemui.keyguard.ui.composable.element.OptionalElementModule import dagger.Module @Module( includes = [ CommunalBlueprintModule::class, OptionalSectionModule::class, ], ) @Module(includes = [CommunalBlueprintModule::class, OptionalElementModule::class]) interface LockscreenSceneBlueprintModule packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +47 −35 Original line number Diff line number Diff line Loading @@ -23,16 +23,21 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.ContentScope import com.android.systemui.keyguard.ui.composable.LockscreenTouchHandling import com.android.systemui.keyguard.ui.composable.element.AmbientIndicationElement import com.android.systemui.keyguard.ui.composable.element.AodPromotedNotificationAreaElement import com.android.systemui.keyguard.ui.composable.element.DateAndWeatherElement import com.android.systemui.keyguard.ui.composable.element.HeadsUpNotificationsElement import com.android.systemui.keyguard.ui.composable.element.IndicationAreaElement import com.android.systemui.keyguard.ui.composable.element.LargeClockElement import com.android.systemui.keyguard.ui.composable.element.LockElement import com.android.systemui.keyguard.ui.composable.element.MediaCarouselElement import com.android.systemui.keyguard.ui.composable.element.NotificationElement import com.android.systemui.keyguard.ui.composable.element.SettingsMenuElement import com.android.systemui.keyguard.ui.composable.element.ShortcutElement import com.android.systemui.keyguard.ui.composable.element.SmallClockElement import com.android.systemui.keyguard.ui.composable.element.SmartSpaceElement import com.android.systemui.keyguard.ui.composable.element.StatusBarElement import com.android.systemui.keyguard.ui.composable.layout.LockscreenSceneLayout import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection import com.android.systemui.keyguard.ui.composable.section.NotificationSection import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection import com.android.systemui.keyguard.ui.composable.section.SmartSpaceSection import com.android.systemui.keyguard.ui.composable.section.StatusBarSection import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import java.util.Optional Loading @@ -45,16 +50,21 @@ import javax.inject.Inject class DefaultBlueprint @Inject constructor( private val statusBarSection: StatusBarSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val notificationSection: NotificationSection, private val clockSection: DefaultClockSection, private val statusBarElement: StatusBarElement, private val lockElement: LockElement, private val ambientIndicationElementOptional: Optional<AmbientIndicationElement>, private val shortcutElement: ShortcutElement, private val indicationAreaElement: IndicationAreaElement, private val settingsMenuElement: SettingsMenuElement, private val headsUpNotificationsElement: HeadsUpNotificationsElement, private val notificationsElement: NotificationElement, private val aodPromotedNotificationAreaElement: AodPromotedNotificationAreaElement, private val smallClockElement: SmallClockElement, private val largeClockElement: LargeClockElement, private val keyguardClockViewModel: KeyguardClockViewModel, private val smartSpaceSection: SmartSpaceSection, private val mediaSection: MediaCarouselSection, private val smartSpaceElement: SmartSpaceElement, private val dateAndWeatherElement: DateAndWeatherElement, private val mediaCarouselElement: MediaCarouselElement, ) : ComposableLockscreenSceneBlueprint { override val id: String = "default" Loading @@ -64,7 +74,7 @@ constructor( val isBypassEnabled = viewModel.isBypassEnabled if (isBypassEnabled) { with(notificationSection) { HeadsUpNotifications() } with(headsUpNotificationsElement) { HeadsUpNotifications() } } LockscreenTouchHandling( Loading @@ -76,10 +86,10 @@ constructor( LockscreenSceneLayout( viewModel = viewModel.layout, statusBar = { with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) } with(statusBarElement) { StatusBar(modifier = Modifier.fillMaxWidth()) } }, smallClock = { with(clockSection) { with(smallClockElement) { SmallClock( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmallClockTopChanged, Loading @@ -87,13 +97,13 @@ constructor( } }, largeClock = { with(clockSection) { LargeClock(burnInParams = burnIn.parameters) } with(largeClockElement) { LargeClock(burnInParams = burnIn.parameters) } }, dateAndWeather = { orientation -> with(smartSpaceSection) { DateAndWeather(orientation) } with(dateAndWeatherElement) { DateAndWeather(orientation) } }, smartSpace = { with(smartSpaceSection) { with(smartSpaceElement) { SmartSpace( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmartspaceTopChanged, Loading @@ -102,37 +112,39 @@ constructor( } }, media = { with(mediaSection) { with(mediaCarouselElement) { KeyguardMediaCarousel(isShadeLayoutWide = viewModel.isShadeLayoutWide) } }, notifications = { with(notificationSection) { Box(modifier = Modifier.fillMaxHeight()) { AodPromotedNotificationArea() with(aodPromotedNotificationAreaElement) { AodPromotedNotificationArea() } with(notificationsElement) { Notifications(areNotificationsVisible = true, burnInParams = null) } } }, lockIcon = { with(lockSection) { LockIcon() } }, lockIcon = { with(lockElement) { LockIcon() } }, startShortcut = { with(bottomAreaSection) { Shortcut(isStart = true, applyPadding = false) } with(shortcutElement) { Shortcut(isStart = true, applyPadding = false) } }, ambientIndication = { if (ambientIndicationSectionOptional.isPresent) { with(ambientIndicationSectionOptional.get()) { if (ambientIndicationElementOptional.isPresent) { with(ambientIndicationElementOptional.get()) { AmbientIndication(modifier = Modifier.fillMaxWidth()) } } }, bottomIndication = { with(bottomAreaSection) { IndicationArea(modifier = Modifier.fillMaxWidth()) } with(indicationAreaElement) { IndicationArea(modifier = Modifier.fillMaxWidth()) } }, endShortcut = { with(bottomAreaSection) { Shortcut(isStart = false, applyPadding = false) } with(shortcutElement) { Shortcut(isStart = false, applyPadding = false) } }, settingsMenu = { with(settingsMenuSection) { SettingsMenu(onPlaced = onSettingsMenuPlaced) } with(settingsMenuElement) { SettingsMenu(onPlaced = onSettingsMenuPlaced) } }, ) } Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/AmbientIndicationSection.kt→packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/AmbientIndicationElement.kt +3 −3 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -14,13 +14,13 @@ * limitations under the License. */ package com.android.systemui.keyguard.ui.composable.section package com.android.systemui.keyguard.ui.composable.element import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.ContentScope /** Defines interface for classes that can render the ambient indication area. */ interface AmbientIndicationSection { interface AmbientIndicationElement { @Composable fun ContentScope.AmbientIndication(modifier: Modifier) } packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt→packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/AodNotificationIconsElement.kt +108 −0 Original line number Diff line number Diff line Loading @@ -14,16 +14,12 @@ * limitations under the License. */ package com.android.systemui.keyguard.ui.composable.section package com.android.systemui.keyguard.ui.composable.element import android.view.ViewGroup import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition import androidx.compose.animation.core.MutableTransitionState import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect Loading @@ -34,112 +30,41 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn import com.android.systemui.keyguard.ui.composable.modifier.burnInAware import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.notifications.ui.composable.ConstrainedNotificationStack import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarIconViewBindingFailureTracker import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel import com.android.systemui.statusbar.notification.promoted.AODPromotedNotification import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi import com.android.systemui.statusbar.notification.promoted.ui.viewmodel.AODPromotedNotificationViewModel import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel import com.android.systemui.statusbar.phone.NotificationIconContainer import com.android.systemui.statusbar.ui.SystemBarUtilsState import com.android.systemui.util.ui.isAnimating import com.android.systemui.util.ui.stopAnimating import com.android.systemui.util.ui.value import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.launch @SysUISingleton class NotificationSection class AodNotificationIconsElement @Inject constructor( private val stackScrollView: Lazy<NotificationScrollView>, private val viewModelFactory: NotificationsPlaceholderViewModel.Factory, private val aodBurnInViewModel: AodBurnInViewModel, sharedNotificationContainer: SharedNotificationContainer, sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, stackScrollLayout: NotificationStackScrollLayout, sharedNotificationContainerBinder: SharedNotificationContainerBinder, private val keyguardRootViewModel: KeyguardRootViewModel, @ShadeDisplayAware private val configurationState: ConfigurationState, private val iconBindingFailureTracker: StatusBarIconViewBindingFailureTracker, private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore, private val aodPromotedNotificationViewModelFactory: AODPromotedNotificationViewModel.Factory, private val systemBarUtilsState: SystemBarUtilsState, private val keyguardClockViewModel: KeyguardClockViewModel, ) { init { // This scene container section moves the NSSL to the SharedNotificationContainer. // This also requires that SharedNotificationContainer gets moved to the // SceneWindowRootView by the SceneWindowRootViewBinder. Prior to Scene Container, // NSSL is moved into this container by the NotificationStackScrollLayoutSection. // Ensure stackScrollLayout is a child of sharedNotificationContainer. if (stackScrollLayout.parent != sharedNotificationContainer) { (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout) sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout) } sharedNotificationContainerBinder.bind( sharedNotificationContainer, sharedNotificationContainerViewModel, ) } @Composable fun AodPromotedNotificationArea(modifier: Modifier = Modifier) { if (!PromotedNotificationUi.isEnabled) { return } val isVisible by keyguardRootViewModel.isAodPromotedNotifVisible.collectAsStateWithLifecycle() val transitionState = remember { MutableTransitionState(isVisible.value) } LaunchedEffect(key1 = isVisible, key2 = transitionState.isIdle) { transitionState.targetState = isVisible.value if (isVisible.isAnimating && transitionState.isIdle) { isVisible.stopAnimating() } } val burnIn = rememberBurnIn(keyguardClockViewModel) AnimatedVisibility( visibleState = transitionState, enter = if (isVisible.isAnimating) fadeIn() else EnterTransition.None, exit = if (isVisible.isAnimating) fadeOut() else ExitTransition.None, modifier = modifier.burnInAware(aodBurnInViewModel, burnIn.parameters), ) { AODPromotedNotification( aodPromotedNotificationViewModelFactory, modifier = Modifier.sysuiResTag("aod_promoted_notification_frame"), ) } } @Composable fun AodNotificationIcons(modifier: Modifier = Modifier) { val isVisible by Loading Loading @@ -180,40 +105,4 @@ constructor( ) } } @Composable fun ContentScope.HeadsUpNotifications() { SnoozeableHeadsUpNotificationSpace( stackScrollView = stackScrollView.get(), viewModel = rememberViewModel("HeadsUpNotifications") { viewModelFactory.create() }, ) } /** * @param burnInParams params to make this view adaptive to burn-in, `null` to disable burn-in * adjustment */ @Composable fun ContentScope.Notifications( areNotificationsVisible: Boolean, burnInParams: BurnInParameters?, modifier: Modifier = Modifier, ) { if (!areNotificationsVisible) { return } ConstrainedNotificationStack( stackScrollView = stackScrollView.get(), viewModel = rememberViewModel("Notifications") { viewModelFactory.create() }, modifier = modifier.fillMaxWidth().let { if (burnInParams == null) { it } else { it.burnInAware(viewModel = aodBurnInViewModel, params = burnInParams) } }, ) } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt +6 −8 Original line number Diff line number Diff line Loading @@ -35,15 +35,14 @@ import com.android.compose.animation.scene.ContentScope import com.android.systemui.Flags import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection import com.android.systemui.communal.ui.compose.section.CommunalLockSection import com.android.systemui.communal.ui.compose.section.CommunalPopupSection import com.android.systemui.communal.ui.compose.section.HubOnboardingSection import com.android.systemui.communal.ui.view.layout.sections.CommunalAppWidgetSection import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.keyguard.ui.composable.element.IndicationAreaElement import com.android.systemui.keyguard.ui.composable.element.LockElement import com.android.systemui.keyguard.ui.composable.layout.LockIconAlignmentLines import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialogFactory import javax.inject.Inject Loading @@ -58,10 +57,9 @@ constructor( private val interactionHandler: SmartspaceInteractionHandler, private val communalSettingsInteractor: CommunalSettingsInteractor, private val dialogFactory: SystemUIDialogFactory, private val lockSection: LockSection, private val lockElement: LockElement, private val communalLockSection: CommunalLockSection, private val bottomAreaSection: BottomAreaSection, private val ambientStatusBarSection: AmbientStatusBarSection, private val indicationAreaElement: IndicationAreaElement, private val communalPopupSection: CommunalPopupSection, private val widgetSection: CommunalAppWidgetSection, private val hubOnboardingSection: HubOnboardingSection, Loading Loading @@ -91,14 +89,14 @@ constructor( LockIcon(modifier = Modifier.element(Communal.Elements.LockIcon)) } } else { with(lockSection) { with(lockElement) { LockIcon( overrideColor = MaterialTheme.colorScheme.onPrimaryContainer, modifier = Modifier.element(Communal.Elements.LockIcon), ) } } with(bottomAreaSection) { with(indicationAreaElement) { IndicationArea( Modifier.element(Communal.Elements.IndicationArea) .fillMaxWidth() Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt +2 −8 Original line number Diff line number Diff line Loading @@ -17,14 +17,8 @@ package com.android.systemui.keyguard.ui.composable import com.android.systemui.keyguard.ui.composable.blueprint.CommunalBlueprintModule import com.android.systemui.keyguard.ui.composable.section.OptionalSectionModule import com.android.systemui.keyguard.ui.composable.element.OptionalElementModule import dagger.Module @Module( includes = [ CommunalBlueprintModule::class, OptionalSectionModule::class, ], ) @Module(includes = [CommunalBlueprintModule::class, OptionalElementModule::class]) interface LockscreenSceneBlueprintModule
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +47 −35 Original line number Diff line number Diff line Loading @@ -23,16 +23,21 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.ContentScope import com.android.systemui.keyguard.ui.composable.LockscreenTouchHandling import com.android.systemui.keyguard.ui.composable.element.AmbientIndicationElement import com.android.systemui.keyguard.ui.composable.element.AodPromotedNotificationAreaElement import com.android.systemui.keyguard.ui.composable.element.DateAndWeatherElement import com.android.systemui.keyguard.ui.composable.element.HeadsUpNotificationsElement import com.android.systemui.keyguard.ui.composable.element.IndicationAreaElement import com.android.systemui.keyguard.ui.composable.element.LargeClockElement import com.android.systemui.keyguard.ui.composable.element.LockElement import com.android.systemui.keyguard.ui.composable.element.MediaCarouselElement import com.android.systemui.keyguard.ui.composable.element.NotificationElement import com.android.systemui.keyguard.ui.composable.element.SettingsMenuElement import com.android.systemui.keyguard.ui.composable.element.ShortcutElement import com.android.systemui.keyguard.ui.composable.element.SmallClockElement import com.android.systemui.keyguard.ui.composable.element.SmartSpaceElement import com.android.systemui.keyguard.ui.composable.element.StatusBarElement import com.android.systemui.keyguard.ui.composable.layout.LockscreenSceneLayout import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection import com.android.systemui.keyguard.ui.composable.section.NotificationSection import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection import com.android.systemui.keyguard.ui.composable.section.SmartSpaceSection import com.android.systemui.keyguard.ui.composable.section.StatusBarSection import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import java.util.Optional Loading @@ -45,16 +50,21 @@ import javax.inject.Inject class DefaultBlueprint @Inject constructor( private val statusBarSection: StatusBarSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val notificationSection: NotificationSection, private val clockSection: DefaultClockSection, private val statusBarElement: StatusBarElement, private val lockElement: LockElement, private val ambientIndicationElementOptional: Optional<AmbientIndicationElement>, private val shortcutElement: ShortcutElement, private val indicationAreaElement: IndicationAreaElement, private val settingsMenuElement: SettingsMenuElement, private val headsUpNotificationsElement: HeadsUpNotificationsElement, private val notificationsElement: NotificationElement, private val aodPromotedNotificationAreaElement: AodPromotedNotificationAreaElement, private val smallClockElement: SmallClockElement, private val largeClockElement: LargeClockElement, private val keyguardClockViewModel: KeyguardClockViewModel, private val smartSpaceSection: SmartSpaceSection, private val mediaSection: MediaCarouselSection, private val smartSpaceElement: SmartSpaceElement, private val dateAndWeatherElement: DateAndWeatherElement, private val mediaCarouselElement: MediaCarouselElement, ) : ComposableLockscreenSceneBlueprint { override val id: String = "default" Loading @@ -64,7 +74,7 @@ constructor( val isBypassEnabled = viewModel.isBypassEnabled if (isBypassEnabled) { with(notificationSection) { HeadsUpNotifications() } with(headsUpNotificationsElement) { HeadsUpNotifications() } } LockscreenTouchHandling( Loading @@ -76,10 +86,10 @@ constructor( LockscreenSceneLayout( viewModel = viewModel.layout, statusBar = { with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) } with(statusBarElement) { StatusBar(modifier = Modifier.fillMaxWidth()) } }, smallClock = { with(clockSection) { with(smallClockElement) { SmallClock( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmallClockTopChanged, Loading @@ -87,13 +97,13 @@ constructor( } }, largeClock = { with(clockSection) { LargeClock(burnInParams = burnIn.parameters) } with(largeClockElement) { LargeClock(burnInParams = burnIn.parameters) } }, dateAndWeather = { orientation -> with(smartSpaceSection) { DateAndWeather(orientation) } with(dateAndWeatherElement) { DateAndWeather(orientation) } }, smartSpace = { with(smartSpaceSection) { with(smartSpaceElement) { SmartSpace( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmartspaceTopChanged, Loading @@ -102,37 +112,39 @@ constructor( } }, media = { with(mediaSection) { with(mediaCarouselElement) { KeyguardMediaCarousel(isShadeLayoutWide = viewModel.isShadeLayoutWide) } }, notifications = { with(notificationSection) { Box(modifier = Modifier.fillMaxHeight()) { AodPromotedNotificationArea() with(aodPromotedNotificationAreaElement) { AodPromotedNotificationArea() } with(notificationsElement) { Notifications(areNotificationsVisible = true, burnInParams = null) } } }, lockIcon = { with(lockSection) { LockIcon() } }, lockIcon = { with(lockElement) { LockIcon() } }, startShortcut = { with(bottomAreaSection) { Shortcut(isStart = true, applyPadding = false) } with(shortcutElement) { Shortcut(isStart = true, applyPadding = false) } }, ambientIndication = { if (ambientIndicationSectionOptional.isPresent) { with(ambientIndicationSectionOptional.get()) { if (ambientIndicationElementOptional.isPresent) { with(ambientIndicationElementOptional.get()) { AmbientIndication(modifier = Modifier.fillMaxWidth()) } } }, bottomIndication = { with(bottomAreaSection) { IndicationArea(modifier = Modifier.fillMaxWidth()) } with(indicationAreaElement) { IndicationArea(modifier = Modifier.fillMaxWidth()) } }, endShortcut = { with(bottomAreaSection) { Shortcut(isStart = false, applyPadding = false) } with(shortcutElement) { Shortcut(isStart = false, applyPadding = false) } }, settingsMenu = { with(settingsMenuSection) { SettingsMenu(onPlaced = onSettingsMenuPlaced) } with(settingsMenuElement) { SettingsMenu(onPlaced = onSettingsMenuPlaced) } }, ) } Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/AmbientIndicationSection.kt→packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/AmbientIndicationElement.kt +3 −3 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -14,13 +14,13 @@ * limitations under the License. */ package com.android.systemui.keyguard.ui.composable.section package com.android.systemui.keyguard.ui.composable.element import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.ContentScope /** Defines interface for classes that can render the ambient indication area. */ interface AmbientIndicationSection { interface AmbientIndicationElement { @Composable fun ContentScope.AmbientIndication(modifier: Modifier) }
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt→packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/AodNotificationIconsElement.kt +108 −0 Original line number Diff line number Diff line Loading @@ -14,16 +14,12 @@ * limitations under the License. */ package com.android.systemui.keyguard.ui.composable.section package com.android.systemui.keyguard.ui.composable.element import android.view.ViewGroup import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition import androidx.compose.animation.core.MutableTransitionState import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect Loading @@ -34,112 +30,41 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn import com.android.systemui.keyguard.ui.composable.modifier.burnInAware import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.notifications.ui.composable.ConstrainedNotificationStack import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarIconViewBindingFailureTracker import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel import com.android.systemui.statusbar.notification.promoted.AODPromotedNotification import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi import com.android.systemui.statusbar.notification.promoted.ui.viewmodel.AODPromotedNotificationViewModel import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel import com.android.systemui.statusbar.phone.NotificationIconContainer import com.android.systemui.statusbar.ui.SystemBarUtilsState import com.android.systemui.util.ui.isAnimating import com.android.systemui.util.ui.stopAnimating import com.android.systemui.util.ui.value import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.launch @SysUISingleton class NotificationSection class AodNotificationIconsElement @Inject constructor( private val stackScrollView: Lazy<NotificationScrollView>, private val viewModelFactory: NotificationsPlaceholderViewModel.Factory, private val aodBurnInViewModel: AodBurnInViewModel, sharedNotificationContainer: SharedNotificationContainer, sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, stackScrollLayout: NotificationStackScrollLayout, sharedNotificationContainerBinder: SharedNotificationContainerBinder, private val keyguardRootViewModel: KeyguardRootViewModel, @ShadeDisplayAware private val configurationState: ConfigurationState, private val iconBindingFailureTracker: StatusBarIconViewBindingFailureTracker, private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore, private val aodPromotedNotificationViewModelFactory: AODPromotedNotificationViewModel.Factory, private val systemBarUtilsState: SystemBarUtilsState, private val keyguardClockViewModel: KeyguardClockViewModel, ) { init { // This scene container section moves the NSSL to the SharedNotificationContainer. // This also requires that SharedNotificationContainer gets moved to the // SceneWindowRootView by the SceneWindowRootViewBinder. Prior to Scene Container, // NSSL is moved into this container by the NotificationStackScrollLayoutSection. // Ensure stackScrollLayout is a child of sharedNotificationContainer. if (stackScrollLayout.parent != sharedNotificationContainer) { (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout) sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout) } sharedNotificationContainerBinder.bind( sharedNotificationContainer, sharedNotificationContainerViewModel, ) } @Composable fun AodPromotedNotificationArea(modifier: Modifier = Modifier) { if (!PromotedNotificationUi.isEnabled) { return } val isVisible by keyguardRootViewModel.isAodPromotedNotifVisible.collectAsStateWithLifecycle() val transitionState = remember { MutableTransitionState(isVisible.value) } LaunchedEffect(key1 = isVisible, key2 = transitionState.isIdle) { transitionState.targetState = isVisible.value if (isVisible.isAnimating && transitionState.isIdle) { isVisible.stopAnimating() } } val burnIn = rememberBurnIn(keyguardClockViewModel) AnimatedVisibility( visibleState = transitionState, enter = if (isVisible.isAnimating) fadeIn() else EnterTransition.None, exit = if (isVisible.isAnimating) fadeOut() else ExitTransition.None, modifier = modifier.burnInAware(aodBurnInViewModel, burnIn.parameters), ) { AODPromotedNotification( aodPromotedNotificationViewModelFactory, modifier = Modifier.sysuiResTag("aod_promoted_notification_frame"), ) } } @Composable fun AodNotificationIcons(modifier: Modifier = Modifier) { val isVisible by Loading Loading @@ -180,40 +105,4 @@ constructor( ) } } @Composable fun ContentScope.HeadsUpNotifications() { SnoozeableHeadsUpNotificationSpace( stackScrollView = stackScrollView.get(), viewModel = rememberViewModel("HeadsUpNotifications") { viewModelFactory.create() }, ) } /** * @param burnInParams params to make this view adaptive to burn-in, `null` to disable burn-in * adjustment */ @Composable fun ContentScope.Notifications( areNotificationsVisible: Boolean, burnInParams: BurnInParameters?, modifier: Modifier = Modifier, ) { if (!areNotificationsVisible) { return } ConstrainedNotificationStack( stackScrollView = stackScrollView.get(), viewModel = rememberViewModel("Notifications") { viewModelFactory.create() }, modifier = modifier.fillMaxWidth().let { if (burnInParams == null) { it } else { it.burnInAware(viewModel = aodBurnInViewModel, params = burnInParams) } }, ) } }