Merge "Use only one BurnInParameters for AoD Burn in" 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 aaf49ff..9444664 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
@@ -42,8 +42,9 @@
     isClock: Boolean = false,
 ): Modifier {
     val translationYState = remember { mutableStateOf(0F) }
-    val copiedParams = params.copy(translationY = { translationYState.value })
-    val burnIn = viewModel.movement(copiedParams)
+    viewModel.updateBurnInParams(params.copy(translationY = { translationYState.value }))
+
+    val burnIn = viewModel.movement
     val translationX by
         burnIn.map { it.translationX.toFloat() }.collectAsStateWithLifecycle(initialValue = 0f)
     val translationY by
@@ -51,12 +52,7 @@
     translationYState.value = translationY
     val scaleViewModel by
         burnIn
-            .map {
-                BurnInScaleViewModel(
-                    scale = it.scale,
-                    scaleClockOnly = it.scaleClockOnly,
-                )
-            }
+            .map { BurnInScaleViewModel(scale = it.scale, scaleClockOnly = it.scaleClockOnly) }
             .collectAsStateWithLifecycle(initialValue = BurnInScaleViewModel())
 
     return this.graphicsLayer {
@@ -72,8 +68,6 @@
 
 /** Reports the "top" coordinate of the modified composable to the given [consumer]. */
 @Composable
-fun Modifier.onTopPlacementChanged(
-    consumer: (Float) -> Unit,
-): Modifier {
+fun Modifier.onTopPlacementChanged(consumer: (Float) -> Unit): Modifier {
     return onPlaced { coordinates -> consumer(coordinates.boundsInWindow().top) }
 }
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 ff6ea3a..40a9add 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
@@ -91,12 +91,13 @@
         kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
 
         underTest = kosmos.aodBurnInViewModel
+        underTest.updateBurnInParams(burnInParameters)
     }
 
     @Test
     fun movement_initializedToDefaultValues() =
         testScope.runTest {
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            val movement by collectLastValue(underTest.movement)
             assertThat(movement?.translationY).isEqualTo(0)
             assertThat(movement?.translationX).isEqualTo(0)
             assertThat(movement?.scale).isEqualTo(1f)
@@ -105,7 +106,7 @@
     @Test
     fun translationAndScale_whenNotDozing() =
         testScope.runTest {
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            val movement by collectLastValue(underTest.movement)
 
             // Set to not dozing (on lockscreen)
             keyguardTransitionRepository.sendTransitionStep(
@@ -130,8 +131,8 @@
     @Test
     fun translationAndScale_whenFullyDozing() =
         testScope.runTest {
-            burnInParameters = burnInParameters.copy(minViewY = 100)
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100))
+            val movement by collectLastValue(underTest.movement)
 
             // Set to dozing (on AOD)
             keyguardTransitionRepository.sendTransitionStep(
@@ -171,8 +172,8 @@
     @DisableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
     fun translationAndScale_whenFullyDozing_MigrationFlagOff_staysOutOfTopInset() =
         testScope.runTest {
-            burnInParameters = burnInParameters.copy(minViewY = 100, topInset = 80)
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80))
+            val movement by collectLastValue(underTest.movement)
 
             // Set to dozing (on AOD)
             keyguardTransitionRepository.sendTransitionStep(
@@ -213,8 +214,8 @@
     @EnableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
     fun translationAndScale_whenFullyDozing_MigrationFlagOn_staysOutOfTopInset() =
         testScope.runTest {
-            burnInParameters = burnInParameters.copy(minViewY = 100, topInset = 80)
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80))
+            val movement by collectLastValue(underTest.movement)
 
             // Set to dozing (on AOD)
             keyguardTransitionRepository.sendTransitionStep(
@@ -256,7 +257,7 @@
         testScope.runTest {
             whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true)
 
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            val movement by collectLastValue(underTest.movement)
 
             // Set to dozing (on AOD)
             keyguardTransitionRepository.sendTransitionStep(
@@ -374,7 +375,7 @@
             whenever(clockController.config.useAlternateSmartspaceAODTransition)
                 .thenReturn(if (isWeatherClock) true else false)
 
-            val movement by collectLastValue(underTest.movement(burnInParameters))
+            val movement by collectLastValue(underTest.movement)
 
             // Set to dozing (on AOD)
             keyguardTransitionRepository.sendTransitionStep(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 4adf693..add7ac9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -55,7 +55,6 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
-import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
 import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
 import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
@@ -70,7 +69,6 @@
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -155,7 +153,7 @@
     fun setUp() {
         shadeTestUtil.setSplitShade(false)
         movementFlow = MutableStateFlow(BurnInModel())
-        whenever(aodBurnInViewModel.movement(any())).thenReturn(movementFlow)
+        whenever(aodBurnInViewModel.movement).thenReturn(movementFlow)
         underTest = kosmos.sharedNotificationContainerViewModel
     }
 
@@ -810,7 +808,7 @@
     @DisableSceneContainer
     fun translationYUpdatesOnKeyguardForBurnIn() =
         testScope.runTest {
-            val translationY by collectLastValue(underTest.translationY(BurnInParameters()))
+            val translationY by collectLastValue(underTest.translationY)
 
             showLockscreen()
             assertThat(translationY).isEqualTo(0)
@@ -823,7 +821,7 @@
     @DisableSceneContainer
     fun translationYUpdatesOnKeyguard() =
         testScope.runTest {
-            val translationY by collectLastValue(underTest.translationY(BurnInParameters()))
+            val translationY by collectLastValue(underTest.translationY)
 
             configurationRepository.setDimensionPixelSize(
                 R.dimen.keyguard_translate_distance_on_swipe_up,
@@ -844,7 +842,7 @@
     @DisableSceneContainer
     fun translationYDoesNotUpdateWhenShadeIsExpanded() =
         testScope.runTest {
-            val translationY by collectLastValue(underTest.translationY(BurnInParameters()))
+            val translationY by collectLastValue(underTest.translationY)
 
             configurationRepository.setDimensionPixelSize(
                 R.dimen.keyguard_translate_distance_on_swipe_up,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index b89eb27..cf9d60f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -19,6 +19,7 @@
 import com.android.keyguard.logging.KeyguardLogger
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.log.core.LogLevel.VERBOSE
 import com.android.systemui.power.domain.interactor.PowerInteractor
@@ -44,6 +45,7 @@
     private val powerInteractor: PowerInteractor,
     private val sharedNotificationContainerViewModel: SharedNotificationContainerViewModel,
     private val keyguardRootViewModel: KeyguardRootViewModel,
+    private val aodBurnInViewModel: AodBurnInViewModel,
     private val shadeInteractor: ShadeInteractor,
     private val keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
 ) {
@@ -132,7 +134,7 @@
         }
 
         scope.launch {
-            keyguardRootViewModel.burnInModel.debounce(20L).collect {
+            aodBurnInViewModel.movement.debounce(20L).collect {
                 logger.log(TAG, VERBOSE, "BurnInModel (debounced)", it)
             }
         }
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 ba9f018..5f76f64 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
@@ -32,6 +32,7 @@
 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.AodBurnInViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
@@ -58,6 +59,7 @@
         keyguardClockInteractor: KeyguardClockInteractor,
         blueprintInteractor: KeyguardBlueprintInteractor,
         rootViewModel: KeyguardRootViewModel,
+        aodBurnInViewModel: AodBurnInViewModel,
     ): DisposableHandle {
         val disposables = DisposableHandles()
         disposables +=
@@ -78,7 +80,7 @@
                             updateBurnInLayer(
                                 keyguardRootView,
                                 viewModel,
-                                viewModel.clockSize.value
+                                viewModel.clockSize.value,
                             )
                             applyConstraints(clockSection, keyguardRootView, true)
                         }
@@ -114,7 +116,7 @@
                         if (!MigrateClocksToBlueprint.isEnabled) return@launch
                         combine(
                                 viewModel.hasAodIcons,
-                                rootViewModel.isNotifIconContainerVisible.map { it.value }
+                                rootViewModel.isNotifIconContainerVisible.map { it.value },
                             ) { hasIcon, isVisible ->
                                 hasIcon && isVisible
                             }
@@ -130,13 +132,13 @@
 
                     launch {
                         if (!MigrateClocksToBlueprint.isEnabled) return@launch
-                        rootViewModel.burnInModel.collect { burnInModel ->
+                        aodBurnInViewModel.movement.collect { burnInModel ->
                             viewModel.currentClock.value?.let {
                                 it.largeClock.layout.applyAodBurnIn(
                                     AodClockBurnInModel(
                                         translationX = burnInModel.translationX.toFloat(),
                                         translationY = burnInModel.translationY.toFloat(),
-                                        scale = burnInModel.scale
+                                        scale = burnInModel.scale,
                                     )
                                 )
                             }
@@ -175,7 +177,7 @@
     private fun cleanupClockViews(
         currentClock: ClockController?,
         rootView: ConstraintLayout,
-        burnInLayer: Layer?
+        burnInLayer: Layer?,
     ) {
         if (lastClock == currentClock) {
             return
@@ -192,10 +194,7 @@
     }
 
     @VisibleForTesting
-    fun addClockViews(
-        clockController: ClockController?,
-        rootView: ConstraintLayout,
-    ) {
+    fun addClockViews(clockController: ClockController?, rootView: ConstraintLayout) {
         // We'll collect the same clock when exiting wallpaper picker without changing clock
         // so we need to remove clock views from parent before addView again
         clockController?.let { clock ->
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 b5f6b41..445da24 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
@@ -261,10 +261,7 @@
                             ->
                             if (biometricMessage?.message != null) {
                                 chipbarCoordinator!!.displayView(
-                                    createChipbarInfo(
-                                        biometricMessage.message,
-                                        R.drawable.ic_lock,
-                                    )
+                                    createChipbarInfo(biometricMessage.message, R.drawable.ic_lock)
                                 )
                             } else {
                                 chipbarCoordinator!!.removeView(ID, "occludingAppMsgNull")
@@ -382,7 +379,7 @@
                                 if (msdlFeedback()) {
                                     msdlPlayer?.playToken(
                                         MSDLToken.UNLOCK,
-                                        authInteractionProperties
+                                        authInteractionProperties,
                                     )
                                 } else {
                                     vibratorHelper.performHapticFeedback(
@@ -398,7 +395,7 @@
                                 if (msdlFeedback()) {
                                     msdlPlayer?.playToken(
                                         MSDLToken.FAILURE,
-                                        authInteractionProperties
+                                        authInteractionProperties,
                                     )
                                 } else {
                                     vibratorHelper.performHapticFeedback(
@@ -425,7 +422,7 @@
                     blueprintViewModel,
                     clockViewModel,
                     childViews,
-                    burnInParams
+                    burnInParams,
                 )
             )
 
@@ -464,11 +461,7 @@
      */
     private fun createChipbarInfo(message: String, @DrawableRes icon: Int): ChipbarInfo {
         return ChipbarInfo(
-            startIcon =
-                TintedIcon(
-                    Icon.Resource(icon, null),
-                    ChipbarInfo.DEFAULT_ICON_TINT,
-                ),
+            startIcon = TintedIcon(Icon.Resource(icon, null), ChipbarInfo.DEFAULT_ICON_TINT),
             text = Text.Loaded(message),
             endItem = null,
             vibrationEffect = null,
@@ -499,7 +492,7 @@
             oldLeft: Int,
             oldTop: Int,
             oldRight: Int,
-            oldBottom: Int
+            oldBottom: Int,
         ) {
             // After layout, ensure the notifications are positioned correctly
             childViews[nsslPlaceholderId]?.let { notificationListPlaceholder ->
@@ -515,7 +508,7 @@
                 viewModel.onNotificationContainerBoundsChanged(
                     notificationListPlaceholder.top.toFloat(),
                     notificationListPlaceholder.bottom.toFloat(),
-                    animate = shouldAnimate
+                    animate = shouldAnimate,
                 )
             }
 
@@ -531,7 +524,7 @@
                                         Int.MAX_VALUE
                                     } else {
                                         view.getTop()
-                                    }
+                                    },
                                 )
                             }
                         } else {
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 be6b0eb..ff84826 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
@@ -37,6 +37,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardSection
 import com.android.systemui.keyguard.ui.binder.KeyguardClockViewBinder
+import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
@@ -49,25 +50,17 @@
 import javax.inject.Inject
 import kotlinx.coroutines.DisposableHandle
 
-internal fun ConstraintSet.setVisibility(
-    views: Iterable<View>,
-    visibility: Int,
-) = views.forEach { view -> this.setVisibility(view.id, visibility) }
+internal fun ConstraintSet.setVisibility(views: Iterable<View>, visibility: Int) =
+    views.forEach { view -> this.setVisibility(view.id, visibility) }
 
-internal fun ConstraintSet.setAlpha(
-    views: Iterable<View>,
-    alpha: Float,
-) = views.forEach { view -> this.setAlpha(view.id, alpha) }
+internal fun ConstraintSet.setAlpha(views: Iterable<View>, alpha: Float) =
+    views.forEach { view -> this.setAlpha(view.id, alpha) }
 
-internal fun ConstraintSet.setScaleX(
-    views: Iterable<View>,
-    alpha: Float,
-) = views.forEach { view -> this.setScaleX(view.id, alpha) }
+internal fun ConstraintSet.setScaleX(views: Iterable<View>, alpha: Float) =
+    views.forEach { view -> this.setScaleX(view.id, alpha) }
 
-internal fun ConstraintSet.setScaleY(
-    views: Iterable<View>,
-    alpha: Float,
-) = views.forEach { view -> this.setScaleY(view.id, alpha) }
+internal fun ConstraintSet.setScaleY(views: Iterable<View>, alpha: Float) =
+    views.forEach { view -> this.setScaleY(view.id, alpha) }
 
 @SysUISingleton
 class ClockSection
@@ -79,6 +72,7 @@
     val smartspaceViewModel: KeyguardSmartspaceViewModel,
     val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>,
     private val rootViewModel: KeyguardRootViewModel,
+    private val aodBurnInViewModel: AodBurnInViewModel,
 ) : KeyguardSection() {
     private var disposableHandle: DisposableHandle? = null
 
@@ -97,6 +91,7 @@
                 clockInteractor,
                 blueprintInteractor.get(),
                 rootViewModel,
+                aodBurnInViewModel,
             )
     }
 
@@ -120,7 +115,7 @@
 
     private fun buildConstraints(
         clock: ClockController,
-        constraintSet: ConstraintSet
+        constraintSet: ConstraintSet,
     ): ConstraintSet {
         // Add constraint between rootView and clockContainer
         applyDefaultConstraints(constraintSet)
@@ -136,8 +131,8 @@
             if (!keyguardClockViewModel.isLargeClockVisible.value) {
                 connect(sharedR.id.bc_smartspace_view, TOP, sharedR.id.date_smartspace_view, BOTTOM)
             } else {
-                setScaleX(getTargetClockFace(clock).views, rootViewModel.burnInModel.value.scale)
-                setScaleY(getTargetClockFace(clock).views, rootViewModel.burnInModel.value.scale)
+                setScaleX(getTargetClockFace(clock).views, aodBurnInViewModel.movement.value.scale)
+                setScaleY(getTargetClockFace(clock).views, aodBurnInViewModel.movement.value.scale)
             }
         }
     }
@@ -156,7 +151,7 @@
                 R.id.weather_clock_bc_smartspace_bottom,
                 Barrier.BOTTOM,
                 getDimen(ENHANCED_SMARTSPACE_HEIGHT),
-                (custR.id.weather_clock_time)
+                (custR.id.weather_clock_time),
             )
             if (
                 rootViewModel.isNotifIconContainerVisible.value.value &&
@@ -168,15 +163,15 @@
                     0,
                     *intArrayOf(
                         R.id.aod_notification_icon_container,
-                        R.id.weather_clock_bc_smartspace_bottom
-                    )
+                        R.id.weather_clock_bc_smartspace_bottom,
+                    ),
                 )
             } else {
                 createBarrier(
                     R.id.weather_clock_date_and_icons_barrier_bottom,
                     Barrier.BOTTOM,
                     0,
-                    *intArrayOf(R.id.weather_clock_bc_smartspace_bottom)
+                    *intArrayOf(R.id.weather_clock_bc_smartspace_bottom),
                 )
             }
         }
@@ -204,7 +199,7 @@
             constrainWidth(R.id.lockscreen_clock_view, WRAP_CONTENT)
             constrainHeight(
                 R.id.lockscreen_clock_view,
-                context.resources.getDimensionPixelSize(custR.dimen.small_clock_height)
+                context.resources.getDimensionPixelSize(custR.dimen.small_clock_height),
             )
             connect(
                 R.id.lockscreen_clock_view,
@@ -212,7 +207,7 @@
                 PARENT_ID,
                 START,
                 context.resources.getDimensionPixelSize(custR.dimen.clock_padding_start) +
-                    context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+                    context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal),
             )
             val smallClockTopMargin = keyguardClockViewModel.getSmallClockTopMargin()
             create(R.id.small_clock_guideline_top, ConstraintSet.HORIZONTAL_GUIDELINE)
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 62b4782..998c1c8 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
@@ -23,6 +23,7 @@
 import com.android.app.animation.Interpolators
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -34,13 +35,17 @@
 import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlin.math.max
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
 
 /**
  * Models UI state for elements that need to apply anti-burn-in tactics when showing in AOD
@@ -50,6 +55,7 @@
 class AodBurnInViewModel
 @Inject
 constructor(
+    @Application private val applicationScope: CoroutineScope,
     private val burnInInteractor: BurnInInteractor,
     private val configurationInteractor: ConfigurationInteractor,
     private val keyguardInteractor: KeyguardInteractor,
@@ -61,91 +67,101 @@
     private val keyguardClockViewModel: KeyguardClockViewModel,
 ) {
     private val TAG = "AodBurnInViewModel"
+    private val burnInParams = MutableStateFlow(BurnInParameters())
 
-    /** All burn-in movement: x,y,scale, to shift items and prevent burn-in */
-    fun movement(
-        burnInParams: BurnInParameters,
-    ): Flow<BurnInModel> {
-        val params =
-            if (burnInParams.minViewY < burnInParams.topInset) {
+    fun updateBurnInParams(params: BurnInParameters) {
+        burnInParams.value =
+            if (params.minViewY < params.topInset) {
                 // minViewY should never be below the inset. Correct it if needed
-                Log.w(TAG, "minViewY is below topInset: $burnInParams")
-                burnInParams.copy(minViewY = burnInParams.topInset)
+                Log.w(TAG, "minViewY is below topInset: $params")
+                params.copy(minViewY = params.topInset)
             } else {
-                burnInParams
+                params
             }
-        return configurationInteractor
-            .dimensionPixelSize(
-                setOf(
-                    R.dimen.keyguard_enter_from_top_translation_y,
-                    R.dimen.keyguard_enter_from_side_translation_x,
-                )
-            )
-            .flatMapLatest { dimens ->
-                combine(
-                    keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
-                    burnIn(params).onStart { emit(BurnInModel()) },
-                    goneToAodTransitionViewModel
-                        .enterFromTopTranslationY(
-                            dimens[R.dimen.keyguard_enter_from_top_translation_y]!!
-                        )
-                        .onStart { emit(StateToValue()) },
-                    goneToAodTransitionViewModel
-                        .enterFromSideTranslationX(
-                            dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
-                        )
-                        .onStart { emit(StateToValue()) },
-                    lockscreenToAodTransitionViewModel
-                        .enterFromSideTranslationX(
-                            dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
-                        )
-                        .onStart { emit(StateToValue()) },
-                    occludedToLockscreenTransitionViewModel.lockscreenTranslationY.onStart {
-                        emit(0f)
-                    },
-                    aodToLockscreenTransitionViewModel.translationY(params.translationY).onStart {
-                        emit(StateToValue())
-                    },
-                ) { flows ->
-                    val keyguardTranslationY = flows[0] as Float
-                    val burnInModel = flows[1] as BurnInModel
-                    val goneToAodTranslationY = flows[2] as StateToValue
-                    val goneToAodTranslationX = flows[3] as StateToValue
-                    val lockscreenToAodTranslationX = flows[4] as StateToValue
-                    val occludedToLockscreen = flows[5] as Float
-                    val aodToLockscreen = flows[6] as StateToValue
-
-                    val translationY =
-                        if (aodToLockscreen.transitionState.isTransitioning()) {
-                            aodToLockscreen.value ?: 0f
-                        } else if (goneToAodTranslationY.transitionState.isTransitioning()) {
-                            (goneToAodTranslationY.value ?: 0f) + burnInModel.translationY
-                        } else {
-                            burnInModel.translationY + occludedToLockscreen + keyguardTranslationY
-                        }
-                    val translationX =
-                        burnInModel.translationX +
-                            (goneToAodTranslationX.value ?: 0f) +
-                            (lockscreenToAodTranslationX.value ?: 0f)
-                    burnInModel.copy(
-                        translationX = translationX.toInt(),
-                        translationY = translationY.toInt(),
-                    )
-                }
-            }
-            .distinctUntilChanged()
     }
 
-    private fun burnIn(
-        params: BurnInParameters,
-    ): Flow<BurnInModel> {
+    /** All burn-in movement: x,y,scale, to shift items and prevent burn-in */
+    val movement: StateFlow<BurnInModel> =
+        burnInParams
+            .flatMapLatest { params ->
+                configurationInteractor
+                    .dimensionPixelSize(
+                        setOf(
+                            R.dimen.keyguard_enter_from_top_translation_y,
+                            R.dimen.keyguard_enter_from_side_translation_x,
+                        )
+                    )
+                    .flatMapLatest { dimens ->
+                        combine(
+                            keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
+                            burnIn(params).onStart { emit(BurnInModel()) },
+                            goneToAodTransitionViewModel
+                                .enterFromTopTranslationY(
+                                    dimens[R.dimen.keyguard_enter_from_top_translation_y]!!
+                                )
+                                .onStart { emit(StateToValue()) },
+                            goneToAodTransitionViewModel
+                                .enterFromSideTranslationX(
+                                    dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
+                                )
+                                .onStart { emit(StateToValue()) },
+                            lockscreenToAodTransitionViewModel
+                                .enterFromSideTranslationX(
+                                    dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
+                                )
+                                .onStart { emit(StateToValue()) },
+                            occludedToLockscreenTransitionViewModel.lockscreenTranslationY.onStart {
+                                emit(0f)
+                            },
+                            aodToLockscreenTransitionViewModel
+                                .translationY(params.translationY)
+                                .onStart { emit(StateToValue()) },
+                        ) { flows ->
+                            val keyguardTranslationY = flows[0] as Float
+                            val burnInModel = flows[1] as BurnInModel
+                            val goneToAodTranslationY = flows[2] as StateToValue
+                            val goneToAodTranslationX = flows[3] as StateToValue
+                            val lockscreenToAodTranslationX = flows[4] as StateToValue
+                            val occludedToLockscreen = flows[5] as Float
+                            val aodToLockscreen = flows[6] as StateToValue
+
+                            val translationY =
+                                if (aodToLockscreen.transitionState.isTransitioning()) {
+                                    aodToLockscreen.value ?: 0f
+                                } else if (
+                                    goneToAodTranslationY.transitionState.isTransitioning()
+                                ) {
+                                    (goneToAodTranslationY.value ?: 0f) + burnInModel.translationY
+                                } else {
+                                    burnInModel.translationY +
+                                        occludedToLockscreen +
+                                        keyguardTranslationY
+                                }
+                            val translationX =
+                                burnInModel.translationX +
+                                    (goneToAodTranslationX.value ?: 0f) +
+                                    (lockscreenToAodTranslationX.value ?: 0f)
+                            burnInModel.copy(
+                                translationX = translationX.toInt(),
+                                translationY = translationY.toInt(),
+                            )
+                        }
+                    }
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = BurnInModel(),
+            )
+
+    private fun burnIn(params: BurnInParameters): Flow<BurnInModel> {
         return combine(
             keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).map {
                 Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it)
             },
             burnInInteractor.burnIn(
                 xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
-                yDimenResourceId = R.dimen.burn_in_prevention_offset_y
+                yDimenResourceId = R.dimen.burn_in_prevention_offset_y,
             ),
         ) { interpolated, burnIn ->
             val useAltAod =
@@ -168,7 +184,7 @@
                 translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(),
                 translationY = translationY,
                 scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated),
-                scaleClockOnly = useScaleOnly
+                scaleClockOnly = useScaleOnly,
             )
         }
     }
@@ -181,7 +197,7 @@
     /** The min y-value of the visible elements on lockscreen */
     val minViewY: Int = Int.MAX_VALUE,
     /** The current y translation of the view */
-    val translationY: () -> Float? = { null }
+    val translationY: () -> Float? = { null },
 )
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 38ca888..efb5744 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -20,7 +20,6 @@
 import android.graphics.Point
 import android.util.MathUtils
 import android.view.View.VISIBLE
-import com.android.app.tracing.coroutines.launch
 import com.android.systemui.Flags.newAodTransition
 import com.android.systemui.common.shared.model.NotificationContainerBounds
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
@@ -29,7 +28,6 @@
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.BurnInModel
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
@@ -58,12 +56,9 @@
 import kotlin.math.max
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.combineTransform
 import kotlinx.coroutines.flow.distinctUntilChanged
@@ -127,10 +122,6 @@
     private val aodAlphaViewModel: AodAlphaViewModel,
     private val shadeInteractor: ShadeInteractor,
 ) {
-    private var burnInJob: Job? = null
-    private val _burnInModel = MutableStateFlow(BurnInModel())
-    val burnInModel = _burnInModel.asStateFlow()
-
     val burnInLayerVisibility: Flow<Int> =
         keyguardTransitionInteractor.startedKeyguardTransitionStep
             .filter { it.to == AOD || it.to == LOCKSCREEN }
@@ -283,30 +274,24 @@
     /** For elements that appear and move during the animation -> AOD */
     val burnInLayerAlpha: Flow<Float> = aodAlphaViewModel.alpha
 
-    val translationY: Flow<Float> = burnInModel.map { it.translationY.toFloat() }
+    val translationY: Flow<Float> = aodBurnInViewModel.movement.map { it.translationY.toFloat() }
 
     val translationX: Flow<StateToValue> =
         merge(
-            burnInModel.map { StateToValue(to = AOD, value = it.translationX.toFloat()) },
+            aodBurnInViewModel.movement.map {
+                StateToValue(to = AOD, value = it.translationX.toFloat())
+            },
             lockscreenToGlanceableHubTransitionViewModel.keyguardTranslationX,
             glanceableHubToLockscreenTransitionViewModel.keyguardTranslationX,
         )
 
     fun updateBurnInParams(params: BurnInParameters) {
-        burnInJob?.cancel()
-
-        burnInJob =
-            applicationScope.launch("$TAG#aodBurnInViewModel") {
-                aodBurnInViewModel.movement(params).collect { _burnInModel.value = it }
-            }
+        aodBurnInViewModel.updateBurnInParams(params)
     }
 
     val scale: Flow<BurnInScaleViewModel> =
-        burnInModel.map {
-            BurnInScaleViewModel(
-                scale = it.scale,
-                scaleClockOnly = it.scaleClockOnly,
-            )
+        aodBurnInViewModel.movement.map {
+            BurnInScaleViewModel(scale = it.scale, scaleClockOnly = it.scaleClockOnly)
         }
 
     /** Is the notification icon container visible? */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 5ae5a32..b22143f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -16,16 +16,12 @@
 
 package com.android.systemui.statusbar.notification.stack.ui.viewbinder
 
-import android.view.View
-import android.view.WindowInsets
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.common.ui.view.onApplyWindowInsets
 import com.android.systemui.common.ui.view.onLayoutChanged
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
 import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -39,9 +35,6 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.update
 import kotlinx.coroutines.launch
 
 /** Binds the shared notification container to its view-model. */
@@ -85,7 +78,6 @@
                 }
             }
 
-        val burnInParams = MutableStateFlow(BurnInParameters())
         val viewState = ViewStateAccessor(alpha = { controller.getAlpha() })
 
         /*
@@ -140,9 +132,7 @@
 
                     if (!SceneContainerFlag.isEnabled) {
                         launch {
-                            burnInParams
-                                .flatMapLatest { params -> viewModel.translationY(params) }
-                                .collect { y -> controller.setTranslationY(y) }
+                            viewModel.translationY.collect { y -> controller.setTranslationY(y) }
                         }
                     }
 
@@ -178,16 +168,6 @@
 
         controller.setOnHeightChangedRunnable { viewModel.notificationStackChanged() }
         disposables += DisposableHandle { controller.setOnHeightChangedRunnable(null) }
-
-        disposables +=
-            view.onApplyWindowInsets { _: View, insets: WindowInsets ->
-                val insetTypes = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
-                burnInParams.update { current ->
-                    current.copy(topInset = insets.getInsetsIgnoringVisibility(insetTypes).top)
-                }
-                insets
-            }
-
         disposables += view.onLayoutChanged { viewModel.notificationStackChanged() }
 
         return disposables
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 8ca26be..57be629 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.keyguard.ui.viewmodel.AodToGoneTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.AodToOccludedTransitionViewModel
-import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
 import com.android.systemui.keyguard.ui.viewmodel.DozingToGlanceableHubTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.DozingToLockscreenTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.DozingToOccludedTransitionViewModel
@@ -536,20 +535,18 @@
      * Under certain scenarios, such as swiping up on the lockscreen, the container will need to be
      * translated as the keyguard fades out.
      */
-    fun translationY(params: BurnInParameters): Flow<Float> {
-        // with SceneContainer, x translation is handled by views, y is handled by compose
-        SceneContainerFlag.assertInLegacyMode()
-        return combine(
-                aodBurnInViewModel
-                    .movement(params)
-                    .map { it.translationY.toFloat() }
-                    .onStart { emit(0f) },
+    val translationY: Flow<Float> =
+        combine(
+                aodBurnInViewModel.movement.map { it.translationY.toFloat() }.onStart { emit(0f) },
                 isOnLockscreenWithoutShade,
                 merge(
                     keyguardInteractor.keyguardTranslationY,
                     occludedToLockscreenTransitionViewModel.lockscreenTranslationY,
                 ),
             ) { burnInY, isOnLockscreenWithoutShade, translationY ->
+                // with SceneContainer, x translation is handled by views, y is handled by compose
+                SceneContainerFlag.assertInLegacyMode()
+
                 if (isOnLockscreenWithoutShade) {
                     burnInY + translationY
                 } else {
@@ -557,7 +554,6 @@
                 }
             }
             .dumpWhileCollecting("translationY")
-    }
 
     /** Horizontal translation to apply to the container. */
     val translationX: Flow<Float> =
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 6e381ca..0b944f0 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.keyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardSmartspaceInteractor
 import com.android.systemui.keyguard.shared.model.ClockSize
+import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel
@@ -120,6 +121,7 @@
                     keyguardSmartspaceViewModel,
                     { keyguardBlueprintInteractor },
                     keyguardRootViewModel,
+                    aodBurnInViewModel,
                 )
         }
     }
@@ -313,7 +315,7 @@
             referencedIds.contentEquals(
                 intArrayOf(
                     com.android.systemui.shared.R.id.bc_smartspace_view,
-                    R.id.aod_notification_icon_container
+                    R.id.aod_notification_icon_container,
                 )
             )
         }
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 fb12897..12d7c49 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.view.layout.sections.SmartspaceSection
+import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
 import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel
@@ -41,6 +42,7 @@
             smartspaceViewModel = keyguardSmartspaceViewModel,
             blueprintInteractor = { keyguardBlueprintInteractor },
             rootViewModel = keyguardRootViewModel,
+            aodBurnInViewModel = aodBurnInViewModel,
         )
     }
 
@@ -95,11 +97,7 @@
     Kosmos.Fixture {
         spy(
             KeyguardBlueprintRepository(
-                blueprints =
-                    setOf(
-                        defaultKeyguardBlueprint,
-                        splitShadeBlueprint,
-                    ),
+                blueprints = setOf(defaultKeyguardBlueprint, splitShadeBlueprint),
                 handler = fakeExecutorHandler,
                 assert = mock(),
             )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
index 6cf668c..c3c2c8c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
@@ -24,10 +24,12 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 var Kosmos.aodBurnInViewModel by Fixture {
     AodBurnInViewModel(
+        applicationScope = applicationCoroutineScope,
         burnInInteractor = burnInInteractor,
         configurationInteractor = configurationInteractor,
         keyguardInteractor = keyguardInteractor,