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,