Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt +32 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,38 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { assertThat(transitionValues).isEqualTo(listOf(0f, 0.5f, 1f, 1f, 0.5f, 0f)) } @Test fun transitionValue_badTransitionResetsTransitionValue() = testScope.runTest { resetTransitionValueReplayCache(setOf(AOD, DOZING, LOCKSCREEN)) val transitionValues by collectValues(underTest.transitionValue(state = DOZING)) val toSteps = listOf( TransitionStep(AOD, DOZING, 0f, STARTED), TransitionStep(AOD, DOZING, 0.5f, RUNNING), ) toSteps.forEach { repository.sendTransitionStep(it) runCurrent() } // This is an intentionally bad sequence that will leave the transitionValue for // DOZING in a bad place, since no CANCELED will be issued for DOZING val fromSteps = listOf( TransitionStep(AOD, LOCKSCREEN, 0f, STARTED), TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING), TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED), ) fromSteps.forEach { repository.sendTransitionStep(it) runCurrent() } assertThat(transitionValues).isEqualTo(listOf(0f, 0.5f, 0f)) } @Test fun transitionValue_canceled_toAnotherState() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ constructor( } } private suspend fun FromOccludedTransitionInteractor.startTransitionToLockscreenOrHub( private suspend fun startTransitionToLockscreenOrHub( isIdleOnCommunal: Boolean, showCommunalFromOccluded: Boolean, dreamFromOccluded: Boolean, Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +19 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,25 @@ constructor( } } } // Safety: When any transition is FINISHED, ensure all other transitionValue flows other // than the FINISHED state are reset to a value of 0f. There have been rare but severe // bugs that get the device stuck in a bad state when these are not properly reset. scope.launch { repository.transitions .filter { it.transitionState == TransitionState.FINISHED } .collect { for (state in KeyguardState.entries) { if (state != it.to) { val flow = getTransitionValueFlow(state) val replayCache = flow.replayCache if (!replayCache.isEmpty() && replayCache.last() != 0f) { flow.emit(0f) } } } } } } fun transition(edge: Edge, edgeWithoutSceneContainer: Edge): Flow<TransitionStep> { Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt +32 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,38 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { assertThat(transitionValues).isEqualTo(listOf(0f, 0.5f, 1f, 1f, 0.5f, 0f)) } @Test fun transitionValue_badTransitionResetsTransitionValue() = testScope.runTest { resetTransitionValueReplayCache(setOf(AOD, DOZING, LOCKSCREEN)) val transitionValues by collectValues(underTest.transitionValue(state = DOZING)) val toSteps = listOf( TransitionStep(AOD, DOZING, 0f, STARTED), TransitionStep(AOD, DOZING, 0.5f, RUNNING), ) toSteps.forEach { repository.sendTransitionStep(it) runCurrent() } // This is an intentionally bad sequence that will leave the transitionValue for // DOZING in a bad place, since no CANCELED will be issued for DOZING val fromSteps = listOf( TransitionStep(AOD, LOCKSCREEN, 0f, STARTED), TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING), TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED), ) fromSteps.forEach { repository.sendTransitionStep(it) runCurrent() } assertThat(transitionValues).isEqualTo(listOf(0f, 0.5f, 0f)) } @Test fun transitionValue_canceled_toAnotherState() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ constructor( } } private suspend fun FromOccludedTransitionInteractor.startTransitionToLockscreenOrHub( private suspend fun startTransitionToLockscreenOrHub( isIdleOnCommunal: Boolean, showCommunalFromOccluded: Boolean, dreamFromOccluded: Boolean, Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +19 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,25 @@ constructor( } } } // Safety: When any transition is FINISHED, ensure all other transitionValue flows other // than the FINISHED state are reset to a value of 0f. There have been rare but severe // bugs that get the device stuck in a bad state when these are not properly reset. scope.launch { repository.transitions .filter { it.transitionState == TransitionState.FINISHED } .collect { for (state in KeyguardState.entries) { if (state != it.to) { val flow = getTransitionValueFlow(state) val replayCache = flow.replayCache if (!replayCache.isEmpty() && replayCache.last() != 0f) { flow.emit(0f) } } } } } } fun transition(edge: Edge, edgeWithoutSceneContainer: Edge): Flow<TransitionStep> { Loading