Merge "Change burn in preventing mechanism for clock" into main
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt
index c109e51..abbf0ea 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt
@@ -58,15 +58,11 @@
.collectAsState(initial = BurnInScaleViewModel())
return this.graphicsLayer {
- val scale =
- when {
- scaleViewModel.scaleClockOnly && isClock -> scaleViewModel.scale
- else -> 1f
- }
-
this.translationX = if (isClock) 0F else translationX
this.translationY = translationY
this.alpha = alpha
+
+ val scale = if (scaleViewModel.scaleClockOnly) scaleViewModel.scale else 1f
this.scaleX = scale
this.scaleY = scale
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
index e270d9e..519bb6e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -62,8 +62,8 @@
private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
private val keyguardClockRepository = kosmos.fakeKeyguardClockRepository
private lateinit var underTest: AodBurnInViewModel
-
- private var burnInParameters = BurnInParameters()
+ // assign a smaller value to minViewY to avoid overflow
+ private var burnInParameters = BurnInParameters(minViewY = Int.MAX_VALUE / 2)
private val burnInFlow = MutableStateFlow(BurnInModel())
@Before
@@ -296,52 +296,111 @@
scale = 0.5f,
)
- assertThat(movement?.translationX).isEqualTo(0)
- assertThat(movement?.translationY).isEqualTo(0)
+ assertThat(movement?.translationX).isEqualTo(20)
+ assertThat(movement?.translationY).isEqualTo(30)
assertThat(movement?.scale).isEqualTo(0.5f)
assertThat(movement?.scaleClockOnly).isEqualTo(false)
}
@Test
- fun translationAndScale_composeFlagOn_weatherLargeClock() =
- testBurnInViewModelWhenComposeFlagOn(
+ fun translationAndScale_composeFlagOff_weatherLargeClock() =
+ testBurnInViewModelForClocks(
isSmallClock = false,
isWeatherClock = true,
- expectedScaleOnly = false
+ expectedScaleOnly = false,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = false
+ )
+
+ @Test
+ fun translationAndScale_composeFlagOff_weatherSmallClock() =
+ testBurnInViewModelForClocks(
+ isSmallClock = true,
+ isWeatherClock = true,
+ expectedScaleOnly = false,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = false
+ )
+
+ @Test
+ fun translationAndScale_composeFlagOff_nonWeatherLargeClock() =
+ testBurnInViewModelForClocks(
+ isSmallClock = false,
+ isWeatherClock = false,
+ expectedScaleOnly = true,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = false
+ )
+
+ @Test
+ fun translationAndScale_composeFlagOff_nonWeatherSmallClock() =
+ testBurnInViewModelForClocks(
+ isSmallClock = true,
+ isWeatherClock = false,
+ expectedScaleOnly = false,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = false
+ )
+
+ @Test
+ fun translationAndScale_composeFlagOn_weatherLargeClock() =
+ testBurnInViewModelForClocks(
+ isSmallClock = false,
+ isWeatherClock = true,
+ expectedScaleOnly = false,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = true
)
@Test
fun translationAndScale_composeFlagOn_weatherSmallClock() =
- testBurnInViewModelWhenComposeFlagOn(
+ testBurnInViewModelForClocks(
isSmallClock = true,
isWeatherClock = true,
- expectedScaleOnly = true
+ expectedScaleOnly = false,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = true
)
@Test
fun translationAndScale_composeFlagOn_nonWeatherLargeClock() =
- testBurnInViewModelWhenComposeFlagOn(
+ testBurnInViewModelForClocks(
isSmallClock = false,
isWeatherClock = false,
- expectedScaleOnly = true
+ expectedScaleOnly = true,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = true
)
@Test
fun translationAndScale_composeFlagOn_nonWeatherSmallClock() =
- testBurnInViewModelWhenComposeFlagOn(
+ testBurnInViewModelForClocks(
isSmallClock = true,
isWeatherClock = false,
- expectedScaleOnly = true
+ expectedScaleOnly = false,
+ enableMigrateClocksToBlueprintFlag = true,
+ enableComposeLockscreenFlag = true
)
- private fun testBurnInViewModelWhenComposeFlagOn(
+ private fun testBurnInViewModelForClocks(
isSmallClock: Boolean,
isWeatherClock: Boolean,
- expectedScaleOnly: Boolean
+ expectedScaleOnly: Boolean,
+ enableMigrateClocksToBlueprintFlag: Boolean,
+ enableComposeLockscreenFlag: Boolean
) =
testScope.runTest {
- mSetFlagsRule.enableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
- mSetFlagsRule.enableFlags(AConfigFlags.FLAG_COMPOSE_LOCKSCREEN)
+ if (enableMigrateClocksToBlueprintFlag) {
+ mSetFlagsRule.enableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+ } else {
+ mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+ }
+
+ if (enableComposeLockscreenFlag) {
+ mSetFlagsRule.enableFlags(AConfigFlags.FLAG_COMPOSE_LOCKSCREEN)
+ } else {
+ mSetFlagsRule.disableFlags(AConfigFlags.FLAG_COMPOSE_LOCKSCREEN)
+ }
if (isSmallClock) {
keyguardClockRepository.setClockSize(ClockSize.SMALL)
// we need the following step to update stateFlow value
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
index 79bf5f1..629c96c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
@@ -109,6 +109,12 @@
val largeClockMessageBuffer: MessageBuffer,
)
+data class AodClockBurnInModel(
+ val scale: Float,
+ val translationX: Float,
+ val translationY: Float,
+)
+
/** Specifies layout information for the */
interface ClockFaceLayout {
/** All clock views to add to the root constraint layout before applying constraints. */
@@ -118,6 +124,8 @@
fun applyConstraints(constraints: ConstraintSet): ConstraintSet
fun applyPreviewConstraints(constraints: ConstraintSet): ConstraintSet
+
+ fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel)
}
/** A ClockFaceLayout that applies the default lockscreen layout to a single view */
@@ -137,6 +145,10 @@
override fun applyPreviewConstraints(constraints: ConstraintSet): ConstraintSet {
return constraints
}
+
+ override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) {
+ // Default clock doesn't need detailed control of view
+ }
}
/** Events that should call when various rendering parameters change */
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 ed5d53c..c846cbe 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
@@ -33,14 +33,18 @@
import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type
import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.plugins.clocks.AodClockBurnInModel
import com.android.systemui.plugins.clocks.ClockController
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
object KeyguardClockViewBinder {
private val TAG = KeyguardClockViewBinder::class.simpleName!!
// When changing to new clock, we need to remove old clock views from burnInLayer
private var lastClock: ClockController? = null
+
@JvmStatic
fun bind(
clockSection: ClockSection,
@@ -48,6 +52,7 @@
viewModel: KeyguardClockViewModel,
keyguardClockInteractor: KeyguardClockInteractor,
blueprintInteractor: KeyguardBlueprintInteractor,
+ rootViewModel: KeyguardRootViewModel,
) {
keyguardRootView.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
@@ -105,6 +110,28 @@
}
}
}
+
+ launch {
+ if (!MigrateClocksToBlueprint.isEnabled) return@launch
+ combine(
+ rootViewModel.translationX,
+ rootViewModel.translationY,
+ rootViewModel.scale,
+ ::Triple
+ )
+ .collect { (translationX, translationY, scale) ->
+ viewModel.currentClock.value
+ ?.largeClock
+ ?.layout
+ ?.applyAodBurnIn(
+ AodClockBurnInModel(
+ translationX = translationX.value!!,
+ translationY = translationY,
+ scale = scale.scale
+ )
+ )
+ }
+ }
}
}
}
@@ -117,17 +144,16 @@
) {
val burnInLayer = viewModel.burnInLayer
val clockController = viewModel.currentClock.value
+ // Large clocks won't be added to or removed from burn in layer
+ // Weather large clock has customized burn in preventing mechanism
+ // Non-weather large clock will only scale and translate vertically
clockController?.let { clock ->
when (clockSize) {
ClockSize.LARGE -> {
clock.smallClock.layout.views.forEach { burnInLayer?.removeView(it) }
- if (clock.config.useAlternateSmartspaceAODTransition) {
- clock.largeClock.layout.views.forEach { burnInLayer?.addView(it) }
- }
}
ClockSize.SMALL -> {
clock.smallClock.layout.views.forEach { burnInLayer?.addView(it) }
- clock.largeClock.layout.views.forEach { burnInLayer?.removeView(it) }
}
}
}
@@ -148,13 +174,6 @@
burnInLayer?.removeView(it)
rootView.removeView(it)
}
-
- // add large clock to burn in layer only when it will have same transition with other
- // components in AOD otherwise, it will have a separate scale transition while other
- // components only have translate transition
- if (clock.config.useAlternateSmartspaceAODTransition) {
- clock.largeClock.layout.views.forEach { burnInLayer?.removeView(it) }
- }
clock.largeClock.layout.views.forEach { rootView.removeView(it) }
}
lastClock = currentClock
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 4451bca..39db22d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -257,23 +257,6 @@
it.scaleX = scaleViewModel.scale
it.scaleY = scaleViewModel.scale
}
- // Make sure to reset these views, or they will be invisible
- if (childViews[burnInLayerId]?.scaleX != 1f) {
- childViews[burnInLayerId]?.scaleX = 1f
- childViews[burnInLayerId]?.scaleY = 1f
- childViews[aodNotificationIconContainerId]?.scaleX = 1f
- childViews[aodNotificationIconContainerId]?.scaleY = 1f
- view.requestLayout()
- }
- } else {
- // For weather clock, large clock should have only scale
- // transition with other parts in burnInLayer
- childViews[burnInLayerId]?.scaleX = scaleViewModel.scale
- childViews[burnInLayerId]?.scaleY = scaleViewModel.scale
- childViews[aodNotificationIconContainerId]?.scaleX =
- scaleViewModel.scale
- childViews[aodNotificationIconContainerId]?.scaleY =
- scaleViewModel.scale
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index ef29270..b367715 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -38,6 +38,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.binder.KeyguardClockViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockFaceLayout
@@ -64,6 +65,7 @@
private val context: Context,
val smartspaceViewModel: KeyguardSmartspaceViewModel,
val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>,
+ private val rootViewModel: KeyguardRootViewModel,
) : KeyguardSection() {
override fun addViews(constraintLayout: ConstraintLayout) {}
override fun bindData(constraintLayout: ConstraintLayout) {
@@ -75,7 +77,8 @@
constraintLayout,
keyguardClockViewModel,
clockInteractor,
- blueprintInteractor.get()
+ blueprintInteractor.get(),
+ rootViewModel,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index 5b83a10..c05a1b7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -27,7 +27,6 @@
import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.ComposeLockscreen
import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.keyguard.ui.StateToValue
@@ -121,11 +120,13 @@
),
) { interpolated, burnIn ->
val useAltAod =
- keyguardClockViewModel.currentClock.value?.let { clock ->
- clock.config.useAlternateSmartspaceAODTransition
- } == true
+ keyguardClockViewModel.currentClock.value
+ ?.config
+ ?.useAlternateSmartspaceAODTransition == true
+ // Only scale large non-weather clocks
+ // elements in large weather clock will translate the same as smartspace
val useScaleOnly =
- useAltAod && keyguardClockViewModel.clockSize.value == ClockSize.LARGE
+ (!useAltAod) && keyguardClockViewModel.clockSize.value == ClockSize.LARGE
val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolated).toInt()
val translationY =
@@ -134,35 +135,12 @@
} else {
max(params.topInset, params.minViewY + burnInY) - params.minViewY
}
- if (ComposeLockscreen.isEnabled) {
- BurnInModel(
- translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(),
- translationY = translationY,
- scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated),
- scaleClockOnly = !useScaleOnly,
- )
- } else {
- if (useScaleOnly) {
- BurnInModel(
- translationX = 0,
- translationY = 0,
- scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated),
- )
- } else {
- // Ensure the desired translation doesn't encroach on the top inset
- BurnInModel(
- translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(),
- translationY = translationY,
- scale =
- MathUtils.lerp(
- /* start= */ burnIn.scale,
- /* stop= */ 1f,
- /* amount= */ 1f - interpolated,
- ),
- scaleClockOnly = true,
- )
- }
- }
+ BurnInModel(
+ translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(),
+ translationY = translationY,
+ scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated),
+ scaleClockOnly = useScaleOnly
+ )
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
index 2f650c4..040d3b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
@@ -85,7 +85,6 @@
setupWeatherClock()
KeyguardClockViewBinder.updateBurnInLayer(rootView, clockViewModel, ClockSize.LARGE)
verify(burnInLayer).removeView(smallClockView)
- verify(burnInLayer).addView(largeClockView)
}
@Test
@@ -101,7 +100,6 @@
setupNonWeatherClock()
KeyguardClockViewBinder.updateBurnInLayer(rootView, clockViewModel, ClockSize.SMALL)
verify(burnInLayer).addView(smallClockView)
- verify(burnInLayer).removeView(largeClockView)
}
private fun setupWeatherClock() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
index ba2efe6..b3cc5c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
@@ -32,6 +32,7 @@
import com.android.systemui.keyguard.domain.interactor.keyguardSmartspaceInteractor
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel
+import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
@@ -117,6 +118,7 @@
context,
keyguardSmartspaceViewModel,
{ keyguardBlueprintInteractor },
+ keyguardRootViewModel,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
index 90a93f4..a6b40df 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
@@ -24,6 +24,7 @@
import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection
import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel
+import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.util.mockito.mock
@@ -37,6 +38,7 @@
context = applicationContext,
smartspaceViewModel = keyguardSmartspaceViewModel,
blueprintInteractor = { keyguardBlueprintInteractor },
+ rootViewModel = keyguardRootViewModel,
)
}