diff options
2 files changed, 120 insertions, 78 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt index 558e7e6564ae..3a28471b5f9a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runCurrent @@ -215,6 +216,39 @@ class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() { } @Test + fun onFingerprintFailed_failedAuthenticationStatusWithOtherStatuses() = + testScope.runTest { + val failStatus by + collectLastValue( + underTest.authenticationStatus.filterIsInstance< + FailFingerprintAuthenticationStatus + >() + ) + runCurrent() + + verify(keyguardUpdateMonitor).registerCallback(updateMonitorCallback.capture()) + updateMonitorCallback.value.onBiometricAcquired( + BiometricSourceType.FINGERPRINT, + /* acquireInfo */ 0, + ) + updateMonitorCallback.value.onBiometricAuthFailed( + BiometricSourceType.FINGERPRINT, + ) + updateMonitorCallback.value.onBiometricHelp( + /* msgId */ 7, + /* errString */ "Not recognized.", + BiometricSourceType.FINGERPRINT, + ) + updateMonitorCallback.value.onBiometricError( + /* msgId */ 7, + /* errString */ "Too many attempts.", + BiometricSourceType.FINGERPRINT, + ) + + assertThat(failStatus).isNotNull() + } + + @Test fun onFingerprintError_errorAuthenticationStatus() = testScope.runTest { val authenticationStatus by collectLastValue(underTest.authenticationStatus) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt index b152eea63028..2bede977c958 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt @@ -40,6 +40,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.shareIn @@ -177,92 +178,99 @@ constructor( // TODO(b/322555228) Remove after consolidating device entry auth messages with BP auth messages // in BiometricStatusRepository + /** + * FingerprintAuthenticationStatus Multiple statuses may arrive in immediate sequence (ie: + * acquired, failed, help, error), so we use a buffer to ensure consumers receive each distinct + * status. + */ override val authenticationStatus: Flow<FingerprintAuthenticationStatus> - get() = conflatedCallbackFlow { - val callback = - object : KeyguardUpdateMonitorCallback() { - override fun onBiometricAuthenticated( - userId: Int, - biometricSourceType: BiometricSourceType, - isStrongBiometric: Boolean, - ) { - sendUpdateIfFingerprint( - biometricSourceType, - SuccessFingerprintAuthenticationStatus( - userId, - isStrongBiometric, - ), - ) - } + get() = + conflatedCallbackFlow { + val callback = + object : KeyguardUpdateMonitorCallback() { + override fun onBiometricAuthenticated( + userId: Int, + biometricSourceType: BiometricSourceType, + isStrongBiometric: Boolean, + ) { + sendUpdateIfFingerprint( + biometricSourceType, + SuccessFingerprintAuthenticationStatus( + userId, + isStrongBiometric, + ), + ) + } - override fun onBiometricError( - msgId: Int, - errString: String?, - biometricSourceType: BiometricSourceType, - ) { - sendUpdateIfFingerprint( - biometricSourceType, - ErrorFingerprintAuthenticationStatus( - msgId, - errString, - ), - ) - } + override fun onBiometricError( + msgId: Int, + errString: String?, + biometricSourceType: BiometricSourceType, + ) { + sendUpdateIfFingerprint( + biometricSourceType, + ErrorFingerprintAuthenticationStatus( + msgId, + errString, + ), + ) + } - override fun onBiometricHelp( - msgId: Int, - helpString: String?, - biometricSourceType: BiometricSourceType, - ) { - sendUpdateIfFingerprint( - biometricSourceType, - HelpFingerprintAuthenticationStatus( - msgId, - helpString, - ), - ) - } + override fun onBiometricHelp( + msgId: Int, + helpString: String?, + biometricSourceType: BiometricSourceType, + ) { + sendUpdateIfFingerprint( + biometricSourceType, + HelpFingerprintAuthenticationStatus( + msgId, + helpString, + ), + ) + } - override fun onBiometricAuthFailed( - biometricSourceType: BiometricSourceType, - ) { - sendUpdateIfFingerprint( - biometricSourceType, - FailFingerprintAuthenticationStatus, - ) - } + override fun onBiometricAuthFailed( + biometricSourceType: BiometricSourceType, + ) { + sendUpdateIfFingerprint( + biometricSourceType, + FailFingerprintAuthenticationStatus, + ) + } - override fun onBiometricAcquired( - biometricSourceType: BiometricSourceType, - acquireInfo: Int, - ) { - sendUpdateIfFingerprint( - biometricSourceType, - AcquiredFingerprintAuthenticationStatus( - AuthenticationReason.DeviceEntryAuthentication, - acquireInfo - ), - ) - } + override fun onBiometricAcquired( + biometricSourceType: BiometricSourceType, + acquireInfo: Int, + ) { + sendUpdateIfFingerprint( + biometricSourceType, + AcquiredFingerprintAuthenticationStatus( + AuthenticationReason.DeviceEntryAuthentication, + acquireInfo + ), + ) + } - private fun sendUpdateIfFingerprint( - biometricSourceType: BiometricSourceType, - authenticationStatus: FingerprintAuthenticationStatus - ) { - if (biometricSourceType != BiometricSourceType.FINGERPRINT) { - return - } + private fun sendUpdateIfFingerprint( + biometricSourceType: BiometricSourceType, + authenticationStatus: FingerprintAuthenticationStatus + ) { + if (biometricSourceType != BiometricSourceType.FINGERPRINT) { + return + } - trySendWithFailureLogging( - authenticationStatus, - TAG, - "new fingerprint authentication status" - ) - } + trySendWithFailureLogging( + authenticationStatus, + TAG, + "new fingerprint authentication status" + ) + } + } + keyguardUpdateMonitor.registerCallback(callback) + awaitClose { keyguardUpdateMonitor.removeCallback(callback) } } - keyguardUpdateMonitor.registerCallback(callback) - awaitClose { keyguardUpdateMonitor.removeCallback(callback) } - } + .buffer(capacity = 4) override val shouldUpdateIndicatorVisibility: Flow<Boolean> = conflatedCallbackFlow { |