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

Commit 84051e9e authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge "Transitions - Consolidate DREAMING->*" into main

parents a0a7b4a6 8534ceaf
Loading
Loading
Loading
Loading
+21 −62
Original line number Diff line number Diff line
@@ -33,20 +33,18 @@ import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy
import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.kosmos.useStandardTestDispatcher
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.pipeline.battery.shared.StatusBarUniversalBatteryDataSource
@@ -58,6 +56,7 @@ import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
@@ -70,13 +69,13 @@ import platform.test.runner.parameterized.Parameters

@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
@DisableFlags(Flags.FLAG_SCENE_CONTAINER, Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiTestCase() {
    companion object {
        @JvmStatic
        @Parameters(name = "{0}")
        fun getParams(): List<FlagsParameterization> {
            return FlagsParameterization.allCombinationsOf(FLAG_GLANCEABLE_HUB_V2)
                .andSceneContainer()
        }
    }

@@ -85,7 +84,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu
    }

    private val kosmos =
        testKosmos().useUnconfinedTestDispatcher().apply {
        testKosmos().useStandardTestDispatcher().apply {
            this.fakeKeyguardTransitionRepository =
                FakeKeyguardTransitionRepository(
                    // This test sends transition steps manually in the test cases.
@@ -103,6 +102,11 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu
    @Before
    fun setup() {
        runBlocking {
            kosmos.fakeKeyguardRepository.setKeyguardOccluded(true)
            kosmos.fakeKeyguardRepository.setDreaming(true)
            // Get past initial setup
            kosmos.testScope.advanceTimeBy(600L)

            kosmos.transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
@@ -120,15 +124,6 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu
    @Ignore("Until b/349837588 is fixed")
    fun testTransitionToOccluded_ifDreamEnds_occludingActivityOnTop() =
        kosmos.runTest {
            fakeKeyguardRepository.setDreaming(true)
            transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
                kosmos.testScope,
            )

            reset(transitionRepository)

            keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true)
            fakeKeyguardRepository.setDreaming(false)

@@ -137,59 +132,31 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu
        }

    @Test
    @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testDoesNotTransitionToOccluded_occludingActivityOnTop_whileStillDreaming() =
    fun testTransitionsToLockscreen_whenOccludingActivityEnds() =
        kosmos.runTest {
            fakeKeyguardRepository.setDreaming(true)
            transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
                testScope,
            )
            reset(transitionRepository)
            keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true)
            fakeKeyguardRepository.setDreaming(false)
            fakeKeyguardRepository.setKeyguardOccluded(false)
            testScope.advanceTimeBy(110L)

            assertThat(transitionRepository).noTransitionsStarted()
            assertThat(transitionRepository)
                .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.LOCKSCREEN)
        }

    @Test
    fun testTransitionsToLockscreen_whenOccludingActivityEnds() =
    fun testTransitionsToOccluded_whenDreamEnds_andStillOccluded() =
        kosmos.runTest {
            fakeKeyguardRepository.setDreaming(true)
            keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(true)
            // Transition to DREAMING and set the power interactor awake
            powerInteractor.setAwakeForTest()

            transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
                testScope,
            )
            fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE)

            // Get past initial setup
            testScope.advanceTimeBy(600L)
            reset(transitionRepository)

            keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = false)
            fakeKeyguardRepository.setDreaming(false)
            testScope.advanceTimeBy(60L)
            testScope.advanceTimeBy(110L)

            assertThat(transitionRepository)
                .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.LOCKSCREEN)
                .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.OCCLUDED)
        }

    @Test
    fun testTransitionToAlternateBouncer() =
        kosmos.runTest {
            transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
                testScope,
            )
            reset(transitionRepository)

            fakeKeyguardBouncerRepository.setAlternateVisible(true)
            testScope.runCurrent()

            assertThat(transitionRepository)
                .startedTransition(
@@ -199,17 +166,9 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu
        }

    @Test
    @DisableFlags(Flags.FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun testTransitionToGlanceableHubOnWake() =
        kosmos.runTest {
            transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.DREAMING,
                testScope,
            )
            reset(transitionRepository)

            setCommunalAvailable(true)
            if (glanceableHubV2()) {
                val user = fakeUserRepository.asMainUser()
                fakeSettings.putIntForUser(
@@ -228,7 +187,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu

            // Device wakes up.
            powerInteractor.setAwakeForTest()
            testScope.advanceTimeBy(150L)
            testScope.advanceTimeBy(60L)

            // We transition to the hub when waking up.
            assertThat(communalSceneRepository.currentScene.value)
+5 −3
Original line number Diff line number Diff line
@@ -454,17 +454,19 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
            runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.DREAMING)
            advanceTimeBy(60L)

            reset(transitionRepository)

            // WHEN the device wakes up without a keyguard
            keyguardRepository.setKeyguardShowing(false)
            keyguardRepository.setKeyguardDismissible(true)
            keyguardRepository.setDreamingWithOverlay(false)
            advanceTimeBy(60L)
            advanceTimeBy(160L)

            assertThat(transitionRepository)
                .startedTransition(
                    to = KeyguardState.GONE,
                    from = KeyguardState.DREAMING,
                    ownerName = "FromDreamingTransitionInteractor",
                    to = KeyguardState.GONE,
                    ownerName = "FromDreamingTransitionInteractor(No longer dreaming; dismissable)",
                    animatorAssertion = { it.isNotNull() },
                )

+21 −67
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
import com.android.systemui.keyguard.shared.model.DozeStateModel
@@ -79,10 +78,8 @@ constructor(
    @SuppressLint("MissingPermission")
    override fun start() {
        listenForDreamingToAlternateBouncer()
        listenForDreamingToOccluded()
        listenForDreamingToGoneWhenDismissable()
        listenForDreamingToOccludedOrGoneOrLockscreen()
        listenForDreamingToGoneFromBiometricUnlock()
        listenForDreamingToLockscreenOrGone()
        listenForDreamingToAodOrDozing()
        listenForTransitionToCamera(scope, keyguardInteractor)
        listenForDreamingToGlanceableHubFromPowerButton()
@@ -171,51 +168,31 @@ constructor(
    }

    @OptIn(FlowPreview::class)
    private fun listenForDreamingToOccluded() {
        if (!KeyguardWmStateRefactor.isEnabled) {
    private fun listenForDreamingToOccludedOrGoneOrLockscreen() {
        if (SceneContainerFlag.isEnabled) return
        scope.launch {
                combine(
                        keyguardInteractor.isKeyguardOccluded,
                        keyguardInteractor.isAbleToDream,
                        ::Pair,
                    )
            combine(keyguardInteractor.isKeyguardOccluded, keyguardInteractor.isAbleToDream, ::Pair)
                // Debounce signals since there is a race condition between the occluded and
                // dreaming signals when starting or stopping dreaming. 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)
                    .filterRelevantKeyguardStateAnd { (isOccluded, isDreaming) ->
                        isOccluded && !isDreaming
                    }
                    .collect {
                        startTransitionTo(
                            toState = KeyguardState.OCCLUDED,
                            ownerReason = "Occluded but no longer dreaming",
                        )
                    }
            }
        }
    }
                .filterRelevantKeyguardStateAnd { (isOccluded, isDreaming) -> !isDreaming }
                .collect { (isOccluded, isDreaming) ->
                    val isDismissible =
                        keyguardInteractor.isKeyguardDismissible.value &&
                            !keyguardInteractor.isKeyguardShowing.value

    private fun listenForDreamingToLockscreenOrGone() {
        scope.launch {
            keyguardInteractor.isAbleToDream
                .filterRelevantKeyguardStateAnd { !it }
                .sample(
                    if (SceneContainerFlag.isEnabled) {
                        deviceEntryInteractor.isUnlocked
                    } else {
                        keyguardInteractor.isKeyguardDismissible
                    },
                    ::Pair,
                )
                .collect { (_, dismissable) ->
                    // TODO(b/349837588): Add check for -> OCCLUDED.
                    if (dismissable) {
                    if (isDismissible) {
                        startTransitionTo(
                            KeyguardState.GONE,
                            ownerReason = "No longer dreaming; dismissable",
                        )
                    } else if (isOccluded) {
                        startTransitionTo(
                            toState = KeyguardState.OCCLUDED,
                            ownerReason = "Occluded but no longer dreaming",
                        )
                    } else {
                        startTransitionTo(
                            KeyguardState.LOCKSCREEN,
@@ -226,29 +203,6 @@ constructor(
        }
    }

    private fun listenForDreamingToGoneWhenDismissable() {
        if (SceneContainerFlag.isEnabled) {
            return
        }

        if (KeyguardWmStateRefactor.isEnabled) {
            return
        }

        scope.launch {
            keyguardInteractor.isAbleToDream
                .filterRelevantKeyguardStateAnd { isDreaming -> !isDreaming }
                .collect {
                    if (
                        keyguardInteractor.isKeyguardDismissible.value &&
                            !keyguardInteractor.isKeyguardShowing.value
                    ) {
                        startTransitionTo(KeyguardState.GONE)
                    }
                }
        }
    }

    private fun listenForDreamingToGoneFromBiometricUnlock() {
        // TODO(b/353542570): Adaptation for scene framework is needed
        if (SceneContainerFlag.isEnabled) return