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

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

Merge "Fix alarms launching while on the hub" into main

parents 83aa0229 b32df115
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.flow.MutableStateFlow
@@ -2135,6 +2136,14 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
    @EnableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
    fun glanceableHubToOccluded_communalKtfRefactor() =
        testScope.runTest {
            // GIVEN device is not dreaming
            powerInteractor.setAwakeForTest()
            keyguardRepository.setDreaming(false)
            keyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
            )
            advanceTimeBy(600.milliseconds)

            // GIVEN a prior transition has run to GLANCEABLE_HUB
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")
            runCurrent()
@@ -2298,6 +2307,54 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
            coroutineContext.cancelChildren()
        }

    @Test
    @BrokenWithSceneContainer(339465026)
    @EnableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
    fun glanceableHubToOccludedDoesNotTriggerWhenDreamStateChanges_communalKtfRefactor() =
        testScope.runTest {
            // GIVEN that we are dreaming and not dozing
            powerInteractor.setAwakeForTest()
            keyguardRepository.setDreaming(true)
            keyguardRepository.setKeyguardOccluded(true)
            keyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
            )
            advanceTimeBy(700.milliseconds)
            clearInvocations(transitionRepository)

            // GIVEN a prior transition has run to GLANCEABLE_HUB
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")
            runCurrent()
            assertThat(transitionRepository)
                .startedTransition(
                    ownerName = CommunalSceneTransitionInteractor::class.simpleName,
                    from = KeyguardState.DREAMING,
                    to = KeyguardState.GLANCEABLE_HUB,
                )
            clearInvocations(transitionRepository)

            // WHEN dream ends but we are still occluded
            keyguardRepository.setDreaming(false)
            runCurrent()
            assertThat(transitionRepository).noTransitionsStarted()

            // Simulate occlusion signal changing due to dream terminating and then occluding again
            // due to a new activity starting a couple milliseconds later.
            keyguardRepository.setKeyguardOccluded(false)
            advanceTimeBy(10.milliseconds)
            keyguardRepository.setKeyguardOccluded(true)
            advanceTimeBy(200.milliseconds)

            assertThat(transitionRepository)
                .startedTransition(
                    ownerName = CommunalSceneTransitionInteractor::class.simpleName,
                    from = KeyguardState.GLANCEABLE_HUB,
                    to = KeyguardState.OCCLUDED,
                )

            coroutineContext.cancelChildren()
        }

    private suspend fun TestScope.runTransitionAndSetWakefulness(
        from: KeyguardState,
        to: KeyguardState
+23 −11
Original line number Diff line number Diff line
@@ -37,16 +37,21 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.noneOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@OptIn(FlowPreview::class)
@SysUISingleton
class FromGlanceableHubTransitionInteractor
@Inject
@@ -196,19 +201,26 @@ constructor(
            }
        } else if (communalSceneKtfRefactor()) {
            scope.launch {
                allOf(
                combine(
                        keyguardInteractor.isKeyguardOccluded,
                        noneOf(
                            // Dream is a special-case of occluded, so filter out the dreaming
                            // case here.
                            keyguardInteractor.isDreaming,
                        keyguardInteractor.isAbleToDream
                            // Debounce the dreaming signal since there is a race condition between
                            // the occluded and dreaming signals. We therefore add a small delay
                            // to give enough time for occluded to flip to false when the dream
                            // ends, to avoid transitioning to OCCLUDED erroneously when exiting
                            // the dream.
                            .debounce(100.milliseconds),
                        ::Pair
                    )
                    .sampleFilter(
                        // When launching activities from widgets on the hub, we have a
                        // custom occlusion animation.
                        communalSceneInteractor.isLaunchingWidget,
                        ),
                    )
                    .filterRelevantKeyguardStateAnd { isOccludedAndNotDreamingNorLaunchingWidget ->
                        isOccludedAndNotDreamingNorLaunchingWidget
                    ) { launchingWidget ->
                        !launchingWidget
                    }
                    .filterRelevantKeyguardStateAnd { (isOccluded, isDreaming) ->
                        isOccluded && !isDreaming
                    }
                    .collect { _ ->
                        communalSceneInteractor.changeScene(