diff options
| author | 2024-11-04 19:48:22 +0000 | |
|---|---|---|
| committer | 2024-11-04 20:07:45 +0000 | |
| commit | c9ce255f85a3c25dc3f73c82538656039b55c4e7 (patch) | |
| tree | 7204ea017a18511d8ba9cfd98d8e75cb11babfe4 | |
| parent | cd1ea09d418470879f723e00356fc6cbce830095 (diff) | |
Enable smoother burn-in adjustments on transition cancel
Using transitionValue() when a transition is canceled produces
a jump in values and a bad animation. Listening to transition
edges directly does not have that same effect, as it will use
the last real value emitted. To make sure values reset, also
listent to all transition to LOCKSCREEN.
Test: atest AodBurnInViewModelTest
Test: double-tap launch camera from AOD/LOCKSCREEN
Test: repeatedly unlock/lock with sidefps
Fixes: 336241173
Fixes: 369173324
Flag: EXEMPT bugfix
Change-Id: I084f06be7133d4c9e84d5983660f5086cee76337
3 files changed, 33 insertions, 5 deletions
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 7f0937059494..0e3b03f74c02 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 @@ -44,6 +44,7 @@ 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.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Ignore @@ -107,6 +108,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { fun translationAndScale_whenNotDozing() = testScope.runTest { val movement by collectLastValue(underTest.movement) + assertThat(movement?.translationX).isEqualTo(0) // Set to not dozing (on lockscreen) keyguardTransitionRepository.sendTransitionStep( @@ -180,6 +182,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { testScope.runTest { underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100)) val movement by collectLastValue(underTest.movement) + assertThat(movement?.translationX).isEqualTo(0) // Set to dozing (on AOD) keyguardTransitionRepository.sendTransitionStep( @@ -221,6 +224,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { testScope.runTest { underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80)) val movement by collectLastValue(underTest.movement) + assertThat(movement?.translationX).isEqualTo(0) // Set to dozing (on AOD) keyguardTransitionRepository.sendTransitionStep( @@ -263,6 +267,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { testScope.runTest { underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80)) val movement by collectLastValue(underTest.movement) + assertThat(movement?.translationX).isEqualTo(0) // Set to dozing (on AOD) keyguardTransitionRepository.sendTransitionStep( @@ -305,6 +310,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true) val movement by collectLastValue(underTest.movement) + assertThat(movement?.translationX).isEqualTo(0) // Set to dozing (on AOD) keyguardTransitionRepository.sendTransitionStep( @@ -423,6 +429,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { .thenReturn(if (isWeatherClock) true else false) val movement by collectLastValue(underTest.movement) + assertThat(movement?.translationX).isEqualTo(0) // Set to dozing (on AOD) keyguardTransitionRepository.sendTransitionStep( @@ -434,6 +441,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { ), validateStep = false, ) + runCurrent() // Trigger a change to the burn-in model burnInFlow.value = BurnInModel(translationX = 20, translationY = 30, scale = 0.5f) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt index abd7f90bbf22..7d4d377c768a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor import android.animation.ValueAnimator import android.util.Log +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState @@ -33,7 +34,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map -import com.android.app.tracing.coroutines.launchTraced as launch /** * Each TransitionInteractor is responsible for determining under which conditions to notify @@ -201,9 +201,18 @@ sealed class TransitionInteractor( scope.launch { keyguardInteractor.onCameraLaunchDetected.filterRelevantKeyguardState().collect { if (!maybeHandleInsecurePowerGesture()) { + val lastStep = transitionInteractor.transitionState.value + val modeOnCanceled = + if (lastStep.to == KeyguardState.AOD) { + // Enabled smooth transition when double-tap camera cancels + // transition to AOD + TransitionModeOnCanceled.REVERSE + } else { + TransitionModeOnCanceled.RESET + } startTransitionTo( toState = KeyguardState.OCCLUDED, - modeOnCanceled = TransitionModeOnCanceled.RESET, + modeOnCanceled = modeOnCanceled, ownerReason = "keyguardInteractor.onCameraLaunchDetected", ) } 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 c78e0c9f5266..478372d4dc0c 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 @@ -30,6 +30,7 @@ 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.ClockSize +import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.StateToValue import com.android.systemui.res.R @@ -42,8 +43,10 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine +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 import kotlinx.coroutines.flow.stateIn @@ -164,9 +167,17 @@ constructor( private fun burnIn(params: BurnInParameters): Flow<BurnInModel> { return combine( - keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).map { - Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it) - }, + merge( + keyguardTransitionInteractor.transition(Edge.create(to = KeyguardState.AOD)), + keyguardTransitionInteractor + .transition(Edge.create(from = KeyguardState.AOD)) + .map { it.copy(value = 1f - it.value) }, + keyguardTransitionInteractor + .transition(Edge.create(to = KeyguardState.LOCKSCREEN)) + .filter { it.from != KeyguardState.AOD } + .map { it.copy(value = 0f) }, + ) + .map { Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it.value) }, burnInInteractor.burnIn( xDimenResourceId = R.dimen.burn_in_prevention_offset_x, yDimenResourceId = R.dimen.burn_in_prevention_offset_y, |