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

Commit 0356921e authored by Will Leshner's avatar Will Leshner Committed by Android (Google) Code Review
Browse files

Merge "Transition to hub from screen off when applicable." into main

parents d5417c34 94d43c05
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -451,6 +451,24 @@ class CommunalSceneStartableTest : SysuiTestCase() {
            }
        }

    @Test
    fun transitionFromDozingToGlanceableHub_forcesCommunal() =
        with(kosmos) {
            testScope.runTest {
                val scene by collectLastValue(communalSceneInteractor.currentScene)
                communalSceneInteractor.changeScene(CommunalScenes.Blank)
                assertThat(scene).isEqualTo(CommunalScenes.Blank)

                fakeKeyguardTransitionRepository.sendTransitionSteps(
                    from = KeyguardState.DOZING,
                    to = KeyguardState.GLANCEABLE_HUB,
                    testScope = this
                )

                assertThat(scene).isEqualTo(CommunalScenes.Communal)
            }
        }

    private fun TestScope.updateDocked(docked: Boolean) =
        with(kosmos) {
            runCurrent()
+64 −0
Original line number Diff line number Diff line
@@ -34,12 +34,14 @@ package com.android.systemui.keyguard.domain.interactor

import android.os.PowerManager
import android.platform.test.annotations.EnableFlags
import android.service.dream.dreamManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -64,8 +66,10 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
import org.mockito.kotlin.whenever

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -118,6 +122,66 @@ class FromDozingTransitionInteractorTest : SysuiTestCase() {
                )
        }

    @Test
    @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testTransitionToLockscreen_onWakeup_canDream_glanceableHubAvailable() =
        testScope.runTest {
            whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
            kosmos.setCommunalAvailable(true)
            runCurrent()

            powerInteractor.setAwakeForTest()
            runCurrent()

            // If dreaming is possible and communal is available, then we should transition to
            // GLANCEABLE_HUB when waking up.
            assertThat(transitionRepository)
                .startedTransition(
                    from = KeyguardState.DOZING,
                    to = KeyguardState.GLANCEABLE_HUB,
                )
        }

    @Test
    @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testTransitionToLockscreen_onWakeup_canNotDream_glanceableHubAvailable() =
        testScope.runTest {
            whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(false)
            kosmos.setCommunalAvailable(true)
            runCurrent()

            powerInteractor.setAwakeForTest()
            runCurrent()

            // If dreaming is NOT possible but communal is available, then we should transition to
            // LOCKSCREEN when waking up.
            assertThat(transitionRepository)
                .startedTransition(
                    from = KeyguardState.DOZING,
                    to = KeyguardState.LOCKSCREEN,
                )
        }

    @Test
    @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testTransitionToLockscreen_onWakeup_canNDream_glanceableHubNotAvailable() =
        testScope.runTest {
            whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
            kosmos.setCommunalAvailable(false)
            runCurrent()

            powerInteractor.setAwakeForTest()
            runCurrent()

            // If dreaming is possible but communal is NOT available, then we should transition to
            // LOCKSCREEN when waking up.
            assertThat(transitionRepository)
                .startedTransition(
                    from = KeyguardState.DOZING,
                    to = KeyguardState.LOCKSCREEN,
                )
        }

    @Test
    @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testTransitionToGlanceableHub_onWakeup_ifIdleOnCommunal_noOccludingActivity() =
+13 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.communal

import android.provider.Settings
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.CoreStartable
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -91,8 +92,8 @@ constructor(
        keyguardTransitionInteractor.startedKeyguardTransitionStep
            .mapLatest(::determineSceneAfterTransition)
            .filterNotNull()
            .onEach { nextScene ->
                communalSceneInteractor.changeScene(nextScene, CommunalTransitionKeys.SimpleFade)
            .onEach { (nextScene, nextTransition) ->
                communalSceneInteractor.changeScene(nextScene, nextTransition)
            }
            .launchIn(applicationScope)

@@ -188,7 +189,7 @@ constructor(

    private suspend fun determineSceneAfterTransition(
        lastStartedTransition: TransitionStep,
    ): SceneKey? {
    ): Pair<SceneKey, TransitionKey>? {
        val to = lastStartedTransition.to
        val from = lastStartedTransition.from
        val docked = dockManager.isDocked
@@ -201,22 +202,27 @@ constructor(
                // underneath the hub is shown. When launching activities over lockscreen, we only
                // change scenes once the activity launch animation is finished, so avoid
                // changing the scene here.
                CommunalScenes.Blank
                Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
            }
            to == KeyguardState.GLANCEABLE_HUB && from == KeyguardState.OCCLUDED -> {
                // When transitioning to the hub from an occluded state, fade out the hub without
                // doing any translation.
                CommunalScenes.Communal
                Pair(CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade)
            }
            // Transitioning to Blank scene when entering the edit mode will be handled separately
            // with custom animations.
            to == KeyguardState.GONE && !communalInteractor.editModeOpen.value ->
                CommunalScenes.Blank
                Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
            !docked && !KeyguardState.deviceIsAwakeInState(to) -> {
                // If the user taps the screen and wakes the device within this timeout, we don't
                // want to dismiss the hub
                delay(AWAKE_DEBOUNCE_DELAY)
                CommunalScenes.Blank
                Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
            }
            from == KeyguardState.DOZING && to == KeyguardState.GLANCEABLE_HUB -> {
                // Make sure the communal hub is showing (immediately, not fading in) when
                // transitioning from dozing to hub.
                Pair(CommunalScenes.Communal, CommunalTransitionKeys.Immediately)
            }
            else -> null
        }
+18 −2
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.systemui.keyguard.domain.interactor

import android.animation.ValueAnimator
import android.app.DreamManager
import com.android.app.animation.Interpolators
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -51,8 +53,10 @@ constructor(
    keyguardInteractor: KeyguardInteractor,
    powerInteractor: PowerInteractor,
    private val communalInteractor: CommunalInteractor,
    private val communalSceneInteractor: CommunalSceneInteractor,
    keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
    val deviceEntryRepository: DeviceEntryRepository,
    private val dreamManager: DreamManager,
) :
    TransitionInteractor(
        fromState = KeyguardState.DOZING,
@@ -119,7 +123,8 @@ constructor(
                .filterRelevantKeyguardStateAnd { isAwake -> isAwake }
                .sample(
                    keyguardInteractor.isKeyguardOccluded,
                    communalInteractor.isIdleOnCommunal,
                    communalInteractor.isCommunalAvailable,
                    communalSceneInteractor.isIdleOnCommunal,
                    canTransitionToGoneOnWake,
                    keyguardInteractor.primaryBouncerShowing,
                )
@@ -127,6 +132,7 @@ constructor(
                    (
                        _,
                        occluded,
                        isCommunalAvailable,
                        isIdleOnCommunal,
                        canTransitionToGoneOnWake,
                        primaryBouncerShowing) ->
@@ -141,6 +147,10 @@ constructor(
                            KeyguardState.OCCLUDED
                        } else if (isIdleOnCommunal) {
                            KeyguardState.GLANCEABLE_HUB
                        } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) {
                            // This case handles tapping the power button to transition through
                            // dream -> off -> hub.
                            KeyguardState.GLANCEABLE_HUB
                        } else {
                            KeyguardState.LOCKSCREEN
                        }
@@ -159,7 +169,8 @@ constructor(
            powerInteractor.detailedWakefulness
                .filterRelevantKeyguardStateAnd { it.isAwake() }
                .sample(
                    communalInteractor.isIdleOnCommunal,
                    communalInteractor.isCommunalAvailable,
                    communalSceneInteractor.isIdleOnCommunal,
                    keyguardInteractor.biometricUnlockState,
                    canTransitionToGoneOnWake,
                    keyguardInteractor.primaryBouncerShowing,
@@ -167,6 +178,7 @@ constructor(
                .collect {
                    (
                        _,
                        isCommunalAvailable,
                        isIdleOnCommunal,
                        biometricUnlockState,
                        canDismissLockscreen,
@@ -188,6 +200,10 @@ constructor(
                                KeyguardState.PRIMARY_BOUNCER
                            } else if (isIdleOnCommunal) {
                                KeyguardState.GLANCEABLE_HUB
                            } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) {
                                // This case handles tapping the power button to transition through
                                // dream -> off -> hub.
                                KeyguardState.GLANCEABLE_HUB
                            } else {
                                KeyguardState.LOCKSCREEN
                            },
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.systemui

import android.app.ActivityManager
import android.app.DreamManager
import android.app.admin.DevicePolicyManager
import android.app.trust.TrustManager
import android.os.UserManager
@@ -32,6 +33,7 @@ import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.biometrics.AuthController
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.ScreenLifecycle
@@ -93,6 +95,7 @@ data class TestMocksModule(
    @get:Provides val demoModeController: DemoModeController = mock(),
    @get:Provides val deviceProvisionedController: DeviceProvisionedController = mock(),
    @get:Provides val dozeParameters: DozeParameters = mock(),
    @get:Provides val dreamManager: DreamManager = mock(),
    @get:Provides val dumpManager: DumpManager = mock(),
    @get:Provides val headsUpManager: HeadsUpManager = mock(),
    @get:Provides val guestResumeSessionReceiver: GuestResumeSessionReceiver = mock(),
@@ -130,6 +133,7 @@ data class TestMocksModule(
    @get:Provides val systemUIDialogManager: SystemUIDialogManager = mock(),
    @get:Provides val deviceEntryIconTransitions: Set<DeviceEntryIconTransition> = emptySet(),
    @get:Provides val communalInteractor: CommunalInteractor = mock(),
    @get:Provides val communalSceneInteractor: CommunalSceneInteractor = mock(),
    @get:Provides val sceneLogger: SceneLogger = mock(),
    @get:Provides val trustManager: TrustManager = mock(),
    @get:Provides val primaryBouncerInteractor: PrimaryBouncerInteractor = mock(),
Loading