summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ale Nijamkin <nijamkin@google.com> 2024-01-03 01:10:13 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-01-03 01:10:13 +0000
commit867d604f41ce5852a1459310029ceda849c7f89b (patch)
treedae6959d968126f8527266235bda0b9d56334114
parent37ad976c77c471f3b5ac404913466147f6f7c8da (diff)
parent0e2ae4ee41233044c09d0bea33627d5faadf3afb (diff)
Merge changes I10c4cbc5,I1b4affba into main
* changes: [flexiglass] Adds horizontal spacing to status bar section. [flexiglass] Adds burn-in to smartspace section elements.
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/ViewBasedLockscreenContent.kt10
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt94
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt18
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt18
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt68
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt10
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt33
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelTest.kt108
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt290
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt207
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt74
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModel.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt192
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt133
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt498
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractorKosmos.kt27
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelKosmos.kt33
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt39
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt2
32 files changed, 1288 insertions, 694 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/ViewBasedLockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/ViewBasedLockscreenContent.kt
index 976161b3beb7..8119d2a119ca 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/ViewBasedLockscreenContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/ViewBasedLockscreenContent.kt
@@ -31,6 +31,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.qualifiers.KeyguardRootView
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.notifications.ui.composable.NotificationStack
import com.android.systemui.res.R
@@ -47,8 +48,9 @@ import javax.inject.Inject
class ViewBasedLockscreenContent
@Inject
constructor(
- private val viewModel: LockscreenSceneViewModel,
+ private val lockscreenSceneViewModel: LockscreenSceneViewModel,
@KeyguardRootView private val viewProvider: () -> @JvmSuppressWildcards View,
+ private val keyguardRootViewModel: KeyguardRootViewModel,
) {
@Composable
fun SceneScope.Content(
@@ -59,7 +61,7 @@ constructor(
}
LockscreenLongPress(
- viewModel = viewModel.longPress,
+ viewModel = lockscreenSceneViewModel.longPress,
modifier = modifier,
) { onSettingsMenuPlaced ->
AndroidView(
@@ -74,7 +76,7 @@ constructor(
)
val notificationStackPosition by
- viewModel.keyguardRoot.notificationBounds.collectAsState()
+ keyguardRootViewModel.notificationBounds.collectAsState()
Layout(
modifier =
@@ -92,7 +94,7 @@ constructor(
},
content = {
NotificationStack(
- viewModel = viewModel.notifications,
+ viewModel = lockscreenSceneViewModel.notifications,
isScrimVisible = false,
)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt
new file mode 100644
index 000000000000..c4184905f28d
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.composable.blueprint
+
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.displayCutout
+import androidx.compose.foundation.layout.systemBars
+import androidx.compose.foundation.layout.union
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.platform.LocalDensity
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
+import com.android.systemui.plugins.clocks.ClockController
+import kotlin.math.min
+import kotlin.math.roundToInt
+
+/** Produces a [BurnInState] that can be used to query the `LockscreenBurnInViewModel` flows. */
+@Composable
+fun rememberBurnIn(
+ clockInteractor: KeyguardClockInteractor,
+): BurnInState {
+ val clock by clockInteractor.currentClock.collectAsState()
+
+ val (smartspaceTop, onSmartspaceTopChanged) = remember { mutableStateOf<Float?>(null) }
+ val (smallClockTop, onSmallClockTopChanged) = remember { mutableStateOf<Float?>(null) }
+
+ val topmostTop =
+ when {
+ smartspaceTop != null && smallClockTop != null -> min(smartspaceTop, smallClockTop)
+ smartspaceTop != null -> smartspaceTop
+ smallClockTop != null -> smallClockTop
+ else -> 0f
+ }.roundToInt()
+
+ val params = rememberBurnInParameters(clock, topmostTop)
+
+ return remember(params, onSmartspaceTopChanged, onSmallClockTopChanged) {
+ BurnInState(
+ parameters = params,
+ onSmartspaceTopChanged = onSmartspaceTopChanged,
+ onSmallClockTopChanged = onSmallClockTopChanged,
+ )
+ }
+}
+
+@Composable
+private fun rememberBurnInParameters(
+ clock: ClockController?,
+ topmostTop: Int,
+): BurnInParameters {
+ val density = LocalDensity.current
+ val topInset = WindowInsets.systemBars.union(WindowInsets.displayCutout).getTop(density)
+
+ return remember(clock, topInset, topmostTop) {
+ BurnInParameters(
+ clockControllerProvider = { clock },
+ topInset = topInset,
+ statusViewTop = topmostTop,
+ )
+ }
+}
+
+data class BurnInState(
+ /** Parameters for use with the `LockscreenBurnInViewModel. */
+ val parameters: BurnInParameters,
+ /**
+ * Callback to invoke when the top coordinate of the smartspace element is updated, pass `null`
+ * when the element is not shown.
+ */
+ val onSmartspaceTopChanged: (Float?) -> Unit,
+ /**
+ * Callback to invoke when the top coordinate of the small clock element is updated, pass `null`
+ * when the element is not shown.
+ */
+ val onSmallClockTopChanged: (Float?) -> Unit,
+)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index d9d98cbd2da6..7385a251200e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.SceneScope
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.ui.composable.LockscreenLongPress
import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
@@ -55,6 +56,7 @@ constructor(
private val ambientIndicationSection: AmbientIndicationSection,
private val bottomAreaSection: BottomAreaSection,
private val settingsMenuSection: SettingsMenuSection,
+ private val clockInteractor: KeyguardClockInteractor,
) : LockscreenSceneBlueprint {
override val id: String = "default"
@@ -62,6 +64,7 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
+ val burnIn = rememberBurnIn(clockInteractor)
LockscreenLongPress(
viewModel = viewModel.longPress,
@@ -74,8 +77,19 @@ constructor(
modifier = Modifier.fillMaxWidth(),
) {
with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { SmallClock(modifier = Modifier.fillMaxWidth()) }
- with(smartSpaceSection) { SmartSpace(modifier = Modifier.fillMaxWidth()) }
+ with(clockSection) {
+ SmallClock(
+ onTopChanged = burnIn.onSmallClockTopChanged,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
+ with(smartSpaceSection) {
+ SmartSpace(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmartspaceTopChanged,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
with(notificationSection) {
Notifications(modifier = Modifier.fillMaxWidth().weight(1f))
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
index 4704f5c3d1eb..acd47797baca 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
@@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.SceneScope
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.ui.composable.LockscreenLongPress
import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
@@ -55,6 +56,7 @@ constructor(
private val ambientIndicationSection: AmbientIndicationSection,
private val bottomAreaSection: BottomAreaSection,
private val settingsMenuSection: SettingsMenuSection,
+ private val clockInteractor: KeyguardClockInteractor,
) : LockscreenSceneBlueprint {
override val id: String = "shortcuts-besides-udfps"
@@ -62,6 +64,7 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
+ val burnIn = rememberBurnIn(clockInteractor)
LockscreenLongPress(
viewModel = viewModel.longPress,
@@ -74,8 +77,19 @@ constructor(
modifier = Modifier.fillMaxWidth(),
) {
with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { SmallClock(modifier = Modifier.fillMaxWidth()) }
- with(smartSpaceSection) { SmartSpace(modifier = Modifier.fillMaxWidth()) }
+ with(clockSection) {
+ SmallClock(
+ onTopChanged = burnIn.onSmallClockTopChanged,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
+ with(smartSpaceSection) {
+ SmartSpace(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmartspaceTopChanged,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
with(notificationSection) {
Notifications(modifier = Modifier.fillMaxWidth().weight(1f))
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
new file mode 100644
index 000000000000..f9dd04b66b1f
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.composable.modifier
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.layout.boundsInWindow
+import androidx.compose.ui.layout.onPlaced
+import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
+import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
+import com.android.systemui.keyguard.ui.viewmodel.BurnInScaleViewModel
+
+/**
+ * Modifies the composable to account for anti-burn in translation, alpha, and scaling.
+ *
+ * Please override [isClock] as `true` if the composable is an element that's part of a clock.
+ */
+@Composable
+fun Modifier.burnInAware(
+ viewModel: AodBurnInViewModel,
+ params: BurnInParameters,
+ isClock: Boolean = false,
+): Modifier {
+ val translationX by viewModel.translationX(params).collectAsState(initial = 0f)
+ val translationY by viewModel.translationY(params).collectAsState(initial = 0f)
+ val alpha by viewModel.alpha.collectAsState(initial = 1f)
+ val scaleViewModel by viewModel.scale(params).collectAsState(initial = BurnInScaleViewModel())
+
+ return this.graphicsLayer {
+ val scale =
+ when {
+ scaleViewModel.scaleClockOnly && isClock -> scaleViewModel.scale
+ !scaleViewModel.scaleClockOnly -> scaleViewModel.scale
+ else -> 1f
+ }
+
+ this.translationX = translationX
+ this.translationY = translationY
+ this.alpha = alpha
+ this.scaleX = scale
+ this.scaleY = scale
+ }
+}
+
+/** Reports the "top" coordinate of the modified composable to the given [consumer]. */
+@Composable
+fun Modifier.onTopPlacementChanged(
+ consumer: (Float) -> Unit,
+): Modifier {
+ return onPlaced { coordinates -> consumer(coordinates.boundsInWindow().top) }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
index db20f65ee78d..4f3498e8dff5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
@@ -35,10 +35,10 @@ import com.android.systemui.animation.view.LaunchableImageView
import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder
import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
+import com.android.systemui.keyguard.ui.viewmodel.AodAlphaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
import com.android.systemui.statusbar.KeyguardIndicationController
@@ -55,7 +55,7 @@ constructor(
private val vibratorHelper: VibratorHelper,
private val indicationController: KeyguardIndicationController,
private val indicationAreaViewModel: KeyguardIndicationAreaViewModel,
- private val keyguardRootViewModel: KeyguardRootViewModel,
+ private val alphaViewModel: AodAlphaViewModel,
) {
/**
* Renders a single lockscreen shortcut.
@@ -101,7 +101,7 @@ constructor(
) {
IndicationArea(
indicationAreaViewModel = indicationAreaViewModel,
- keyguardRootViewModel = keyguardRootViewModel,
+ alphaViewModel = alphaViewModel,
indicationController = indicationController,
)
}
@@ -179,7 +179,7 @@ constructor(
@Composable
private fun IndicationArea(
indicationAreaViewModel: KeyguardIndicationAreaViewModel,
- keyguardRootViewModel: KeyguardRootViewModel,
+ alphaViewModel: AodAlphaViewModel,
indicationController: KeyguardIndicationController,
modifier: Modifier = Modifier,
) {
@@ -192,7 +192,7 @@ constructor(
KeyguardIndicationAreaBinder.bind(
view = view,
viewModel = indicationAreaViewModel,
- keyguardRootViewModel = keyguardRootViewModel,
+ aodAlphaViewModel = alphaViewModel,
indicationController = indicationController,
)
)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt
index eaf8063b6f15..0b49922a8412 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/ClockSection.kt
@@ -26,6 +26,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
+import com.android.systemui.keyguard.ui.composable.modifier.onTopPlacementChanged
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import javax.inject.Inject
@@ -35,8 +36,12 @@ constructor(
private val viewModel: KeyguardClockViewModel,
) {
@Composable
- fun SceneScope.SmallClock(modifier: Modifier = Modifier) {
+ fun SceneScope.SmallClock(
+ onTopChanged: (top: Float?) -> Unit,
+ modifier: Modifier = Modifier,
+ ) {
if (viewModel.useLargeClock) {
+ onTopChanged(null)
return
}
@@ -45,7 +50,10 @@ constructor(
modifier = modifier,
) {
Box(
- modifier = Modifier.fillMaxWidth().background(Color.Magenta),
+ modifier =
+ Modifier.fillMaxWidth()
+ .background(Color.Magenta)
+ .onTopPlacementChanged(onTopChanged)
) {
Text(
text = "TODO(b/316211368): Small clock",
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
index 3c49cbcc1f7a..9b718444b75c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
@@ -36,6 +36,10 @@ import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.keyguard.ui.composable.modifier.burnInAware
+import com.android.systemui.keyguard.ui.composable.modifier.onTopPlacementChanged
+import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
+import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
import com.android.systemui.res.R
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
@@ -47,11 +51,16 @@ constructor(
private val lockscreenSmartspaceController: LockscreenSmartspaceController,
private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController,
private val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel,
+ private val aodBurnInViewModel: AodBurnInViewModel,
) {
@Composable
- fun SceneScope.SmartSpace(modifier: Modifier = Modifier) {
+ fun SceneScope.SmartSpace(
+ burnInParams: BurnInParameters,
+ onTopChanged: (top: Float?) -> Unit,
+ modifier: Modifier = Modifier,
+ ) {
Column(
- modifier = modifier.element(SmartSpaceElementKey),
+ modifier = modifier.element(SmartSpaceElementKey).onTopPlacementChanged(onTopChanged),
) {
if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) {
return
@@ -71,9 +80,21 @@ constructor(
start = paddingBelowClockStart,
),
) {
- Date()
+ Date(
+ modifier =
+ Modifier.burnInAware(
+ viewModel = aodBurnInViewModel,
+ params = burnInParams,
+ ),
+ )
Spacer(modifier = Modifier.width(4.dp))
- Weather()
+ Weather(
+ modifier =
+ Modifier.burnInAware(
+ viewModel = aodBurnInViewModel,
+ params = burnInParams,
+ ),
+ )
}
}
@@ -84,6 +105,10 @@ constructor(
start = paddingBelowClockStart,
end = paddingBelowClockEnd,
)
+ .burnInAware(
+ viewModel = aodBurnInViewModel,
+ params = burnInParams,
+ ),
)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt
index 6811eb4cea5c..5727e3436126 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt
@@ -21,9 +21,11 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
@@ -78,7 +80,7 @@ constructor(
view
},
modifier =
- Modifier.fillMaxWidth().height {
+ Modifier.fillMaxWidth().padding(horizontal = 16.dp).height {
Utils.getStatusBarHeaderHeightKeyguard(context)
},
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelTest.kt
new file mode 100644
index 000000000000..83782e214780
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelTest.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AodAlphaViewModelTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var occludedToLockscreenTransitionViewModel:
+ OccludedToLockscreenTransitionViewModel
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val keyguardRepository = kosmos.fakeKeyguardRepository
+ private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+ private val occludedToLockscreenAlpha = MutableStateFlow(0f)
+
+ private lateinit var underTest: AodAlphaViewModel
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(occludedToLockscreenTransitionViewModel.lockscreenAlpha)
+ .thenReturn(occludedToLockscreenAlpha)
+ kosmos.occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel
+
+ underTest = kosmos.aodAlphaViewModel
+ }
+
+ @Test
+ fun alpha() =
+ testScope.runTest {
+ val alpha by collectLastValue(underTest.alpha)
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.OFF,
+ to = KeyguardState.LOCKSCREEN,
+ testScope = testScope,
+ )
+
+ keyguardRepository.setKeyguardAlpha(0.1f)
+ assertThat(alpha).isEqualTo(0.1f)
+ keyguardRepository.setKeyguardAlpha(0.5f)
+ assertThat(alpha).isEqualTo(0.5f)
+ keyguardRepository.setKeyguardAlpha(0.2f)
+ assertThat(alpha).isEqualTo(0.2f)
+ keyguardRepository.setKeyguardAlpha(0f)
+ assertThat(alpha).isEqualTo(0f)
+ occludedToLockscreenAlpha.value = 0.8f
+ assertThat(alpha).isEqualTo(0.8f)
+ }
+
+ @Test
+ fun alpha_whenGone_equalsZero() =
+ testScope.runTest {
+ val alpha by collectLastValue(underTest.alpha)
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ testScope = testScope,
+ )
+
+ keyguardRepository.setKeyguardAlpha(0.1f)
+ assertThat(alpha).isEqualTo(0f)
+ keyguardRepository.setKeyguardAlpha(0.5f)
+ assertThat(alpha).isEqualTo(0f)
+ keyguardRepository.setKeyguardAlpha(1f)
+ assertThat(alpha).isEqualTo(0f)
+ }
+}
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
new file mode 100644
index 000000000000..0543bc257440
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
+import com.android.systemui.keyguard.domain.interactor.burnInInteractor
+import com.android.systemui.keyguard.shared.model.BurnInModel
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Answers
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AodBurnInViewModelTest : SysuiTestCase() {
+
+ @Mock private lateinit var burnInInteractor: BurnInInteractor
+ @Mock private lateinit var goneToAodTransitionViewModel: GoneToAodTransitionViewModel
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+ private lateinit var underTest: AodBurnInViewModel
+
+ private var burnInParameters =
+ BurnInParameters(
+ clockControllerProvider = { clockController },
+ )
+ private val burnInFlow = MutableStateFlow(BurnInModel())
+ private val enterFromTopAnimationAlpha = MutableStateFlow(0f)
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow)
+ kosmos.burnInInteractor = burnInInteractor
+ whenever(goneToAodTransitionViewModel.enterFromTopAnimationAlpha)
+ .thenReturn(enterFromTopAnimationAlpha)
+ whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
+ .thenReturn(emptyFlow())
+ kosmos.goneToAodTransitionViewModel = goneToAodTransitionViewModel
+
+ underTest = kosmos.aodBurnInViewModel
+ }
+
+ @Test
+ fun translationY_initializedToZero() =
+ testScope.runTest {
+ val translationY by collectLastValue(underTest.translationY(burnInParameters))
+ assertThat(translationY).isEqualTo(0)
+ }
+
+ @Test
+ fun translationAndScale_whenNotDozing() =
+ testScope.runTest {
+ val translationX by collectLastValue(underTest.translationX(burnInParameters))
+ val translationY by collectLastValue(underTest.translationY(burnInParameters))
+ val scale by collectLastValue(underTest.scale(burnInParameters))
+
+ // Set to not dozing (on lockscreen)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.AOD,
+ to = KeyguardState.LOCKSCREEN,
+ value = 1f,
+ transitionState = TransitionState.FINISHED
+ ),
+ validateStep = false,
+ )
+
+ // Trigger a change to the burn-in model
+ burnInFlow.value =
+ BurnInModel(
+ translationX = 20,
+ translationY = 30,
+ scale = 0.5f,
+ )
+
+ assertThat(translationX).isEqualTo(0)
+ assertThat(translationY).isEqualTo(0)
+ assertThat(scale)
+ .isEqualTo(
+ BurnInScaleViewModel(
+ scale = 1f,
+ scaleClockOnly = true,
+ )
+ )
+ }
+
+ @Test
+ fun translationAndScale_whenFullyDozing() =
+ testScope.runTest {
+ burnInParameters = burnInParameters.copy(statusViewTop = 100)
+ val translationX by collectLastValue(underTest.translationX(burnInParameters))
+ val translationY by collectLastValue(underTest.translationY(burnInParameters))
+ val scale by collectLastValue(underTest.scale(burnInParameters))
+
+ // Set to dozing (on AOD)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ value = 1f,
+ transitionState = TransitionState.FINISHED
+ ),
+ validateStep = false,
+ )
+ // Trigger a change to the burn-in model
+ burnInFlow.value =
+ BurnInModel(
+ translationX = 20,
+ translationY = 30,
+ scale = 0.5f,
+ )
+
+ assertThat(translationX).isEqualTo(20)
+ assertThat(translationY).isEqualTo(30)
+ assertThat(scale)
+ .isEqualTo(
+ BurnInScaleViewModel(
+ scale = 0.5f,
+ scaleClockOnly = true,
+ )
+ )
+
+ // Set to the beginning of GONE->AOD transition
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ value = 0f,
+ transitionState = TransitionState.STARTED
+ ),
+ validateStep = false,
+ )
+ assertThat(translationX).isEqualTo(0)
+ assertThat(translationY).isEqualTo(0)
+ assertThat(scale)
+ .isEqualTo(
+ BurnInScaleViewModel(
+ scale = 1f,
+ scaleClockOnly = true,
+ )
+ )
+ }
+
+ @Test
+ fun translationAndScale_whenFullyDozing_staysOutOfTopInset() =
+ testScope.runTest {
+ burnInParameters =
+ burnInParameters.copy(
+ statusViewTop = 100,
+ topInset = 80,
+ )
+ val translationX by collectLastValue(underTest.translationX(burnInParameters))
+ val translationY by collectLastValue(underTest.translationY(burnInParameters))
+ val scale by collectLastValue(underTest.scale(burnInParameters))
+
+ // Set to dozing (on AOD)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ value = 1f,
+ transitionState = TransitionState.FINISHED
+ ),
+ validateStep = false,
+ )
+
+ // Trigger a change to the burn-in model
+ burnInFlow.value =
+ BurnInModel(
+ translationX = 20,
+ translationY = -30,
+ scale = 0.5f,
+ )
+ assertThat(translationX).isEqualTo(20)
+ // -20 instead of -30, due to inset of 80
+ assertThat(translationY).isEqualTo(-20)
+ assertThat(scale)
+ .isEqualTo(
+ BurnInScaleViewModel(
+ scale = 0.5f,
+ scaleClockOnly = true,
+ )
+ )
+
+ // Set to the beginning of GONE->AOD transition
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ value = 0f,
+ transitionState = TransitionState.STARTED
+ ),
+ validateStep = false,
+ )
+ assertThat(translationX).isEqualTo(0)
+ assertThat(translationY).isEqualTo(0)
+ assertThat(scale)
+ .isEqualTo(
+ BurnInScaleViewModel(
+ scale = 1f,
+ scaleClockOnly = true,
+ )
+ )
+ }
+
+ @Test
+ fun translationAndScale_useScaleOnly() =
+ testScope.runTest {
+ whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true)
+
+ val translationX by collectLastValue(underTest.translationX(burnInParameters))
+ val translationY by collectLastValue(underTest.translationY(burnInParameters))
+ val scale by collectLastValue(underTest.scale(burnInParameters))
+
+ // Set to dozing (on AOD)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ value = 1f,
+ transitionState = TransitionState.FINISHED
+ ),
+ validateStep = false,
+ )
+
+ // Trigger a change to the burn-in model
+ burnInFlow.value =
+ BurnInModel(
+ translationX = 20,
+ translationY = 30,
+ scale = 0.5f,
+ )
+
+ assertThat(translationX).isEqualTo(0)
+ assertThat(translationY).isEqualTo(0)
+ assertThat(scale).isEqualTo(BurnInScaleViewModel(scale = 0.5f, scaleClockOnly = false))
+ }
+
+ @Test
+ fun alpha() =
+ testScope.runTest {
+ val alpha by collectLastValue(underTest.alpha)
+
+ enterFromTopAnimationAlpha.value = 0.2f
+ assertThat(alpha).isEqualTo(0.2f)
+
+ enterFromTopAnimationAlpha.value = 1f
+ assertThat(alpha).isEqualTo(1f)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
new file mode 100644
index 000000000000..7c3dc972cfd0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags as AConfigFlags
+import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.notification.data.repository.fakeNotificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.phone.dozeParameters
+import com.android.systemui.statusbar.phone.screenOffAnimationController
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.ui.isAnimating
+import com.android.systemui.util.ui.stopAnimating
+import com.android.systemui.util.ui.value
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardRootViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+ private val screenOffAnimationController = kosmos.screenOffAnimationController
+ private val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
+ private val fakeNotificationsKeyguardViewStateRepository =
+ kosmos.fakeNotificationsKeyguardViewStateRepository
+ private val dozeParameters = kosmos.dozeParameters
+ private val underTest = kosmos.keyguardRootViewModel
+
+ @Before
+ fun setUp() {
+ mSetFlagsRule.enableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
+ mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
+ mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+ }
+
+ @Test
+ fun burnInLayerVisibility() =
+ testScope.runTest {
+ val burnInLayerVisibility by collectLastValue(underTest.burnInLayerVisibility)
+
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.AOD,
+ value = 0f,
+ transitionState = TransitionState.STARTED
+ ),
+ validateStep = false,
+ )
+ assertThat(burnInLayerVisibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
+ fun iconContainer_isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.OFF,
+ to = KeyguardState.GONE,
+ testScope,
+ )
+ whenever(screenOffAnimationController.shouldShowAodIconsWhenShade()).thenReturn(false)
+ runCurrent()
+
+ assertThat(isVisible?.value).isFalse()
+ assertThat(isVisible?.isAnimating).isFalse()
+ }
+
+ @Test
+ fun iconContainer_isVisible_bypassEnabled() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ deviceEntryRepository.setBypassEnabled(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isTrue()
+ }
+
+ @Test
+ fun iconContainer_isNotVisible_pulseExpanding_notBypassing() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(true)
+ deviceEntryRepository.setBypassEnabled(false)
+ runCurrent()
+
+ assertThat(isVisible?.value).isEqualTo(false)
+ }
+
+ @Test
+ fun iconContainer_isVisible_notifsFullyHidden_bypassEnabled() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(true)
+ fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isTrue()
+ assertThat(isVisible?.isAnimating).isTrue()
+ }
+
+ @Test
+ fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_aodDisabled() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParameters.alwaysOn).thenReturn(false)
+ fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isTrue()
+ assertThat(isVisible?.isAnimating).isFalse()
+ }
+
+ @Test
+ fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_displayNeedsBlanking() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParameters.alwaysOn).thenReturn(true)
+ whenever(dozeParameters.displayNeedsBlanking).thenReturn(true)
+ fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isTrue()
+ assertThat(isVisible?.isAnimating).isFalse()
+ }
+
+ @Test
+ fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParameters.alwaysOn).thenReturn(true)
+ whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
+ fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isTrue()
+ assertThat(isVisible?.isAnimating).isTrue()
+ }
+
+ @Test
+ fun isIconContainerVisible_stopAnimation() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParameters.alwaysOn).thenReturn(true)
+ whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
+ fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible?.isAnimating).isEqualTo(true)
+ isVisible?.stopAnimating()
+ runCurrent()
+
+ assertThat(isVisible?.isAnimating).isEqualTo(false)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index d07836d3abce..74d309c1d359 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.keyguard.ui.viewmodel
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -26,6 +28,7 @@ import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -94,7 +97,6 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
KeyguardLongPressViewModel(
interactor = mock(),
),
- keyguardRoot = utils.keyguardRootViewModel(),
notifications = utils.notificationsPlaceholderViewModel(),
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 224903ff36b8..efd4f9bdf449 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -153,7 +153,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
KeyguardLongPressViewModel(
interactor = mock(),
),
- keyguardRoot = utils.keyguardRootViewModel(),
notifications = utils.notificationsPlaceholderViewModel(),
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index af5d48d9ae07..50836fe9ee51 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -39,6 +39,7 @@ import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder
import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.keyguard.ui.view.layout.KeyguardBlueprintCommandListener
+import com.android.systemui.keyguard.ui.viewmodel.AodAlphaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
@@ -83,6 +84,7 @@ constructor(
private val deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor,
private val vibratorHelper: VibratorHelper,
private val falsingManager: FalsingManager,
+ private val aodAlphaViewModel: AodAlphaViewModel,
) : CoreStartable {
private var rootViewHandle: DisposableHandle? = null
@@ -126,7 +128,7 @@ constructor(
KeyguardIndicationAreaBinder.bind(
notificationShadeWindowView.requireViewById(R.id.keyguard_indication_area),
keyguardIndicationAreaViewModel,
- keyguardRootViewModel,
+ aodAlphaViewModel,
indicationController,
)
}
@@ -148,7 +150,6 @@ constructor(
keyguardRootView,
keyguardRootViewModel,
configuration,
- featureFlags,
occludingAppDeviceEntryMessageViewModel,
chipbarCoordinator,
screenOffAnimationController,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
index 4c33d905b785..7c1368af652c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
@@ -23,8 +23,8 @@ import android.widget.TextView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.Flags.keyguardBottomAreaRefactor
+import com.android.systemui.keyguard.ui.viewmodel.AodAlphaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.statusbar.KeyguardIndicationController
@@ -51,7 +51,7 @@ object KeyguardIndicationAreaBinder {
fun bind(
view: ViewGroup,
viewModel: KeyguardIndicationAreaViewModel,
- keyguardRootViewModel: KeyguardRootViewModel,
+ aodAlphaViewModel: AodAlphaViewModel,
indicationController: KeyguardIndicationController,
): DisposableHandle {
indicationController.setIndicationArea(view)
@@ -69,7 +69,7 @@ object KeyguardIndicationAreaBinder {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
if (keyguardBottomAreaRefactor()) {
- keyguardRootViewModel.alpha.collect { alpha ->
+ aodAlphaViewModel.alpha.collect { alpha ->
view.apply {
this.importantForAccessibility =
if (alpha == 0f) {
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 fad0370a85d7..2aebd99e3664 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
@@ -42,9 +42,9 @@ import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.TintedIcon
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
-import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl
import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessageViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
@@ -68,7 +68,10 @@ import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
/** Bind occludingAppDeviceEntryMessageViewModel to run whenever the keyguard view is attached. */
@@ -81,7 +84,6 @@ object KeyguardRootViewBinder {
view: ViewGroup,
viewModel: KeyguardRootViewModel,
configuration: ConfigurationState,
- featureFlags: FeatureFlagsClassic,
occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel,
chipbarCoordinator: ChipbarCoordinator,
screenOffAnimationController: ScreenOffAnimationController,
@@ -108,6 +110,8 @@ object KeyguardRootViewBinder {
}
}
+ val burnInParams = MutableStateFlow(BurnInParameters())
+
val disposableHandle =
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
@@ -164,35 +168,41 @@ object KeyguardRootViewBinder {
// large clock isn't added to burnInLayer due to its scale transition
// so we also need to add translation to it here
// same as translationX
- viewModel.translationY.collect { y ->
- childViews[burnInLayerId]?.translationY = y
- childViews[largeClockId]?.translationY = y
- }
+ burnInParams
+ .flatMapLatest { params -> viewModel.translationY(params) }
+ .collect { y ->
+ childViews[burnInLayerId]?.translationY = y
+ childViews[largeClockId]?.translationY = y
+ }
}
launch {
- viewModel.translationX.collect { x ->
- childViews[burnInLayerId]?.translationX = x
- childViews[largeClockId]?.translationX = x
- }
+ burnInParams
+ .flatMapLatest { params -> viewModel.translationX(params) }
+ .collect { x ->
+ childViews[burnInLayerId]?.translationX = x
+ childViews[largeClockId]?.translationX = x
+ }
}
launch {
- viewModel.scale.collect { (scale, scaleClockOnly) ->
- if (scaleClockOnly) {
- // For clocks except weather clock, we have scale transition
- // besides translate
- childViews[largeClockId]?.let {
- it.scaleX = scale
- it.scaleY = scale
+ burnInParams
+ .flatMapLatest { params -> viewModel.scale(params) }
+ .collect { scaleViewModel ->
+ if (scaleViewModel.scaleClockOnly) {
+ // For clocks except weather clock, we have scale transition
+ // besides translate
+ childViews[largeClockId]?.let {
+ it.scaleX = scaleViewModel.scale
+ it.scaleY = scaleViewModel.scale
+ }
+ } 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
}
- } else {
- // For weather clock, large clock should have only scale
- // transition with other parts in burnInLayer
- childViews[burnInLayerId]?.scaleX = scale
- childViews[burnInLayerId]?.scaleY = scale
}
- }
}
if (NotificationIconContainerRefactor.isEnabled) {
@@ -274,10 +284,12 @@ object KeyguardRootViewBinder {
}
if (!migrateClocksToBlueprint()) {
- viewModel.clockControllerProvider = clockControllerProvider
+ burnInParams.update { current ->
+ current.copy(clockControllerProvider = clockControllerProvider)
+ }
}
- onLayoutChangeListener = OnLayoutChange(viewModel)
+ onLayoutChangeListener = OnLayoutChange(viewModel, burnInParams)
view.addOnLayoutChangeListener(onLayoutChangeListener)
// Views will be added or removed after the call to bind(). This is needed to avoid many
@@ -296,7 +308,9 @@ object KeyguardRootViewBinder {
view.setOnApplyWindowInsetsListener { v: View, insets: WindowInsets ->
val insetTypes = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
- viewModel.topInset = insets.getInsetsIgnoringVisibility(insetTypes).top
+ burnInParams.update { current ->
+ current.copy(topInset = insets.getInsetsIgnoringVisibility(insetTypes).top)
+ }
insets
}
@@ -333,8 +347,10 @@ object KeyguardRootViewBinder {
)
}
- private class OnLayoutChange(private val viewModel: KeyguardRootViewModel) :
- OnLayoutChangeListener {
+ private class OnLayoutChange(
+ private val viewModel: KeyguardRootViewModel,
+ private val burnInParams: MutableStateFlow<BurnInParameters>,
+ ) : OnLayoutChangeListener {
override fun onLayoutChange(
view: View,
left: Int,
@@ -355,7 +371,7 @@ object KeyguardRootViewBinder {
}
view.findViewById<View>(R.id.keyguard_status_view)?.let { statusView ->
- viewModel.statusViewTop = statusView.top
+ burnInParams.update { current -> current.copy(statusViewTop = statusView.top) }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 03e45fdbe75f..eb3afb7c9eec 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -367,7 +367,6 @@ constructor(
keyguardRootView,
keyguardRootViewModel,
configuration,
- featureFlags,
occludingAppDeviceEntryMessageViewModel,
chipbarCoordinator,
screenOffAnimationController,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt
index 66c137f7d75e..ea05c1d878b8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt
@@ -25,8 +25,8 @@ import com.android.systemui.Flags.keyguardBottomAreaRefactor
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder
import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
+import com.android.systemui.keyguard.ui.viewmodel.AodAlphaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.res.R
import com.android.systemui.statusbar.KeyguardIndicationController
import javax.inject.Inject
@@ -37,7 +37,7 @@ class DefaultIndicationAreaSection
constructor(
private val context: Context,
private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel,
- private val keyguardRootViewModel: KeyguardRootViewModel,
+ private val aodAlphaViewModel: AodAlphaViewModel,
private val indicationController: KeyguardIndicationController,
) : KeyguardSection() {
private val indicationAreaViewId = R.id.keyguard_indication_area
@@ -56,7 +56,7 @@ constructor(
KeyguardIndicationAreaBinder.bind(
constraintLayout.requireViewById(R.id.keyguard_indication_area),
keyguardIndicationAreaViewModel,
- keyguardRootViewModel,
+ aodAlphaViewModel,
indicationController,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModel.kt
new file mode 100644
index 000000000000..d4ea728bbffb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModel.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onStart
+
+/** Models UI state for the alpha of the AOD (always-on display). */
+@SysUISingleton
+class AodAlphaViewModel
+@Inject
+constructor(
+ keyguardInteractor: KeyguardInteractor,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+) {
+
+ /** The alpha level for the entire lockscreen while in AOD. */
+ val alpha: Flow<Float> =
+ combine(
+ keyguardTransitionInteractor.transitionValue(KeyguardState.GONE).onStart {
+ emit(0f)
+ },
+ merge(
+ keyguardInteractor.keyguardAlpha,
+ occludedToLockscreenTransitionViewModel.lockscreenAlpha,
+ )
+ ) { transitionToGone, alpha ->
+ if (transitionToGone == 1f) {
+ // Ensures content is not visible when in GONE state
+ 0f
+ } else {
+ alpha
+ }
+ }
+ .distinctUntilChanged()
+}
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
new file mode 100644
index 000000000000..780e323a96bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import android.util.MathUtils
+import com.android.app.animation.Interpolators
+import com.android.keyguard.KeyguardClockSwitch
+import com.android.systemui.Flags
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.BurnInModel
+import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.res.R
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlin.math.max
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onStart
+
+/**
+ * Models UI state for elements that need to apply anti-burn-in tactics when showing in AOD
+ * (always-on display).
+ */
+@SysUISingleton
+class AodBurnInViewModel
+@Inject
+constructor(
+ private val burnInInteractor: BurnInInteractor,
+ private val configurationInteractor: ConfigurationInteractor,
+ private val keyguardInteractor: KeyguardInteractor,
+ private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
+ private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+ private val keyguardClockViewModel: KeyguardClockViewModel,
+) {
+ /** Alpha for elements that appear and move during the animation -> AOD */
+ val alpha: Flow<Float> = goneToAodTransitionViewModel.enterFromTopAnimationAlpha
+
+ /** Horizontal translation for elements that need to apply anti-burn-in tactics. */
+ fun translationX(
+ params: BurnInParameters,
+ ): Flow<Float> {
+ return burnIn(params).map { it.translationX.toFloat() }
+ }
+
+ /** Vertical translation for elements that need to apply anti-burn-in tactics. */
+ fun translationY(
+ params: BurnInParameters,
+ ): Flow<Float> {
+ return configurationInteractor
+ .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
+ .flatMapLatest { enterFromTopAmount ->
+ combine(
+ keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
+ burnIn(params).map { it.translationY.toFloat() }.onStart { emit(0f) },
+ goneToAodTransitionViewModel
+ .enterFromTopTranslationY(enterFromTopAmount)
+ .onStart { emit(0f) },
+ occludedToLockscreenTransitionViewModel.lockscreenTranslationY.onStart {
+ emit(0f)
+ },
+ ) {
+ keyguardTransitionY,
+ burnInTranslationY,
+ goneToAodTransitionTranslationY,
+ occludedToLockscreenTransitionTranslationY ->
+
+ // All values need to be combined for a smooth translation
+ keyguardTransitionY +
+ burnInTranslationY +
+ goneToAodTransitionTranslationY +
+ occludedToLockscreenTransitionTranslationY
+ }
+ }
+ .distinctUntilChanged()
+ }
+
+ /** Scale for elements that need to apply anti-burn-in tactics. */
+ fun scale(
+ params: BurnInParameters,
+ ): Flow<BurnInScaleViewModel> {
+ return burnIn(params).map {
+ BurnInScaleViewModel(
+ scale = it.scale,
+ scaleClockOnly = it.scaleClockOnly,
+ )
+ }
+ }
+
+ private fun burnIn(
+ params: BurnInParameters,
+ ): Flow<BurnInModel> {
+ return combine(
+ merge(
+ keyguardTransitionInteractor.goneToAodTransition.map { it.value },
+ keyguardTransitionInteractor.dozeAmountTransition.map { it.value },
+ )
+ .map { dozeAmount -> Interpolators.FAST_OUT_SLOW_IN.getInterpolation(dozeAmount) },
+ burnInInteractor.keyguardBurnIn,
+ ) { interpolated, burnIn ->
+ val useScaleOnly =
+ (clockController(params.clockControllerProvider)
+ ?.get()
+ ?.config
+ ?.useAlternateSmartspaceAODTransition
+ ?: false) && keyguardClockViewModel.clockSize.value == KeyguardClockSwitch.LARGE
+
+ if (useScaleOnly) {
+ BurnInModel(
+ translationX = 0,
+ translationY = 0,
+ scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated),
+ )
+ } else {
+ // Ensure the desired translation doesn't encroach on the top inset
+ val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolated).toInt()
+ val translationY =
+ if (Flags.migrateClocksToBlueprint()) {
+ burnInY
+ } else {
+ max(params.topInset, params.statusViewTop + burnInY) - params.statusViewTop
+ }
+
+ BurnInModel(
+ translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(),
+ translationY = translationY,
+ scale =
+ MathUtils.lerp(
+ /* start= */ burnIn.scale,
+ /* stop= */ 1f,
+ /* amount= */ 1f - interpolated,
+ ),
+ scaleClockOnly = true,
+ )
+ }
+ }
+ }
+
+ private fun clockController(
+ provider: Provider<ClockController>?,
+ ): Provider<ClockController>? {
+ return if (Flags.migrateClocksToBlueprint()) {
+ Provider { keyguardClockViewModel.clock }
+ } else {
+ provider
+ }
+ }
+}
+
+/** UI-sourced parameters to pass into the various methods of [AodBurnInViewModel]. */
+data class BurnInParameters(
+ val clockControllerProvider: Provider<ClockController>? = null,
+ /** System insets that keyguard needs to stay out of */
+ val topInset: Int = 0,
+ /** Status view top, without translation added in */
+ val statusViewTop: Int = 0,
+)
+
+/**
+ * Models UI state of the scaling to apply to elements that need to be scaled for anti-burn-in
+ * purposes.
+ */
+data class BurnInScaleViewModel(
+ val scale: Float = 1f,
+ /** Whether the scale only applies to clock UI elements. */
+ val scaleClockOnly: Boolean = false,
+)
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 26dace00ad76..5059e6be9080 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
@@ -18,27 +18,17 @@
package com.android.systemui.keyguard.ui.viewmodel
import android.graphics.Point
-import android.util.MathUtils
import android.view.View.VISIBLE
-import com.android.app.animation.Interpolators
-import com.android.keyguard.KeyguardClockSwitch.LARGE
-import com.android.systemui.Flags.migrateClocksToBlueprint
import com.android.systemui.Flags.newAodTransition
import com.android.systemui.common.shared.model.NotificationContainerBounds
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
-import com.android.systemui.flags.FeatureFlagsClassic
-import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
-import com.android.systemui.plugins.clocks.ClockController
-import com.android.systemui.res.R
import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
@@ -49,51 +39,29 @@ import com.android.systemui.util.ui.AnimatedValue
import com.android.systemui.util.ui.toAnimatedValueFlow
import com.android.systemui.util.ui.zip
import javax.inject.Inject
-import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.onStart
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class KeyguardRootViewModel
@Inject
constructor(
- configurationInteractor: ConfigurationInteractor,
private val deviceEntryInteractor: DeviceEntryInteractor,
private val dozeParameters: DozeParameters,
private val keyguardInteractor: KeyguardInteractor,
- private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val notificationsKeyguardInteractor: NotificationsKeyguardInteractor,
- private val burnInInteractor: BurnInInteractor,
- private val keyguardClockViewModel: KeyguardClockViewModel,
- private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
- private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
- private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+ aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
screenOffAnimationController: ScreenOffAnimationController,
- // TODO(b/310989341): remove after changing migrate_clocks_to_blueprint to aconfig
- private val featureFlags: FeatureFlagsClassic,
+ private val aodBurnInViewModel: AodBurnInViewModel,
+ aodAlphaViewModel: AodAlphaViewModel,
) {
- var clockControllerProvider: Provider<ClockController>? = null
- get() {
- if (migrateClocksToBlueprint()) {
- return Provider { keyguardClockViewModel.clock }
- } else {
- return field
- }
- }
-
- /** System insets that keyguard needs to stay out of */
- var topInset: Int = 0
- /** Status view top, without translation added in */
- var statusViewTop: Int = 0
val burnInLayerVisibility: Flow<Int> =
keyguardTransitionInteractor.startedKeyguardState
@@ -110,96 +78,25 @@ constructor(
keyguardInteractor.notificationContainerBounds
/** An observable for the alpha level for the entire keyguard root view. */
- val alpha: Flow<Float> =
- combine(
- keyguardTransitionInteractor.transitionValue(GONE).onStart { emit(0f) },
- merge(
- keyguardInteractor.keyguardAlpha,
- occludedToLockscreenTransitionViewModel.lockscreenAlpha,
- )
- ) { transitionToGone, alpha ->
- if (transitionToGone == 1f) {
- // Ensures content is not visible when in GONE state
- 0f
- } else {
- alpha
- }
- }
- .distinctUntilChanged()
-
- private fun burnIn(): Flow<BurnInModel> {
- val dozingAmount: Flow<Float> =
- merge(
- keyguardTransitionInteractor.goneToAodTransition.map { it.value },
- keyguardTransitionInteractor.dozeAmountTransition.map { it.value },
- )
-
- return combine(dozingAmount, burnInInteractor.keyguardBurnIn) { dozeAmount, burnIn ->
- val interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(dozeAmount)
- val useScaleOnly =
- (clockControllerProvider?.get()?.config?.useAlternateSmartspaceAODTransition
- ?: false) && keyguardClockViewModel.clockSize.value == LARGE
- if (useScaleOnly) {
- BurnInModel(
- translationX = 0,
- translationY = 0,
- scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation),
- )
- } else {
- // Ensure the desired translation doesn't encroach on the top inset
- val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt()
- val translationY =
- if (migrateClocksToBlueprint()) {
- burnInY
- } else {
- -(statusViewTop - Math.max(topInset, statusViewTop + burnInY))
- }
- BurnInModel(
- translationX = MathUtils.lerp(0, burnIn.translationX, interpolation).toInt(),
- translationY = translationY,
- scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation),
- scaleClockOnly = true,
- )
- }
- }
- }
+ val alpha: Flow<Float> = aodAlphaViewModel.alpha
/** Specific alpha value for elements visible during [KeyguardState.LOCKSCREEN] */
val lockscreenStateAlpha: Flow<Float> = aodToLockscreenTransitionViewModel.lockscreenAlpha
/** For elements that appear and move during the animation -> AOD */
- val burnInLayerAlpha: Flow<Float> = goneToAodTransitionViewModel.enterFromTopAnimationAlpha
+ val burnInLayerAlpha: Flow<Float> = aodBurnInViewModel.alpha
- val translationY: Flow<Float> =
- configurationInteractor
- .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
- .flatMapLatest { enterFromTopAmount ->
- combine(
- keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
- burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
- goneToAodTransitionViewModel
- .enterFromTopTranslationY(enterFromTopAmount)
- .onStart { emit(0f) },
- occludedToLockscreenTransitionViewModel.lockscreenTranslationY.onStart {
- emit(0f)
- },
- ) {
- keyguardTransitionY,
- burnInTranslationY,
- goneToAodTransitionTranslationY,
- occludedToLockscreenTransitionTranslationY ->
- // All values need to be combined for a smooth translation
- keyguardTransitionY +
- burnInTranslationY +
- goneToAodTransitionTranslationY +
- occludedToLockscreenTransitionTranslationY
- }
- }
- .distinctUntilChanged()
+ fun translationY(params: BurnInParameters): Flow<Float> {
+ return aodBurnInViewModel.translationY(params)
+ }
- val translationX: Flow<Float> = burnIn().map { it.translationX.toFloat() }
+ fun translationX(params: BurnInParameters): Flow<Float> {
+ return aodBurnInViewModel.translationX(params)
+ }
- val scale: Flow<Pair<Float, Boolean>> = burnIn().map { Pair(it.scale, it.scaleClockOnly) }
+ fun scale(params: BurnInParameters): Flow<BurnInScaleViewModel> {
+ return aodBurnInViewModel.scale(params)
+ }
/** Is the notification icon container visible? */
val isNotifIconContainerVisible: Flow<AnimatedValue<Boolean>> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 539db7fb1ae3..2b28a71b4a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -38,7 +38,6 @@ constructor(
deviceEntryInteractor: DeviceEntryInteractor,
communalInteractor: CommunalInteractor,
val longPress: KeyguardLongPressViewModel,
- val keyguardRoot: KeyguardRootViewModel,
val notifications: NotificationsPlaceholderViewModel,
) {
/** The key of the scene we should switch to when swiping up. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt
index 8dd33d5e60bb..1205dceb49e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt
@@ -21,11 +21,11 @@ import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
-import com.android.systemui.SysuiTestCase
import com.android.systemui.Flags as AConfigFlags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyguard.ui.viewmodel.AodAlphaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
+import com.android.systemui.res.R
import com.android.systemui.statusbar.KeyguardIndicationController
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -38,8 +38,9 @@ import org.mockito.MockitoAnnotations
@RunWith(JUnit4::class)
@SmallTest
class DefaultIndicationAreaSectionTest : SysuiTestCase() {
+
@Mock private lateinit var keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel
- @Mock private lateinit var keyguardRootViewModel: KeyguardRootViewModel
+ @Mock private lateinit var aodAlphaViewModel: AodAlphaViewModel
@Mock private lateinit var indicationController: KeyguardIndicationController
private lateinit var underTest: DefaultIndicationAreaSection
@@ -51,7 +52,7 @@ class DefaultIndicationAreaSectionTest : SysuiTestCase() {
DefaultIndicationAreaSection(
context,
keyguardIndicationAreaViewModel,
- keyguardRootViewModel,
+ aodAlphaViewModel,
indicationController,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
deleted file mode 100644
index ee1be10607cf..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
-package com.android.systemui.keyguard.ui.viewmodel
-
-import android.view.View
-import androidx.test.filters.SmallTest
-import com.android.systemui.Flags as AConfigFlags
-import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
-import com.android.systemui.common.ui.domain.interactor.configurationInteractor
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
-import com.android.systemui.flags.featureFlagsClassic
-import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.BurnInModel
-import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.plugins.clocks.ClockController
-import com.android.systemui.statusbar.notification.data.repository.fakeNotificationsKeyguardViewStateRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
-import com.android.systemui.statusbar.phone.dozeParameters
-import com.android.systemui.statusbar.phone.screenOffAnimationController
-import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.ui.isAnimating
-import com.android.systemui.util.ui.stopAnimating
-import com.android.systemui.util.ui.value
-import com.google.common.truth.Truth.assertThat
-import javax.inject.Provider
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.emptyFlow
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.mockito.Answers
-import org.mockito.Mock
-import org.mockito.Mockito.RETURNS_DEEP_STUBS
-import org.mockito.Mockito.anyInt
-import org.mockito.MockitoAnnotations
-
-@SmallTest
-@RunWith(JUnit4::class)
-class KeyguardRootViewModelTest : SysuiTestCase() {
- private val kosmos = testKosmos()
- private val testScope = kosmos.testScope
- private val repository = kosmos.fakeKeyguardRepository
- private val configurationRepository = kosmos.fakeConfigurationRepository
- private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
- private val screenOffAnimationController = kosmos.screenOffAnimationController
- private val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
- private val notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor
- private val fakeNotificationsKeyguardViewStateRepository =
- kosmos.fakeNotificationsKeyguardViewStateRepository
- private val dozeParameters = kosmos.dozeParameters
- private lateinit var underTest: KeyguardRootViewModel
-
- @Mock private lateinit var burnInInteractor: BurnInInteractor
- private val burnInFlow = MutableStateFlow(BurnInModel())
-
- @Mock private lateinit var goneToAodTransitionViewModel: GoneToAodTransitionViewModel
- private val enterFromTopAnimationAlpha = MutableStateFlow(0f)
-
- @Mock
- private lateinit var aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel
- @Mock
- private lateinit var occludedToLockscreenTransitionViewModel:
- OccludedToLockscreenTransitionViewModel
- private val occludedToLockscreenTranslationY = MutableStateFlow(0f)
- private val occludedToLockscreenAlpha = MutableStateFlow(0f)
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
-
- mSetFlagsRule.enableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
- mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
- mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
-
- whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
- .thenReturn(emptyFlow<Float>())
- whenever(goneToAodTransitionViewModel.enterFromTopAnimationAlpha)
- .thenReturn(enterFromTopAnimationAlpha)
-
- whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow)
-
- whenever(occludedToLockscreenTransitionViewModel.lockscreenTranslationY)
- .thenReturn(occludedToLockscreenTranslationY)
- whenever(occludedToLockscreenTransitionViewModel.lockscreenAlpha)
- .thenReturn(occludedToLockscreenAlpha)
-
- underTest =
- KeyguardRootViewModel(
- configurationInteractor = kosmos.configurationInteractor,
- deviceEntryInteractor = kosmos.deviceEntryInteractor,
- dozeParameters = kosmos.dozeParameters,
- keyguardInteractor = kosmos.keyguardInteractor,
- keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
- notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor,
- burnInInteractor = burnInInteractor,
- keyguardClockViewModel = kosmos.keyguardClockViewModel,
- goneToAodTransitionViewModel = goneToAodTransitionViewModel,
- aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
- occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
- screenOffAnimationController = screenOffAnimationController,
- // TODO(b/310989341): remove after change to aconfig
- featureFlags = kosmos.featureFlagsClassic
- )
-
- underTest.clockControllerProvider = Provider { clockController }
- }
-
- @Test
- fun alpha() =
- testScope.runTest {
- val alpha by collectLastValue(underTest.alpha)
-
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.OFF,
- to = KeyguardState.LOCKSCREEN,
- testScope = testScope,
- )
-
- repository.setKeyguardAlpha(0.1f)
- assertThat(alpha).isEqualTo(0.1f)
- repository.setKeyguardAlpha(0.5f)
- assertThat(alpha).isEqualTo(0.5f)
- repository.setKeyguardAlpha(0.2f)
- assertThat(alpha).isEqualTo(0.2f)
- repository.setKeyguardAlpha(0f)
- assertThat(alpha).isEqualTo(0f)
- occludedToLockscreenAlpha.value = 0.8f
- assertThat(alpha).isEqualTo(0.8f)
- }
-
- @Test
- fun alphaWhenGoneEqualsZero() =
- testScope.runTest {
- val alpha by collectLastValue(underTest.alpha)
-
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- testScope = testScope,
- )
-
- repository.setKeyguardAlpha(0.1f)
- assertThat(alpha).isEqualTo(0f)
- repository.setKeyguardAlpha(0.5f)
- assertThat(alpha).isEqualTo(0f)
- repository.setKeyguardAlpha(1f)
- assertThat(alpha).isEqualTo(0f)
- }
-
- @Test
- fun translationYInitialValueIsZero() =
- testScope.runTest {
- val translationY by collectLastValue(underTest.translationY)
- assertThat(translationY).isEqualTo(0)
- }
-
- @Test
- fun translationAndScaleFromBurnInNotDozing() =
- testScope.runTest {
- val translationX by collectLastValue(underTest.translationX)
- val translationY by collectLastValue(underTest.translationY)
- val scale by collectLastValue(underTest.scale)
-
- // Set to not dozing (on lockscreen)
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.AOD,
- to = KeyguardState.LOCKSCREEN,
- value = 1f,
- transitionState = TransitionState.FINISHED
- ),
- validateStep = false,
- )
-
- // Trigger a change to the burn-in model
- burnInFlow.value =
- BurnInModel(
- translationX = 20,
- translationY = 30,
- scale = 0.5f,
- )
-
- assertThat(translationX).isEqualTo(0)
- assertThat(translationY).isEqualTo(0)
- assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */))
- }
-
- @Test
- fun translationAndScaleFromBurnFullyDozing() =
- testScope.runTest {
- val translationX by collectLastValue(underTest.translationX)
- val translationY by collectLastValue(underTest.translationY)
- val scale by collectLastValue(underTest.scale)
-
- underTest.statusViewTop = 100
-
- // Set to dozing (on AOD)
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- value = 1f,
- transitionState = TransitionState.FINISHED
- ),
- validateStep = false,
- )
- // Trigger a change to the burn-in model
- burnInFlow.value =
- BurnInModel(
- translationX = 20,
- translationY = 30,
- scale = 0.5f,
- )
-
- assertThat(translationX).isEqualTo(20)
- assertThat(translationY).isEqualTo(30)
- assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */))
-
- // Set to the beginning of GONE->AOD transition
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- value = 0f,
- transitionState = TransitionState.STARTED
- ),
- validateStep = false,
- )
- assertThat(translationX).isEqualTo(0)
- assertThat(translationY).isEqualTo(0)
- assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */))
- }
-
- @Test
- fun translationAndScaleFromBurnFullyDozingStaysOutOfTopInset() =
- testScope.runTest {
- val translationX by collectLastValue(underTest.translationX)
- val translationY by collectLastValue(underTest.translationY)
- val scale by collectLastValue(underTest.scale)
-
- underTest.statusViewTop = 100
- underTest.topInset = 80
-
- // Set to dozing (on AOD)
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- value = 1f,
- transitionState = TransitionState.FINISHED
- ),
- validateStep = false,
- )
-
- // Trigger a change to the burn-in model
- burnInFlow.value =
- BurnInModel(
- translationX = 20,
- translationY = -30,
- scale = 0.5f,
- )
- assertThat(translationX).isEqualTo(20)
- // -20 instead of -30, due to inset of 80
- assertThat(translationY).isEqualTo(-20)
- assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */))
-
- // Set to the beginning of GONE->AOD transition
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- value = 0f,
- transitionState = TransitionState.STARTED
- ),
- validateStep = false,
- )
- assertThat(translationX).isEqualTo(0)
- assertThat(translationY).isEqualTo(0)
- assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */))
- }
-
- @Test
- fun translationAndScaleFromBurnInUseScaleOnly() =
- testScope.runTest {
- whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true)
-
- val translationX by collectLastValue(underTest.translationX)
- val translationY by collectLastValue(underTest.translationY)
- val scale by collectLastValue(underTest.scale)
-
- // Set to dozing (on AOD)
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- value = 1f,
- transitionState = TransitionState.FINISHED
- ),
- validateStep = false,
- )
-
- // Trigger a change to the burn-in model
- burnInFlow.value =
- BurnInModel(
- translationX = 20,
- translationY = 30,
- scale = 0.5f,
- )
-
- assertThat(translationX).isEqualTo(0)
- assertThat(translationY).isEqualTo(0)
- assertThat(scale).isEqualTo(Pair(0.5f, false /* scaleClockOnly */))
- }
-
- @Test
- fun burnInLayerVisibility() =
- testScope.runTest {
- val burnInLayerVisibility by collectLastValue(underTest.burnInLayerVisibility)
-
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.AOD,
- value = 0f,
- transitionState = TransitionState.STARTED
- ),
- validateStep = false,
- )
- assertThat(burnInLayerVisibility).isEqualTo(View.VISIBLE)
- }
-
- @Test
- fun burnInLayerAlpha() =
- testScope.runTest {
- val burnInLayerAlpha by collectLastValue(underTest.burnInLayerAlpha)
-
- enterFromTopAnimationAlpha.value = 0.2f
- assertThat(burnInLayerAlpha).isEqualTo(0.2f)
-
- enterFromTopAnimationAlpha.value = 1f
- assertThat(burnInLayerAlpha).isEqualTo(1f)
- }
-
- @Test
- fun iconContainer_isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.OFF,
- to = KeyguardState.GONE,
- testScope,
- )
- whenever(screenOffAnimationController.shouldShowAodIconsWhenShade()).thenReturn(false)
- runCurrent()
-
- assertThat(isVisible?.value).isFalse()
- assertThat(isVisible?.isAnimating).isFalse()
- }
-
- @Test
- fun iconContainer_isVisible_bypassEnabled() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- deviceEntryRepository.setBypassEnabled(true)
- runCurrent()
-
- assertThat(isVisible?.value).isTrue()
- }
-
- @Test
- fun iconContainer_isNotVisible_pulseExpanding_notBypassing() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(true)
- deviceEntryRepository.setBypassEnabled(false)
- runCurrent()
-
- assertThat(isVisible?.value).isEqualTo(false)
- }
-
- @Test
- fun iconContainer_isVisible_notifsFullyHidden_bypassEnabled() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
- deviceEntryRepository.setBypassEnabled(true)
- fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
- runCurrent()
-
- assertThat(isVisible?.value).isTrue()
- assertThat(isVisible?.isAnimating).isTrue()
- }
-
- @Test
- fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_aodDisabled() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
- deviceEntryRepository.setBypassEnabled(false)
- whenever(dozeParameters.alwaysOn).thenReturn(false)
- fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
- runCurrent()
-
- assertThat(isVisible?.value).isTrue()
- assertThat(isVisible?.isAnimating).isFalse()
- }
-
- @Test
- fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_displayNeedsBlanking() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
- deviceEntryRepository.setBypassEnabled(false)
- whenever(dozeParameters.alwaysOn).thenReturn(true)
- whenever(dozeParameters.displayNeedsBlanking).thenReturn(true)
- fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
- runCurrent()
-
- assertThat(isVisible?.value).isTrue()
- assertThat(isVisible?.isAnimating).isFalse()
- }
-
- @Test
- fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
- deviceEntryRepository.setBypassEnabled(false)
- whenever(dozeParameters.alwaysOn).thenReturn(true)
- whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
- fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
- runCurrent()
-
- assertThat(isVisible?.value).isTrue()
- assertThat(isVisible?.isAnimating).isTrue()
- }
-
- @Test
- fun isIconContainerVisible_stopAnimation() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
- deviceEntryRepository.setBypassEnabled(false)
- whenever(dozeParameters.alwaysOn).thenReturn(true)
- whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
- fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
- runCurrent()
-
- assertThat(isVisible?.isAnimating).isEqualTo(true)
- isVisible?.stopAnimating()
- runCurrent()
-
- assertThat(isVisible?.isAnimating).isEqualTo(false)
- }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt
index b0d941dc6c24..a9d89a37c542 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt
@@ -26,7 +26,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-val Kosmos.burnInInteractor by Fixture {
+var Kosmos.burnInInteractor by Fixture {
BurnInInteractor(
context = applicationContext,
burnInHelperWrapper = burnInHelperWrapper,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractorKosmos.kt
new file mode 100644
index 000000000000..a3955f7634eb
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractorKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import com.android.systemui.keyguard.data.repository.keyguardRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.keyguardBottomAreaInteractor by Fixture {
+ KeyguardBottomAreaInteractor(
+ repository = keyguardRepository,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelKosmos.kt
new file mode 100644
index 000000000000..6b89e0f8901a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodAlphaViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.aodAlphaViewModel by Fixture {
+ AodAlphaViewModel(
+ keyguardInteractor = keyguardInteractor,
+ keyguardTransitionInteractor = keyguardTransitionInteractor,
+ occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+ )
+}
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
new file mode 100644
index 000000000000..35cfa89e56ed
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.keyguard.domain.interactor.burnInInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.aodBurnInViewModel by Fixture {
+ AodBurnInViewModel(
+ burnInInteractor = burnInInteractor,
+ configurationInteractor = configurationInteractor,
+ keyguardInteractor = keyguardInteractor,
+ keyguardTransitionInteractor = keyguardTransitionInteractor,
+ goneToAodTransitionViewModel = goneToAodTransitionViewModel,
+ occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+ keyguardClockViewModel = keyguardClockViewModel,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
index 14e2cff6a7a5..00ece1482236 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
@@ -25,7 +25,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import kotlinx.coroutines.ExperimentalCoroutinesApi
-val Kosmos.goneToAodTransitionViewModel by Fixture {
+var Kosmos.goneToAodTransitionViewModel by Fixture {
GoneToAodTransitionViewModel(
interactor = keyguardTransitionInteractor,
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
index 13ee74738437..933f50c36b7b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
@@ -18,10 +18,7 @@
package com.android.systemui.keyguard.ui.viewmodel
-import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
-import com.android.systemui.flags.FakeFeatureFlagsClassic
-import com.android.systemui.keyguard.domain.interactor.burnInInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
@@ -33,18 +30,14 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.keyguardRootViewModel by Fixture {
KeyguardRootViewModel(
- configurationInteractor = configurationInteractor,
deviceEntryInteractor = deviceEntryInteractor,
dozeParameters = dozeParameters,
keyguardInteractor = keyguardInteractor,
keyguardTransitionInteractor = keyguardTransitionInteractor,
notificationsKeyguardInteractor = notificationsKeyguardInteractor,
- burnInInteractor = burnInInteractor,
- goneToAodTransitionViewModel = goneToAodTransitionViewModel,
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
- occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
screenOffAnimationController = screenOffAnimationController,
- keyguardClockViewModel = keyguardClockViewModel,
- featureFlags = FakeFeatureFlagsClassic(),
+ aodBurnInViewModel = aodBurnInViewModel,
+ aodAlphaViewModel = aodAlphaViewModel,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
index 5bbde2b1c419..93ecb7968ee2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
@@ -26,7 +26,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import kotlinx.coroutines.ExperimentalCoroutinesApi
-val Kosmos.occludedToLockscreenTransitionViewModel by Fixture {
+var Kosmos.occludedToLockscreenTransitionViewModel by Fixture {
OccludedToLockscreenTransitionViewModel(
interactor = keyguardTransitionInteractor,
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,