diff options
| author | 2023-07-24 03:36:32 +0000 | |
|---|---|---|
| committer | 2023-07-24 03:36:32 +0000 | |
| commit | 3490e6fb8fe5282134aa542f2cde6d66aafbbea4 (patch) | |
| tree | dc3b27a54d49a3f3ec6f4eb7424622c08ef25285 | |
| parent | 85d3b4b60d8bd81be7c61e0bdf118217185c5c42 (diff) | |
| parent | a381768b19847b16f5e68b84935e4505fdded40e (diff) | |
Merge "Minor cleanup: move logic that locks face whenever fingerprint is locked to the interactor" into udc-qpr-dev
8 files changed, 94 insertions, 19 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt index d1f011ea4f9b..bf1e75b09bac 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt @@ -102,6 +102,9 @@ interface DeviceEntryFaceAuthRepository { /** Whether bypass is currently enabled */ val isBypassEnabled: Flow<Boolean> + /** Set whether face authentication should be locked out or not */ + fun lockoutFaceAuth() + /** * Trigger face authentication. * @@ -199,6 +202,10 @@ constructor( } ?: flowOf(false) + override fun lockoutFaceAuth() { + _isLockedOut.value = true + } + private val faceLockoutResetCallback = object : FaceManager.LockoutResetCallback() { override fun onLockoutReset(sensorId: Int) { @@ -396,7 +403,7 @@ constructor( private val faceAuthCallback = object : FaceManager.AuthenticationCallback() { override fun onAuthenticationFailed() { - _authenticationStatus.value = FailedFaceAuthenticationStatus + _authenticationStatus.value = FailedFaceAuthenticationStatus() _isAuthenticated.value = false faceAuthLogger.authenticationFailed() onFaceAuthRequestCompleted() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt index 27e3a749a6c0..5ef9a9e0482c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt @@ -55,6 +55,8 @@ class NoopDeviceEntryFaceAuthRepository @Inject constructor() : DeviceEntryFaceA override val isBypassEnabled: Flow<Boolean> get() = emptyFlow() + override fun lockoutFaceAuth() = Unit + /** * Trigger face authentication. * diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt index 2afe97d9800e..8f4776fa2ed3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt @@ -30,6 +30,7 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository +import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.TransitionState @@ -67,6 +68,7 @@ constructor( private val featureFlags: FeatureFlags, private val faceAuthenticationLogger: FaceAuthenticationLogger, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository, ) : CoreStartable, KeyguardFaceAuthInteractor { private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf() @@ -117,6 +119,15 @@ constructor( ) } .launchIn(applicationScope) + + deviceEntryFingerprintAuthRepository.isLockedOut + .onEach { + if (it) { + faceAuthenticationLogger.faceLockedOut("Fingerprint locked out") + repository.lockoutFaceAuth() + } + } + .launchIn(applicationScope) } override fun onSwipeUpOnBouncer() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt index d9792cf704c8..3de3666fdc3c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt @@ -23,29 +23,40 @@ import android.os.SystemClock.elapsedRealtime * Authentication status provided by * [com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository] */ -sealed class FaceAuthenticationStatus( - // present to break equality check if the same error occurs repeatedly. - val createdAt: Long = elapsedRealtime() -) +sealed class FaceAuthenticationStatus /** Success authentication status. */ -data class SuccessFaceAuthenticationStatus(val successResult: FaceManager.AuthenticationResult) : - FaceAuthenticationStatus() +data class SuccessFaceAuthenticationStatus( + val successResult: FaceManager.AuthenticationResult, + // present to break equality check if the same error occurs repeatedly. + @JvmField val createdAt: Long = elapsedRealtime() +) : FaceAuthenticationStatus() /** Face authentication help message. */ -data class HelpFaceAuthenticationStatus(val msgId: Int, val msg: String?) : - FaceAuthenticationStatus() +data class HelpFaceAuthenticationStatus( + val msgId: Int, + val msg: String?, // present to break equality check if the same error occurs repeatedly. + @JvmField val createdAt: Long = elapsedRealtime() +) : FaceAuthenticationStatus() /** Face acquired message. */ -data class AcquiredFaceAuthenticationStatus(val acquiredInfo: Int) : FaceAuthenticationStatus() +data class AcquiredFaceAuthenticationStatus( + val acquiredInfo: Int, // present to break equality check if the same error occurs repeatedly. + @JvmField val createdAt: Long = elapsedRealtime() +) : FaceAuthenticationStatus() /** Face authentication failed message. */ -object FailedFaceAuthenticationStatus : FaceAuthenticationStatus() +data class FailedFaceAuthenticationStatus( + // present to break equality check if the same error occurs repeatedly. + @JvmField val createdAt: Long = elapsedRealtime() +) : FaceAuthenticationStatus() /** Face authentication error message */ data class ErrorFaceAuthenticationStatus( val msgId: Int, val msg: String? = null, + // present to break equality check if the same error occurs repeatedly. + @JvmField val createdAt: Long = elapsedRealtime() ) : FaceAuthenticationStatus() { /** * Method that checks if [msgId] is a lockout error. A lockout error means that face @@ -80,5 +91,5 @@ data class FaceDetectionStatus( val userId: Int, val isStrongBiometric: Boolean, // present to break equality check if the same error occurs repeatedly. - val createdAt: Long = elapsedRealtime() + @JvmField val createdAt: Long = elapsedRealtime() ) diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt index 373f70582612..66067b11a18c 100644 --- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt @@ -8,6 +8,7 @@ import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.log.core.LogLevel.DEBUG import com.android.systemui.log.dagger.FaceAuthLog +import com.google.errorprone.annotations.CompileTimeConstant import javax.inject.Inject private const val TAG = "DeviceEntryFaceAuthRepositoryLog" @@ -264,4 +265,8 @@ constructor( fun watchdogScheduled() { logBuffer.log(TAG, DEBUG, "FaceManager Biometric watchdog scheduled.") } + + fun faceLockedOut(@CompileTimeConstant reason: String) { + logBuffer.log(TAG, DEBUG, "Face auth has been locked out: $reason") + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 8127ac625748..b3f800087bdf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -265,7 +265,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { val successResult = successResult() authenticationCallback.value.onAuthenticationSucceeded(successResult) - assertThat(authStatus()).isEqualTo(SuccessFaceAuthenticationStatus(successResult)) + val response = authStatus() as SuccessFaceAuthenticationStatus + assertThat(response.successResult).isEqualTo(successResult) assertThat(authenticated()).isTrue() assertThat(authRunning()).isFalse() assertThat(canFaceAuthRun()).isFalse() @@ -494,7 +495,9 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { authenticationCallback.value.onAuthenticationHelp(10, "Ignored help msg") authenticationCallback.value.onAuthenticationHelp(11, "Ignored help msg") - assertThat(authStatus()).isEqualTo(HelpFaceAuthenticationStatus(9, "help msg")) + val response = authStatus() as HelpFaceAuthenticationStatus + assertThat(response.msg).isEqualTo("help msg") + assertThat(response.msgId).isEqualTo(response.msgId) } @Test @@ -550,10 +553,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test - fun authenticateDoesNotRunWhenFpIsLockedOut() = - testScope.runTest { - testGatingCheckForFaceAuth { deviceEntryFingerprintAuthRepository.setLockedOut(true) } - } + fun authenticateDoesNotRunWhenFaceIsDisabled() = + testScope.runTest { testGatingCheckForFaceAuth { underTest.lockoutFaceAuth() } } @Test fun authenticateDoesNotRunWhenUserIsCurrentlyTrusted() = @@ -858,6 +859,19 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test + fun disableFaceUnlockLocksOutFaceUnlock() = + testScope.runTest { + runCurrent() + initCollectors() + assertThat(underTest.isLockedOut.value).isFalse() + + underTest.lockoutFaceAuth() + runCurrent() + + assertThat(underTest.isLockedOut.value).isTrue() + } + + @Test fun detectDoesNotRunWhenFaceAuthNotSupportedInCurrentPosture() = testScope.runTest { testGatingCheckForDetect { @@ -1070,10 +1084,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue() { + verify(faceManager, atLeastOnce()) + .addLockoutResetCallback(faceLockoutResetCallback.capture()) biometricSettingsRepository.setFaceEnrolled(true) biometricSettingsRepository.setIsFaceAuthEnabled(true) fakeUserRepository.setUserSwitching(false) - deviceEntryFingerprintAuthRepository.setLockedOut(false) trustRepository.setCurrentUserTrusted(false) keyguardRepository.setKeyguardGoingAway(false) keyguardRepository.setWakefulnessModel( @@ -1087,6 +1102,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { biometricSettingsRepository.setIsUserInLockdown(false) fakeUserRepository.setSelectedUserInfo(primaryUser) biometricSettingsRepository.setIsFaceAuthSupportedInCurrentPosture(true) + faceLockoutResetCallback.value.onLockoutReset(0) bouncerRepository.setAlternateVisible(true) keyguardRepository.setKeyguardShowing(true) runCurrent() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt index ced0a213ca97..8c9ed5b2ef4e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt @@ -38,6 +38,7 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository +import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus @@ -73,6 +74,8 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor private lateinit var faceAuthRepository: FakeDeviceEntryFaceAuthRepository + private lateinit var fakeDeviceEntryFingerprintAuthRepository: + FakeDeviceEntryFingerprintAuthRepository @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @@ -94,6 +97,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { ) .keyguardTransitionInteractor + fakeDeviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository() underTest = SystemUIKeyguardFaceAuthInteractor( mContext, @@ -127,6 +131,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { featureFlags, FaceAuthenticationLogger(logcatLogBuffer("faceAuthBuffer")), keyguardUpdateMonitor, + fakeDeviceEntryFingerprintAuthRepository ) } @@ -335,4 +340,14 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { assertThat(faceAuthRepository.runningAuthRequest.value) .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER, false)) } + + @Test + fun faceUnlockIsDisabledWhenFpIsLockedOut() = testScope.runTest { + underTest.start() + + fakeDeviceEntryFingerprintAuthRepository.setLockedOut(true) + runCurrent() + + assertThat(faceAuthRepository.wasDisabled).isTrue() + } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt index 548169e6cccd..f4c2db1b944e 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt @@ -27,6 +27,11 @@ import kotlinx.coroutines.flow.filterNotNull class FakeDeviceEntryFaceAuthRepository : DeviceEntryFaceAuthRepository { + private var _wasDisabled: Boolean = false + + val wasDisabled: Boolean + get() = _wasDisabled + override val isAuthenticated = MutableStateFlow(false) override val canRunFaceAuth = MutableStateFlow(false) private val _authenticationStatus = MutableStateFlow<FaceAuthenticationStatus?>(null) @@ -52,6 +57,9 @@ class FakeDeviceEntryFaceAuthRepository : DeviceEntryFaceAuthRepository { override val isAuthRunning: StateFlow<Boolean> = _isAuthRunning override val isBypassEnabled = MutableStateFlow(false) + override fun lockoutFaceAuth() { + _wasDisabled = true + } override suspend fun authenticate(uiEvent: FaceAuthUiEvent, fallbackToDetection: Boolean) { _runningAuthRequest.value = uiEvent to fallbackToDetection |