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

Commit c14d87d9 authored by Chandru S's avatar Chandru S
Browse files

Fix face auth not running as expected when flexiglass is enabled.

When flexiglass is enabled, `keyguardRepository.isKeyguardGoingAway` is not the source of truth anymore for whether lockscreen is going away.

Changing it to rely on transition to UNDEFINED.

Fixes: 353453872
Fixes: 357668029
Test: atest DeviceEntryFaceAuthRepositoryTest
Test: manually, enable face auth, enable flexiglass, go to lockscreen, go to bouncer and swipe up, face auth should run.
Flag: com.android.systemui.scene_container
Change-Id: I5694044ac5a718fe3842e9717906fd597a803003
parent d299a2a6
Loading
Loading
Loading
Loading
+77 −24
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus
import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.keyguard.data.repository.BiometricType
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
@@ -77,6 +78,7 @@ import com.android.systemui.log.table.TableLogBuffer
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.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
@@ -136,12 +138,12 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {

    @Captor
    private lateinit var faceLockoutResetCallback: ArgumentCaptor<FaceManager.LockoutResetCallback>
    private val testDispatcher = kosmos.testDispatcher
    private val testDispatcher by lazy { kosmos.testDispatcher }

    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
    private val testScope = kosmos.testScope
    private val fakeUserRepository = kosmos.fakeUserRepository
    private val fakeExecutor = kosmos.fakeExecutor
    private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
    private val testScope by lazy { kosmos.testScope }
    private val fakeUserRepository by lazy { kosmos.fakeUserRepository }
    private val fakeExecutor by lazy { kosmos.fakeExecutor }
    private lateinit var authStatus: FlowValue<FaceAuthenticationStatus?>
    private lateinit var detectStatus: FlowValue<FaceDetectionStatus?>
    private lateinit var authRunning: FlowValue<Boolean?>
@@ -149,18 +151,19 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
    private lateinit var lockedOut: FlowValue<Boolean?>
    private lateinit var canFaceAuthRun: FlowValue<Boolean?>
    private lateinit var authenticated: FlowValue<Boolean?>
    private val biometricSettingsRepository = kosmos.fakeBiometricSettingsRepository
    private val deviceEntryFingerprintAuthRepository =
    private val biometricSettingsRepository by lazy { kosmos.fakeBiometricSettingsRepository }
    private val deviceEntryFingerprintAuthRepository by lazy {
        kosmos.fakeDeviceEntryFingerprintAuthRepository
    private val trustRepository = kosmos.fakeTrustRepository
    private val keyguardRepository = kosmos.fakeKeyguardRepository
    private val powerInteractor = kosmos.powerInteractor
    private val keyguardInteractor = kosmos.keyguardInteractor
    private val alternateBouncerInteractor = kosmos.alternateBouncerInteractor
    private val displayStateInteractor = kosmos.displayStateInteractor
    private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository
    private val displayRepository = kosmos.displayRepository
    private val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
    }
    private val trustRepository by lazy { kosmos.fakeTrustRepository }
    private val keyguardRepository by lazy { kosmos.fakeKeyguardRepository }
    private val powerInteractor by lazy { kosmos.powerInteractor }
    private val keyguardInteractor by lazy { kosmos.keyguardInteractor }
    private val alternateBouncerInteractor by lazy { kosmos.alternateBouncerInteractor }
    private val displayStateInteractor by lazy { kosmos.displayStateInteractor }
    private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository }
    private val displayRepository by lazy { kosmos.displayRepository }
    private val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
    private lateinit var featureFlags: FakeFeatureFlags

    private var wasAuthCancelled = false
@@ -180,10 +183,12 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
        whenever(bypassController.bypassEnabled).thenReturn(true)
        underTest = createDeviceEntryFaceAuthRepositoryImpl(faceManager, bypassController)

        if (!SceneContainerFlag.isEnabled) {
            mSetFlagsRule.disableFlags(
                AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
            )
        }
    }

    private fun createDeviceEntryFaceAuthRepositoryImpl(
        fmOverride: FaceManager? = faceManager,
@@ -546,6 +551,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
            testGatingCheckForFaceAuth { keyguardRepository.setKeyguardGoingAway(true) }
        }

    @Test
    @EnableSceneContainer
    fun withSceneContainerEnabled_authenticateDoesNotRunWhenKeyguardIsGoingAway() =
        testScope.runTest {
            testGatingCheckForFaceAuth(sceneContainerEnabled = true) {
                keyguardTransitionRepository.sendTransitionStep(
                    TransitionStep(
                        KeyguardState.LOCKSCREEN,
                        KeyguardState.UNDEFINED,
                        value = 0.5f,
                        transitionState = TransitionState.RUNNING
                    ),
                    validateStep = false
                )
                runCurrent()
            }
        }

    @Test
    fun authenticateDoesNotRunWhenDeviceIsGoingToSleep() =
        testScope.runTest {
@@ -840,6 +863,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
            testGatingCheckForDetect { keyguardRepository.setKeyguardGoingAway(true) }
        }

    @Test
    @EnableSceneContainer
    fun withSceneContainer_faceDetectDoesNotRunWhenKeyguardGoingAway() =
        testScope.runTest {
            testGatingCheckForDetect(sceneContainerEnabled = true) {
                keyguardTransitionRepository.sendTransitionStep(
                    TransitionStep(
                        KeyguardState.LOCKSCREEN,
                        KeyguardState.UNDEFINED,
                        value = 0.5f,
                        transitionState = TransitionState.RUNNING
                    ),
                    validateStep = false
                )
                runCurrent()
            }
        }

    @Test
    fun detectDoesNotRunWhenDeviceSleepingStartingToSleep() =
        testScope.runTest {
@@ -1052,10 +1093,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
        }

    private suspend fun TestScope.testGatingCheckForFaceAuth(
        sceneContainerEnabled: Boolean = false,
        gatingCheckModifier: suspend () -> Unit
    ) {
        initCollectors()
        allPreconditionsToRunFaceAuthAreTrue()
        allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)

        gatingCheckModifier()
        runCurrent()
@@ -1069,7 +1111,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
        faceAuthenticateIsNotCalled()

        // flip the gating check back on.
        allPreconditionsToRunFaceAuthAreTrue()
        allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)
        assertThat(underTest.canRunFaceAuth.value).isTrue()

        faceAuthenticateIsCalled()
@@ -1094,10 +1136,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
    }

    private suspend fun TestScope.testGatingCheckForDetect(
        sceneContainerEnabled: Boolean = false,
        gatingCheckModifier: suspend () -> Unit
    ) {
        initCollectors()
        allPreconditionsToRunFaceAuthAreTrue()
        allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)

        // This will stop face auth from running but is required to be false for detect.
        biometricSettingsRepository.setIsFaceAuthCurrentlyAllowed(false)
@@ -1145,12 +1188,22 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
        cancellationSignal.value.setOnCancelListener { wasAuthCancelled = true }
    }

    private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue() {
    private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue(
        sceneContainerEnabled: Boolean = false
    ) {
        fakeExecutor.runAllReady()
        verify(faceManager, atLeastOnce())
            .addLockoutResetCallback(faceLockoutResetCallback.capture())
        trustRepository.setCurrentUserTrusted(false)
        if (sceneContainerEnabled) {
            // Keyguard is not going away
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                TransitionStep(KeyguardState.OFF, KeyguardState.LOCKSCREEN, value = 1.0f),
                validateStep = false
            )
        } else {
            keyguardRepository.setKeyguardGoingAway(false)
        }
        powerInteractor.setAwakeForTest()
        biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
        biometricSettingsRepository.setIsFaceAuthSupportedInCurrentPosture(true)
+11 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.log.SessionTracker
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.user.data.model.SelectionStatus
@@ -385,7 +386,16 @@ constructor(
                biometricSettingsRepository.isFaceAuthEnrolledAndEnabled,
                "isFaceAuthEnrolledAndEnabled"
            ),
            Pair(keyguardRepository.isKeyguardGoingAway.isFalse(), "keyguardNotGoingAway"),
            Pair(
                if (SceneContainerFlag.isEnabled) {
                    keyguardTransitionInteractor
                        .isInTransitionWhere(toStatePredicate = { it == KeyguardState.UNDEFINED })
                        .isFalse()
                } else {
                    keyguardRepository.isKeyguardGoingAway.isFalse()
                },
                "keyguardNotGoingAway"
            ),
            Pair(
                keyguardTransitionInteractor
                    .isInTransitionWhere(toStatePredicate = KeyguardState::deviceIsAsleepInState)