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

Commit bb50d429 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix LsSceneTransitionInteractor's handling of canceled overlay transitions." into main

parents 916213b8 5a9d80ee
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.realKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -39,12 +40,14 @@ import kotlin.test.Test
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableSceneContainer
class LockscreenSceneTransitionInteractorTest : SysuiTestCase() {
    private val kosmos =
        testKosmos().apply { keyguardTransitionRepository = realKeyguardTransitionRepository }
@@ -1397,6 +1400,88 @@ class LockscreenSceneTransitionInteractorTest : SysuiTestCase() {
            )
        }

    /**
     * Transition from Bouncer to Lockscreen which is canceled, returning to Bouncer.
     *
     * We need to ensure that despite technically finishing a transition to Scenes.Lockscreen, we
     * return to UNDEFINED since the Bouncer overlay remained visible.
     */
    @Test
    fun canceledTransitionFromBouncerToLockscreen_returnsToUndefined() =
        testScope.runTest {
            val currentStep by collectLastValue(kosmos.realKeyguardTransitionRepository.transitions)
            sceneTransitions.value = goneToLs
            runCurrent()

            sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
            runCurrent()

            sceneTransitions.value =
                ObservableTransitionState.Transition.ShowOrHideOverlay(
                    overlay = Overlays.Bouncer,
                    fromContent = Scenes.Lockscreen,
                    toContent = Overlays.Bouncer,
                    currentScene = Scenes.Lockscreen,
                    currentOverlays = flowOf(emptySet()),
                    progress,
                    isInitiatedByUserInput = false,
                    isUserInputOngoing = flowOf(false),
                    previewProgress = flowOf(0f),
                    isInPreviewStage = flowOf(false),
                )
            runCurrent()

            // Idle on Lockscreen with Bouncer showing.
            sceneTransitions.value =
                ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
            runCurrent()

            assertTransition(
                step = currentStep!!,
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.UNDEFINED,
                state = TransitionState.FINISHED,
            )

            // Start hiding Bouncer.
            progress.value = 0.4f
            sceneTransitions.value =
                ObservableTransitionState.Transition.ShowOrHideOverlay(
                    overlay = Overlays.Bouncer,
                    fromContent = Overlays.Bouncer,
                    toContent = Scenes.Lockscreen,
                    currentScene = Scenes.Lockscreen,
                    currentOverlays = flowOf(setOf(Overlays.Bouncer)),
                    progress,
                    isInitiatedByUserInput = false,
                    isUserInputOngoing = flowOf(false),
                    previewProgress = flowOf(0f),
                    isInPreviewStage = flowOf(false),
                )
            runCurrent()

            assertTransition(
                step = currentStep!!,
                from = KeyguardState.UNDEFINED,
                to = KeyguardState.LOCKSCREEN,
                state = TransitionState.RUNNING,
                progress = 0.4f,
            )

            // Go back to Bouncer.
            sceneTransitions.value =
                ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
            runCurrent()

            assertTransition(
                step = currentStep!!,
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.UNDEFINED,
                state = TransitionState.FINISHED,
                progress = 1f,
            )
        }

    private fun assertTransition(
        step: TransitionStep,
        from: KeyguardState? = null,
+10 −1
Original line number Diff line number Diff line
@@ -111,8 +111,17 @@ constructor(
        if (currentTransitionId == null) return
        if (prevTransition !is ObservableTransitionState.Transition) return

        // If the previous transition's fromContent is still in currentOverlays, we canceled a
        // transition away from that overlay.
        val canceledOverlayTransition = idle.currentOverlays.contains(prevTransition.fromContent)

        val idleOnToContentAfterCompletedTransition =
            idle.currentScene == prevTransition.toContent && !canceledOverlayTransition

        // Finish the current transition if we've completed a scene transition to a new scene or a
        // new overlay.
        if (
            idle.currentScene == prevTransition.toContent ||
            idleOnToContentAfterCompletedTransition ||
                idle.currentOverlays.contains(prevTransition.toContent)
        ) {
            finishCurrentTransition()