Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31156689 authored by Andreas Miko's avatar Andreas Miko
Browse files

Fix FINISHED/CANCELED step filtered out incorrectly

The terminal step was filtered out because the transitioning condition
in STL is not met anymore as STL just moves on to any other
ObservalableTransitionState without guarantee of order. We need to look
at the previous transition to understand if the terminal step belongs
to one or another.

Bug: 361785511
Flag: com.android.systemui.scene_container
Test: tests modified to match real transition sequence of KTF/STL
Change-Id: I5cdd8be86c48903a5ad0d8025d9b93e9891f7b0f
parent 4f76b942
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -1394,9 +1394,11 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {

            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
            val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
            sendSteps(sendStep1)
            kosmos.setSceneTransition(Idle(Scenes.Gone))
            val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
            val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
            sendSteps(sendStep1, sendStep2, sendStep3)
            sendSteps(sendStep2, sendStep3)

            assertEquals(listOf(sendStep1, sendStep2), currentStates)
            assertEquals(listOf(sendStep1, sendStep2), currentStatesConverted)
@@ -1410,6 +1412,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {

            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
            val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
            val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
            val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
            sendSteps(sendStep1, sendStep2, sendStep3)
@@ -1426,6 +1429,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {

            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
            val sendStep1 = TransitionStep(LOCKSCREEN, DOZING, 0f, STARTED)
            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
            val sendStep2 = TransitionStep(LOCKSCREEN, DOZING, 1f, FINISHED)
            val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
            sendSteps(sendStep1, sendStep2, sendStep3)
@@ -1443,6 +1447,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {

            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
            val sendStep1 = TransitionStep(LOCKSCREEN, DOZING, 0f, STARTED)
            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
            val sendStep2 = TransitionStep(LOCKSCREEN, DOZING, 1f, FINISHED)
            val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
            val sendStep4 = TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)
@@ -1461,10 +1466,12 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {

            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
            val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
            sendSteps(sendStep1)
            kosmos.setSceneTransition(Idle(Scenes.Gone))
            val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
            val sendStep3 = TransitionStep(UNDEFINED, AOD, 0f, STARTED)
            val sendStep4 = TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)
            sendSteps(sendStep1, sendStep2, sendStep3, sendStep4)
            sendSteps(sendStep2, sendStep3, sendStep4)

            assertEquals(listOf(sendStep1, sendStep2), currentStates)
            assertEquals(listOf(sendStep1, sendStep2), currentStatesMapped)
@@ -1478,10 +1485,12 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {

            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
            val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
            sendSteps(sendStep1)
            kosmos.setSceneTransition(Idle(Scenes.Gone))
            val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
            val sendStep3 = TransitionStep(UNDEFINED, AOD, 0f, STARTED)
            val sendStep4 = TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)
            sendSteps(sendStep1, sendStep2, sendStep3, sendStep4)
            sendSteps(sendStep2, sendStep3, sendStep4)

            assertEquals(listOf<TransitionStep>(), currentStatesMapped)
        }
+30 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.WithPrev
import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -103,6 +104,18 @@ constructor(
    val transitionState: StateFlow<TransitionStep> =
        transitions.stateIn(scope, SharingStarted.Eagerly, TransitionStep())

    private val sceneTransitionPair =
        sceneInteractor.transitionState
            .pairwise()
            .stateIn(
                scope,
                SharingStarted.Eagerly,
                WithPrev(
                    sceneInteractor.transitionState.value,
                    sceneInteractor.transitionState.value
                )
            )

    /**
     * A pair of the most recent STARTED step, and the transition step immediately preceding it. The
     * transition framework enforces that the previous step is either a CANCELED or FINISHED step,
@@ -209,7 +222,7 @@ constructor(
            }

        return if (SceneContainerFlag.isEnabled) {
            flow.filter {
            flow.filter { step ->
                val fromScene =
                    when (edge) {
                        is Edge.StateToState -> edge.from?.mapToSceneContainerScene()
@@ -226,8 +239,23 @@ constructor(

                fun SceneKey?.isLockscreenOrNull() = this == Scenes.Lockscreen || this == null

                return@filter (fromScene.isLockscreenOrNull() && toScene.isLockscreenOrNull()) ||
                val isTransitioningBetweenLockscreenStates =
                    fromScene.isLockscreenOrNull() && toScene.isLockscreenOrNull()
                val isTransitioningBetweenDesiredScenes =
                    sceneInteractor.transitionState.value.isTransitioning(fromScene, toScene)

                // We can't compare the terminal step with the current sceneTransition because
                // a) STL has no guarantee that it will settle in Idle() when finished/canceled
                // b) Comparing to Idle(toScene) would make any other FINISHED step settling in
                //    toScene pass as well
                val terminalStepBelongsToPreviousTransition =
                    (step.transitionState == TransitionState.FINISHED ||
                        step.transitionState == TransitionState.CANCELED) &&
                        sceneTransitionPair.value.previousValue.isTransitioning(fromScene, toScene)

                return@filter isTransitioningBetweenLockscreenStates ||
                    isTransitioningBetweenDesiredScenes ||
                    terminalStepBelongsToPreviousTransition
            }
        } else {
            flow