Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +31 −4 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ 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.ClockRegionElementProvider 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.element.MediaCarouselElement Loading @@ -40,8 +41,12 @@ import com.android.systemui.keyguard.ui.composable.modifier.burnInAware import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import com.android.systemui.log.LogBuffer import com.android.systemui.log.dagger.KeyguardBlueprintLog import com.android.systemui.plugins.clocks.LockscreenElementContext import com.android.systemui.plugins.clocks.LockscreenElementFactory import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockSmall import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceCards import java.util.Optional import javax.inject.Inject Loading @@ -63,7 +68,9 @@ constructor( private val notificationsElement: NotificationElement, private val aodPromotedNotificationAreaElement: AodPromotedNotificationAreaElement, private val smartspaceElementProvider: SmartspaceElementProvider, private val clockRegionElementProvider: ClockRegionElementProvider, private val mediaCarouselElement: MediaCarouselElement, @KeyguardBlueprintLog private val blueprintLog: LogBuffer, ) : ComposableLockscreenSceneBlueprint { override val id: String = "default" Loading @@ -72,12 +79,17 @@ constructor( override fun ContentScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) { val currentClock = keyguardClockViewModel.currentClock.collectAsStateWithLifecycle() val elementFactory = remember(currentClock, smartspaceElementProvider.elements) { LockscreenElementFactory.build { putAll -> remember( currentClock, smartspaceElementProvider.elements, clockRegionElementProvider.elements, ) { LockscreenElementFactory.build(blueprintLog) { putAll -> putAll(smartspaceElementProvider.elements) putAll(clockRegionElementProvider.elements) currentClock.value?.apply { putAll(largeClock.layout.elements) putAll(smallClock.layout.elements) putAll(largeClock.layout.elements) } } } Loading @@ -87,7 +99,22 @@ constructor( LockscreenElementContext( scope = this, burnInModifier = Modifier.burnInAware(viewModel = aodBurnInViewModel, params = burnIn.parameters), Modifier.burnInAware( viewModel = aodBurnInViewModel, params = burnIn.parameters, ), onElementPositioned = { key, rect -> when (key) { ClockSmall -> { burnIn.onSmallClockTopChanged(rect.top) viewModel.setSmallClockBottom(rect.bottom) } SmartspaceCards -> { burnIn.onSmartspaceTopChanged(rect.top) viewModel.setSmartspaceCardBottom(rect.bottom) } } }, ) LockscreenTouchHandling( Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/ClockRegionElementProvider.kt 0 → 100644 +144 −0 Original line number Diff line number Diff line /* * 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.keyguard.ui.composable.element import android.content.Context import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.padding import com.android.systemui.customization.clocks.R as clocksR import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.plugins.clocks.LockscreenElement import com.android.systemui.plugins.clocks.LockscreenElementContext import com.android.systemui.plugins.clocks.LockscreenElementFactory import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockLarge import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockRegionLarge import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockRegionSmall import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockSmall import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceCards import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateSmallClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherSmallClock import com.android.systemui.plugins.clocks.LockscreenElementProvider import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject /** Provides default clock regions, if not overridden by the clock itself */ class ClockRegionElementProvider @Inject constructor( @ShadeDisplayAware private val context: Context, private val keyguardClockViewModel: KeyguardClockViewModel, ) : LockscreenElementProvider { override val elements by lazy { listOf(smallClockRegionElement, largeClockRegionElement) } private val smallClockRegionElement = object : LockscreenElement { override val key = ClockRegionSmall override val context = this@ClockRegionElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { val shouldDateWeatherBeBelowSmallClock: Boolean by keyguardClockViewModel.shouldDateWeatherBeBelowSmallClock .collectAsStateWithLifecycle() val paddingModifier = Modifier.padding( horizontal = dimensionResource(clocksR.dimen.clock_padding_start) ) Column { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically, modifier = paddingModifier, ) { factory.lockscreenElement(ClockSmall, context) if (!shouldDateWeatherBeBelowSmallClock) { Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(4.dp), modifier = context.burnInModifier, ) { factory.lockscreenElement(SmartspaceDateSmallClock, context) factory.lockscreenElement(SmartspaceWeatherSmallClock, context) } } } if (shouldDateWeatherBeBelowSmallClock) { Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, modifier = paddingModifier.then(context.burnInModifier), ) { factory.lockscreenElement(SmartspaceDateSmallClock, context) factory.lockscreenElement(SmartspaceWeatherSmallClock, context) } } factory.lockscreenElement(SmartspaceCards, context) } } } private val largeClockRegionElement = object : LockscreenElement { override val key = ClockRegionLarge override val context = this@ClockRegionElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically), ) { factory.lockscreenElement(SmartspaceCards, context) factory.lockscreenElement(ClockLarge, context) // TODO(b/432451019): This ends up with 0 height and doesn't render Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, modifier = context.burnInModifier, ) { factory.lockscreenElement(SmartspaceDateLargeClock, context) factory.lockscreenElement(SmartspaceWeatherLargeClock, context) } } } } } packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/SmartspaceElementProvider.kt +70 −140 Original line number Diff line number Diff line Loading @@ -17,21 +17,18 @@ package com.android.systemui.keyguard.ui.composable.element import android.content.Context import android.view.View import android.widget.FrameLayout import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row 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.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.modifiers.padding import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel Loading @@ -39,7 +36,11 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.plugins.clocks.LockscreenElement import com.android.systemui.plugins.clocks.LockscreenElementContext import com.android.systemui.plugins.clocks.LockscreenElementFactory import com.android.systemui.plugins.clocks.LockscreenElementKeys import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceCards import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateSmallClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherSmallClock import com.android.systemui.plugins.clocks.LockscreenElementProvider import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware Loading @@ -50,24 +51,25 @@ class SmartspaceElementProvider @Inject constructor( @ShadeDisplayAware private val context: Context, private val lockscreenSmartspaceController: LockscreenSmartspaceController, private val smartspaceController: LockscreenSmartspaceController, private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController, private val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel, private val aodBurnInViewModel: AodBurnInViewModel, ) : LockscreenElementProvider { override val elements by lazy { listOf( dateElement, weatherElement, dateAndWeatherVerticalElement, dateAndWeatherHorizontalElement, DateElement(SmartspaceDateLargeClock, isLargeClock = true), DateElement(SmartspaceDateSmallClock, isLargeClock = false), WeatherElement(SmartspaceWeatherLargeClock, isLargeClock = true), WeatherElement(SmartspaceWeatherSmallClock, isLargeClock = false), cardsElement, ) } private val dateElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceDate private inner class DateElement( override val key: ElementKey, private val isLargeClock: Boolean, ) : LockscreenElement { override val context = this@SmartspaceElementProvider.context @Composable Loading @@ -75,25 +77,23 @@ constructor( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { val isVisible = keyguardSmartspaceViewModel.isDateVisible.collectAsStateWithLifecycle() if (!isVisible.value || !keyguardSmartspaceViewModel.isSmartspaceEnabled) { val isDateEnabled = keyguardSmartspaceViewModel.isDateEnabled if (!keyguardSmartspaceViewModel.isSmartspaceEnabled || !isDateEnabled) { return } AndroidView( factory = { context -> wrapView(context) { frame -> lockscreenSmartspaceController.buildAndConnectDateView(frame, false) } factory = { ctx -> smartspaceController.buildAndConnectDateView(ctx, isLargeClock)!! } ) } } private val weatherElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceWeather private inner class WeatherElement( override val key: ElementKey, private val isLargeClock: Boolean, ) : LockscreenElement { override val context = this@SmartspaceElementProvider.context @Composable Loading @@ -101,65 +101,23 @@ constructor( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { val isVisible = keyguardSmartspaceViewModel.isWeatherVisible.collectAsStateWithLifecycle() if (!isVisible.value || !keyguardSmartspaceViewModel.isSmartspaceEnabled) { val isWeatherEnabled: Boolean by keyguardSmartspaceViewModel.isWeatherEnabled.collectAsStateWithLifecycle(false) if (!keyguardSmartspaceViewModel.isSmartspaceEnabled || !isWeatherEnabled) { return } AndroidView( factory = { context -> wrapView(context) { frame -> lockscreenSmartspaceController.buildAndConnectWeatherView(frame, false) } factory = { ctx -> smartspaceController.buildAndConnectWeatherView(ctx, isLargeClock)!! } ) } } private val dateAndWeatherHorizontalElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceDateWeatherHorizontal override val context = this@SmartspaceElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { factory.lockscreenElement(LockscreenElementKeys.SmartspaceDate, context) factory.lockscreenElement(LockscreenElementKeys.SmartspaceWeather, context) } } } private val dateAndWeatherVerticalElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceDateWeatherVertical override val context = this@SmartspaceElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(4.dp), ) { factory.lockscreenElement(LockscreenElementKeys.SmartspaceDate, context) factory.lockscreenElement(LockscreenElementKeys.SmartspaceWeather, context) } } } private val cardsElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceCards override val key = SmartspaceCards override val context = this@SmartspaceElementProvider.context @Composable Loading @@ -171,55 +129,27 @@ constructor( return } // TODO(b/432451019): Reserve card space even if no cards are currently visible // TODO(b/432451019): Placement/positional modifiers need an implementation Column( modifier = Modifier // .onTopPlacementChanged(onTopChanged) .padding( // top = { smartSpacePaddingTop(LocalResources.current) }, bottom = dimensionResource(R.dimen.keyguard_status_view_bottom_margin) ) ) { AndroidView( factory = { context -> wrapView(context) { frame -> val view = lockscreenSmartspaceController.buildAndConnectView(frame) factory = { ctx -> val view = smartspaceController.buildAndConnectView(ctx)!! keyguardUnlockAnimationController.lockscreenSmartspace = view view } }, onRelease = { onRelease = { view -> if (keyguardUnlockAnimationController.lockscreenSmartspace == view) { keyguardUnlockAnimationController.lockscreenSmartspace = null } }, modifier = Modifier.fillMaxWidth() .padding( horizontal = dimensionResource(R.dimen.below_clock_padding_end) // Note: smartspace adds 16dp of start padding internally start = 12.dp, bottom = dimensionResource(R.dimen.keyguard_status_view_bottom_margin), ) .then(context.burnInModifier), // .onGloballyPositioned { coordinates -> // onBottomChanged?.invoke(coordinates.boundsInWindow().bottom) // }, ) } } } companion object { private fun wrapView(context: Context, builder: (FrameLayout) -> View?): View { return FrameLayout(context).apply { builder(this)?.let { view -> view.layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, ) addView(view) } } } } } packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/layout/LockscreenSceneLayout.kt +40 −167 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/customization/clocks/common/src/com/android/systemui/customization/clocks/DefaultClockFaceLayout.kt +1 −10 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView Loading Loading @@ -80,20 +79,12 @@ open class DefaultClockFaceLayout(val view: View) : ClockFaceLayout { // } val topMargin = 0.dp // TODO(b/432451019): Placement/positional modifiers need an implementation clockView( view = view, modifier = Modifier.height(dimensionResource(clocksR.dimen.small_clock_height)) .padding( horizontal = dimensionResource(clocksR.dimen.clock_padding_start) ) .padding(top = topMargin) // .onTopPlacementChanged(onTopChanged) .then(context.burnInModifier) .onGloballyPositioned { coordinates -> // onBottomChanged?.invoke(coordinates.boundsInWindow().bottom) }, .then(context.burnInModifier), ) } } Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +31 −4 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ 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.ClockRegionElementProvider 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.element.MediaCarouselElement Loading @@ -40,8 +41,12 @@ import com.android.systemui.keyguard.ui.composable.modifier.burnInAware import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import com.android.systemui.log.LogBuffer import com.android.systemui.log.dagger.KeyguardBlueprintLog import com.android.systemui.plugins.clocks.LockscreenElementContext import com.android.systemui.plugins.clocks.LockscreenElementFactory import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockSmall import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceCards import java.util.Optional import javax.inject.Inject Loading @@ -63,7 +68,9 @@ constructor( private val notificationsElement: NotificationElement, private val aodPromotedNotificationAreaElement: AodPromotedNotificationAreaElement, private val smartspaceElementProvider: SmartspaceElementProvider, private val clockRegionElementProvider: ClockRegionElementProvider, private val mediaCarouselElement: MediaCarouselElement, @KeyguardBlueprintLog private val blueprintLog: LogBuffer, ) : ComposableLockscreenSceneBlueprint { override val id: String = "default" Loading @@ -72,12 +79,17 @@ constructor( override fun ContentScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) { val currentClock = keyguardClockViewModel.currentClock.collectAsStateWithLifecycle() val elementFactory = remember(currentClock, smartspaceElementProvider.elements) { LockscreenElementFactory.build { putAll -> remember( currentClock, smartspaceElementProvider.elements, clockRegionElementProvider.elements, ) { LockscreenElementFactory.build(blueprintLog) { putAll -> putAll(smartspaceElementProvider.elements) putAll(clockRegionElementProvider.elements) currentClock.value?.apply { putAll(largeClock.layout.elements) putAll(smallClock.layout.elements) putAll(largeClock.layout.elements) } } } Loading @@ -87,7 +99,22 @@ constructor( LockscreenElementContext( scope = this, burnInModifier = Modifier.burnInAware(viewModel = aodBurnInViewModel, params = burnIn.parameters), Modifier.burnInAware( viewModel = aodBurnInViewModel, params = burnIn.parameters, ), onElementPositioned = { key, rect -> when (key) { ClockSmall -> { burnIn.onSmallClockTopChanged(rect.top) viewModel.setSmallClockBottom(rect.bottom) } SmartspaceCards -> { burnIn.onSmartspaceTopChanged(rect.top) viewModel.setSmartspaceCardBottom(rect.bottom) } } }, ) LockscreenTouchHandling( Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/ClockRegionElementProvider.kt 0 → 100644 +144 −0 Original line number Diff line number Diff line /* * 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.keyguard.ui.composable.element import android.content.Context import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.padding import com.android.systemui.customization.clocks.R as clocksR import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.plugins.clocks.LockscreenElement import com.android.systemui.plugins.clocks.LockscreenElementContext import com.android.systemui.plugins.clocks.LockscreenElementFactory import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockLarge import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockRegionLarge import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockRegionSmall import com.android.systemui.plugins.clocks.LockscreenElementKeys.ClockSmall import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceCards import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateSmallClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherSmallClock import com.android.systemui.plugins.clocks.LockscreenElementProvider import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject /** Provides default clock regions, if not overridden by the clock itself */ class ClockRegionElementProvider @Inject constructor( @ShadeDisplayAware private val context: Context, private val keyguardClockViewModel: KeyguardClockViewModel, ) : LockscreenElementProvider { override val elements by lazy { listOf(smallClockRegionElement, largeClockRegionElement) } private val smallClockRegionElement = object : LockscreenElement { override val key = ClockRegionSmall override val context = this@ClockRegionElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { val shouldDateWeatherBeBelowSmallClock: Boolean by keyguardClockViewModel.shouldDateWeatherBeBelowSmallClock .collectAsStateWithLifecycle() val paddingModifier = Modifier.padding( horizontal = dimensionResource(clocksR.dimen.clock_padding_start) ) Column { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically, modifier = paddingModifier, ) { factory.lockscreenElement(ClockSmall, context) if (!shouldDateWeatherBeBelowSmallClock) { Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(4.dp), modifier = context.burnInModifier, ) { factory.lockscreenElement(SmartspaceDateSmallClock, context) factory.lockscreenElement(SmartspaceWeatherSmallClock, context) } } } if (shouldDateWeatherBeBelowSmallClock) { Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, modifier = paddingModifier.then(context.burnInModifier), ) { factory.lockscreenElement(SmartspaceDateSmallClock, context) factory.lockscreenElement(SmartspaceWeatherSmallClock, context) } } factory.lockscreenElement(SmartspaceCards, context) } } } private val largeClockRegionElement = object : LockscreenElement { override val key = ClockRegionLarge override val context = this@ClockRegionElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically), ) { factory.lockscreenElement(SmartspaceCards, context) factory.lockscreenElement(ClockLarge, context) // TODO(b/432451019): This ends up with 0 height and doesn't render Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, modifier = context.burnInModifier, ) { factory.lockscreenElement(SmartspaceDateLargeClock, context) factory.lockscreenElement(SmartspaceWeatherLargeClock, context) } } } } }
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/element/SmartspaceElementProvider.kt +70 −140 Original line number Diff line number Diff line Loading @@ -17,21 +17,18 @@ package com.android.systemui.keyguard.ui.composable.element import android.content.Context import android.view.View import android.widget.FrameLayout import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row 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.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.modifiers.padding import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel Loading @@ -39,7 +36,11 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.plugins.clocks.LockscreenElement import com.android.systemui.plugins.clocks.LockscreenElementContext import com.android.systemui.plugins.clocks.LockscreenElementFactory import com.android.systemui.plugins.clocks.LockscreenElementKeys import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceCards import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceDateSmallClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherLargeClock import com.android.systemui.plugins.clocks.LockscreenElementKeys.SmartspaceWeatherSmallClock import com.android.systemui.plugins.clocks.LockscreenElementProvider import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware Loading @@ -50,24 +51,25 @@ class SmartspaceElementProvider @Inject constructor( @ShadeDisplayAware private val context: Context, private val lockscreenSmartspaceController: LockscreenSmartspaceController, private val smartspaceController: LockscreenSmartspaceController, private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController, private val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel, private val aodBurnInViewModel: AodBurnInViewModel, ) : LockscreenElementProvider { override val elements by lazy { listOf( dateElement, weatherElement, dateAndWeatherVerticalElement, dateAndWeatherHorizontalElement, DateElement(SmartspaceDateLargeClock, isLargeClock = true), DateElement(SmartspaceDateSmallClock, isLargeClock = false), WeatherElement(SmartspaceWeatherLargeClock, isLargeClock = true), WeatherElement(SmartspaceWeatherSmallClock, isLargeClock = false), cardsElement, ) } private val dateElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceDate private inner class DateElement( override val key: ElementKey, private val isLargeClock: Boolean, ) : LockscreenElement { override val context = this@SmartspaceElementProvider.context @Composable Loading @@ -75,25 +77,23 @@ constructor( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { val isVisible = keyguardSmartspaceViewModel.isDateVisible.collectAsStateWithLifecycle() if (!isVisible.value || !keyguardSmartspaceViewModel.isSmartspaceEnabled) { val isDateEnabled = keyguardSmartspaceViewModel.isDateEnabled if (!keyguardSmartspaceViewModel.isSmartspaceEnabled || !isDateEnabled) { return } AndroidView( factory = { context -> wrapView(context) { frame -> lockscreenSmartspaceController.buildAndConnectDateView(frame, false) } factory = { ctx -> smartspaceController.buildAndConnectDateView(ctx, isLargeClock)!! } ) } } private val weatherElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceWeather private inner class WeatherElement( override val key: ElementKey, private val isLargeClock: Boolean, ) : LockscreenElement { override val context = this@SmartspaceElementProvider.context @Composable Loading @@ -101,65 +101,23 @@ constructor( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { val isVisible = keyguardSmartspaceViewModel.isWeatherVisible.collectAsStateWithLifecycle() if (!isVisible.value || !keyguardSmartspaceViewModel.isSmartspaceEnabled) { val isWeatherEnabled: Boolean by keyguardSmartspaceViewModel.isWeatherEnabled.collectAsStateWithLifecycle(false) if (!keyguardSmartspaceViewModel.isSmartspaceEnabled || !isWeatherEnabled) { return } AndroidView( factory = { context -> wrapView(context) { frame -> lockscreenSmartspaceController.buildAndConnectWeatherView(frame, false) } factory = { ctx -> smartspaceController.buildAndConnectWeatherView(ctx, isLargeClock)!! } ) } } private val dateAndWeatherHorizontalElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceDateWeatherHorizontal override val context = this@SmartspaceElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { factory.lockscreenElement(LockscreenElementKeys.SmartspaceDate, context) factory.lockscreenElement(LockscreenElementKeys.SmartspaceWeather, context) } } } private val dateAndWeatherVerticalElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceDateWeatherVertical override val context = this@SmartspaceElementProvider.context @Composable override fun ContentScope.LockscreenElement( factory: LockscreenElementFactory, context: LockscreenElementContext, ) { Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(4.dp), ) { factory.lockscreenElement(LockscreenElementKeys.SmartspaceDate, context) factory.lockscreenElement(LockscreenElementKeys.SmartspaceWeather, context) } } } private val cardsElement = object : LockscreenElement { override val key = LockscreenElementKeys.SmartspaceCards override val key = SmartspaceCards override val context = this@SmartspaceElementProvider.context @Composable Loading @@ -171,55 +129,27 @@ constructor( return } // TODO(b/432451019): Reserve card space even if no cards are currently visible // TODO(b/432451019): Placement/positional modifiers need an implementation Column( modifier = Modifier // .onTopPlacementChanged(onTopChanged) .padding( // top = { smartSpacePaddingTop(LocalResources.current) }, bottom = dimensionResource(R.dimen.keyguard_status_view_bottom_margin) ) ) { AndroidView( factory = { context -> wrapView(context) { frame -> val view = lockscreenSmartspaceController.buildAndConnectView(frame) factory = { ctx -> val view = smartspaceController.buildAndConnectView(ctx)!! keyguardUnlockAnimationController.lockscreenSmartspace = view view } }, onRelease = { onRelease = { view -> if (keyguardUnlockAnimationController.lockscreenSmartspace == view) { keyguardUnlockAnimationController.lockscreenSmartspace = null } }, modifier = Modifier.fillMaxWidth() .padding( horizontal = dimensionResource(R.dimen.below_clock_padding_end) // Note: smartspace adds 16dp of start padding internally start = 12.dp, bottom = dimensionResource(R.dimen.keyguard_status_view_bottom_margin), ) .then(context.burnInModifier), // .onGloballyPositioned { coordinates -> // onBottomChanged?.invoke(coordinates.boundsInWindow().bottom) // }, ) } } } companion object { private fun wrapView(context: Context, builder: (FrameLayout) -> View?): View { return FrameLayout(context).apply { builder(this)?.let { view -> view.layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, ) addView(view) } } } } }
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/layout/LockscreenSceneLayout.kt +40 −167 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/customization/clocks/common/src/com/android/systemui/customization/clocks/DefaultClockFaceLayout.kt +1 −10 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView Loading Loading @@ -80,20 +79,12 @@ open class DefaultClockFaceLayout(val view: View) : ClockFaceLayout { // } val topMargin = 0.dp // TODO(b/432451019): Placement/positional modifiers need an implementation clockView( view = view, modifier = Modifier.height(dimensionResource(clocksR.dimen.small_clock_height)) .padding( horizontal = dimensionResource(clocksR.dimen.clock_padding_start) ) .padding(top = topMargin) // .onTopPlacementChanged(onTopChanged) .then(context.burnInModifier) .onGloballyPositioned { coordinates -> // onBottomChanged?.invoke(coordinates.boundsInWindow().bottom) }, .then(context.burnInModifier), ) } } Loading