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

Commit 795e61c4 authored by Chandru S's avatar Chandru S
Browse files

Update the face auth locked out state only if face auth is enrolled,

When fingerprint is locked out for user A and we switch from another user to user A, the following happens:

 1. we use FingerprintManager#getLockoutModeForUser(...) to get the lockout mode for the current user and store it in KeyguardUpdateMonitor this returns BIOMETRIC_LOCKOUT_PERMANENT
 2. we use faceManager#getLockoutModeForUser(...) to get the lockout mode for the current user and store it in DeviceEntryFaceAuthRepository this also returns BIOMETRIC_LOCKOUT_PERMANENT (even though face is not enrolled)
 3. once we unlock the phone by entering the PIN/pattern/password, we receive a call through FingerprintManager.LockoutResetCallback#onLockoutReset this resets the state stored in KeyguardUpdateMonitor
 4. we don't receive a call on FaceManager.LockoutResetCallback#onLockoutReset so that state in DeviceEntryFaceAuthRepository never gets reset.
 5. face auth remains locked out, when we lock the device again we assume fingerprint is not allowed because face auth is strong and is locked out.

Bug: 365629896
Fixes: 348456150
Flag: EXEMPT bugfix
Test: atest
Test: verified manually,
 1. create 2 users, user A and B
 2. enroll fingerprint for both users
 3. lockout fingerprint for user A
 4. switch to user B
 5. switch back to user A
 6. "Face unlock unavailable" message should not be shown on lock screen
 7. unlock the device using pin/pattern/password
 8. lock the device again
 9. udfps should be available.
Change-Id: I9983f37075cb2638127b2fac6c1785e2496473cc
parent 331bbabf
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                TransitionStep(
                    KeyguardState.OFF,
                    KeyguardState.LOCKSCREEN,
                    transitionState = TransitionState.STARTED
                    transitionState = TransitionState.STARTED,
                )
            )

@@ -181,7 +181,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                TransitionStep(
                    KeyguardState.AOD,
                    KeyguardState.LOCKSCREEN,
                    transitionState = TransitionState.STARTED
                    transitionState = TransitionState.STARTED,
                )
            )

@@ -206,7 +206,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                TransitionStep(
                    KeyguardState.DOZING,
                    KeyguardState.LOCKSCREEN,
                    transitionState = TransitionState.STARTED
                    transitionState = TransitionState.STARTED,
                )
            )

@@ -229,7 +229,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                TransitionStep(
                    KeyguardState.DOZING,
                    KeyguardState.LOCKSCREEN,
                    transitionState = TransitionState.STARTED
                    transitionState = TransitionState.STARTED,
                )
            )

@@ -244,12 +244,14 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
    fun faceAuthLockedOutStateIsUpdatedAfterUserSwitch() =
        testScope.runTest {
            underTest.start()
            runCurrent()
            fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)

            // User switching has started
            fakeUserRepository.setSelectedUserInfo(primaryUser, SelectionStatus.SELECTION_COMPLETE)
            fakeUserRepository.setSelectedUserInfo(
                primaryUser,
                SelectionStatus.SELECTION_IN_PROGRESS
                SelectionStatus.SELECTION_IN_PROGRESS,
            )
            runCurrent()

@@ -258,7 +260,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
            facePropertyRepository.setLockoutMode(secondaryUser.id, LockoutMode.NONE)
            fakeUserRepository.setSelectedUserInfo(
                secondaryUser,
                SelectionStatus.SELECTION_COMPLETE
                SelectionStatus.SELECTION_COMPLETE,
            )
            runCurrent()

@@ -316,7 +318,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                .isEqualTo(
                    Pair(
                        FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
                        false
                        false,
                    )
                )
        }
@@ -600,7 +602,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {

            faceAuthRepository.requestAuthenticate(
                FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED,
                true
                true,
            )
            facePropertyRepository.setCameraIno(CameraInfo("0", "1", null))

+9 −6
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ constructor(
                faceAuthenticationLogger.bouncerVisibilityChanged()
                runFaceAuth(
                    FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN,
                    fallbackToDetect = false
                    fallbackToDetect = false,
                )
            }
            .launchIn(applicationScope)
@@ -125,7 +125,7 @@ constructor(
                faceAuthenticationLogger.alternateBouncerVisibilityChanged()
                runFaceAuth(
                    FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
                    fallbackToDetect = false
                    fallbackToDetect = false,
                )
            }
            .launchIn(applicationScope)
@@ -153,7 +153,7 @@ constructor(
                    it.lastWakeReason.powerManagerWakeReason
                runFaceAuth(
                    FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED,
                    fallbackToDetect = true
                    fallbackToDetect = true,
                )
            }
            .launchIn(applicationScope)
@@ -193,13 +193,16 @@ constructor(
            .map { (_, curr) -> curr.userInfo.id }
            .sample(isBouncerVisible, ::Pair)
            .onEach { (userId, isBouncerCurrentlyVisible) ->
                if (!isFaceAuthEnabledAndEnrolled()) {
                    return@onEach
                }
                resetLockedOutState(userId)
                yield()
                runFaceAuth(
                    FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING,
                    // Fallback to detection if bouncer is not showing so that we can detect a
                    // face and then show the bouncer to the user if face auth can't run
                    fallbackToDetect = !isBouncerCurrentlyVisible
                    fallbackToDetect = !isBouncerCurrentlyVisible,
                )
            }
            .launchIn(applicationScope)
@@ -210,7 +213,7 @@ constructor(
                    repository.cancel()
                    runFaceAuth(
                        FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED,
                        fallbackToDetect = true
                        fallbackToDetect = true,
                    )
                }
            }
@@ -321,7 +324,7 @@ constructor(
            faceAuthenticationStatusOverride.value =
                ErrorFaceAuthenticationStatus(
                    BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT,
                    context.resources.getString(R.string.keyguard_face_unlock_unavailable)
                    context.resources.getString(R.string.keyguard_face_unlock_unavailable),
                )
        } else {
            faceAuthenticationStatusOverride.value = null