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

Commit 4d1620f2 authored by Steve Elliott's avatar Steve Elliott
Browse files

[flexiglass] Double-tap power gesture when GONE

Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT
Fixes: 332324876
Test: atest SceneContainerStartableTest
Test: double-tap power while in Gone scene, observe camera launch
Change-Id: Id9dbc4d58d87fc379714a01888a8b7f345a3af5e
parent 6f67bf71
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -73,7 +73,16 @@ sealed interface ObservableTransitionState {
         * the transition completes/settles.
         */
        val isUserInputOngoing: Flow<Boolean>,
    ) : ObservableTransitionState
    ) : ObservableTransitionState {
        override fun toString(): String =
            """Transition
                |(from=$fromScene,
                | to=$toScene,
                | isInitiatedByUserInput=$isInitiatedByUserInput,
                | isUserInputOngoing=$isUserInputOngoing
                |)"""
                .trimMargin()
    }

    fun isIdle(scene: SceneKey?): Boolean {
        return this is Idle && (scene == null || this.currentScene == scene)
+25 −0
Original line number Diff line number Diff line
@@ -125,6 +125,31 @@ class SceneInteractorTest : SysuiTestCase() {
            underTest.changeScene(Scenes.Gone, "reason")
        }

    @Test
    fun changeScene_toGoneWhenTransitionToLockedFromGone() =
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val currentScene by collectLastValue(underTest.currentScene)
            val transitionTo by collectLastValue(underTest.transitioningTo)
            kosmos.sceneContainerRepository.setTransitionState(
                flowOf(
                    ObservableTransitionState.Transition(
                        fromScene = Scenes.Gone,
                        toScene = Scenes.Lockscreen,
                        currentScene = flowOf(Scenes.Lockscreen),
                        progress = flowOf(.5f),
                        isInitiatedByUserInput = true,
                        isUserInputOngoing = flowOf(false),
                    )
                )
            )
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
            assertThat(transitionTo).isEqualTo(Scenes.Lockscreen)

            underTest.changeScene(Scenes.Gone, "simulate double tap power")
            assertThat(currentScene).isEqualTo(Scenes.Gone)
        }

    @Test
    fun snapToScene_toUnknownScene_doesNothing() =
        testScope.runTest {
+38 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.scene.domain.interactor.sceneContainerStartable
import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -382,6 +383,43 @@ class SceneContainerStartableTest : SysuiTestCase() {
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
        }

    @Test
    fun switchToGoneWhenDoubleTapPowerGestureIsTriggeredFromGone() =
        testScope.runTest {
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val transitionStateFlow =
                prepareState(
                    authenticationMethod = AuthenticationMethodModel.Pin,
                    isDeviceUnlocked = true,
                    initialSceneKey = Scenes.Gone,
                )
            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
            underTest.start()

            kosmos.fakePowerRepository.updateWakefulness(
                rawState = WakefulnessState.STARTING_TO_SLEEP,
                lastSleepReason = WakeSleepReason.POWER_BUTTON,
                powerButtonLaunchGestureTriggered = false,
            )
            transitionStateFlow.value =
                ObservableTransitionState.Transition(
                    fromScene = Scenes.Gone,
                    toScene = Scenes.Lockscreen,
                    currentScene = flowOf(Scenes.Lockscreen),
                    progress = flowOf(0.5f),
                    isInitiatedByUserInput = true,
                    isUserInputOngoing = flowOf(false),
                )
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)

            kosmos.fakePowerRepository.updateWakefulness(
                rawState = WakefulnessState.STARTING_TO_WAKE,
                lastSleepReason = WakeSleepReason.POWER_BUTTON,
                powerButtonLaunchGestureTriggered = true,
            )
            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
        }

    @Test
    fun hydrateSystemUiState() =
        testScope.runTest {
+11 −3
Original line number Diff line number Diff line
@@ -315,9 +315,17 @@ constructor(
            return false
        }

        check(to != Scenes.Gone || deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked) {
            "Cannot change to the Gone scene while the device is locked. Logging reason for scene" +
                " change was: $loggingReason"
        val inMidTransitionFromGone =
            (transitionState.value as? ObservableTransitionState.Transition)?.fromScene ==
                Scenes.Gone
        val isChangeAllowed =
            to != Scenes.Gone ||
                inMidTransitionFromGone ||
                deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
        check(isChangeAllowed) {
            "Cannot change to the Gone scene while the device is locked and not currently" +
                " transitioning from Gone. Current transition state is ${transitionState.value}." +
                " Logging reason for scene change was: $loggingReason"
        }

        return from != to
+24 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import com.android.systemui.model.updateFlags
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.FalsingManager.FalsingBeliefListener
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.scene.data.model.asIterable
import com.android.systemui.scene.domain.interactor.SceneBackInteractor
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
@@ -364,6 +365,29 @@ constructor(
    }

    private fun handlePowerState() {
        applicationScope.launch {
            powerInteractor.detailedWakefulness.collect { wakefulness ->
                // Detect a double-tap-power-button gesture that was started while the device was
                // still awake.
                if (wakefulness.isAsleep()) return@collect
                if (!wakefulness.powerButtonLaunchGestureTriggered) return@collect
                if (wakefulness.lastSleepReason != WakeSleepReason.POWER_BUTTON) return@collect

                // If we're mid-transition from Gone to Lockscreen due to the first power button
                // press, then return to Gone.
                val transition: ObservableTransitionState.Transition =
                    sceneInteractor.transitionState.value as? ObservableTransitionState.Transition
                        ?: return@collect
                if (
                    transition.fromScene == Scenes.Gone && transition.toScene == Scenes.Lockscreen
                ) {
                    switchToScene(
                        targetSceneKey = Scenes.Gone,
                        loggingReason = "double-tap power gesture",
                    )
                }
            }
        }
        applicationScope.launch {
            powerInteractor.isAsleep.collect { isAsleep ->
                if (isAsleep) {