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

Commit 7de73f27 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Add FingerprintAuthenticationStatus" into udc-qpr-dev

parents f081ea2a 864ea0da
Loading
Loading
Loading
Loading
+22 −18
Original line number Diff line number Diff line
@@ -164,13 +164,13 @@ import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.domain.interactor.FaceAuthenticationListener;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
import com.android.systemui.keyguard.shared.constants.TrustAgentUiEvent;
import com.android.systemui.keyguard.shared.model.AcquiredAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.AuthenticationStatus;
import com.android.systemui.keyguard.shared.model.DetectionStatus;
import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.FailedAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.AcquiredFaceAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.FaceDetectionStatus;
import com.android.systemui.keyguard.shared.model.FailedFaceAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.HelpFaceAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.SuccessFaceAuthenticationStatus;
import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.WeatherData;
@@ -1471,27 +1471,31 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private FaceAuthenticationListener mFaceAuthenticationListener =
            new FaceAuthenticationListener() {
                @Override
                public void onAuthenticationStatusChanged(@NonNull AuthenticationStatus status) {
                    if (status instanceof AcquiredAuthenticationStatus) {
                public void onAuthenticationStatusChanged(
                        @NonNull FaceAuthenticationStatus status
                ) {
                    if (status instanceof AcquiredFaceAuthenticationStatus) {
                        handleFaceAcquired(
                                ((AcquiredAuthenticationStatus) status).getAcquiredInfo());
                    } else if (status instanceof ErrorAuthenticationStatus) {
                        ErrorAuthenticationStatus error = (ErrorAuthenticationStatus) status;
                                ((AcquiredFaceAuthenticationStatus) status).getAcquiredInfo());
                    } else if (status instanceof ErrorFaceAuthenticationStatus) {
                        ErrorFaceAuthenticationStatus error =
                                (ErrorFaceAuthenticationStatus) status;
                        handleFaceError(error.getMsgId(), error.getMsg());
                    } else if (status instanceof FailedAuthenticationStatus) {
                    } else if (status instanceof FailedFaceAuthenticationStatus) {
                        handleFaceAuthFailed();
                    } else if (status instanceof HelpAuthenticationStatus) {
                        HelpAuthenticationStatus helpMsg = (HelpAuthenticationStatus) status;
                    } else if (status instanceof HelpFaceAuthenticationStatus) {
                        HelpFaceAuthenticationStatus helpMsg =
                                (HelpFaceAuthenticationStatus) status;
                        handleFaceHelp(helpMsg.getMsgId(), helpMsg.getMsg());
                    } else if (status instanceof SuccessAuthenticationStatus) {
                    } else if (status instanceof SuccessFaceAuthenticationStatus) {
                        FaceManager.AuthenticationResult result =
                                ((SuccessAuthenticationStatus) status).getSuccessResult();
                                ((SuccessFaceAuthenticationStatus) status).getSuccessResult();
                        handleFaceAuthenticated(result.getUserId(), result.isStrongBiometric());
                    }
                }

                @Override
                public void onDetectionStatusChanged(@NonNull DetectionStatus status) {
                public void onDetectionStatusChanged(@NonNull FaceDetectionStatus status) {
                    handleFaceAuthenticated(status.getUserId(), status.isStrongBiometric());
                }
            };
+3 −3
Original line number Diff line number Diff line
@@ -16,10 +16,10 @@

package com.android.systemui.bouncer.domain.interactor

import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.time.SystemClock
@@ -35,8 +35,8 @@ constructor(
    private val keyguardStateController: KeyguardStateController,
    private val bouncerRepository: KeyguardBouncerRepository,
    private val biometricSettingsRepository: BiometricSettingsRepository,
    private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
    private val systemClock: SystemClock,
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
) {
    var receivedDownTouch = false
    val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
@@ -78,7 +78,7 @@ constructor(
            biometricSettingsRepository.isFingerprintEnrolled.value &&
            biometricSettingsRepository.isStrongBiometricAllowed.value &&
            biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value &&
            !deviceEntryFingerprintAuthRepository.isLockedOut.value &&
            !keyguardUpdateMonitor.isFingerprintLockedOut &&
            !keyguardStateController.isUnlocked &&
            !statusBarStateController.isDozing
    }
+19 −19
Original line number Diff line number Diff line
@@ -38,13 +38,13 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AcquiredAuthenticationStatus
import com.android.systemui.keyguard.shared.model.AuthenticationStatus
import com.android.systemui.keyguard.shared.model.DetectionStatus
import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FailedAuthenticationStatus
import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus
import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus
import com.android.systemui.keyguard.shared.model.AcquiredFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FaceDetectionStatus
import com.android.systemui.keyguard.shared.model.FailedFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.HelpFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.SuccessFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.log.SessionTracker
@@ -88,10 +88,10 @@ interface DeviceEntryFaceAuthRepository {
    val canRunFaceAuth: StateFlow<Boolean>

    /** Provide the current status of face authentication. */
    val authenticationStatus: Flow<AuthenticationStatus>
    val authenticationStatus: Flow<FaceAuthenticationStatus>

    /** Provide the current status of face detection. */
    val detectionStatus: Flow<DetectionStatus>
    val detectionStatus: Flow<FaceDetectionStatus>

    /** Current state of whether face authentication is locked out or not. */
    val isLockedOut: StateFlow<Boolean>
@@ -151,13 +151,13 @@ constructor(
    private var cancelNotReceivedHandlerJob: Job? = null
    private var halErrorRetryJob: Job? = null

    private val _authenticationStatus: MutableStateFlow<AuthenticationStatus?> =
    private val _authenticationStatus: MutableStateFlow<FaceAuthenticationStatus?> =
        MutableStateFlow(null)
    override val authenticationStatus: Flow<AuthenticationStatus>
    override val authenticationStatus: Flow<FaceAuthenticationStatus>
        get() = _authenticationStatus.filterNotNull()

    private val _detectionStatus = MutableStateFlow<DetectionStatus?>(null)
    override val detectionStatus: Flow<DetectionStatus>
    private val _detectionStatus = MutableStateFlow<FaceDetectionStatus?>(null)
    override val detectionStatus: Flow<FaceDetectionStatus>
        get() = _detectionStatus.filterNotNull()

    private val _isLockedOut = MutableStateFlow(false)
@@ -396,18 +396,18 @@ constructor(
    private val faceAuthCallback =
        object : FaceManager.AuthenticationCallback() {
            override fun onAuthenticationFailed() {
                _authenticationStatus.value = FailedAuthenticationStatus
                _authenticationStatus.value = FailedFaceAuthenticationStatus
                _isAuthenticated.value = false
                faceAuthLogger.authenticationFailed()
                onFaceAuthRequestCompleted()
            }

            override fun onAuthenticationAcquired(acquireInfo: Int) {
                _authenticationStatus.value = AcquiredAuthenticationStatus(acquireInfo)
                _authenticationStatus.value = AcquiredFaceAuthenticationStatus(acquireInfo)
            }

            override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
                val errorStatus = ErrorAuthenticationStatus(errorCode, errString.toString())
                val errorStatus = ErrorFaceAuthenticationStatus(errorCode, errString.toString())
                if (errorStatus.isLockoutError()) {
                    _isLockedOut.value = true
                }
@@ -433,11 +433,11 @@ constructor(
                if (faceAcquiredInfoIgnoreList.contains(code)) {
                    return
                }
                _authenticationStatus.value = HelpAuthenticationStatus(code, helpStr.toString())
                _authenticationStatus.value = HelpFaceAuthenticationStatus(code, helpStr.toString())
            }

            override fun onAuthenticationSucceeded(result: FaceManager.AuthenticationResult) {
                _authenticationStatus.value = SuccessAuthenticationStatus(result)
                _authenticationStatus.value = SuccessFaceAuthenticationStatus(result)
                _isAuthenticated.value = true
                faceAuthLogger.faceAuthSuccess(result)
                onFaceAuthRequestCompleted()
@@ -482,7 +482,7 @@ constructor(
    private val detectionCallback =
        FaceManager.FaceDetectionCallback { sensorId, userId, isStrong ->
            faceAuthLogger.faceDetected()
            _detectionStatus.value = DetectionStatus(sensorId, userId, isStrong)
            _detectionStatus.value = FaceDetectionStatus(sensorId, userId, isStrong)
        }

    private var cancellationInProgress = false
+100 −17
Original line number Diff line number Diff line
@@ -21,27 +21,29 @@ import android.hardware.biometrics.BiometricAuthenticator.Modality
import android.hardware.biometrics.BiometricSourceType
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.Dumpable
import com.android.systemui.biometrics.AuthController
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.dump.DumpManager
import java.io.PrintWriter
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FailedFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn

/** Encapsulates state about device entry fingerprint auth mechanism. */
interface DeviceEntryFingerprintAuthRepository {
    /** Whether the device entry fingerprint auth is locked out. */
    val isLockedOut: StateFlow<Boolean>
    val isLockedOut: Flow<Boolean>

    /**
     * Whether the fingerprint sensor is currently listening, this doesn't mean that the user is
@@ -53,6 +55,9 @@ interface DeviceEntryFingerprintAuthRepository {
     * Fingerprint sensor type present on the device, null if fingerprint sensor is not available.
     */
    val availableFpSensorType: Flow<BiometricType?>

    /** Provide the current status of fingerprint authentication. */
    val authenticationStatus: Flow<FingerprintAuthenticationStatus>
}

/**
@@ -69,16 +74,7 @@ constructor(
    val authController: AuthController,
    val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    @Application scope: CoroutineScope,
    dumpManager: DumpManager,
) : DeviceEntryFingerprintAuthRepository, Dumpable {

    init {
        dumpManager.registerDumpable(this)
    }

    override fun dump(pw: PrintWriter, args: Array<String?>) {
        pw.println("isLockedOut=${isLockedOut.value}")
    }
) : DeviceEntryFingerprintAuthRepository {

    override val availableFpSensorType: Flow<BiometricType?>
        get() {
@@ -114,7 +110,7 @@ constructor(
        else if (authController.isRearFpsSupported) BiometricType.REAR_FINGERPRINT else null
    }

    override val isLockedOut: StateFlow<Boolean> =
    override val isLockedOut: Flow<Boolean> =
        conflatedCallbackFlow {
                val sendLockoutUpdate =
                    fun() {
@@ -138,7 +134,7 @@ constructor(
                sendLockoutUpdate()
                awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
            }
            .stateIn(scope, started = SharingStarted.Eagerly, initialValue = false)
            .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)

    override val isRunning: Flow<Boolean>
        get() = conflatedCallbackFlow {
@@ -166,6 +162,93 @@ constructor(
            awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
        }

    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,
                            ),
                        )
                    }

                    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 onBiometricAuthFailed(
                        biometricSourceType: BiometricSourceType,
                    ) {
                        sendUpdateIfFingerprint(
                            biometricSourceType,
                            FailedFingerprintAuthenticationStatus,
                        )
                    }

                    override fun onBiometricAcquired(
                        biometricSourceType: BiometricSourceType,
                        acquireInfo: Int,
                    ) {
                        sendUpdateIfFingerprint(
                            biometricSourceType,
                            AcquiredFingerprintAuthenticationStatus(
                                acquireInfo,
                            ),
                        )
                    }

                    private fun sendUpdateIfFingerprint(
                        biometricSourceType: BiometricSourceType,
                        authenticationStatus: FingerprintAuthenticationStatus
                    ) {
                        if (biometricSourceType != BiometricSourceType.FINGERPRINT) {
                            return
                        }

                        trySendWithFailureLogging(
                            authenticationStatus,
                            TAG,
                            "new fingerprint authentication status"
                        )
                    }
                }
            keyguardUpdateMonitor.registerCallback(callback)
            awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
        }

    companion object {
        const val TAG = "DeviceEntryFingerprintAuthRepositoryImpl"
    }
+4 −4
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@ package com.android.systemui.keyguard.data.repository

import com.android.keyguard.FaceAuthUiEvent
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.AuthenticationStatus
import com.android.systemui.keyguard.shared.model.DetectionStatus
import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FaceDetectionStatus
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -40,10 +40,10 @@ class NoopDeviceEntryFaceAuthRepository @Inject constructor() : DeviceEntryFaceA
    private val _canRunFaceAuth = MutableStateFlow(false)
    override val canRunFaceAuth: StateFlow<Boolean> = _canRunFaceAuth

    override val authenticationStatus: Flow<AuthenticationStatus>
    override val authenticationStatus: Flow<FaceAuthenticationStatus>
        get() = emptyFlow()

    override val detectionStatus: Flow<DetectionStatus>
    override val detectionStatus: Flow<FaceDetectionStatus>
        get() = emptyFlow()

    private val _isLockedOut = MutableStateFlow(false)
Loading