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

Commit 8119510d authored by Chandru S's avatar Chandru S Committed by Android (Google) Code Review
Browse files

Merge "Reset face locked out state whenever fingerprint lockout state gets reset" into main

parents c10dabd7 26815092
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -39,4 +39,6 @@ constructor(
    /** Provide the current status of fingerprint authentication. */
    val authenticationStatus: Flow<FingerprintAuthenticationStatus> =
        repository.authenticationStatus

    val isLockedOut: Flow<Boolean> = repository.isLockedOut
}
+23 −10
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.log.FaceAuthenticationLogger
@@ -78,7 +77,7 @@ constructor(
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
    private val faceAuthenticationLogger: FaceAuthenticationLogger,
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
    private val deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
    private val userRepository: UserRepository,
    private val facePropertyRepository: FacePropertyRepository,
    private val faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig,
@@ -149,14 +148,24 @@ constructor(
            }
            .launchIn(applicationScope)

        deviceEntryFingerprintAuthRepository.isLockedOut
            .onEach {
                if (it) {
                    faceAuthenticationLogger.faceLockedOut("Fingerprint locked out")
        deviceEntryFingerprintAuthInteractor.isLockedOut
            .sample(biometricSettingsRepository.isFaceAuthEnrolledAndEnabled, ::Pair)
            .filter { (_, faceEnabledAndEnrolled) ->
                // We don't care about this if face auth is not enabled.
                faceEnabledAndEnrolled
            }
            .map { (fpLockedOut, _) -> fpLockedOut }
            .sample(userRepository.selectedUser, ::Pair)
            .onEach { (fpLockedOut, currentUser) ->
                if (fpLockedOut) {
                    faceAuthenticationLogger.faceLockedOut("Fingerprint locked out")
                    if (isFaceAuthEnabledAndEnrolled()) {
                        repository.setLockedOut(true)
                    }
                } else {
                    // Fingerprint is not locked out anymore, revert face lockout state back to
                    // previous value.
                    resetLockedOutState(currentUser.userInfo.id)
                }
            }
            .launchIn(applicationScope)
@@ -169,10 +178,7 @@ constructor(
                val wasSwitching = previous.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS
                val isSwitching = curr.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS
                if (wasSwitching && !isSwitching) {
                    val lockoutMode = facePropertyRepository.getLockoutMode(curr.userInfo.id)
                    repository.setLockedOut(
                        lockoutMode == LockoutMode.PERMANENT || lockoutMode == LockoutMode.TIMED
                    )
                    resetLockedOutState(curr.userInfo.id)
                    yield()
                    runFaceAuth(
                        FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING,
@@ -185,6 +191,13 @@ constructor(
            .launchIn(applicationScope)
    }

    private suspend fun resetLockedOutState(currentUserId: Int) {
        val lockoutMode = facePropertyRepository.getLockoutMode(currentUserId)
        repository.setLockedOut(
            lockoutMode == LockoutMode.PERMANENT || lockoutMode == LockoutMode.TIMED
        )
    }

    override fun onSwipeUpOnBouncer() {
        runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER, false)
    }
+59 −31
Original line number Diff line number Diff line
@@ -33,8 +33,7 @@ import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepositor
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.FaceWakeUpTriggersConfig
import com.android.systemui.deviceentry.data.repository.faceWakeUpTriggersConfig
import com.android.systemui.deviceentry.data.repository.fakeFaceWakeUpTriggersConfig
import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
@@ -56,10 +55,9 @@ import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -68,37 +66,33 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
    val kosmos =
        testKosmos().apply { this.faceWakeUpTriggersConfig = mock<FaceWakeUpTriggersConfig>() }
    private val kosmos = testKosmos()
    private val testScope: TestScope = kosmos.testScope

    private lateinit var underTest: SystemUIDeviceEntryFaceAuthInteractor
    private val testScope = kosmos.testScope
    private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository
    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
    private val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
    private val faceAuthRepository = kosmos.fakeDeviceEntryFaceAuthRepository
    private val fakeUserRepository = kosmos.fakeUserRepository
    private val facePropertyRepository = kosmos.facePropertyRepository
    private val fakeDeviceEntryFingerprintAuthRepository =
        kosmos.fakeDeviceEntryFingerprintAuthRepository
    private val fakeDeviceEntryFingerprintAuthInteractor =
        kosmos.deviceEntryFingerprintAuthInteractor
    private val powerInteractor = kosmos.powerInteractor
    private val fakeBiometricSettingsRepository = kosmos.fakeBiometricSettingsRepository

    private val keyguardUpdateMonitor = kosmos.keyguardUpdateMonitor
    private val faceWakeUpTriggersConfig = kosmos.faceWakeUpTriggersConfig
    private val faceWakeUpTriggersConfig = kosmos.fakeFaceWakeUpTriggersConfig
    private val trustManager = kosmos.trustManager

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        fakeUserRepository.setUserInfos(listOf(primaryUser, secondaryUser))

        underTest =
            SystemUIDeviceEntryFaceAuthInteractor(
                mContext,
@@ -110,7 +104,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                keyguardTransitionInteractor,
                FaceAuthenticationLogger(logcatLogBuffer("faceAuthBuffer")),
                keyguardUpdateMonitor,
                fakeDeviceEntryFingerprintAuthRepository,
                fakeDeviceEntryFingerprintAuthInteractor,
                fakeUserRepository,
                facePropertyRepository,
                faceWakeUpTriggersConfig,
@@ -126,10 +120,9 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
            underTest.start()

            powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LID)
            whenever(
                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID)
            faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom(
                setOf(WakeSleepReason.LID.powerManagerWakeReason)
            )
                .thenReturn(true)

            keyguardTransitionRepository.sendTransitionStep(
                TransitionStep(
@@ -168,10 +161,9 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
            underTest.start()

            powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LID)
            whenever(
                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID)
            faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom(
                setOf(WakeSleepReason.LID.powerManagerWakeReason)
            )
                .thenReturn(true)

            keyguardTransitionRepository.sendTransitionStep(
                TransitionStep(
@@ -194,10 +186,9 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
            underTest.start()

            powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LIFT)
            whenever(
                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LIFT)
            faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom(
                setOf(WakeSleepReason.LID.powerManagerWakeReason)
            )
                .thenReturn(false)

            keyguardTransitionRepository.sendTransitionStep(
                TransitionStep(
@@ -217,10 +208,9 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
            underTest.start()

            powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LID)
            whenever(
                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID)
            faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom(
                setOf(WakeSleepReason.LID.powerManagerWakeReason)
            )
                .thenReturn(true)

            keyguardTransitionRepository.sendTransitionStep(
                TransitionStep(
@@ -440,7 +430,45 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
            underTest.start()
            fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)

            fakeDeviceEntryFingerprintAuthRepository.setLockedOut(true)
            kosmos.fakeDeviceEntryFingerprintAuthRepository.setLockedOut(true)
            runCurrent()

            assertThat(faceAuthRepository.isLockedOut.value).isTrue()
        }

    @Test
    fun faceLockoutStateIsResetWheneverFingerprintIsNotLockedOut() =
        testScope.runTest {
            underTest.start()
            fakeUserRepository.setSelectedUserInfo(primaryUser, SelectionStatus.SELECTION_COMPLETE)
            fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setLockedOut(true)
            runCurrent()

            assertThat(faceAuthRepository.isLockedOut.value).isTrue()
            facePropertyRepository.setLockoutMode(primaryUserId, LockoutMode.NONE)

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setLockedOut(false)
            runCurrent()

            assertThat(faceAuthRepository.isLockedOut.value).isFalse()
        }

    @Test
    fun faceLockoutStateIsSetToUsersLockoutStateWheneverFingerprintIsNotLockedOut() =
        testScope.runTest {
            underTest.start()
            fakeUserRepository.setSelectedUserInfo(primaryUser, SelectionStatus.SELECTION_COMPLETE)
            fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setLockedOut(true)
            runCurrent()

            assertThat(faceAuthRepository.isLockedOut.value).isTrue()
            facePropertyRepository.setLockoutMode(primaryUserId, LockoutMode.TIMED)

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setLockedOut(false)
            runCurrent()

            assertThat(faceAuthRepository.isLockedOut.value).isTrue()
+3 −1
Original line number Diff line number Diff line
@@ -18,5 +18,7 @@ package com.android.systemui.deviceentry.data.repository

import com.android.systemui.kosmos.Kosmos

var Kosmos.fakeFaceWakeUpTriggersConfig by Kosmos.Fixture { FakeFaceWakeUpTriggersConfig() }

var Kosmos.faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig by
    Kosmos.Fixture { FakeFaceWakeUpTriggersConfig() }
    Kosmos.Fixture { fakeFaceWakeUpTriggersConfig }
+1 −2
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteract
import com.android.systemui.deviceentry.data.repository.faceWakeUpTriggersConfig
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -51,7 +50,7 @@ val Kosmos.deviceEntryFaceAuthInteractor by
            keyguardTransitionInteractor = keyguardTransitionInteractor,
            faceAuthenticationLogger = faceAuthLogger,
            keyguardUpdateMonitor = keyguardUpdateMonitor,
            deviceEntryFingerprintAuthRepository = deviceEntryFingerprintAuthRepository,
            deviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor,
            userRepository = userRepository,
            facePropertyRepository = facePropertyRepository,
            faceWakeUpTriggersConfig = faceWakeUpTriggersConfig,