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

Commit 9bc83d31 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix GONE->AOD->GONE with timeout" into main

parents e1b2a0a9 744ef308
Loading
Loading
Loading
Loading
+17 −21
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.os.PowerManager
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.lockPatternUtils
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -54,16 +53,15 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import junit.framework.Assert.assertEquals
import kotlin.test.Test
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy

@@ -93,6 +91,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
        // Transition to AOD and set the power interactor asleep.
        powerInteractor.setAsleepForTest()
        runBlocking {
            kosmos.fakeKeyguardRepository.setKeyguardShowing(false)
            transitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.AOD,
@@ -108,7 +107,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
    fun testTransitionToLockscreen_onWakeup() =
        testScope.runTest {
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // Under default conditions, we should transition to LOCKSCREEN when waking up.
            assertThat(transitionRepository)
@@ -124,7 +123,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
        testScope.runTest {
            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true)
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED.
            assertThat(transitionRepository)
@@ -140,7 +139,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
        testScope.runTest {
            powerInteractor.onCameraLaunchGestureDetected()
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should head back to GONE since we started there.
            assertThat(transitionRepository)
@@ -154,7 +153,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
            kosmos.fakeKeyguardRepository.setKeyguardDismissible(true)
            powerInteractor.onCameraLaunchGestureDetected()
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should head back to GONE since we started there.
            assertThat(transitionRepository)
@@ -191,7 +190,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
            reset(transitionRepository)
            powerInteractor.onCameraLaunchGestureDetected()
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should head back to GONE since we started there.
            assertThat(transitionRepository)
@@ -225,7 +224,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
            reset(transitionRepository)
            powerInteractor.onCameraLaunchGestureDetected()
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should go to OCCLUDED - we came from GONE, but we finished in AOD, so this is no
            // longer an insecure camera launch and it would be bad if we unlocked now.
@@ -266,7 +265,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
            reset(transitionRepository)
            powerInteractor.onCameraLaunchGestureDetected()
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should head back to GONE since we started there.
            assertThat(transitionRepository)
@@ -286,7 +285,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
            assertThat(transitionRepository).noTransitionsStarted()

            underTest.dismissAod()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            assertThat(transitionRepository)
                .startedTransition(from = KeyguardState.AOD, to = KeyguardState.GONE)
@@ -297,7 +296,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
        testScope.runTest {
            kosmos.fakeKeyguardRepository.setKeyguardOccluded(true)
            powerInteractor.setAwakeForTest()
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // Waking up from AOD while occluded should transition to OCCLUDED.
            assertThat(transitionRepository)
@@ -307,11 +306,10 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
    @Test
    fun testTransitionToGone_onWakeUpFromAod_dismissibleKeyguard_securityNone() =
        testScope.runTest {
            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
            kosmos.fakeKeyguardRepository.setKeyguardShowing(false)
            kosmos.fakeKeyguardRepository.setKeyguardDismissible(true)
            powerInteractor.setAwakeForTest()
            testScope.testScheduler.advanceTimeBy(100) // account for debouncing
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should head back to GONE since we started there.
            assertThat(transitionRepository)
@@ -319,15 +317,13 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
        }

    @Test
    fun testTransitionToGone_onWakeUpFromAod_dismissibleKeyguard_securitySwipe() =
    fun testTransitionToLockscreen_onWakeUpFromAod_dismissibleKeyguard_securitySwipe() =
        testScope.runTest {
            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
            kosmos.fakeKeyguardRepository.setKeyguardShowing(true)
            kosmos.fakeKeyguardRepository.setKeyguardDismissible(true)
            powerInteractor.setAwakeForTest()
            testScope.testScheduler.advanceTimeBy(100) // account for debouncing
            runCurrent()
            advanceTimeBy(100) // account for debouncing

            // We should head back to GONE since we started there.
            assertThat(transitionRepository)
                .startedTransition(from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN)
        }
+21 −42
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launch
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -29,12 +28,13 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion
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.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce

@SysUISingleton
@@ -49,8 +49,6 @@ constructor(
    private val keyguardInteractor: KeyguardInteractor,
    powerInteractor: PowerInteractor,
    keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
    private val lockPatternUtils: LockPatternUtils,
    private val selectedUserInteractor: SelectedUserInteractor,
) :
    TransitionInteractor(
        fromState = KeyguardState.AOD,
@@ -65,10 +63,18 @@ constructor(
        listenForAodToAwake()
        listenForAodToOccluded()
        listenForAodToPrimaryBouncer()
        listenForAodToGone()
        listenForTransitionToCamera(scope, keyguardInteractor)
    }

    private val canDismissLockscreen: Flow<Boolean> =
        combine(
            keyguardInteractor.isKeyguardShowing,
            keyguardInteractor.isKeyguardDismissible,
            keyguardInteractor.biometricUnlockState,
        ) { isKeyguardShowing, isKeyguardDismissible, biometricUnlockState ->
            (isWakeAndUnlock(biometricUnlockState) || (!isKeyguardShowing && isKeyguardDismissible))
        }

    /**
     * Listen for the signal that we're waking up and figure what state we need to transition to.
     */
@@ -79,12 +85,13 @@ constructor(
        scope.launch("$TAG#listenForAodToAwake") {
            powerInteractor.detailedWakefulness
                .filterRelevantKeyguardStateAnd { wakefulness -> wakefulness.isAwake() }
                .debounce(50L)
                .sample(
                    startedKeyguardTransitionStep,
                    keyguardInteractor.biometricUnlockState,
                    keyguardInteractor.primaryBouncerShowing,
                    keyguardInteractor.isKeyguardOccluded,
                    selectedUserInteractor.selectedUser,
                    canDismissLockscreen,
                )
                .collect {
                    (
@@ -93,10 +100,9 @@ constructor(
                        biometricUnlockState,
                        primaryBouncerShowing,
                        isKeyguardOccludedLegacy,
                        currentUser,
                        canDismissLockscreen,
                    ) ->
                    if (!maybeHandleInsecurePowerGesture()) {
                        val securityNone = lockPatternUtils.isLockScreenDisabled(currentUser)
                        val shouldTransitionToLockscreen =
                            if (KeyguardWmStateRefactor.isEnabled) {
                                // Check with the superclass to see if an occlusion transition is
@@ -105,13 +111,11 @@ constructor(
                                // completes.
                                !maybeStartTransitionToOccludedOrInsecureCamera() &&
                                    !isWakeAndUnlock(biometricUnlockState) &&
                                    !primaryBouncerShowing &&
                                    !securityNone
                                    !primaryBouncerShowing
                            } else {
                                !isKeyguardOccludedLegacy &&
                                    !isWakeAndUnlock(biometricUnlockState) &&
                                    !primaryBouncerShowing &&
                                    !securityNone
                                    !primaryBouncerShowing
                            }

                        // With the refactor enabled, maybeStartTransitionToOccludedOrInsecureCamera
@@ -119,7 +123,11 @@ constructor(
                        val shouldTransitionToOccluded =
                            !KeyguardWmStateRefactor.isEnabled && isKeyguardOccludedLegacy

                        if (shouldTransitionToLockscreen) {
                        if (canDismissLockscreen) {
                            startTransitionTo(
                                toState = KeyguardState.GONE,
                            )
                        } else if (shouldTransitionToLockscreen) {
                            val modeOnCanceled =
                                if (startedStep.from == KeyguardState.LOCKSCREEN) {
                                    TransitionModeOnCanceled.REVERSE
@@ -181,35 +189,6 @@ constructor(
        }
    }

    private fun listenForAodToGone() {
        if (KeyguardWmStateRefactor.isEnabled) {
            // Handled via #dismissAod.
            return
        }

        scope.launch("$TAG#listenForAodToGone") {
            powerInteractor.isAwake
                .debounce(50L)
                .filterRelevantKeyguardState()
                .sample(
                    keyguardInteractor.biometricUnlockState,
                    keyguardInteractor.isKeyguardShowing,
                    keyguardInteractor.isKeyguardDismissible,
                )
                .collect { (isAwake, biometricUnlockState, isKeyguardShowing, isKeyguardDismissible)
                    ->
                    KeyguardWmStateRefactor.assertInLegacyMode()
                    if (
                        isAwake &&
                            (isWakeAndUnlock(biometricUnlockState) ||
                                (!isKeyguardShowing && isKeyguardDismissible))
                    ) {
                        startTransitionTo(KeyguardState.GONE)
                    }
                }
        }
    }

    /**
     * Dismisses AOD and transitions to GONE. This is called whenever authentication occurs while on
     * AOD.
+0 −6
Original line number Diff line number Diff line
@@ -100,12 +100,6 @@ constructor(
            keyguardInteractor.isDozing.collect { logger.log(TAG, VERBOSE, "isDozing", it) }
        }

        scope.launch {
            keyguardInteractor.isKeyguardDismissible.collect {
                logger.log(TAG, VERBOSE, "isKeyguardDismissable", it)
            }
        }

        scope.launch {
            keyguardInteractor.isAbleToDream.collect {
                logger.log(TAG, VERBOSE, "isAbleToDream", it)
+0 −4
Original line number Diff line number Diff line
@@ -16,14 +16,12 @@

package com.android.systemui.keyguard.domain.interactor

import com.android.internal.widget.lockPatternUtils
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
import com.android.systemui.user.domain.interactor.selectedUserInteractor

val Kosmos.fromAodTransitionInteractor by
    Kosmos.Fixture {
@@ -36,7 +34,5 @@ val Kosmos.fromAodTransitionInteractor by
            keyguardInteractor = keyguardInteractor,
            powerInteractor = powerInteractor,
            keyguardOcclusionInteractor = keyguardOcclusionInteractor,
            selectedUserInteractor = selectedUserInteractor,
            lockPatternUtils = lockPatternUtils,
        )
    }