Fall back to above large clock date weather if space is tight
When font and display sizes are large, there is
not much space below large clock to display
date and weather. We should fall back to the
prior behavior of date weather above large clock
in this case.
Additionally special-cased the metro and
number-overlap clocks because metro large clock
is quite tall, and number-overlap has a lot of
extra internal padding around it.
Wallpaper picker has been updated for these
scenarios.
Bug: 419171516
Bug: 419262872
Test: atest KeyguardClockViewModelTest.kt
Flag: com.android.systemui.shared.clock_reactive_smartspace_layout
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:dbdba307cdc7bbfe73f0c04ea15eefc6c71db72a)
Merged-In: Iada0345ce3d22728861143780231e3d38eaa23c3
Change-Id: Iada0345ce3d22728861143780231e3d38eaa23c3
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt
index b1e2c2f..707e64c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt
@@ -70,6 +70,7 @@
private val clockShouldBeCentered = MutableStateFlow(false)
private val hasCustomWeatherDataDisplay = MutableStateFlow(false)
private val shouldDateWeatherBeBelowSmallClock = MutableStateFlow(true)
+ private val shouldDateWeatherBeBelowLargeClock = MutableStateFlow(true)
private val isWeatherVisibleFlow = MutableStateFlow(false)
private val isShadeLayoutWide = MutableStateFlow(false)
private val isLargeClockVisible = MutableStateFlow(true)
@@ -100,6 +101,8 @@
whenever(keyguardClockViewModel.isLargeClockVisible).thenReturn(isLargeClockVisible)
whenever(keyguardClockViewModel.shouldDateWeatherBeBelowSmallClock)
.thenReturn(shouldDateWeatherBeBelowSmallClock)
+ whenever(keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock)
+ .thenReturn(shouldDateWeatherBeBelowLargeClock)
whenever(keyguardClockViewModel.clockShouldBeCentered).thenReturn(clockShouldBeCentered)
whenever(keyguardSmartspaceViewModel.isSmartspaceEnabled).thenReturn(true)
whenever(keyguardSmartspaceViewModel.isWeatherVisible).thenReturn(isWeatherVisibleFlow)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
index 92f2a5c..013bf9c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
@@ -285,6 +285,15 @@
}
@Test
+ @DisableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
+ fun dateWeatherBelowLargeClock_smartspacelayoutflag_off_false() =
+ testScope.runTest {
+ val result by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+
+ assertThat(result).isFalse()
+ }
+
+ @Test
@EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
fun dateWeatherBelowSmallClock_defaultFontAndDisplaySize_shadeLayoutNotWide_false() =
testScope.runTest {
@@ -301,6 +310,72 @@
@Test
@EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
+ fun dateWeatherBelowLargeClock_variousFontAndDisplaySize_true() =
+ testScope.runTest {
+ mockConfiguration.fontScale = 1.0f
+ mockConfiguration.screenWidthDp = 347
+ val result1 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result1).isTrue()
+
+ mockConfiguration.fontScale = 1.2f
+ mockConfiguration.screenWidthDp = 347
+ val result2 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result2).isTrue()
+
+ mockConfiguration.fontScale = 1.7f
+ mockConfiguration.screenWidthDp = 412
+ val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result3).isTrue()
+ }
+
+ @Test
+ @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
+ fun dateWeatherBelowLargeClock_variousFontAndDisplaySize_false() =
+ testScope.runTest {
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+ mockConfiguration.fontScale = 1.0f
+ mockConfiguration.screenWidthDp = 310
+ val result1 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result1).isFalse()
+
+ mockConfiguration.fontScale = 1.5f
+ mockConfiguration.screenWidthDp = 347
+ val result2 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result2).isFalse()
+
+ mockConfiguration.fontScale = 2.0f
+ mockConfiguration.screenWidthDp = 411
+ val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result3).isFalse()
+ }
+
+ @Test
+ @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
+ fun dateWeatherBelowSmallClock_numberOverlapClock_variousFontAndDisplaySize_true() =
+ testScope.runTest {
+ config = ClockConfig("DIGITAL_CLOCK_NUMBEROVERLAP", "Test", "")
+ kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+ mockConfiguration.fontScale = 0.85f
+ mockConfiguration.screenWidthDp = 376
+ val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowSmallClock)
+ assertThat(result3).isTrue()
+ }
+
+ @Test
+ @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
+ fun dateWeatherBelowLargeClock_metroClock_variousFontAndDisplaySize_false() =
+ testScope.runTest {
+ config = ClockConfig("DIGITAL_CLOCK_METRO", "Test", "")
+ kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
+ mockConfiguration.fontScale = 0.85f
+ mockConfiguration.screenWidthDp = 375
+ val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
+ assertThat(result3).isFalse()
+ }
+
+ @Test
+ @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
fun dateWeatherBelowSmallClock_variousFontAndDisplaySize_shadeLayoutNotWide_false() =
testScope.runTest {
kosmos.shadeRepository.setShadeLayoutWide(false)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
index 94093c7..0569b9b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
@@ -173,6 +173,18 @@
)
}
}
+
+ launch("$TAG#clockViewModel.shouldDateWeatherBeBelowLargeClock") {
+ viewModel.shouldDateWeatherBeBelowLargeClock.collect {
+ blueprintInteractor.refreshBlueprint(
+ Config(
+ Type.SmartspaceVisibility,
+ checkPriority = false,
+ terminatePrevious = false,
+ )
+ )
+ }
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
index dc1b171..58a0647 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
@@ -18,6 +18,12 @@
package com.android.systemui.keyguard.ui.binder
import android.view.View
+import android.widget.LinearLayout
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
import androidx.core.view.isInvisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -25,8 +31,11 @@
import com.android.systemui.customization.clocks.ViewUtils.animateToAlpha
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.ClockPreviewConfig
+import com.android.systemui.plugins.clocks.ClockViewIds
+import com.android.systemui.res.R
import kotlinx.coroutines.flow.combine
/** Binder for the small clock view, large clock view and smartspace. */
@@ -36,14 +45,20 @@
private var currentShowSmartspace: Boolean? = null
@JvmStatic
- fun bind(parentView: View, viewModel: KeyguardPreviewSmartspaceViewModel) {
+ fun bind(
+ parentView: ConstraintLayout,
+ viewModel: KeyguardPreviewSmartspaceViewModel,
+ previewViewModel: KeyguardPreviewViewModel,
+ ) {
if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
val largeDateView =
parentView.findViewById<View>(
com.android.systemui.shared.R.id.date_smartspace_view_large
)
val smallDateView =
- parentView.findViewById<View>(com.android.systemui.shared.R.id.date_smartspace_view)
+ parentView.requireViewById<View>(
+ com.android.systemui.shared.R.id.date_smartspace_view
+ )
parentView.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch("$TAG#viewModel.previewClockSize") {
@@ -54,7 +69,13 @@
val largeDateViewVisibility =
if (showSmartspace) {
when (clockSize) {
- ClockSizeSetting.DYNAMIC -> View.VISIBLE
+ ClockSizeSetting.DYNAMIC -> {
+ if (viewModel.shouldDateWeatherBeBelowLargeClock) {
+ View.VISIBLE
+ } else {
+ View.INVISIBLE
+ }
+ }
ClockSizeSetting.SMALL -> View.INVISIBLE
}
} else {
@@ -63,7 +84,13 @@
val smallDateViewVisibility =
if (showSmartspace) {
when (clockSize) {
- ClockSizeSetting.DYNAMIC -> View.INVISIBLE
+ ClockSizeSetting.DYNAMIC -> {
+ if (viewModel.shouldDateWeatherBeBelowLargeClock) {
+ View.INVISIBLE
+ } else {
+ View.VISIBLE
+ }
+ }
ClockSizeSetting.SMALL -> View.VISIBLE
}
} else {
@@ -75,7 +102,7 @@
}
it.visibility = largeDateViewVisibility
}
- smallDateView?.let {
+ smallDateView.let {
if (shouldFadeIn && smallDateViewVisibility == View.VISIBLE) {
it.alpha = 0F
}
@@ -86,9 +113,113 @@
largeDateView?.animateToAlpha(1F)
}
if (smallDateViewVisibility == View.VISIBLE) {
- smallDateView?.animateToAlpha(1F)
+ smallDateView.animateToAlpha(1F)
}
}
+ val cs = ConstraintSet()
+ cs.clone(parentView)
+ cs.apply {
+ val smallClockViewId = ClockViewIds.LOCKSCREEN_CLOCK_VIEW_SMALL
+ val largeClockViewId = ClockViewIds.LOCKSCREEN_CLOCK_VIEW_LARGE
+ when (clockSize) {
+ ClockSizeSetting.DYNAMIC -> {
+ if (viewModel.shouldDateWeatherBeBelowLargeClock) {
+ largeDateView.also { view ->
+ constrainWidth(
+ view.id,
+ ConstraintSet.WRAP_CONTENT,
+ )
+ constrainHeight(
+ view.id,
+ ConstraintSet.WRAP_CONTENT,
+ )
+ connect(view.id, START, largeClockViewId, START)
+ connect(
+ view.id,
+ ConstraintSet.END,
+ largeClockViewId,
+ ConstraintSet.END,
+ )
+ connect(
+ view.id,
+ TOP,
+ largeClockViewId,
+ ConstraintSet.BOTTOM,
+ viewModel.getDateWeatherEndPadding(
+ view.context
+ ),
+ )
+ }
+ } else {
+ smallDateView.also { view ->
+ constrainWidth(
+ view.id,
+ ConstraintSet.WRAP_CONTENT,
+ )
+ constrainHeight(
+ view.id,
+ ConstraintSet.WRAP_CONTENT,
+ )
+ (view as? LinearLayout)?.orientation =
+ LinearLayout.HORIZONTAL
+ connect(view.id, START, smallClockViewId, START)
+ clear(view.id, TOP)
+ connect(
+ view.id,
+ TOP,
+ PARENT_ID,
+ TOP,
+ viewModel.getLargeClockSmartspaceTopPadding(
+ parentView.context,
+ previewViewModel.buildPreviewConfig(),
+ ),
+ )
+ }
+ }
+ }
+
+ ClockSizeSetting.SMALL -> {
+ smallDateView.also { view ->
+ constrainWidth(view.id, ConstraintSet.WRAP_CONTENT)
+ constrainHeight(view.id, ConstraintSet.WRAP_CONTENT)
+ if (viewModel.shouldDateWeatherBeBelowSmallClock) {
+ (view as? LinearLayout)?.orientation =
+ LinearLayout.HORIZONTAL
+ connect(view.id, START, smallClockViewId, START)
+ connect(
+ view.id,
+ TOP,
+ smallClockViewId,
+ ConstraintSet.BOTTOM,
+ view.resources.getDimensionPixelSize(
+ R.dimen.smartspace_padding_vertical
+ ),
+ )
+ } else {
+ (view as? LinearLayout)?.orientation =
+ LinearLayout.VERTICAL
+ connect(
+ view.id,
+ START,
+ smallClockViewId,
+ ConstraintSet.END,
+ view.resources.getDimensionPixelSize(
+ R.dimen.smartspace_padding_horizontal
+ ),
+ )
+ connect(view.id, TOP, smallClockViewId, TOP)
+ connect(
+ view.id,
+ ConstraintSet.BOTTOM,
+ smallClockViewId,
+ ConstraintSet.BOTTOM,
+ )
+ }
+ }
+ }
+ }
+ }
+ cs.applyTo(parentView)
currentShowSmartspace = showSmartspace
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
index cc075a1..38c2d81 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
@@ -101,7 +101,7 @@
launch("$TAG#smartspaceViewModel.isLargeClockVisible") {
clockViewModel.isLargeClockVisible.collect { isLargeClock ->
- if (isLargeClock) {
+ if (isLargeClock && clockViewModel.shouldDateWeatherBeBelowLargeClock.value) {
// hide small clock date/weather
keyguardRootView.findViewById<View>(smallViewId)?.let {
it.visibility = View.GONE
@@ -129,7 +129,7 @@
::Pair,
)
.collect { (isLargeClock, clockBounds) ->
- val viewId = if (isLargeClock) smallViewId else largeViewId
+ val viewId = if (isLargeClock && clockViewModel.shouldDateWeatherBeBelowLargeClock.value) smallViewId else largeViewId
keyguardRootView.findViewById<View>(viewId)?.let {
it.visibility = View.GONE
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 3cca552..0c618f8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -242,9 +242,16 @@
if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
when (clockSize) {
ClockSizeSetting.DYNAMIC -> {
- largeDateView?.post {
- smallDateView?.visibility = View.GONE
- largeDateView?.visibility = View.VISIBLE
+ if (clockViewModel.shouldSmallDateWeatherBeBelowLargeClock()) {
+ largeDateView?.post {
+ smallDateView?.visibility = View.GONE
+ largeDateView?.visibility = View.VISIBLE
+ }
+ } else {
+ largeDateView?.post {
+ smallDateView?.visibility = View.VISIBLE
+ largeDateView?.visibility = View.GONE
+ }
}
}
@@ -306,62 +313,13 @@
val cs = ConstraintSet()
cs.clone(parentView)
cs.apply {
- val largeClockViewId = ClockViewIds.LOCKSCREEN_CLOCK_VIEW_LARGE
- val smallClockViewId = ClockViewIds.LOCKSCREEN_CLOCK_VIEW_SMALL
largeDateView =
lockscreenSmartspaceController
.buildAndConnectDateView(parentView, true)
- ?.also { view ->
- constrainWidth(view.id, ConstraintSet.WRAP_CONTENT)
- constrainHeight(view.id, ConstraintSet.WRAP_CONTENT)
- connect(view.id, START, largeClockViewId, START)
- connect(view.id, ConstraintSet.END, largeClockViewId, ConstraintSet.END)
- connect(
- view.id,
- TOP,
- largeClockViewId,
- ConstraintSet.BOTTOM,
- smartspaceViewModel.getDateWeatherEndPadding(previewContext),
- )
- }
+
smallDateView =
lockscreenSmartspaceController
.buildAndConnectDateView(parentView, false)
- ?.also { view ->
- constrainWidth(view.id, ConstraintSet.WRAP_CONTENT)
- constrainHeight(view.id, ConstraintSet.WRAP_CONTENT)
- if (clockViewModel.shouldSmallDateWeatherBeBelowSmallClock()) {
- (view as? LinearLayout)?.orientation = LinearLayout.HORIZONTAL
- connect(view.id, START, smallClockViewId, START)
- connect(
- view.id,
- TOP,
- smallClockViewId,
- ConstraintSet.BOTTOM,
- context.resources.getDimensionPixelSize(
- R.dimen.smartspace_padding_vertical
- ),
- )
- } else {
- (view as? LinearLayout)?.orientation = LinearLayout.VERTICAL
- connect(
- view.id,
- START,
- smallClockViewId,
- ConstraintSet.END,
- previewContext.resources.getDimensionPixelSize(
- R.dimen.smartspace_padding_horizontal
- ),
- )
- connect(view.id, TOP, smallClockViewId, TOP)
- connect(
- view.id,
- ConstraintSet.BOTTOM,
- smallClockViewId,
- ConstraintSet.BOTTOM,
- )
- }
- }
parentView.addView(largeDateView)
parentView.addView(smallDateView)
}
@@ -415,7 +373,11 @@
setUpClock(previewContext, rootView)
if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
setUpSmartspace(previewContext, keyguardRootView)
- KeyguardPreviewSmartspaceViewBinder.bind(keyguardRootView, smartspaceViewModel)
+ KeyguardPreviewSmartspaceViewBinder.bind(
+ keyguardRootView,
+ smartspaceViewModel,
+ previewViewModel,
+ )
}
KeyguardPreviewClockViewBinder.bind(
keyguardRootView,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
index d7fcaf5..2255df9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
@@ -137,7 +137,11 @@
KeyguardSmartspaceViewModel.getSmartspaceHorizontalMargin(context)
val dateWeatherBelowSmallClock =
keyguardClockViewModel.shouldDateWeatherBeBelowSmallClock.value
+ val dateWeatherBelowLargeClock =
+ keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock.value
+
val isLargeClockVisible = keyguardClockViewModel.isLargeClockVisible.value
+
if (clockReactiveSmartspaceLayout()) {
if (dateWeatherBelowSmallClock) {
dateView?.orientation = LinearLayout.HORIZONTAL
@@ -148,7 +152,7 @@
constraintSet.apply {
constrainHeight(sharedR.id.date_smartspace_view, ConstraintSet.WRAP_CONTENT)
constrainWidth(sharedR.id.date_smartspace_view, ConstraintSet.WRAP_CONTENT)
- if (dateWeatherBelowSmallClock) {
+ if (dateWeatherBelowSmallClock || !dateWeatherBelowLargeClock) {
connect(
sharedR.id.date_smartspace_view,
ConstraintSet.START,
@@ -186,7 +190,7 @@
} else {
clear(sharedR.id.date_smartspace_view, ConstraintSet.BOTTOM)
if (clockReactiveSmartspaceLayout()) {
- if (dateWeatherBelowSmallClock) {
+ if (dateWeatherBelowSmallClock || !dateWeatherBelowLargeClock) {
connect(
sharedR.id.date_smartspace_view,
ConstraintSet.TOP,
@@ -224,7 +228,10 @@
}
if (clockReactiveSmartspaceLayout()) {
- if (isLargeClockVisible) {
+ if (
+ isLargeClockVisible &&
+ keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock.value
+ ) {
setVisibility(sharedR.id.date_smartspace_view, GONE)
constrainHeight(
sharedR.id.date_smartspace_view_large,
@@ -267,7 +274,7 @@
ConstraintSet.CHAIN_PACKED,
)
} else {
- if (dateWeatherBelowSmallClock) {
+ if (dateWeatherBelowSmallClock || !dateWeatherBelowLargeClock) {
connect(
sharedR.id.date_smartspace_view,
ConstraintSet.START,
@@ -305,7 +312,7 @@
}
if (clockReactiveSmartspaceLayout()) {
- if (dateWeatherBelowSmallClock) {
+ if (dateWeatherBelowSmallClock || !dateWeatherBelowLargeClock) {
createBarrier(
R.id.smart_space_barrier_bottom,
Barrier.BOTTOM,
@@ -378,7 +385,11 @@
smartspaceController.requestSmartspaceUpdate()
val weatherId: Int
val dateId: Int
- if (clockReactiveSmartspaceLayout() && isLargeClockVisible) {
+ if (
+ clockReactiveSmartspaceLayout() &&
+ isLargeClockVisible &&
+ keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock.value
+ ) {
weatherId = sharedR.id.weather_smartspace_view_large
dateId = sharedR.id.date_smartspace_view_large
} else {
@@ -392,12 +403,17 @@
setAlpha(weatherId, if (showWeather) 1f else 0f)
val showDateView =
- !keyguardClockViewModel.hasCustomWeatherDataDisplay.value || !isLargeClockVisible
+ !keyguardClockViewModel.hasCustomWeatherDataDisplay.value ||
+ !isLargeClockVisible ||
+ !keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock.value
setVisibility(dateId, if (showDateView) VISIBLE else GONE)
setAlpha(dateId, if (showDateView) 1f else 0f)
if (clockReactiveSmartspaceLayout()) {
- if (isLargeClockVisible) {
+ if (
+ isLargeClockVisible &&
+ keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock.value
+ ) {
setVisibility(sharedR.id.date_smartspace_view, GONE)
} else {
setVisibility(sharedR.id.date_smartspace_view_large, GONE)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
index 92a3236..fb36107 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
@@ -318,7 +318,11 @@
addTarget(ClockViewIds.LOCKSCREEN_CLOCK_VIEW_LARGE)
}
if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
- addTarget(sharedR.id.date_smartspace_view_large)
+ if (viewModel.shouldDateWeatherBeBelowLargeClock.value) {
+ addTarget(sharedR.id.date_smartspace_view_large)
+ } else {
+ addTarget(sharedR.id.date_smartspace_view)
+ }
}
} else {
logger.i("Adding small clock")
@@ -404,7 +408,7 @@
duration =
if (isLargeClock) STATUS_AREA_MOVE_UP_MILLIS else STATUS_AREA_MOVE_DOWN_MILLIS
interpolator = Interpolators.EMPHASIZED
- if (viewModel.shouldDateWeatherBeBelowSmallClock.value) {
+ if (viewModel.shouldDateWeatherBeBelowSmallClock.value || !viewModel.shouldDateWeatherBeBelowLargeClock.value) {
addTarget(sharedR.id.date_smartspace_view)
}
addTarget(sharedR.id.bc_smartspace_view)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index bb52baa..7e6c704 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -30,7 +30,9 @@
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.KeyguardLargeClockLog
import com.android.systemui.log.dagger.KeyguardSmallClockLog
+import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockPreviewConfig
import com.android.systemui.res.R as SysuiR
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -63,6 +65,7 @@
// TODO: b/374267505 - Use ShadeDisplayAware resources here.
@Main private val resources: Resources,
@KeyguardSmallClockLog private val smallClockLogBuffer: LogBuffer,
+ @KeyguardLargeClockLog private val largeClockLogBuffer: LogBuffer,
) {
var burnInLayer: Layer? = null
@@ -203,6 +206,44 @@
val largeClockTextSize: Flow<Int> =
configurationInteractor.dimensionPixelSize(clocksR.dimen.large_clock_text_size)
+ val shouldDateWeatherBeBelowLargeClock: StateFlow<Boolean> =
+ if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
+ combine(
+ shadeModeInteractor.isShadeLayoutWide,
+ configurationInteractor.configurationValues,
+ keyguardClockInteractor.currentClock,
+ ) { isShadeLayoutWide, configurationValues, currentClock ->
+ val screenWidthDp = configurationValues.screenWidthDp
+ val fontScale = configurationValues.fontScale
+
+ var belowLargeClock =
+ !isFontAndDisplaySizeBreaking(
+ currentClock = currentClock,
+ screenWidthDp = screenWidthDp,
+ fontScale = fontScale,
+ isShadeLayoutWide = isShadeLayoutWide,
+ )
+ largeClockLogBuffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = screenWidthDp
+ double1 = fontScale.toDouble()
+ bool1 = belowLargeClock
+ },
+ { "belowLargeClock:$bool1, Width:$int1, FontScale:$double1" },
+ )
+ belowLargeClock
+ }
+ } else {
+ flowOf(false)
+ }
+ .stateIn(
+ scope = backgroundScope,
+ started = SharingStarted.Eagerly,
+ initialValue = false,
+ )
+
val shouldDateWeatherBeBelowSmallClock: StateFlow<Boolean> =
if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
combine(
@@ -210,8 +251,11 @@
shadeModeInteractor.isShadeLayoutWide,
configurationInteractor.configurationValues,
keyguardClockInteractor.currentClock,
- ) { hasCustomWeatherDataDisplay, isShadeLayoutWide, configurationValues, _ ->
- var fallBelow = false
+ ) {
+ hasCustomWeatherDataDisplay,
+ isShadeLayoutWide,
+ configurationValues,
+ currentClock ->
if (hasCustomWeatherDataDisplay) {
return@combine true
}
@@ -229,18 +273,14 @@
}
val screenWidthDp = configurationValues.screenWidthDp
-
- // if the shade is wide, we should account for the possibility of date/weather
- // going past the halfway point
- val adjustedScreenWidth =
- if (isShadeLayoutWide) screenWidthDp / 2 else screenWidthDp
val fontScale = configurationValues.fontScale
- for ((font, width) in BREAKING_PAIRS) {
- if (fontScale >= font && adjustedScreenWidth <= width) {
- fallBelow = true
- break
- }
- }
+ var fallBelow =
+ isFontAndDisplaySizeBreaking(
+ currentClock = currentClock,
+ screenWidthDp = screenWidthDp,
+ fontScale = fontScale,
+ isShadeLayoutWide = isShadeLayoutWide,
+ )
smallClockLogBuffer.log(
TAG,
LogLevel.INFO,
@@ -262,6 +302,31 @@
}
.stateIn(scope = backgroundScope, started = SharingStarted.Eagerly, initialValue = true)
+ private fun isFontAndDisplaySizeBreaking(
+ currentClock: ClockController?,
+ screenWidthDp: Int,
+ fontScale: Float,
+ isShadeLayoutWide: Boolean? = null,
+ ): Boolean {
+ val breakingPairs: List<Pair<Float, Int>> =
+ when (currentClock?.config?.id) {
+ NUMBER_OVERLAP_CLOCK_ID -> NUMBER_OVERLAP_BREAKING_PAIRS
+ METRO_CLOCK_ID -> METRO_CLOCK_BREAKING_PAIRS
+ else -> DEFAULT_BREAKING_PAIRS
+ }
+
+ // if the shade is wide, we should account for the possibility of date/weather
+ // going past the halfway point
+ val adjustedScreenWidth =
+ if (isShadeLayoutWide == true) screenWidthDp / 2 else screenWidthDp
+ for ((font, width) in breakingPairs) {
+ if (fontScale >= font && adjustedScreenWidth <= width) {
+ return true
+ }
+ }
+ return false
+ }
+
enum class ClockLayout {
LARGE_CLOCK,
SMALL_CLOCK,
@@ -277,7 +342,7 @@
// font size to display size
// These values come from changing the font size and display size on a non-foldable.
// Visually looked at which configs cause the date/weather to push off of the screen
- private val BREAKING_PAIRS =
+ private val DEFAULT_BREAKING_PAIRS =
listOf(
0.85f to 320, // tiny font size but large display size
1f to 346,
@@ -286,6 +351,26 @@
1.8f to 411, // large font size but tiny display size
)
+ private const val NUMBER_OVERLAP_CLOCK_ID = "DIGITAL_CLOCK_NUMBEROVERLAP"
+ private const val METRO_CLOCK_ID = "DIGITAL_CLOCK_METRO"
+
+ private val NUMBER_OVERLAP_BREAKING_PAIRS =
+ listOf(
+ 0.85f to 376, // tiny font size but large display size
+ 1f to 376,
+ 1.15f to 411,
+ 1.3f to 411,
+ 1.5f to 411, // large font size but tiny display size
+ )
+
+ private val METRO_CLOCK_BREAKING_PAIRS =
+ listOf(
+ 0.85f to 376, // tiny font size but large display size
+ 1f to 376,
+ 1.15f to 376,
+ 1.3f to 376, // large font size but tiny display size
+ )
+
// Font axes width max cutoff
// A font with a wider font axes than this is at risk of being pushed off screen
// Value determined by the very robust and scientific process of eye-balling a few devices
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt
index bf11948..070e46f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt
@@ -67,4 +67,7 @@
fun shouldSmallDateWeatherBeBelowSmallClock() =
keyguardClockViewModel.shouldDateWeatherBeBelowSmallClock.value
+
+ fun shouldSmallDateWeatherBeBelowLargeClock() =
+ keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock.value
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index dc3c340..41e40d6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -51,6 +51,12 @@
) {
val previewClockSize = clockViewModel.previewClockSize
+ val shouldDateWeatherBeBelowSmallClock
+ get() = clockViewModel.shouldSmallDateWeatherBeBelowSmallClock()
+
+ val shouldDateWeatherBeBelowLargeClock
+ get() = clockViewModel.shouldSmallDateWeatherBeBelowLargeClock()
+
val previewAlpha = if (previewInteractor.shouldHighlightSelectedAffordance) DIM_ALPHA else 1.0f
val shouldHideSmartspace: Flow<Boolean> =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt
index aebe118..c30f300 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt
@@ -70,6 +70,10 @@
fun setShouldForceSmallClock(shouldForceSmallClock: Boolean) {
_shouldForceSmallClock = shouldForceSmallClock
}
+
+ fun setCurrentClockId(clockId: ClockId) {
+ _currentClockId.value = clockId
+ }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
index c4e11aa..a45acdc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
@@ -40,6 +40,7 @@
systemBarUtils = systemBarUtilsProxy,
configurationInteractor = configurationInteractor,
resources = mainResources,
- smallClockLogBuffer = logcatLogBuffer(name = "KeyguardClockViewModel"),
+ smallClockLogBuffer = logcatLogBuffer(name = "KeyguardSmallClockViewModel"),
+ largeClockLogBuffer = logcatLogBuffer(name = "KeyguardLargeClockViewModel"),
)
}