Add AOD fold animation
When folding the device and entering AOD, keyguard
should fade in from the side and not the top as is
the default.
Bug: 346325723
Test: atest GoneToAodTransitionViewModelTest
Flag: com.android.systemui.migrate_clocks_to_blueprint
Change-Id: Ie754bf839c7121a3bd5a85a878c379021804e47c
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
index 519bb6e..63d06a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -55,6 +55,8 @@
@Mock private lateinit var burnInInteractor: BurnInInteractor
@Mock private lateinit var goneToAodTransitionViewModel: GoneToAodTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController
private val kosmos = testKosmos()
@@ -76,7 +78,12 @@
kosmos.burnInInteractor = burnInInteractor
whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
.thenReturn(emptyFlow())
+ whenever(goneToAodTransitionViewModel.enterFromSideTranslationX(anyInt()))
+ .thenReturn(emptyFlow())
+ whenever(lockscreenToAodTransitionViewModel.enterFromSideTranslationX(anyInt()))
+ .thenReturn(emptyFlow())
kosmos.goneToAodTransitionViewModel = goneToAodTransitionViewModel
+ kosmos.lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel
kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
underTest = kosmos.aodBurnInViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
similarity index 71%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
index 716c40d..bab466a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
@@ -28,6 +28,9 @@
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.data.repository.powerRepository
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.testKosmos
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
@@ -47,10 +50,18 @@
private val underTest = kosmos.goneToAodTransitionViewModel
private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
private val biometricSettingsRepository = kosmos.biometricSettingsRepository
+ private val powerRepository = kosmos.powerRepository
@Test
- fun enterFromTopTranslationY() =
+ fun enterFromTopTranslationY_whenNotOnFold() =
testScope.runTest {
+ powerRepository.updateWakefulness(
+ rawState = WakefulnessState.STARTING_TO_SLEEP,
+ lastWakeReason = WakeSleepReason.POWER_BUTTON,
+ lastSleepReason = WakeSleepReason.POWER_BUTTON,
+ powerButtonLaunchGestureTriggered = false
+ )
+
val pixels = -100f
val enterFromTopTranslationY by
collectLastValue(underTest.enterFromTopTranslationY(pixels.toInt()))
@@ -88,6 +99,80 @@
}
@Test
+ fun enterFromTopTranslationY_whenOnFold_emitsNothing() =
+ testScope.runTest {
+ powerRepository.updateWakefulness(
+ rawState = WakefulnessState.STARTING_TO_SLEEP,
+ lastWakeReason = WakeSleepReason.POWER_BUTTON,
+ lastSleepReason = WakeSleepReason.FOLD,
+ powerButtonLaunchGestureTriggered = false
+ )
+
+ val pixels = -100f
+ val enterFromTopTranslationY by
+ collectLastValue(underTest.enterFromTopTranslationY(pixels.toInt()))
+ runCurrent()
+
+ repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+ assertThat(enterFromTopTranslationY).isNull()
+
+ repository.sendTransitionStep(step(.55f))
+ assertThat(enterFromTopTranslationY).isNull()
+
+ repository.sendTransitionStep(step(.85f))
+ assertThat(enterFromTopTranslationY).isNull()
+
+ repository.sendTransitionStep(step(1f))
+ assertThat(enterFromTopTranslationY).isNull()
+ }
+
+ @Test
+ fun enterFromSideTranslationX_onFold() =
+ testScope.runTest {
+ powerRepository.updateWakefulness(
+ rawState = WakefulnessState.STARTING_TO_SLEEP,
+ lastWakeReason = WakeSleepReason.POWER_BUTTON,
+ lastSleepReason = WakeSleepReason.FOLD,
+ powerButtonLaunchGestureTriggered = false
+ )
+
+ val pixels = -100f
+ val enterFromSideTranslationX by
+ collectLastValue(underTest.enterFromSideTranslationX(pixels.toInt()))
+ runCurrent()
+
+ // The animation should only start > .4f way through
+ repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+ assertThat(enterFromSideTranslationX)
+ .isEqualTo(
+ StateToValue(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ transitionState = TransitionState.STARTED,
+ value = pixels
+ )
+ )
+
+ repository.sendTransitionStep(step(.55f))
+ assertThat(enterFromSideTranslationX!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
+
+ repository.sendTransitionStep(step(.85f))
+ assertThat(enterFromSideTranslationX!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
+
+ // At the end, the translation should be complete and set to zero
+ repository.sendTransitionStep(step(1f))
+ assertThat(enterFromSideTranslationX)
+ .isEqualTo(
+ StateToValue(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ transitionState = TransitionState.RUNNING,
+ value = 0f
+ )
+ )
+ }
+
+ @Test
fun enterFromTopAnimationAlpha() =
testScope.runTest {
val enterFromTopAnimationAlpha by collectLastValue(underTest.enterFromTopAnimationAlpha)
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cf91326..40bdc3e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -810,6 +810,8 @@
<dimen name="keyguard_smartspace_top_offset">12dp</dimen>
<!-- The amount to translate lockscreen elements on the GONE->AOD transition -->
<dimen name="keyguard_enter_from_top_translation_y">-100dp</dimen>
+ <!-- The amount to translate lockscreen elements on the GONE->AOD transition, on device fold -->
+ <dimen name="keyguard_enter_from_side_translation_x">-100dp</dimen>
<dimen name="notification_scrim_corner_radius">32dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index f30eef0..35a2d58 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -34,6 +34,7 @@
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason.FOLD
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.ShadeRepository
@@ -368,7 +369,12 @@
// being delayed in KeyguardViewMediator
KeyguardState.DREAMING -> TO_DREAMING_DURATION + 100.milliseconds
KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION
- KeyguardState.AOD -> TO_AOD_DURATION
+ KeyguardState.AOD ->
+ if (powerInteractor.detailedWakefulness.value.lastSleepReason == FOLD) {
+ TO_AOD_FOLD_DURATION
+ } else {
+ TO_AOD_DURATION
+ }
KeyguardState.DOZING -> TO_DOZING_DURATION
KeyguardState.DREAMING_LOCKSCREEN_HOSTED -> TO_DREAMING_HOSTED_DURATION
KeyguardState.GLANCEABLE_HUB -> TO_GLANCEABLE_HUB_DURATION
@@ -385,6 +391,7 @@
val TO_DREAMING_HOSTED_DURATION = 933.milliseconds
val TO_OCCLUDED_DURATION = 450.milliseconds
val TO_AOD_DURATION = 500.milliseconds
+ val TO_AOD_FOLD_DURATION = 1100.milliseconds
val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
val TO_GONE_DURATION = 633.milliseconds
val TO_GLANCEABLE_HUB_DURATION = 1.seconds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
index 6729246..21b9e53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
@@ -16,30 +16,17 @@
package com.android.systemui.keyguard.domain.interactor
-import android.animation.ValueAnimator
import android.view.ViewGroup
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.TransitionInfo
-import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.shade.NotificationPanelViewController
import com.android.systemui.shade.ShadeFoldAnimator
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
@SysUISingleton
class ToAodFoldTransitionInteractor
@Inject
constructor(
private val keyguardClockInteractor: KeyguardClockInteractor,
- private val transitionInteractor: KeyguardTransitionInteractor,
- private val transitionRepository: KeyguardTransitionRepository,
- @Application private val mainScope: CoroutineScope,
- @Main private val mainDispatcher: CoroutineDispatcher,
) {
private var parentAnimator: NotificationPanelViewController.ShadeFoldAnimatorImpl? = null
@@ -50,7 +37,6 @@
get() = throw NotImplementedError("Deprecated. Do not call.")
override fun prepareFoldToAodAnimation() {
- forceToAod()
parentAnimator?.prepareFoldToAodAnimation()
}
@@ -78,21 +64,6 @@
parentAnimator as? NotificationPanelViewController.ShadeFoldAnimatorImpl?
}
- /** Forces the keyguard into AOD or Doze */
- private fun forceToAod() {
- mainScope.launch(mainDispatcher) {
- transitionRepository.startTransition(
- TransitionInfo(
- "$TAG (Fold transition triggered)",
- transitionInteractor.getCurrentState(),
- transitionInteractor.asleepKeyguardState.value,
- ValueAnimator().apply { duration = 0 },
- TransitionModeOnCanceled.LAST_VALUE,
- )
- )
- }
- }
-
companion object {
private val TAG = ToAodFoldTransitionInteractor::class.simpleName!!
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index d9a6d64..62b4782 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -55,6 +55,7 @@
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
+ private val lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
private val keyguardClockViewModel: KeyguardClockViewModel,
@@ -74,13 +75,30 @@
burnInParams
}
return configurationInteractor
- .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
- .flatMapLatest { enterFromTopAmount ->
+ .dimensionPixelSize(
+ setOf(
+ R.dimen.keyguard_enter_from_top_translation_y,
+ R.dimen.keyguard_enter_from_side_translation_x,
+ )
+ )
+ .flatMapLatest { dimens ->
combine(
keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
burnIn(params).onStart { emit(BurnInModel()) },
goneToAodTransitionViewModel
- .enterFromTopTranslationY(enterFromTopAmount)
+ .enterFromTopTranslationY(
+ dimens[R.dimen.keyguard_enter_from_top_translation_y]!!
+ )
+ .onStart { emit(StateToValue()) },
+ goneToAodTransitionViewModel
+ .enterFromSideTranslationX(
+ dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
+ )
+ .onStart { emit(StateToValue()) },
+ lockscreenToAodTransitionViewModel
+ .enterFromSideTranslationX(
+ dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
+ )
.onStart { emit(StateToValue()) },
occludedToLockscreenTransitionViewModel.lockscreenTranslationY.onStart {
emit(0f)
@@ -88,21 +106,31 @@
aodToLockscreenTransitionViewModel.translationY(params.translationY).onStart {
emit(StateToValue())
},
- ) {
- keyguardTranslationY,
- burnInModel,
- goneToAod,
- occludedToLockscreen,
- aodToLockscreen ->
+ ) { flows ->
+ val keyguardTranslationY = flows[0] as Float
+ val burnInModel = flows[1] as BurnInModel
+ val goneToAodTranslationY = flows[2] as StateToValue
+ val goneToAodTranslationX = flows[3] as StateToValue
+ val lockscreenToAodTranslationX = flows[4] as StateToValue
+ val occludedToLockscreen = flows[5] as Float
+ val aodToLockscreen = flows[6] as StateToValue
+
val translationY =
if (aodToLockscreen.transitionState.isTransitioning()) {
aodToLockscreen.value ?: 0f
- } else if (goneToAod.transitionState.isTransitioning()) {
- (goneToAod.value ?: 0f) + burnInModel.translationY
+ } else if (goneToAodTranslationY.transitionState.isTransitioning()) {
+ (goneToAodTranslationY.value ?: 0f) + burnInModel.translationY
} else {
burnInModel.translationY + occludedToLockscreen + keyguardTranslationY
}
- burnInModel.copy(translationY = translationY.toInt())
+ val translationX =
+ burnInModel.translationX +
+ (goneToAodTranslationX.value ?: 0f) +
+ (lockscreenToAodTranslationX.value ?: 0f)
+ burnInModel.copy(
+ translationX = translationX.toInt(),
+ translationY = translationY.toInt(),
+ )
}
}
.distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
index 74f7d75..2bc8e51 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
@@ -26,13 +26,17 @@
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason.FOLD
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.transform
/** Breaks down GONE->AOD transition into discrete steps for corresponding views to consume. */
@ExperimentalCoroutinesApi
@@ -41,6 +45,7 @@
@Inject
constructor(
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+ private val powerInteractor: PowerInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
) : DeviceEntryIconTransition {
@@ -56,13 +61,38 @@
/** y-translation from the top of the screen for AOD */
fun enterFromTopTranslationY(translatePx: Int): Flow<StateToValue> {
- return transitionAnimation.sharedFlowWithState(
- startTime = 600.milliseconds,
- duration = 500.milliseconds,
- onStep = { translatePx + it * -translatePx },
- onFinish = { 0f },
- interpolator = EMPHASIZED_DECELERATE,
- )
+ return transitionAnimation
+ .sharedFlowWithState(
+ startTime = 600.milliseconds,
+ duration = 500.milliseconds,
+ onStep = { translatePx + it * -translatePx },
+ onFinish = { 0f },
+ interpolator = EMPHASIZED_DECELERATE,
+ )
+ .sample(powerInteractor.detailedWakefulness, ::Pair)
+ .transform { (stateToValue, wakefulness) ->
+ if (wakefulness.lastSleepReason != FOLD) {
+ emit(stateToValue)
+ }
+ }
+ }
+
+ /** x-translation from the side of the screen for fold animation */
+ fun enterFromSideTranslationX(translatePx: Int): Flow<StateToValue> {
+ return transitionAnimation
+ .sharedFlowWithState(
+ startTime = 500.milliseconds,
+ duration = 600.milliseconds,
+ onStep = { translatePx + it * -translatePx },
+ onFinish = { 0f },
+ interpolator = EMPHASIZED_DECELERATE,
+ )
+ .sample(powerInteractor.detailedWakefulness, ::Pair)
+ .transform { (stateToValue, wakefulness) ->
+ if (wakefulness.lastSleepReason == FOLD) {
+ emit(stateToValue)
+ }
+ }
}
val notificationAlpha: Flow<Float> =
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 aefff7d..d7ac976 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
@@ -251,6 +251,7 @@
goneToDreamingTransitionViewModel.lockscreenAlpha,
goneToLockscreenTransitionViewModel.lockscreenAlpha,
lockscreenToAodTransitionViewModel.lockscreenAlpha(viewState),
+ lockscreenToAodTransitionViewModel.lockscreenAlphaOnFold,
lockscreenToDozingTransitionViewModel.lockscreenAlpha,
lockscreenToDreamingTransitionViewModel.lockscreenAlpha,
lockscreenToGlanceableHubTransitionViewModel.keyguardAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
index 8b5b347..5408428 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.ui.viewmodel
import android.util.MathUtils
+import com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
@@ -24,12 +25,17 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason.FOLD
+import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.transform
/**
* Breaks down LOCKSCREEN->AOD transition into discrete steps for corresponding views to consume.
@@ -40,6 +46,7 @@
@Inject
constructor(
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+ private val powerInteractor: PowerInteractor,
shadeDependentFlows: ShadeDependentFlows,
animationFlow: KeyguardTransitionAnimationFlow,
) : DeviceEntryIconTransition {
@@ -50,6 +57,12 @@
edge = Edge.create(from = LOCKSCREEN, to = AOD),
)
+ private val transitionAnimationOnFold =
+ animationFlow.setup(
+ duration = FromLockscreenTransitionInteractor.TO_AOD_FOLD_DURATION,
+ edge = Edge.create(from = LOCKSCREEN, to = AOD),
+ )
+
val deviceEntryBackgroundViewAlpha: Flow<Float> =
shadeDependentFlows.transitionFlow(
flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f),
@@ -71,11 +84,64 @@
fun lockscreenAlpha(viewState: ViewStateAccessor): Flow<Float> {
var startAlpha = 1f
- return transitionAnimation.sharedFlow(
- duration = 500.milliseconds,
- onStart = { startAlpha = viewState.alpha() },
- onStep = { MathUtils.lerp(startAlpha, 1f, it) },
- )
+ return transitionAnimation
+ .sharedFlow(
+ duration = 500.milliseconds,
+ onStart = { startAlpha = viewState.alpha() },
+ onStep = { MathUtils.lerp(startAlpha, 1f, it) },
+ )
+ .sample(powerInteractor.detailedWakefulness, ::Pair)
+ .transform { (alpha, wakefulness) ->
+ if (wakefulness.lastSleepReason != FOLD) {
+ emit(alpha)
+ }
+ }
+ }
+
+ val lockscreenAlphaOnFold: Flow<Float> =
+ transitionAnimationOnFold
+ .sharedFlow(
+ startTime = 600.milliseconds,
+ duration = 500.milliseconds,
+ onStep = { it },
+ )
+ .sample(powerInteractor.detailedWakefulness, ::Pair)
+ .transform { (alpha, wakefulness) ->
+ if (wakefulness.lastSleepReason == FOLD) {
+ emit(alpha)
+ }
+ }
+
+ val notificationAlphaOnFold: Flow<Float> =
+ transitionAnimationOnFold
+ .sharedFlow(
+ duration = 1100.milliseconds,
+ onStep = { 0f },
+ onFinish = { 1f },
+ )
+ .sample(powerInteractor.detailedWakefulness, ::Pair)
+ .transform { (alpha, wakefulness) ->
+ if (wakefulness.lastSleepReason == FOLD) {
+ emit(alpha)
+ }
+ }
+
+ /** x-translation from the side of the screen for fold animation */
+ fun enterFromSideTranslationX(translatePx: Int): Flow<StateToValue> {
+ return transitionAnimationOnFold
+ .sharedFlowWithState(
+ startTime = 600.milliseconds,
+ duration = 500.milliseconds,
+ onStep = { translatePx + it * -translatePx },
+ onFinish = { 0f },
+ interpolator = EMPHASIZED_DECELERATE,
+ )
+ .sample(powerInteractor.detailedWakefulness, ::Pair)
+ .transform { (stateToValue, wakefulness) ->
+ if (wakefulness.lastSleepReason == FOLD) {
+ emit(stateToValue)
+ }
+ }
}
override val deviceEntryParentViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
index 6f168d4..6cf668c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
@@ -33,6 +33,7 @@
keyguardInteractor = keyguardInteractor,
keyguardTransitionInteractor = keyguardTransitionInteractor,
goneToAodTransitionViewModel = goneToAodTransitionViewModel,
+ lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel,
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
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 19e4241..8549a30 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
@@ -22,11 +22,13 @@
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.power.domain.interactor.powerInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.goneToAodTransitionViewModel by Fixture {
GoneToAodTransitionViewModel(
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+ powerInteractor = powerInteractor,
animationFlow = keyguardTransitionAnimationFlow,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
index 07b4cd4..f45e33b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
@@ -22,11 +22,13 @@
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.power.domain.interactor.powerInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
-val Kosmos.lockscreenToAodTransitionViewModel by Fixture {
+var Kosmos.lockscreenToAodTransitionViewModel by Fixture {
LockscreenToAodTransitionViewModel(
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+ powerInteractor = powerInteractor,
shadeDependentFlows = shadeDependentFlows,
animationFlow = keyguardTransitionAnimationFlow,
)