Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +2 −1 Original line number Diff line number Diff line Loading @@ -173,7 +173,8 @@ constructor( val belowLockIconPlaceable = belowLockIconMeasurable.measure( noMinConstraints.copy( maxHeight = constraints.maxHeight - lockIconBounds.bottom maxHeight = (constraints.maxHeight - lockIconBounds.bottom).coerceAtLeast(0) ) ) val startShortcutPleaceable = startShortcutMeasurable.measure(noMinConstraints) Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt +186 −11 Original line number Diff line number Diff line Loading @@ -16,19 +16,42 @@ package com.android.systemui.keyguard.ui.composable.blueprint import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.material3.Text import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntRect import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope import com.android.compose.modifiers.padding import com.android.systemui.Flags import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.LockscreenLongPress 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.ClockSection import com.android.systemui.keyguard.ui.composable.section.LockSection 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.LockscreenContentViewModel import com.android.systemui.res.R import com.android.systemui.shade.LargeScreenHeaderHelper import dagger.Binds import dagger.Module import dagger.multibindings.IntoSet import java.util.Optional import javax.inject.Inject /** Loading @@ -39,22 +62,174 @@ class SplitShadeBlueprint @Inject constructor( private val viewModel: LockscreenContentViewModel, private val statusBarSection: StatusBarSection, private val clockSection: ClockSection, private val smartSpaceSection: SmartSpaceSection, private val notificationSection: NotificationSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val clockInteractor: KeyguardClockInteractor, private val largeScreenHeaderHelper: LargeScreenHeaderHelper, ) : LockscreenSceneBlueprint { override val id: String = "split-shade" @Composable override fun SceneScope.Content(modifier: Modifier) { val isUdfpsVisible = viewModel.isUdfpsVisible val burnIn = rememberBurnIn(clockInteractor) val resources = LocalContext.current.resources LockscreenLongPress( viewModel = viewModel.longPress, modifier = modifier, ) { _ -> Box(modifier.background(Color.Black)) { Text( text = "TODO(b/316211368): split shade blueprint", color = Color.White, modifier = Modifier.align(Alignment.Center), ) { onSettingsMenuPlaced -> Layout( content = { // Constrained to above the lock icon. Column( modifier = Modifier.fillMaxSize(), ) { with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) } Row( modifier = Modifier.fillMaxSize(), ) { Column( modifier = Modifier.fillMaxHeight().weight(weight = 1f), horizontalAlignment = Alignment.CenterHorizontally, ) { with(smartSpaceSection) { SmartSpace( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmartspaceTopChanged, modifier = Modifier.fillMaxWidth() .padding( top = { viewModel.getSmartSpacePaddingTop(resources) } ), ) } Spacer(modifier = Modifier.weight(weight = 1f)) with(clockSection) { LargeClock() } Spacer(modifier = Modifier.weight(weight = 1f)) } with(notificationSection) { val splitShadeTopMargin: Dp = if (Flags.centralizedStatusBarDimensRefactor()) { largeScreenHeaderHelper.getLargeScreenHeaderHeight().dp } else { dimensionResource( id = R.dimen.large_screen_shade_header_height ) } Notifications( modifier = Modifier.fillMaxHeight() .weight(weight = 1f) .padding(top = splitShadeTopMargin) ) } } if (!isUdfpsVisible && ambientIndicationSectionOptional.isPresent) { with(ambientIndicationSectionOptional.get()) { AmbientIndication(modifier = Modifier.fillMaxWidth()) } } } with(lockSection) { LockIcon() } // Aligned to bottom and constrained to below the lock icon. Column(modifier = Modifier.fillMaxWidth()) { if (isUdfpsVisible && ambientIndicationSectionOptional.isPresent) { with(ambientIndicationSectionOptional.get()) { AmbientIndication(modifier = Modifier.fillMaxWidth()) } } with(bottomAreaSection) { IndicationArea(modifier = Modifier.fillMaxWidth()) } } // Aligned to bottom and NOT constrained by the lock icon. with(bottomAreaSection) { Shortcut(isStart = true, applyPadding = true) Shortcut(isStart = false, applyPadding = true) } with(settingsMenuSection) { SettingsMenu(onSettingsMenuPlaced) } }, modifier = Modifier.fillMaxSize(), ) { measurables, constraints -> check(measurables.size == 6) val aboveLockIconMeasurable = measurables[0] val lockIconMeasurable = measurables[1] val belowLockIconMeasurable = measurables[2] val startShortcutMeasurable = measurables[3] val endShortcutMeasurable = measurables[4] val settingsMenuMeasurable = measurables[5] val noMinConstraints = constraints.copy( minWidth = 0, minHeight = 0, ) val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints) val lockIconBounds = IntRect( left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left], top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top], right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right], bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom], ) val aboveLockIconPlaceable = aboveLockIconMeasurable.measure( noMinConstraints.copy(maxHeight = lockIconBounds.top) ) val belowLockIconPlaceable = belowLockIconMeasurable.measure( noMinConstraints.copy( maxHeight = (constraints.maxHeight - lockIconBounds.bottom).coerceAtLeast(0) ) ) val startShortcutPleaceable = startShortcutMeasurable.measure(noMinConstraints) val endShortcutPleaceable = endShortcutMeasurable.measure(noMinConstraints) val settingsMenuPlaceable = settingsMenuMeasurable.measure(noMinConstraints) layout(constraints.maxWidth, constraints.maxHeight) { aboveLockIconPlaceable.place( x = 0, y = 0, ) lockIconPlaceable.place( x = lockIconBounds.left, y = lockIconBounds.top, ) belowLockIconPlaceable.place( x = 0, y = constraints.maxHeight - belowLockIconPlaceable.height, ) startShortcutPleaceable.place( x = 0, y = constraints.maxHeight - startShortcutPleaceable.height, ) endShortcutPleaceable.place( x = constraints.maxWidth - endShortcutPleaceable.width, y = constraints.maxHeight - endShortcutPleaceable.height, ) settingsMenuPlaceable.place( x = (constraints.maxWidth - settingsMenuPlaceable.width) / 2, y = constraints.maxHeight - settingsMenuPlaceable.height, ) } } } } Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt +28 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package com.android.systemui.keyguard.ui.composable.section import androidx.compose.foundation.layout.fillMaxWidth import android.view.ViewGroup import android.widget.FrameLayout import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect Loading Loading @@ -75,7 +76,13 @@ constructor( ) { content { AndroidView( factory = { checkNotNull(currentClock).smallClock.view }, factory = { context -> FrameLayout(context).apply { val newClockView = checkNotNull(currentClock).smallClock.view (newClockView.parent as? ViewGroup)?.removeView(newClockView) addView(newClockView) } }, modifier = Modifier.padding( horizontal = Loading @@ -83,6 +90,12 @@ constructor( ) .padding(top = { viewModel.getSmallClockTopMargin(view.context) }) .onTopPlacementChanged(onTopChanged), update = { val newClockView = checkNotNull(currentClock).smallClock.view it.removeAllViews() (newClockView.parent as? ViewGroup)?.removeView(newClockView) it.addView(newClockView) }, ) } } Loading Loading @@ -116,8 +129,19 @@ constructor( ) { content { AndroidView( factory = { checkNotNull(currentClock).largeClock.view }, modifier = Modifier.fillMaxWidth() factory = { context -> FrameLayout(context).apply { val newClockView = checkNotNull(currentClock).largeClock.view (newClockView.parent as? ViewGroup)?.removeView(newClockView) addView(newClockView) } }, update = { val newClockView = checkNotNull(currentClock).largeClock.view it.removeAllViews() (newClockView.parent as? ViewGroup)?.removeView(newClockView) it.addView(newClockView) }, ) } } Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +2 −1 Original line number Diff line number Diff line Loading @@ -173,7 +173,8 @@ constructor( val belowLockIconPlaceable = belowLockIconMeasurable.measure( noMinConstraints.copy( maxHeight = constraints.maxHeight - lockIconBounds.bottom maxHeight = (constraints.maxHeight - lockIconBounds.bottom).coerceAtLeast(0) ) ) val startShortcutPleaceable = startShortcutMeasurable.measure(noMinConstraints) Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt +186 −11 Original line number Diff line number Diff line Loading @@ -16,19 +16,42 @@ package com.android.systemui.keyguard.ui.composable.blueprint import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.material3.Text import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntRect import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope import com.android.compose.modifiers.padding import com.android.systemui.Flags import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.LockscreenLongPress 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.ClockSection import com.android.systemui.keyguard.ui.composable.section.LockSection 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.LockscreenContentViewModel import com.android.systemui.res.R import com.android.systemui.shade.LargeScreenHeaderHelper import dagger.Binds import dagger.Module import dagger.multibindings.IntoSet import java.util.Optional import javax.inject.Inject /** Loading @@ -39,22 +62,174 @@ class SplitShadeBlueprint @Inject constructor( private val viewModel: LockscreenContentViewModel, private val statusBarSection: StatusBarSection, private val clockSection: ClockSection, private val smartSpaceSection: SmartSpaceSection, private val notificationSection: NotificationSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val clockInteractor: KeyguardClockInteractor, private val largeScreenHeaderHelper: LargeScreenHeaderHelper, ) : LockscreenSceneBlueprint { override val id: String = "split-shade" @Composable override fun SceneScope.Content(modifier: Modifier) { val isUdfpsVisible = viewModel.isUdfpsVisible val burnIn = rememberBurnIn(clockInteractor) val resources = LocalContext.current.resources LockscreenLongPress( viewModel = viewModel.longPress, modifier = modifier, ) { _ -> Box(modifier.background(Color.Black)) { Text( text = "TODO(b/316211368): split shade blueprint", color = Color.White, modifier = Modifier.align(Alignment.Center), ) { onSettingsMenuPlaced -> Layout( content = { // Constrained to above the lock icon. Column( modifier = Modifier.fillMaxSize(), ) { with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) } Row( modifier = Modifier.fillMaxSize(), ) { Column( modifier = Modifier.fillMaxHeight().weight(weight = 1f), horizontalAlignment = Alignment.CenterHorizontally, ) { with(smartSpaceSection) { SmartSpace( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmartspaceTopChanged, modifier = Modifier.fillMaxWidth() .padding( top = { viewModel.getSmartSpacePaddingTop(resources) } ), ) } Spacer(modifier = Modifier.weight(weight = 1f)) with(clockSection) { LargeClock() } Spacer(modifier = Modifier.weight(weight = 1f)) } with(notificationSection) { val splitShadeTopMargin: Dp = if (Flags.centralizedStatusBarDimensRefactor()) { largeScreenHeaderHelper.getLargeScreenHeaderHeight().dp } else { dimensionResource( id = R.dimen.large_screen_shade_header_height ) } Notifications( modifier = Modifier.fillMaxHeight() .weight(weight = 1f) .padding(top = splitShadeTopMargin) ) } } if (!isUdfpsVisible && ambientIndicationSectionOptional.isPresent) { with(ambientIndicationSectionOptional.get()) { AmbientIndication(modifier = Modifier.fillMaxWidth()) } } } with(lockSection) { LockIcon() } // Aligned to bottom and constrained to below the lock icon. Column(modifier = Modifier.fillMaxWidth()) { if (isUdfpsVisible && ambientIndicationSectionOptional.isPresent) { with(ambientIndicationSectionOptional.get()) { AmbientIndication(modifier = Modifier.fillMaxWidth()) } } with(bottomAreaSection) { IndicationArea(modifier = Modifier.fillMaxWidth()) } } // Aligned to bottom and NOT constrained by the lock icon. with(bottomAreaSection) { Shortcut(isStart = true, applyPadding = true) Shortcut(isStart = false, applyPadding = true) } with(settingsMenuSection) { SettingsMenu(onSettingsMenuPlaced) } }, modifier = Modifier.fillMaxSize(), ) { measurables, constraints -> check(measurables.size == 6) val aboveLockIconMeasurable = measurables[0] val lockIconMeasurable = measurables[1] val belowLockIconMeasurable = measurables[2] val startShortcutMeasurable = measurables[3] val endShortcutMeasurable = measurables[4] val settingsMenuMeasurable = measurables[5] val noMinConstraints = constraints.copy( minWidth = 0, minHeight = 0, ) val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints) val lockIconBounds = IntRect( left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left], top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top], right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right], bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom], ) val aboveLockIconPlaceable = aboveLockIconMeasurable.measure( noMinConstraints.copy(maxHeight = lockIconBounds.top) ) val belowLockIconPlaceable = belowLockIconMeasurable.measure( noMinConstraints.copy( maxHeight = (constraints.maxHeight - lockIconBounds.bottom).coerceAtLeast(0) ) ) val startShortcutPleaceable = startShortcutMeasurable.measure(noMinConstraints) val endShortcutPleaceable = endShortcutMeasurable.measure(noMinConstraints) val settingsMenuPlaceable = settingsMenuMeasurable.measure(noMinConstraints) layout(constraints.maxWidth, constraints.maxHeight) { aboveLockIconPlaceable.place( x = 0, y = 0, ) lockIconPlaceable.place( x = lockIconBounds.left, y = lockIconBounds.top, ) belowLockIconPlaceable.place( x = 0, y = constraints.maxHeight - belowLockIconPlaceable.height, ) startShortcutPleaceable.place( x = 0, y = constraints.maxHeight - startShortcutPleaceable.height, ) endShortcutPleaceable.place( x = constraints.maxWidth - endShortcutPleaceable.width, y = constraints.maxHeight - endShortcutPleaceable.height, ) settingsMenuPlaceable.place( x = (constraints.maxWidth - settingsMenuPlaceable.width) / 2, y = constraints.maxHeight - settingsMenuPlaceable.height, ) } } } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt +28 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package com.android.systemui.keyguard.ui.composable.section import androidx.compose.foundation.layout.fillMaxWidth import android.view.ViewGroup import android.widget.FrameLayout import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect Loading Loading @@ -75,7 +76,13 @@ constructor( ) { content { AndroidView( factory = { checkNotNull(currentClock).smallClock.view }, factory = { context -> FrameLayout(context).apply { val newClockView = checkNotNull(currentClock).smallClock.view (newClockView.parent as? ViewGroup)?.removeView(newClockView) addView(newClockView) } }, modifier = Modifier.padding( horizontal = Loading @@ -83,6 +90,12 @@ constructor( ) .padding(top = { viewModel.getSmallClockTopMargin(view.context) }) .onTopPlacementChanged(onTopChanged), update = { val newClockView = checkNotNull(currentClock).smallClock.view it.removeAllViews() (newClockView.parent as? ViewGroup)?.removeView(newClockView) it.addView(newClockView) }, ) } } Loading Loading @@ -116,8 +129,19 @@ constructor( ) { content { AndroidView( factory = { checkNotNull(currentClock).largeClock.view }, modifier = Modifier.fillMaxWidth() factory = { context -> FrameLayout(context).apply { val newClockView = checkNotNull(currentClock).largeClock.view (newClockView.parent as? ViewGroup)?.removeView(newClockView) addView(newClockView) } }, update = { val newClockView = checkNotNull(currentClock).largeClock.view it.removeAllViews() (newClockView.parent as? ViewGroup)?.removeView(newClockView) it.addView(newClockView) }, ) } } Loading