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

Commit 1837c2e9 authored by Coco Duan's avatar Coco Duan Committed by Android (Google) Code Review
Browse files

Merge "Fix transition stuck in AOD and keyguard clock visible after unlock" into main

parents e48e44f8 f5748468
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import com.android.systemui.communal.ui.compose.Dimensions.Companion.SlideOffset
import com.android.systemui.communal.ui.compose.extensions.allowGestures
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.keyguard.domain.interactor.FromAodTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.FromGlanceableHubTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -97,6 +98,16 @@ val sceneTransitionsV2 = transitions {
        spec = tween(durationMillis = TransitionDuration.TO_GLANCEABLE_HUB_DURATION_MS)
        timestampRange(startMillis = 250) { fade(AllElements) }
    }
    to(CommunalScenes.Communal, key = CommunalTransitionKeys.FromAod) {
        spec =
            tween(
                durationMillis =
                    FromAodTransitionInteractor.TO_GLANCEABLE_HUB_DURATION.toInt(
                        DurationUnit.MILLISECONDS
                    )
            )
        timestampRange(startMillis = 167) { fade(AllElements) }
    }
    to(CommunalScenes.Communal, key = CommunalTransitionKeys.Swipe) {
        spec = tween(durationMillis = TransitionDuration.TO_GLANCEABLE_HUB_DURATION_MS)
        translate(Communal.Elements.Grid, Edge.End)
+23 −1
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ import com.android.systemui.communal.domain.model.CommunalTransitionProgressMode
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.initialSceneKey
import com.android.systemui.scene.shared.model.Scenes
@@ -109,7 +111,7 @@ class CommunalSceneInteractorTest(flags: FlagsParameterization) : SysuiTestCase(

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun changeScene_doesNotCallSceneStateProcessorForDuplicateState() =
    fun changeScene_doesNotCallSceneStateProcessorForDuplicateState_ifKeyguardStateIsNull() =
        testScope.runTest {
            val callback: OnSceneAboutToChangeListener = mock()
            underTest.registerSceneStateProcessor(callback)
@@ -123,6 +125,26 @@ class CommunalSceneInteractorTest(flags: FlagsParameterization) : SysuiTestCase(
            verify(callback, never()).onSceneAboutToChange(any(), anyOrNull())
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun changeScene_callSceneStateProcessorForDuplicateScene_ifBlankSceneWithKeyguardState() =
        testScope.runTest {
            val callback: OnSceneAboutToChangeListener = mock()
            underTest.registerSceneStateProcessor(callback)

            val currentScene by collectLastValue(underTest.currentScene)
            underTest.changeScene(CommunalScenes.Communal, "test")
            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)

            underTest.changeScene(CommunalScenes.Blank, "test", keyguardState = KeyguardState.AOD)
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
            verify(callback).onSceneAboutToChange(CommunalScenes.Blank, KeyguardState.AOD)

            underTest.changeScene(CommunalScenes.Blank, "test", keyguardState = KeyguardState.GONE)
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
            verify(callback).onSceneAboutToChange(CommunalScenes.Blank, KeyguardState.GONE)
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun snapToScene() =
+480 −36

File changed.

Preview size limit exceeded, changes collapsed.

+18 −1
Original line number Diff line number Diff line
@@ -137,7 +137,14 @@ constructor(
                return@launch
            }

            if (currentScene.value == newScene) return@launch
            if (currentScene.value == newScene) {
                // If the same Blank scene, notify listeners since the next keyguard state might
                // require an update.
                if (newScene == CommunalScenes.Blank && keyguardState != null) {
                    notifyListeners(newScene, keyguardState)
                }
                return@launch
            }
            logger.logSceneChangeRequested(
                from = currentScene.value,
                to = newScene,
@@ -224,6 +231,16 @@ constructor(
                )
        }

    /** Target scene requested has changed from the previous transition. */
    val targetSceneChanged: StateFlow<Boolean> =
        currentScene
            .pairwiseBy(initialValue = repository.currentScene.value) { old, new -> old != new }
            .stateIn(
                scope = applicationScope,
                started = SharingStarted.Eagerly,
                initialValue = false,
            )

    private val _editModeState = MutableStateFlow<EditModeState?>(null)
    /**
     * Current state for glanceable hub edit mode, used to chain the animations when transitioning
+69 −6
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ constructor(
                keyguardInteractor.isKeyguardShowing,
            ) { asleep, dreaming, occluded, keyguardGoingAway, keyguardShowing ->
                if (asleep) {
                    KeyguardState.DOZING
                    keyguardInteractor.asleepKeyguardState.value
                } else if (keyguardGoingAway) {
                    KeyguardState.GONE
                } else if (occluded && !dreaming) {
@@ -163,6 +163,10 @@ constructor(
        prevTransition: ObservableTransitionState,
        idle: ObservableTransitionState.Idle,
    ) {
        val isReversedTransition =
            prevTransition is ObservableTransitionState.Transition &&
                currentTransitionId != null &&
                idle.currentScene == prevTransition.fromContent
        if (
            prevTransition is ObservableTransitionState.Transition &&
                currentTransitionId != null &&
@@ -171,13 +175,18 @@ constructor(
            finishCurrentTransition()
        } else {
            // We may receive an Idle event without a corresponding Transition
            // event, such as when snapping to a scene without an animation.
            // event, such as when snapping to a scene without an animation, or the previous
            // is a reversed scene transition.
            val targetState =
                if (idle.currentScene == CommunalScenes.Communal) {
                    KeyguardState.GLANCEABLE_HUB
                } else if (currentToState == KeyguardState.GLANCEABLE_HUB) {
                    nextKeyguardState.value
                } else {
                    if (isReversedTransition) {
                        // Previous is a reversed transition, finish current ktf transition.
                        finishCurrentTransition()
                    }
                    // Do nothing as we are no longer in the hub state.
                    return
                }
@@ -225,12 +234,46 @@ constructor(
        transition: ObservableTransitionState.Transition,
    ) {
        if (
            prevTransition.isTransitioning(from = transition.fromContent, to = transition.toContent)
            prevTransition.isTransitioning(
                from = transition.fromContent,
                to = transition.toContent,
            ) && !sceneInteractor.targetSceneChanged.value
        ) {
            // This is a new transition, but exactly the same as the previous state. Skip resetting
            // KTF for this case and just collect the new progress instead.
            collectProgress(transition)
        } else if (transition.toContent == CommunalScenes.Communal) {
            return
        }
        if (
            prevTransition.isTransitioning(from = transition.fromContent, to = transition.toContent)
        ) {
            // The transition has the same from and to content as the previous transition, but
            // different target scene, it may be a reversed transition.
            val targetScene = sceneInteractor.currentScene.value
            if (
                targetScene == CommunalScenes.Blank &&
                    transition.fromContent == CommunalScenes.Blank
            ) {
                // Prev transition: Blank->Communal, X->hub running
                // New transition: Blank->Communal (reversed->Blank), we should reverse->X
                startReversedTransitionToState(nextKeyguardState.value)
                collectProgress(transition, isReversed = true)
                return
            }
            if (
                targetScene == CommunalScenes.Communal &&
                    transition.fromContent == CommunalScenes.Communal
            ) {
                // Prev transition: Communal->Blank, hub->X running
                // New transition: Communal->Blank (reversed->Communal), we should reverse->hub
                startReversedTransitionToState(KeyguardState.GLANCEABLE_HUB)
                collectProgress(transition, isReversed = true)
                return
            }
        }
        // The new transition does not have the same content key with the previous, or it has the
        // same content key and toContent is just the target scene
        if (transition.toContent == CommunalScenes.Communal) {
            if (currentToState == KeyguardState.GLANCEABLE_HUB) {
                transitionKtfTo(transitionInteractor.startedKeyguardTransitionStep.value.from)
            }
@@ -257,11 +300,18 @@ constructor(
        }
    }

    private fun collectProgress(transition: ObservableTransitionState.Transition) {
    private fun collectProgress(
        transition: ObservableTransitionState.Transition,
        isReversed: Boolean = false,
    ) {
        progressJob?.cancel()
        progressJob =
            applicationScope.launch("$TAG#collectProgress", mainImmediateDispatcher) {
                transition.progress.collect { updateProgress(it) }
                transition.progress.collect {
                    // during a reversed scene transition, the progress is from 1 to 0
                    val progress = if (isReversed) 1f - it else it
                    updateProgress(progress)
                }
            }
    }

@@ -291,6 +341,19 @@ constructor(
        startTransition(newTransition)
    }

    private suspend fun startReversedTransitionToState(state: KeyguardState) {
        val currentState = internalTransitionInteractor.currentTransitionInfoInternal().to
        val newTransition =
            TransitionInfo(
                ownerName = this::class.java.simpleName,
                from = currentState,
                to = state,
                animator = null,
                modeOnCanceled = TransitionModeOnCanceled.REVERSE,
            )
        startTransition(newTransition)
    }

    private suspend fun startTransition(transitionInfo: TransitionInfo) {
        if (currentTransitionId != null) {
            resetTransitionData()
Loading