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

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

Merge "Never ignore OCCLUDED transition" into main

parents c4e7697f 9e843a54
Loading
Loading
Loading
Loading
+4 −21
Original line number Diff line number Diff line
@@ -29,9 +29,7 @@ import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch

@SysUISingleton
@@ -64,29 +62,14 @@ constructor(

    private fun listenForDreamingToOccluded() {
        scope.launch {
            keyguardInteractor.isDreaming
                // Add a slight delay, as dreaming and occluded events will arrive with a small gap
                // in time. This prevents a transition to OCCLUSION happening prematurely.
                .onEach { delay(50) }
                .sample(
                    combine(
                        keyguardInteractor.isKeyguardOccluded,
                        transitionInteractor.startedKeyguardTransitionStep,
                        ::Pair,
                    ),
                    ::toTriple
                )
                .collect { (isDreaming, isOccluded, lastStartedTransition) ->
            combine(keyguardInteractor.isKeyguardOccluded, keyguardInteractor.isDreaming, ::Pair)
                .sample(transitionInteractor.startedKeyguardTransitionStep, ::toTriple)
                .collect { (isOccluded, isDreaming, lastStartedTransition) ->
                    if (
                        isOccluded &&
                            !isDreaming &&
                            (lastStartedTransition.to == KeyguardState.DREAMING ||
                                lastStartedTransition.to == KeyguardState.LOCKSCREEN)
                            lastStartedTransition.to == KeyguardState.DREAMING
                    ) {
                        // At the moment, checking for LOCKSCREEN state above provides a corrective
                        // action. There's no great signal to determine when the dream is ending
                        // and a transition to OCCLUDED is beginning directly. For now, the solution
                        // is DREAMING->LOCKSCREEN->OCCLUDED
                        startTransitionTo(KeyguardState.OCCLUDED)
                    }
                }
+3 −10
Original line number Diff line number Diff line
@@ -318,16 +318,9 @@ constructor(
    private fun listenForLockscreenToOccluded() {
        scope.launch {
            keyguardInteractor.isKeyguardOccluded
                .sample(
                    combine(
                        transitionInteractor.startedKeyguardState,
                        keyguardInteractor.isDreaming,
                        ::Pair
                    ),
                    ::toTriple
                )
                .collect { (isOccluded, keyguardState, isDreaming) ->
                    if (isOccluded && !isDreaming && keyguardState == KeyguardState.LOCKSCREEN) {
                .sample(transitionInteractor.startedKeyguardState, ::Pair)
                .collect { (isOccluded, keyguardState) ->
                    if (isOccluded && keyguardState == KeyguardState.LOCKSCREEN) {
                        startTransitionTo(KeyguardState.OCCLUDED)
                    }
                }
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.util.kotlin
class Utils {
    companion object {
        fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second)
        fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c)

        fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d)
        fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) =
+83 −12
Original line number Diff line number Diff line
@@ -433,7 +433,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {

            // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED
            runTransitionAndSetWakefulness(
                    KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
                KeyguardState.GONE,
                KeyguardState.DREAMING_LOCKSCREEN_HOSTED
            )

            // WHEN the lockscreen hosted dream stops
            keyguardRepository.setIsActiveDreamLockscreenHosted(false)
@@ -457,7 +459,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
        testScope.runTest {
            // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED
            runTransitionAndSetWakefulness(
                    KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
                KeyguardState.GONE,
                KeyguardState.DREAMING_LOCKSCREEN_HOSTED
            )

            // WHEN biometrics succeeds with wake and unlock from dream mode
            keyguardRepository.setBiometricUnlockState(
@@ -487,7 +491,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {

            // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED
            runTransitionAndSetWakefulness(
                    KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
                KeyguardState.GONE,
                KeyguardState.DREAMING_LOCKSCREEN_HOSTED
            )

            // WHEN the primary bouncer is set to show
            bouncerRepository.setPrimaryShow(true)
@@ -515,7 +521,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {

            // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED
            runTransitionAndSetWakefulness(
                    KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
                KeyguardState.GONE,
                KeyguardState.DREAMING_LOCKSCREEN_HOSTED
            )

            // WHEN the device begins to sleep
            keyguardRepository.setIsActiveDreamLockscreenHosted(false)
@@ -547,7 +555,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {

            // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED
            runTransitionAndSetWakefulness(
                    KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
                KeyguardState.GONE,
                KeyguardState.DREAMING_LOCKSCREEN_HOSTED
            )

            // WHEN the keyguard is occluded and the lockscreen hosted dream stops
            keyguardRepository.setIsActiveDreamLockscreenHosted(false)
@@ -783,7 +793,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
        testScope.runTest {
            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
            runTransitionAndSetWakefulness(
                    KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER)
                KeyguardState.LOCKSCREEN,
                KeyguardState.ALTERNATE_BOUNCER
            )

            // WHEN the alternateBouncer stops showing and then the primary bouncer shows
            bouncerRepository.setPrimaryShow(true)
@@ -808,7 +820,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
            bouncerRepository.setAlternateVisible(true)
            runTransitionAndSetWakefulness(
                    KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER)
                KeyguardState.LOCKSCREEN,
                KeyguardState.ALTERNATE_BOUNCER
            )

            // GIVEN the primary bouncer isn't showing, aod available and starting to sleep
            bouncerRepository.setPrimaryShow(false)
@@ -838,7 +852,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
            bouncerRepository.setAlternateVisible(true)
            runTransitionAndSetWakefulness(
                    KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER)
                KeyguardState.LOCKSCREEN,
                KeyguardState.ALTERNATE_BOUNCER
            )

            // GIVEN the primary bouncer isn't showing, aod not available and starting to sleep
            // to sleep
@@ -869,7 +885,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
            bouncerRepository.setAlternateVisible(true)
            runTransitionAndSetWakefulness(
                    KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER)
                KeyguardState.LOCKSCREEN,
                KeyguardState.ALTERNATE_BOUNCER
            )

            // GIVEN the primary bouncer isn't showing and device not sleeping
            bouncerRepository.setPrimaryShow(false)
@@ -980,7 +998,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            // GIVEN a prior transition has run to PRIMARY_BOUNCER
            bouncerRepository.setPrimaryShow(true)
            runTransitionAndSetWakefulness(
                    KeyguardState.DREAMING_LOCKSCREEN_HOSTED, KeyguardState.PRIMARY_BOUNCER)
                KeyguardState.DREAMING_LOCKSCREEN_HOSTED,
                KeyguardState.PRIMARY_BOUNCER
            )

            // WHEN the primary bouncer stops showing and lockscreen hosted dream still active
            bouncerRepository.setPrimaryShow(false)
@@ -1160,6 +1180,57 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            coroutineContext.cancelChildren()
        }

    @Test
    fun dreamingToOccluded() =
        testScope.runTest {
            // GIVEN a prior transition has run to DREAMING
            keyguardRepository.setDreaming(true)
            runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.DREAMING)
            runCurrent()

            // WHEN the keyguard is occluded and device wakes up and is no longer dreaming
            keyguardRepository.setDreaming(false)
            keyguardRepository.setKeyguardOccluded(true)
            powerInteractor.setAwakeForTest()
            runCurrent()

            val info =
                withArgCaptor<TransitionInfo> {
                    verify(transitionRepository).startTransition(capture(), anyBoolean())
                }
            // THEN a transition to OCCLUDED should occur
            assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor")
            assertThat(info.from).isEqualTo(KeyguardState.DREAMING)
            assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED)
            assertThat(info.animator).isNotNull()

            coroutineContext.cancelChildren()
        }

    @Test
    fun lockscreenToOccluded() =
        testScope.runTest {
            // GIVEN a prior transition has run to LOCKSCREEN
            runTransitionAndSetWakefulness(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
            runCurrent()

            // WHEN the keyguard is occluded
            keyguardRepository.setKeyguardOccluded(true)
            runCurrent()

            val info =
                withArgCaptor<TransitionInfo> {
                    verify(transitionRepository).startTransition(capture(), anyBoolean())
                }
            // THEN a transition to OCCLUDED should occur
            assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
            assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
            assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED)
            assertThat(info.animator).isNotNull()

            coroutineContext.cancelChildren()
        }

    @Test
    fun aodToOccluded() =
        testScope.runTest {