diff options
| author | 2025-02-07 19:58:13 +0000 | |
|---|---|---|
| committer | 2025-02-11 04:30:10 -0800 | |
| commit | c0bb65e54d157bca787c8e718b8fc9b10c0af7f4 (patch) | |
| tree | 0d19751690f42c8e0a675e2a7c50e1db2e1e1b43 | |
| parent | 1b0b0490d0509e6586fd28c1a3c209df82e33073 (diff) | |
Fix UDFPS flicker on LOCKSCREEN->DOZING
The UDFPS background alpha must be set to 0f when in dozing
state. However, it should not animate from its current value.
Allow null values in onStep() return to indicate no change is
needed, and make sure the alpha gets to 0f onCancel or onFinish.
Fixes: 363899639
Test: atest KeyguardTransitionAnimationFlowTest
Test: manual look from flicker on LOCKSCREEN->DOZING
Test: manual ensure pulsing notifications do not show UDFPS
background
Flag: EXEMPT bugfix
Change-Id: Ic956f78db206d5d8d7e227be2b75bf51ab37cacc
4 files changed, 46 insertions, 35 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt index a0fed6bbfc2c..0ec3173ebb2a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt @@ -57,9 +57,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { duration = 1000.milliseconds, edge = Edge.create(from = Scenes.Gone, to = DREAMING), ) - .setupWithoutSceneContainer( - edge = Edge.create(from = GONE, to = DREAMING), - ) + .setupWithoutSceneContainer(edge = Edge.create(from = GONE, to = DREAMING)) } @Test(expected = IllegalArgumentException::class) @@ -75,7 +73,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { underTest.sharedFlow( startTime = 300.milliseconds, duration = 800.milliseconds, - onStep = { it } + onStep = { it }, ) } @@ -112,6 +110,17 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { } @Test + fun onStepReturnsNullEmitsNothing() = + testScope.runTest { + val flow = underTest.sharedFlow(duration = 100.milliseconds, onStep = { null }) + var animationValues = collectLastValue(flow) + runCurrent() + + repository.sendTransitionStep(step(0.5f, TransitionState.RUNNING)) + assertThat(animationValues()).isNull() + } + + @Test fun usesStartTime() = testScope.runTest { val flow = @@ -166,11 +175,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { @Test fun usesOnStepToDoubleValue() = testScope.runTest { - val flow = - underTest.sharedFlow( - duration = 1000.milliseconds, - onStep = { it * 2 }, - ) + val flow = underTest.sharedFlow(duration = 1000.milliseconds, onStep = { it * 2 }) val animationValues by collectLastValue(flow) runCurrent() @@ -190,10 +195,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { fun usesOnStepToDoubleValueWithState() = testScope.runTest { val flow = - underTest.sharedFlowWithState( - duration = 1000.milliseconds, - onStep = { it * 2 }, - ) + underTest.sharedFlowWithState(duration = 1000.milliseconds, onStep = { it * 2 }) val animationValues by collectLastValue(flow) runCurrent() @@ -204,7 +206,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { from = GONE, to = DREAMING, transitionState = TransitionState.STARTED, - value = 0f + value = 0f, ) ) repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING)) @@ -214,7 +216,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { from = GONE, to = DREAMING, transitionState = TransitionState.RUNNING, - value = 0.6f + value = 0.6f, ) ) repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING)) @@ -224,7 +226,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { from = GONE, to = DREAMING, transitionState = TransitionState.RUNNING, - value = 1.2f + value = 1.2f, ) ) repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING)) @@ -234,7 +236,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { from = GONE, to = DREAMING, transitionState = TransitionState.RUNNING, - value = 1.6f + value = 1.6f, ) ) repository.sendTransitionStep(step(1f, TransitionState.RUNNING)) @@ -244,7 +246,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { from = GONE, to = DREAMING, transitionState = TransitionState.RUNNING, - value = 2f + value = 2f, ) ) repository.sendTransitionStep(step(1f, TransitionState.FINISHED)) @@ -254,7 +256,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { from = GONE, to = DREAMING, transitionState = TransitionState.FINISHED, - value = null + value = null, ) ) } @@ -262,11 +264,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { @Test fun sameFloatValueWithTheSameTransitionStateDoesNotEmitTwice() = testScope.runTest { - val flow = - underTest.sharedFlow( - duration = 1000.milliseconds, - onStep = { it }, - ) + val flow = underTest.sharedFlow(duration = 1000.milliseconds, onStep = { it }) val values by collectValues(flow) runCurrent() @@ -280,11 +278,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { @Test fun sameFloatValueWithADifferentTransitionStateDoesEmitTwice() = testScope.runTest { - val flow = - underTest.sharedFlow( - duration = 1000.milliseconds, - onStep = { it }, - ) + val flow = underTest.sharedFlow(duration = 1000.milliseconds, onStep = { it }) val values by collectValues(flow) runCurrent() @@ -302,14 +296,14 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { private fun step( value: Float, - state: TransitionState = TransitionState.RUNNING + state: TransitionState = TransitionState.RUNNING, ): TransitionStep { return TransitionStep( from = GONE, to = DREAMING, value = value, transitionState = state, - ownerName = "GoneToDreamingTransitionViewModelTest" + ownerName = "GoneToDreamingTransitionViewModelTest", ) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt index c8fade3fbf01..6648ae21edc6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt @@ -24,6 +24,7 @@ import com.android.systemui.coroutines.collectLastValue 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.TransitionState.FINISHED 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 @@ -63,7 +64,15 @@ class DeviceEntryBackgroundViewModelTest : SysuiTestCase() { ) runCurrent() - assertThat(alpha).isEqualTo(0.0f) + assertThat(alpha).isEqualTo(1.0f) + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + listOf(lockscreenToDozing(1f, FINISHED)), + testScope, + ) + runCurrent() + + assertThat(alpha).isEqualTo(0f) } private fun lockscreenToDozing(value: Float, state: TransitionState = RUNNING): TransitionStep { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt index 8f6815829ba2..c5127a5e49ba 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt @@ -66,11 +66,14 @@ constructor( * range. This function maps the [startTime] and [duration] into [0, 1], when this subset is * valid. * + * 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 sharedFlow( duration: Duration = transitionDuration, - onStep: (Float) -> Float, + onStep: (Float) -> Float?, startTime: Duration = 0.milliseconds, onStart: (() -> Unit)? = null, onCancel: (() -> Float)? = null, @@ -102,7 +105,7 @@ constructor( */ fun sharedFlowWithState( duration: Duration, - onStep: (Float) -> Float, + onStep: (Float) -> Float?, startTime: Duration = 0.milliseconds, onStart: (() -> Unit)? = null, onCancel: (() -> Float)? = null, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt index dc7fefa1d754..65c0a4fe46a7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt @@ -54,7 +54,12 @@ constructor( ) val deviceEntryBackgroundViewAlpha: Flow<Float> = - transitionAnimation.immediatelyTransitionTo(0f) + transitionAnimation.sharedFlow( + duration = TO_DOZING_DURATION, + onStep = { null }, + onFinish = { 0f }, + onCancel = { 0f }, + ) override val deviceEntryParentViewAlpha: Flow<Float> = deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest { |