Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt +74 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ 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.scene.shared.model.Scenes import com.android.systemui.shade.shadeTestUtil import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.time.Duration.Companion.milliseconds Loading @@ -46,6 +47,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { val testScope = kosmos.testScope val animationFlow = kosmos.keyguardTransitionAnimationFlow val repository = kosmos.fakeKeyguardTransitionRepository val shadeTestUtil by lazy { kosmos.shadeTestUtil } private lateinit var underTest: KeyguardTransitionAnimationFlow.FlowBuilder Loading Loading @@ -290,6 +292,78 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { assertThat(values[0]).isEqualTo(0.3f) } @Test fun sharedFlowWithShadeExpanded() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 1000.milliseconds, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1f }, ) val values by collectValues(flow) shadeTestUtil.setQsExpansion(1f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING)) assertThat(values.size).isEqualTo(2) assertThat(values[0]).isEqualTo(0f) assertThat(values[0]).isEqualTo(0f) } @Test fun sharedFlowWithShadeNotExpanded() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 1000.milliseconds, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1f }, ) val values by collectValues(flow) shadeTestUtil.setQsExpansion(0f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING)) assertThat(values.size).isEqualTo(2) assertThat(values[0]).isEqualTo(1f) assertThat(values[0]).isEqualTo(1f) } @Test fun sharedFlowWithShadeExpanded_onCancelRunsWhenSpecified() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 100.milliseconds, onStep = { step, _ -> step }, onCancel = { isShadeExpanded -> if (isShadeExpanded) 100f else 200f }, ) val animationValues by collectLastValue(flow) shadeTestUtil.setQsExpansion(1f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED)) assertThat(animationValues).isEqualTo(100f) } @Test fun sharedFlowWithShadeNotExpanded_onCancelRunsWhenSpecified() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 100.milliseconds, onStep = { step, _ -> step }, onCancel = { isShadeExpanded -> if (isShadeExpanded) 100f else 200f }, ) val animationValues by collectLastValue(flow) shadeTestUtil.setQsExpansion(0f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED)) assertThat(animationValues).isEqualTo(200f) } private fun assertFloat(actual: Float?, expected: Float) { assertThat(actual!!).isWithin(0.01f).of(expected) } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt +0 −1 Original line number Diff line number Diff line Loading @@ -211,7 +211,6 @@ class LockscreenToOccludedTransitionViewModelTest(flags: FlagsParameterization) testScope.runTest { val actual by collectLastValue(underTest.deviceEntryParentViewAlpha) shadeExpanded(false) runCurrent() // fade out repository.sendTransitionStep(step(0f, TransitionState.STARTED)) Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt +55 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor import dagger.Lazy import javax.inject.Inject import kotlin.math.max import kotlin.math.min Loading @@ -38,6 +40,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapNotNull typealias IsShadeExpanded = Boolean /** * Assists in creating sub-flows for a KeyguardTransition. Call [setup] once for a transition, and * then [sharedFlow] for each sub animation that should be trigged when the overall transition runs. Loading @@ -48,6 +52,7 @@ class KeyguardTransitionAnimationFlow constructor( private val transitionInteractor: KeyguardTransitionInteractor, private val logger: KeyguardTransitionAnimationLogger, private val shadeInteractor: Lazy<ShadeInteractor>, ) { /** Invoke once per transition between FROM->TO states to get access to a shared flow. */ fun setup(duration: Duration, edge: Edge): FlowBuilder { Loading Loading @@ -94,6 +99,56 @@ constructor( .mapNotNull { stateToValue -> stateToValue.value } } /** * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted * in the range of [0, 1]. View animations should begin and end within a subset of this * range. This function maps the [startTime] and [duration] into [0, 1], when this subset is * valid. * * This overload provides additional information about the shade expansion state as recorded * when STARTED was emitted. * * Note that [onStep] accepts a null return value. When null, no animation information will * be emitted, effectively saying "do not change the value on this frame" * * Note that [onCancel] isn't used when the scene framework is enabled. */ fun sharedFlowWithShade( duration: Duration = transitionDuration, onStep: (Float, IsShadeExpanded) -> Float?, startTime: Duration = 0.milliseconds, onStart: (() -> Unit)? = null, onCancel: ((IsShadeExpanded) -> Float)? = null, onFinish: ((IsShadeExpanded) -> Float)? = null, interpolator: Interpolator = LINEAR, name: String? = null, ): Flow<Float> { var isShadeExpanded = false return sharedFlow( duration = duration, onStep = { step -> onStep(step, isShadeExpanded) }, startTime = startTime, onStart = { isShadeExpanded = shadeInteractor.get().isAnyFullyExpanded.value if (onStart != null) onStart() }, onCancel = if (onCancel != null) { { onCancel(isShadeExpanded) } } else { null }, onFinish = if (onFinish != null) { { onFinish(isShadeExpanded) } } else { null }, interpolator = interpolator, name = name, ) } /** * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted * in the range of [0, 1]. View animations should begin and end within a subset of this Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt +42 −30 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow Loading @@ -40,11 +41,8 @@ import kotlinx.coroutines.flow.emptyFlow @SysUISingleton class AlternateBouncerToPrimaryBouncerTransitionViewModel @Inject constructor( animationFlow: KeyguardTransitionAnimationFlow, blurConfig: BlurConfig, shadeDependentFlows: ShadeDependentFlows, ) : DeviceEntryIconTransition, PrimaryBouncerTransition { constructor(animationFlow: KeyguardTransitionAnimationFlow, blurConfig: BlurConfig) : DeviceEntryIconTransition, PrimaryBouncerTransition { private val transitionAnimation = animationFlow .setup( Loading Loading @@ -73,9 +71,17 @@ constructor( val notificationAlpha: Flow<Float> = if (Flags.bouncerUiRevamp()) { shadeDependentFlows.transitionFlow( flowWhenShadeIsNotExpanded = lockscreenAlpha, flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(1f), transitionAnimation.sharedFlowWithShade( duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION, onStep = { step, isShadeExpanded -> if (isShadeExpanded) { 1f } else if (Flags.bouncerUiRevamp()) { alphaForAnimationStep(step) } else { null } }, ) } else { alphaFlow Loading @@ -83,10 +89,11 @@ constructor( override val notificationBlurRadius: Flow<Float> = if (Flags.bouncerUiRevamp()) { shadeDependentFlows.transitionFlow( flowWhenShadeIsNotExpanded = emptyFlow(), flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx), transitionAnimation.sharedFlowWithShade( duration = 1.milliseconds, onStep = { _, isShadeExpanded -> if (isShadeExpanded) blurConfig.maxBlurRadiusPx else null }, ) } else { emptyFlow<Float>() Loading @@ -96,24 +103,29 @@ constructor( transitionAnimation.immediatelyTransitionTo(0f) override val windowBlurRadius: Flow<Float> = shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = transitionAnimation.sharedFlowWithShade( duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION, onStep = { step, isShadeExpanded -> if (isShadeExpanded) { if (Flags.notificationShadeBlur()) { transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx) blurConfig.maxBlurRadiusPx } else { blurConfig.minBlurRadiusPx } } else { transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx) }, flowWhenShadeIsNotExpanded = transitionAnimation.sharedFlow( duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION, onStep = { step -> transitionProgressToBlurRadius( starBlurRadius = blurConfig.minBlurRadiusPx, endBlurRadius = blurConfig.maxBlurRadiusPx, transitionProgress = step, ) } }, onFinish = { isShadeExpanded -> if (isShadeExpanded && !Flags.notificationShadeBlur()) { blurConfig.minBlurRadiusPx } else { blurConfig.maxBlurRadiusPx } }, onFinish = { blurConfig.maxBlurRadiusPx }, ), ) } packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt +25 −47 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ 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.flow.Flow Loading @@ -45,7 +44,6 @@ class LockscreenToAodTransitionViewModel constructor( deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor, private val powerInteractor: PowerInteractor, shadeDependentFlows: ShadeDependentFlows, animationFlow: KeyguardTransitionAnimationFlow, ) : DeviceEntryIconTransition { Loading @@ -62,15 +60,11 @@ constructor( ) val deviceEntryBackgroundViewAlpha: Flow<Float> = shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f), flowWhenShadeIsNotExpanded = transitionAnimation.sharedFlow( transitionAnimation.sharedFlowWithShade( duration = 300.milliseconds, onStep = { 1 - it }, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1 - step }, onCancel = { 0f }, onFinish = { 0f }, ), ) val shortcutsAlpha: Flow<Float> = Loading @@ -89,8 +83,8 @@ constructor( onStart = { startAlpha = viewState.alpha() }, onStep = { MathUtils.lerp(startAlpha, 1f, it) }, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (alpha, wakefulness) -> .transform { alpha -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason != FOLD) { emit(alpha) } Loading @@ -99,13 +93,9 @@ constructor( val lockscreenAlphaOnFold: Flow<Float> = transitionAnimationOnFold .sharedFlow( startTime = 600.milliseconds, duration = 500.milliseconds, onStep = { it }, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (alpha, wakefulness) -> .sharedFlow(startTime = 600.milliseconds, duration = 500.milliseconds, onStep = { it }) .transform { alpha -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason == FOLD) { emit(alpha) } Loading @@ -113,13 +103,9 @@ constructor( val notificationAlphaOnFold: Flow<Float> = transitionAnimationOnFold .sharedFlow( duration = 1100.milliseconds, onStep = { 0f }, onFinish = { 1f }, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (alpha, wakefulness) -> .sharedFlow(duration = 1100.milliseconds, onStep = { 0f }, onFinish = { 1f }) .transform { alpha -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason == FOLD) { emit(alpha) } Loading @@ -135,8 +121,8 @@ constructor( onFinish = { 0f }, interpolator = EMPHASIZED_DECELERATE, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (stateToValue, wakefulness) -> .transform { stateToValue -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason == FOLD) { emit(stateToValue) } Loading @@ -147,26 +133,18 @@ constructor( deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest { isUdfpsEnrolledAndEnabled -> if (isUdfpsEnrolledAndEnabled) { shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = // fade in transitionAnimation.sharedFlow( transitionAnimation.sharedFlowWithShade( duration = 300.milliseconds, onStep = { it }, onStep = { step, isShadeExpanded -> if (isShadeExpanded) step else 1f }, onCancel = { 1f }, onFinish = { 1f }, ), flowWhenShadeIsNotExpanded = transitionAnimation.immediatelyTransitionTo(1f), ) } else { shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f), flowWhenShadeIsNotExpanded = // fade out transitionAnimation.sharedFlow( transitionAnimation.sharedFlowWithShade( duration = 200.milliseconds, onStep = { 1f - it }, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1f - step }, onCancel = { 0f }, onFinish = { 0f }, ), ) } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt +74 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ 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.scene.shared.model.Scenes import com.android.systemui.shade.shadeTestUtil import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.time.Duration.Companion.milliseconds Loading @@ -46,6 +47,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { val testScope = kosmos.testScope val animationFlow = kosmos.keyguardTransitionAnimationFlow val repository = kosmos.fakeKeyguardTransitionRepository val shadeTestUtil by lazy { kosmos.shadeTestUtil } private lateinit var underTest: KeyguardTransitionAnimationFlow.FlowBuilder Loading Loading @@ -290,6 +292,78 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { assertThat(values[0]).isEqualTo(0.3f) } @Test fun sharedFlowWithShadeExpanded() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 1000.milliseconds, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1f }, ) val values by collectValues(flow) shadeTestUtil.setQsExpansion(1f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING)) assertThat(values.size).isEqualTo(2) assertThat(values[0]).isEqualTo(0f) assertThat(values[0]).isEqualTo(0f) } @Test fun sharedFlowWithShadeNotExpanded() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 1000.milliseconds, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1f }, ) val values by collectValues(flow) shadeTestUtil.setQsExpansion(0f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING)) assertThat(values.size).isEqualTo(2) assertThat(values[0]).isEqualTo(1f) assertThat(values[0]).isEqualTo(1f) } @Test fun sharedFlowWithShadeExpanded_onCancelRunsWhenSpecified() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 100.milliseconds, onStep = { step, _ -> step }, onCancel = { isShadeExpanded -> if (isShadeExpanded) 100f else 200f }, ) val animationValues by collectLastValue(flow) shadeTestUtil.setQsExpansion(1f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED)) assertThat(animationValues).isEqualTo(100f) } @Test fun sharedFlowWithShadeNotExpanded_onCancelRunsWhenSpecified() = testScope.runTest { val flow = underTest.sharedFlowWithShade( duration = 100.milliseconds, onStep = { step, _ -> step }, onCancel = { isShadeExpanded -> if (isShadeExpanded) 100f else 200f }, ) val animationValues by collectLastValue(flow) shadeTestUtil.setQsExpansion(0f) repository.sendTransitionStep(step(0.0f, TransitionState.STARTED)) repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED)) assertThat(animationValues).isEqualTo(200f) } private fun assertFloat(actual: Float?, expected: Float) { assertThat(actual!!).isWithin(0.01f).of(expected) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt +0 −1 Original line number Diff line number Diff line Loading @@ -211,7 +211,6 @@ class LockscreenToOccludedTransitionViewModelTest(flags: FlagsParameterization) testScope.runTest { val actual by collectLastValue(underTest.deviceEntryParentViewAlpha) shadeExpanded(false) runCurrent() // fade out repository.sendTransitionStep(step(0f, TransitionState.STARTED)) Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt +55 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor import dagger.Lazy import javax.inject.Inject import kotlin.math.max import kotlin.math.min Loading @@ -38,6 +40,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapNotNull typealias IsShadeExpanded = Boolean /** * Assists in creating sub-flows for a KeyguardTransition. Call [setup] once for a transition, and * then [sharedFlow] for each sub animation that should be trigged when the overall transition runs. Loading @@ -48,6 +52,7 @@ class KeyguardTransitionAnimationFlow constructor( private val transitionInteractor: KeyguardTransitionInteractor, private val logger: KeyguardTransitionAnimationLogger, private val shadeInteractor: Lazy<ShadeInteractor>, ) { /** Invoke once per transition between FROM->TO states to get access to a shared flow. */ fun setup(duration: Duration, edge: Edge): FlowBuilder { Loading Loading @@ -94,6 +99,56 @@ constructor( .mapNotNull { stateToValue -> stateToValue.value } } /** * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted * in the range of [0, 1]. View animations should begin and end within a subset of this * range. This function maps the [startTime] and [duration] into [0, 1], when this subset is * valid. * * This overload provides additional information about the shade expansion state as recorded * when STARTED was emitted. * * Note that [onStep] accepts a null return value. When null, no animation information will * be emitted, effectively saying "do not change the value on this frame" * * Note that [onCancel] isn't used when the scene framework is enabled. */ fun sharedFlowWithShade( duration: Duration = transitionDuration, onStep: (Float, IsShadeExpanded) -> Float?, startTime: Duration = 0.milliseconds, onStart: (() -> Unit)? = null, onCancel: ((IsShadeExpanded) -> Float)? = null, onFinish: ((IsShadeExpanded) -> Float)? = null, interpolator: Interpolator = LINEAR, name: String? = null, ): Flow<Float> { var isShadeExpanded = false return sharedFlow( duration = duration, onStep = { step -> onStep(step, isShadeExpanded) }, startTime = startTime, onStart = { isShadeExpanded = shadeInteractor.get().isAnyFullyExpanded.value if (onStart != null) onStart() }, onCancel = if (onCancel != null) { { onCancel(isShadeExpanded) } } else { null }, onFinish = if (onFinish != null) { { onFinish(isShadeExpanded) } } else { null }, interpolator = interpolator, name = name, ) } /** * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted * in the range of [0, 1]. View animations should begin and end within a subset of this Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt +42 −30 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow Loading @@ -40,11 +41,8 @@ import kotlinx.coroutines.flow.emptyFlow @SysUISingleton class AlternateBouncerToPrimaryBouncerTransitionViewModel @Inject constructor( animationFlow: KeyguardTransitionAnimationFlow, blurConfig: BlurConfig, shadeDependentFlows: ShadeDependentFlows, ) : DeviceEntryIconTransition, PrimaryBouncerTransition { constructor(animationFlow: KeyguardTransitionAnimationFlow, blurConfig: BlurConfig) : DeviceEntryIconTransition, PrimaryBouncerTransition { private val transitionAnimation = animationFlow .setup( Loading Loading @@ -73,9 +71,17 @@ constructor( val notificationAlpha: Flow<Float> = if (Flags.bouncerUiRevamp()) { shadeDependentFlows.transitionFlow( flowWhenShadeIsNotExpanded = lockscreenAlpha, flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(1f), transitionAnimation.sharedFlowWithShade( duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION, onStep = { step, isShadeExpanded -> if (isShadeExpanded) { 1f } else if (Flags.bouncerUiRevamp()) { alphaForAnimationStep(step) } else { null } }, ) } else { alphaFlow Loading @@ -83,10 +89,11 @@ constructor( override val notificationBlurRadius: Flow<Float> = if (Flags.bouncerUiRevamp()) { shadeDependentFlows.transitionFlow( flowWhenShadeIsNotExpanded = emptyFlow(), flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx), transitionAnimation.sharedFlowWithShade( duration = 1.milliseconds, onStep = { _, isShadeExpanded -> if (isShadeExpanded) blurConfig.maxBlurRadiusPx else null }, ) } else { emptyFlow<Float>() Loading @@ -96,24 +103,29 @@ constructor( transitionAnimation.immediatelyTransitionTo(0f) override val windowBlurRadius: Flow<Float> = shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = transitionAnimation.sharedFlowWithShade( duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION, onStep = { step, isShadeExpanded -> if (isShadeExpanded) { if (Flags.notificationShadeBlur()) { transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx) blurConfig.maxBlurRadiusPx } else { blurConfig.minBlurRadiusPx } } else { transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx) }, flowWhenShadeIsNotExpanded = transitionAnimation.sharedFlow( duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION, onStep = { step -> transitionProgressToBlurRadius( starBlurRadius = blurConfig.minBlurRadiusPx, endBlurRadius = blurConfig.maxBlurRadiusPx, transitionProgress = step, ) } }, onFinish = { isShadeExpanded -> if (isShadeExpanded && !Flags.notificationShadeBlur()) { blurConfig.minBlurRadiusPx } else { blurConfig.maxBlurRadiusPx } }, onFinish = { blurConfig.maxBlurRadiusPx }, ), ) }
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt +25 −47 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ 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.flow.Flow Loading @@ -45,7 +44,6 @@ class LockscreenToAodTransitionViewModel constructor( deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor, private val powerInteractor: PowerInteractor, shadeDependentFlows: ShadeDependentFlows, animationFlow: KeyguardTransitionAnimationFlow, ) : DeviceEntryIconTransition { Loading @@ -62,15 +60,11 @@ constructor( ) val deviceEntryBackgroundViewAlpha: Flow<Float> = shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f), flowWhenShadeIsNotExpanded = transitionAnimation.sharedFlow( transitionAnimation.sharedFlowWithShade( duration = 300.milliseconds, onStep = { 1 - it }, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1 - step }, onCancel = { 0f }, onFinish = { 0f }, ), ) val shortcutsAlpha: Flow<Float> = Loading @@ -89,8 +83,8 @@ constructor( onStart = { startAlpha = viewState.alpha() }, onStep = { MathUtils.lerp(startAlpha, 1f, it) }, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (alpha, wakefulness) -> .transform { alpha -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason != FOLD) { emit(alpha) } Loading @@ -99,13 +93,9 @@ constructor( val lockscreenAlphaOnFold: Flow<Float> = transitionAnimationOnFold .sharedFlow( startTime = 600.milliseconds, duration = 500.milliseconds, onStep = { it }, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (alpha, wakefulness) -> .sharedFlow(startTime = 600.milliseconds, duration = 500.milliseconds, onStep = { it }) .transform { alpha -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason == FOLD) { emit(alpha) } Loading @@ -113,13 +103,9 @@ constructor( val notificationAlphaOnFold: Flow<Float> = transitionAnimationOnFold .sharedFlow( duration = 1100.milliseconds, onStep = { 0f }, onFinish = { 1f }, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (alpha, wakefulness) -> .sharedFlow(duration = 1100.milliseconds, onStep = { 0f }, onFinish = { 1f }) .transform { alpha -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason == FOLD) { emit(alpha) } Loading @@ -135,8 +121,8 @@ constructor( onFinish = { 0f }, interpolator = EMPHASIZED_DECELERATE, ) .sample(powerInteractor.detailedWakefulness, ::Pair) .transform { (stateToValue, wakefulness) -> .transform { stateToValue -> val wakefulness = powerInteractor.detailedWakefulness.value if (wakefulness.lastSleepReason == FOLD) { emit(stateToValue) } Loading @@ -147,26 +133,18 @@ constructor( deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest { isUdfpsEnrolledAndEnabled -> if (isUdfpsEnrolledAndEnabled) { shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = // fade in transitionAnimation.sharedFlow( transitionAnimation.sharedFlowWithShade( duration = 300.milliseconds, onStep = { it }, onStep = { step, isShadeExpanded -> if (isShadeExpanded) step else 1f }, onCancel = { 1f }, onFinish = { 1f }, ), flowWhenShadeIsNotExpanded = transitionAnimation.immediatelyTransitionTo(1f), ) } else { shadeDependentFlows.transitionFlow( flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f), flowWhenShadeIsNotExpanded = // fade out transitionAnimation.sharedFlow( transitionAnimation.sharedFlowWithShade( duration = 200.milliseconds, onStep = { 1f - it }, onStep = { step, isShadeExpanded -> if (isShadeExpanded) 0f else 1f - step }, onCancel = { 0f }, onFinish = { 0f }, ), ) } } Loading