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

Commit 392a02e2 authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Add DREAMING -> GONE when dismissible; fix WmLsVis issue with that case and others.

You can wake directly from DREAMING -> GONE if the lockscreen is dismissible, but this behavior is currently broken with the flag enabled.

Also, WmLsVisManager was telling ATMS to show the lockscreen whenever the surface behind is made invisible, but this does not take into account the lockscreen being disabled or otherwise suppressed (such as DREAMING -> GONE while dismissible).

Bug: 278086361
Test: atest android.server.wm.activity.ActivityVisibilityTests
Flag: com.android.systemui.keyguard_wm_state_refactor
Change-Id: I7d73437376f5e147db27ea8f54263151cd633d24
parent 12d762b6
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() {
            repository.setKeyguardEnabled(true)
            runCurrent()

            assertEquals(listOf(false, true, false), canWake)
            assertEquals(listOf(false, true), canWake)
        }

    @Test
@@ -374,6 +374,8 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() {
                    // Should be canceled by the wakeup, but there would still be an
                    // alarm in flight that should be canceled.
                    false,
                    // True once we're actually GONE.
                    true,
                ),
                canWake,
            )
+6 −0
Original line number Diff line number Diff line
@@ -206,6 +206,9 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
    @Test
    @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
    fun setSurfaceBehindVisibility_falseSetsLockscreenVisibility_without_keyguard_shell_transitions() {
        // Show the surface behind, then hide it.
        underTest.setLockscreenShown(true)
        underTest.setSurfaceBehindVisibility(true)
        underTest.setSurfaceBehindVisibility(false)
        verify(activityTaskManagerService).setLockScreenShown(eq(true), any())
    }
@@ -213,6 +216,9 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
    fun setSurfaceBehindVisibility_falseSetsLockscreenVisibility_with_keyguard_shell_transitions() {
        // Show the surface behind, then hide it.
        underTest.setLockscreenShown(true)
        underTest.setSurfaceBehindVisibility(true)
        underTest.setSurfaceBehindVisibility(false)
        verify(keyguardTransitions).startKeyguardTransition(eq(true), any())
    }
+16 −2
Original line number Diff line number Diff line
@@ -131,8 +131,18 @@ constructor(
            Log.d(TAG, "ActivityTaskManagerService#keyguardGoingAway()")
            activityTaskManagerService.keyguardGoingAway(0)
            isKeyguardGoingAway = true
        } else {
            // Hide the surface by setting the lockscreen showing.
        } else if (isLockscreenShowing == true) {
            // Re-show the lockscreen if the surface was visible and we want to make it invisible,
            // and the lockscreen is currently showing (this is the usual case of the going away
            // animation). Re-showing the lockscreen will cancel the going away animation. If we
            // want to hide the surface, but the lockscreen is not currently showing, do nothing and
            // wait for lockscreenVisibility to emit if it's appropriate to show the lockscreen (it
            // might be disabled/suppressed).
            Log.d(
                TAG,
                "setLockscreenShown(true) because we're setting the surface invisible " +
                    "and lockscreen is already showing.",
            )
            setLockscreenShown(true)
        }
    }
@@ -153,6 +163,10 @@ constructor(
        nonApps: Array<RemoteAnimationTarget>,
        finishedCallback: IRemoteAnimationFinishedCallback,
    ) {
        // Make sure this is true - we set it true when requesting keyguardGoingAway, but there are
        // cases where WM starts this transition on its own.
        isKeyguardGoingAway = true

        // Ensure that we've started a dismiss keyguard transition. WindowManager can start the
        // going away animation on its own, if an activity launches and then requests dismissing the
        // keyguard. In this case, this is the first and only signal we'll receive to start
+14 −3
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ constructor(
    private val selectedUserInteractor: SelectedUserInteractor,
    keyguardEnabledInteractor: KeyguardEnabledInteractor,
    keyguardServiceLockNowInteractor: KeyguardServiceLockNowInteractor,
    keyguardInteractor: KeyguardInteractor,
) {

    /**
@@ -106,13 +107,18 @@ constructor(
            .onStart { emit(false) }

    /**
     * Whether we can wake from AOD/DOZING directly to GONE, bypassing LOCKSCREEN/BOUNCER states.
     * Whether we can wake from AOD/DOZING or DREAMING directly to GONE, bypassing
     * LOCKSCREEN/BOUNCER states.
     *
     * This is possible in the following cases:
     * - Keyguard is disabled, either from an app request or from security being set to "None".
     * - Keyguard is suppressed, via adb locksettings.
     * - We're wake and unlocking (fingerprint auth occurred while asleep).
     * - We're allowed to ignore auth and return to GONE, due to timeouts not elapsing.
     * - We're DREAMING and dismissible.
     * - We're already GONE. Technically you're already awake when GONE, but this makes it easier to
     *   reason about this state (for example, if canWakeDirectlyToGone, don't tell WM to pause the
     *   top activity - something you should never do while GONE as well).
     */
    val canWakeDirectlyToGone =
        combine(
@@ -120,14 +126,19 @@ constructor(
                shouldSuppressKeyguard,
                repository.biometricUnlockState,
                repository.canIgnoreAuthAndReturnToGone,
                transitionInteractor.currentKeyguardState,
            ) {
                keyguardEnabled,
                shouldSuppressKeyguard,
                biometricUnlockState,
                canIgnoreAuthAndReturnToGone ->
                canIgnoreAuthAndReturnToGone,
                currentState ->
                (!keyguardEnabled || shouldSuppressKeyguard) ||
                    BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode) ||
                    canIgnoreAuthAndReturnToGone
                    canIgnoreAuthAndReturnToGone ||
                    (currentState == KeyguardState.DREAMING &&
                        keyguardInteractor.isKeyguardDismissible.value) ||
                    currentState == KeyguardState.GONE
            }
            .distinctUntilChanged()

+10 −4
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
import com.android.systemui.util.kotlin.Utils.Companion.toTriple
import com.android.systemui.util.kotlin.Utils.Companion.toQuad
import com.android.systemui.util.kotlin.sample
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import dagger.Lazy
@@ -240,10 +240,11 @@ constructor(
        combine(
                transitionInteractor.currentKeyguardState,
                wakeToGoneInteractor.canWakeDirectlyToGone,
                ::Pair,
                surfaceBehindVisibility,
                ::Triple,
            )
            .sample(transitionInteractor.startedStepWithPrecedingStep, ::toTriple)
            .map { (currentState, canWakeDirectlyToGone, startedWithPrev) ->
            .sample(transitionInteractor.startedStepWithPrecedingStep, ::toQuad)
            .map { (currentState, canWakeDirectlyToGone, surfaceBehindVis, startedWithPrev) ->
                val startedFromStep = startedWithPrev.previousValue
                val startedStep = startedWithPrev.newValue
                val returningToGoneAfterCancellation =
@@ -296,6 +297,11 @@ constructor(
                    // we should simply tell WM that the lockscreen is no longer visible, and
                    // *not* play the going away animation or related animations.
                    false
                } else if (!surfaceBehindVis) {
                    // If the surface behind is not visible, then the lockscreen has to be visible
                    // since there's nothing to show. The surface behind will never be invisible if
                    // the lockscreen is disabled or suppressed.
                    true
                } else {
                    currentState != KeyguardState.GONE
                }
Loading