Loading packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt +2 −6 Original line number Diff line number Diff line Loading @@ -58,15 +58,11 @@ fun Modifier.burnInAware( .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 } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt +75 −16 Original line number Diff line number Diff line Loading @@ -62,8 +62,8 @@ class AodBurnInViewModelTest : SysuiTestCase() { 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 Loading Loading @@ -296,52 +296,111 @@ class AodBurnInViewModelTest : SysuiTestCase() { 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_composeFlagOff_weatherLargeClock() = testBurnInViewModelForClocks( isSmallClock = false, isWeatherClock = true, 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() = testBurnInViewModelWhenComposeFlagOn( testBurnInViewModelForClocks( isSmallClock = false, isWeatherClock = true, expectedScaleOnly = false 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 { 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 Loading packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt +12 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,12 @@ data class ClockMessageBuffers( 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. */ Loading @@ -118,6 +124,8 @@ interface ClockFaceLayout { 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 */ Loading @@ -137,6 +145,10 @@ class DefaultClockFaceLayout(val view: View) : ClockFaceLayout { 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 */ Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt +30 −11 Original line number Diff line number Diff line Loading @@ -33,14 +33,18 @@ import com.android.systemui.keyguard.shared.model.ClockSize 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, Loading @@ -48,6 +52,7 @@ object KeyguardClockViewBinder { viewModel: KeyguardClockViewModel, keyguardClockInteractor: KeyguardClockInteractor, blueprintInteractor: KeyguardBlueprintInteractor, rootViewModel: KeyguardRootViewModel, ) { keyguardRootView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { Loading Loading @@ -105,6 +110,28 @@ object KeyguardClockViewBinder { } } } 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 ) ) } } } } } Loading @@ -117,17 +144,16 @@ object KeyguardClockViewBinder { ) { 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) } } } } Loading @@ -148,13 +174,6 @@ object KeyguardClockViewBinder { 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 Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +0 −17 Original line number Diff line number Diff line Loading @@ -257,23 +257,6 @@ object KeyguardRootViewBinder { 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 } } } Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt +2 −6 Original line number Diff line number Diff line Loading @@ -58,15 +58,11 @@ fun Modifier.burnInAware( .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 } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt +75 −16 Original line number Diff line number Diff line Loading @@ -62,8 +62,8 @@ class AodBurnInViewModelTest : SysuiTestCase() { 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 Loading Loading @@ -296,52 +296,111 @@ class AodBurnInViewModelTest : SysuiTestCase() { 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_composeFlagOff_weatherLargeClock() = testBurnInViewModelForClocks( isSmallClock = false, isWeatherClock = true, 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() = testBurnInViewModelWhenComposeFlagOn( testBurnInViewModelForClocks( isSmallClock = false, isWeatherClock = true, expectedScaleOnly = false 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 { 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 Loading
packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt +12 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,12 @@ data class ClockMessageBuffers( 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. */ Loading @@ -118,6 +124,8 @@ interface ClockFaceLayout { 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 */ Loading @@ -137,6 +145,10 @@ class DefaultClockFaceLayout(val view: View) : ClockFaceLayout { 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 */ Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt +30 −11 Original line number Diff line number Diff line Loading @@ -33,14 +33,18 @@ import com.android.systemui.keyguard.shared.model.ClockSize 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, Loading @@ -48,6 +52,7 @@ object KeyguardClockViewBinder { viewModel: KeyguardClockViewModel, keyguardClockInteractor: KeyguardClockInteractor, blueprintInteractor: KeyguardBlueprintInteractor, rootViewModel: KeyguardRootViewModel, ) { keyguardRootView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { Loading Loading @@ -105,6 +110,28 @@ object KeyguardClockViewBinder { } } } 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 ) ) } } } } } Loading @@ -117,17 +144,16 @@ object KeyguardClockViewBinder { ) { 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) } } } } Loading @@ -148,13 +174,6 @@ object KeyguardClockViewBinder { 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 Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +0 −17 Original line number Diff line number Diff line Loading @@ -257,23 +257,6 @@ object KeyguardRootViewBinder { 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 } } } Loading