Change authenticationState to regular flow

Change authenticationState from conflatedCallbackFlow to regular
callbackFlow to prevent dropping values

Flag: NONE bug fix
Fixes: 355950083
Test: atest BiometricStatusRepositoryTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:51d4c66294c1d8eb6aff931d62fa784c0f277149)
Merged-In: I636eeec062801eba81cc123787430aaa8eb72f2c
Change-Id: I636eeec062801eba81cc123787430aaa8eb72f2c
This commit is contained in:
Grace Cheng 2024-08-01 01:32:13 +00:00 committed by Android Build Coastguard Worker
parent 821db53bc1
commit 87538f0991
2 changed files with 39 additions and 21 deletions

View file

@ -39,7 +39,6 @@ import com.android.systemui.biometrics.shared.model.AuthenticationReason
import com.android.systemui.biometrics.shared.model.AuthenticationReason.SettingsOperations
import com.android.systemui.biometrics.shared.model.AuthenticationState
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
@ -49,6 +48,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
@ -85,7 +85,7 @@ constructor(
* onAcquired in [FingerprintManager.EnrollmentCallback] and [FaceManager.EnrollmentCallback]
*/
private val authenticationState: Flow<AuthenticationState> =
conflatedCallbackFlow {
callbackFlow {
val updateAuthenticationState = { state: AuthenticationState ->
Log.d(TAG, "authenticationState updated: $state")
trySendWithFailureLogging(state, TAG, "Error sending AuthenticationState state")
@ -169,7 +169,9 @@ constructor(
}
}
updateAuthenticationState(AuthenticationState.Idle(AuthenticationReason.NotRunning))
updateAuthenticationState(
AuthenticationState.Idle(requestReason = AuthenticationReason.NotRunning)
)
biometricManager?.registerAuthenticationStateListener(authenticationStateListener)
awaitClose {
biometricManager?.unregisterAuthenticationStateListener(
@ -180,23 +182,32 @@ constructor(
.distinctUntilChanged()
.shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
override val fingerprintAuthenticationReason: Flow<AuthenticationReason> =
private val fingerprintAuthenticationState: Flow<AuthenticationState> =
authenticationState
.filter {
it is AuthenticationState.Idle ||
(it is AuthenticationState.Started &&
it.biometricSourceType == BiometricSourceType.FINGERPRINT) ||
(it is AuthenticationState.Stopped &&
it.biometricSourceType == BiometricSourceType.FINGERPRINT)
it.biometricSourceType == null ||
it.biometricSourceType == BiometricSourceType.FINGERPRINT
}
.onEach { Log.d(TAG, "fingerprintAuthenticationState updated: $it") }
private val fingerprintRunningState: Flow<AuthenticationState> =
fingerprintAuthenticationState
.filter {
it is AuthenticationState.Idle ||
it is AuthenticationState.Started ||
it is AuthenticationState.Stopped
}
.onEach { Log.d(TAG, "fingerprintRunningState updated: $it") }
override val fingerprintAuthenticationReason: Flow<AuthenticationReason> =
fingerprintRunningState
.map { it.requestReason }
.onEach { Log.d(TAG, "fingerprintAuthenticationReason updated: $it") }
override val fingerprintAcquiredStatus: Flow<FingerprintAuthenticationStatus> =
authenticationState
.filterIsInstance<AuthenticationState.Acquired>()
.filter { it.biometricSourceType == BiometricSourceType.FINGERPRINT }
.map { AcquiredFingerprintAuthenticationStatus(it.requestReason, it.acquiredInfo) }
fingerprintAuthenticationState.filterIsInstance<AuthenticationState.Acquired>().map {
AcquiredFingerprintAuthenticationStatus(it.requestReason, it.acquiredInfo)
}
companion object {
private const val TAG = "BiometricStatusRepositoryImpl"

View file

@ -27,6 +27,9 @@ import android.hardware.biometrics.BiometricSourceType
* authentication.
*/
sealed interface AuthenticationState {
/** Indicates [BiometricSourceType] of authentication state update, null in idle auth state. */
val biometricSourceType: BiometricSourceType?
/**
* Indicates [AuthenticationReason] from [BiometricRequestConstants.RequestReason] for
* requesting auth
@ -43,7 +46,7 @@ sealed interface AuthenticationState {
* message.
*/
data class Acquired(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason,
val acquiredInfo: Int
) : AuthenticationState
@ -59,7 +62,7 @@ sealed interface AuthenticationState {
* @param requestReason reason from [BiometricRequestConstants.RequestReason] for authentication
*/
data class Error(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
val errString: String?,
val errCode: Int,
override val requestReason: AuthenticationReason,
@ -73,7 +76,7 @@ sealed interface AuthenticationState {
* @param userId The user id for the requested authentication
*/
data class Failed(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason,
val userId: Int
) : AuthenticationState
@ -87,7 +90,7 @@ sealed interface AuthenticationState {
* @param requestReason reason from [BiometricRequestConstants.RequestReason] for authentication
*/
data class Help(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
val helpString: String?,
val helpCode: Int,
override val requestReason: AuthenticationReason,
@ -96,9 +99,13 @@ sealed interface AuthenticationState {
/**
* Authentication state when no auth is running
*
* @param biometricSourceType null
* @param requestReason [AuthenticationReason.NotRunning]
*/
data class Idle(override val requestReason: AuthenticationReason) : AuthenticationState
data class Idle(
override val biometricSourceType: BiometricSourceType? = null,
override val requestReason: AuthenticationReason
) : AuthenticationState
/**
* AuthenticationState when auth is started
@ -107,7 +114,7 @@ sealed interface AuthenticationState {
* @param requestReason reason from [BiometricRequestConstants.RequestReason] for authentication
*/
data class Started(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason
) : AuthenticationState
@ -118,7 +125,7 @@ sealed interface AuthenticationState {
* @param requestReason [AuthenticationReason.NotRunning]
*/
data class Stopped(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason
) : AuthenticationState
@ -131,7 +138,7 @@ sealed interface AuthenticationState {
* @param userId The user id for the requested authentication
*/
data class Succeeded(
val biometricSourceType: BiometricSourceType,
override val biometricSourceType: BiometricSourceType,
val isStrongBiometric: Boolean,
override val requestReason: AuthenticationReason,
val userId: Int