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

Commit 882518a8 authored by William Xiao's avatar William Xiao
Browse files

Add transitions between glanceable hub and gone state

Further adjustments may be needed so the behavior of glanceable hub
when exiting keyguard, such as closing when unlocking normally, but
staying open when entering edit mode. This change just ensures
KeyguardState remains accurate regardless of the scenario.

Bug: 319721010
Flag: ACONFIG com.android.systemui.communal_hub DEVELOPMENT
Test: atest KeyguardTransitionScenariosTest
Change-Id: I3c80f2a9a173c5e363673d7f836ec864d4c96bf8
parent c121002a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ constructor(
        listenForHubToDozing()
        listenForHubToPrimaryBouncer()
        listenForHubToAlternateBouncer()
        listenForHubToGone()
    }

    override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
@@ -129,6 +130,18 @@ constructor(
        }
    }

    private fun listenForHubToGone() {
        scope.launch {
            keyguardInteractor.isKeyguardGoingAway
                .sample(startedKeyguardTransitionStep, ::Pair)
                .collect { (isKeyguardGoingAway, lastStartedStep) ->
                    if (isKeyguardGoingAway && lastStartedStep.to == fromState) {
                        startTransitionTo(KeyguardState.GONE)
                    }
                }
        }
    }

    companion object {
        const val TAG = "FromGlanceableHubTransitionInteractor"
        val DEFAULT_DURATION = 400.milliseconds
+17 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor

import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -25,6 +26,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.Utils.Companion.toTriple
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
@@ -45,6 +47,7 @@ constructor(
    @Main mainDispatcher: CoroutineDispatcher,
    private val keyguardInteractor: KeyguardInteractor,
    private val powerInteractor: PowerInteractor,
    private val communalInteractor: CommunalInteractor,
) :
    TransitionInteractor(
        fromState = KeyguardState.GONE,
@@ -56,18 +59,27 @@ constructor(
    override fun start() {
        listenForGoneToAodOrDozing()
        listenForGoneToDreaming()
        listenForGoneToLockscreen()
        listenForGoneToLockscreenOrHub()
        listenForGoneToDreamingLockscreenHosted()
    }

    // Primarily for when the user chooses to lock down the device
    private fun listenForGoneToLockscreen() {
    private fun listenForGoneToLockscreenOrHub() {
        scope.launch {
            keyguardInteractor.isKeyguardShowing
                .sample(startedKeyguardTransitionStep, ::Pair)
                .collect { (isKeyguardShowing, lastStartedStep) ->
                .sample(
                    startedKeyguardTransitionStep,
                    communalInteractor.isIdleOnCommunal,
                )
                .collect { (isKeyguardShowing, lastStartedStep, isIdleOnCommunal) ->
                    if (isKeyguardShowing && lastStartedStep.to == KeyguardState.GONE) {
                        startTransitionTo(KeyguardState.LOCKSCREEN)
                        val to =
                            if (isIdleOnCommunal) {
                                KeyguardState.GLANCEABLE_HUB
                            } else {
                                KeyguardState.LOCKSCREEN
                            }
                        startTransitionTo(to)
                    }
                }
        }
+56 −0
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
                    transitionRepository = transitionRepository,
                    transitionInteractor = transitionInteractor,
                    powerInteractor = powerInteractor,
                    communalInteractor = communalInteractor,
                )
                .apply { start() }

@@ -905,6 +906,37 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            coroutineContext.cancelChildren()
        }

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

            // GIVEN the device is idle on the glanceable hub
            val idleTransitionState =
                MutableStateFlow<ObservableCommunalTransitionState>(
                    ObservableCommunalTransitionState.Idle(CommunalSceneKey.Communal)
                )
            communalInteractor.setTransitionState(idleTransitionState)
            runCurrent()

            // WHEN the keyguard starts to show
            keyguardRepository.setKeyguardShowing(true)
            runCurrent()

            val info =
                withArgCaptor<TransitionInfo> {
                    verify(transitionRepository).startTransition(capture())
                }
            // THEN a transition to DOZING should occur
            assertThat(info.ownerName).isEqualTo(FromGoneTransitionInteractor::class.simpleName)
            assertThat(info.from).isEqualTo(KeyguardState.GONE)
            assertThat(info.to).isEqualTo(KeyguardState.GLANCEABLE_HUB)
            assertThat(info.animator).isNotNull()

            coroutineContext.cancelChildren()
        }

    @Test
    fun alternateBouncerToPrimaryBouncer() =
        testScope.runTest {
@@ -1764,6 +1796,30 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
            coroutineContext.cancelChildren()
        }

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

            // WHEN keyguard goes away
            keyguardRepository.setKeyguardGoingAway(true)
            runCurrent()

            val info =
                withArgCaptor<TransitionInfo> {
                    verify(transitionRepository).startTransition(capture())
                }
            // THEN a transition to DOZING should occur
            assertThat(info.ownerName)
                .isEqualTo(FromGlanceableHubTransitionInteractor::class.simpleName)
            assertThat(info.from).isEqualTo(KeyguardState.GLANCEABLE_HUB)
            assertThat(info.to).isEqualTo(KeyguardState.GONE)
            assertThat(info.animator).isNotNull()

            coroutineContext.cancelChildren()
        }

    private fun createKeyguardInteractor(): KeyguardInteractor {
        return KeyguardInteractorFactory.create(
                featureFlags = featureFlags,