summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chandru S <chandruis@google.com> 2023-04-17 19:54:52 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-04-17 19:54:52 +0000
commit0889fb51c230d2867f8fa3ccf4c8a9f51a8a3dcd (patch)
tree7cb6ff8c81536a71cb8cf65bd39516c66c47e38c
parente47c0ec08586b227b746622709d8e1434bc82905 (diff)
parent0d775341acabae950eff92f336d57ddab2d03e0e (diff)
Merge "Retry face auth whenever there is a hardware error" into udc-dev
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt21
4 files changed, 92 insertions, 8 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 5f6098b8758f..05ab01bf2b9a 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
@@ -140,8 +140,10 @@ constructor(
private var authCancellationSignal: CancellationSignal? = null
private var detectCancellationSignal: CancellationSignal? = null
private var faceAcquiredInfoIgnoreList: Set<Int>
+ private var retryCount = 0
private var cancelNotReceivedHandlerJob: Job? = null
+ private var halErrorRetryJob: Job? = null
private val _authenticationStatus: MutableStateFlow<AuthenticationStatus?> =
MutableStateFlow(null)
@@ -228,6 +230,8 @@ constructor(
.onEach { goingAwayOrUserSwitchingInProgress ->
if (goingAwayOrUserSwitchingInProgress) {
_isAuthenticated.value = false
+ retryCount = 0
+ halErrorRetryJob?.cancel()
}
}
.launchIn(applicationScope)
@@ -385,14 +389,11 @@ constructor(
_authenticationStatus.value = errorStatus
_isAuthenticated.value = false
if (errorStatus.isCancellationError()) {
- cancelNotReceivedHandlerJob?.cancel()
- applicationScope.launch {
- faceAuthLogger.launchingQueuedFaceAuthRequest(
- faceAuthRequestedWhileCancellation
- )
- faceAuthRequestedWhileCancellation?.let { authenticate(it) }
- faceAuthRequestedWhileCancellation = null
- }
+ handleFaceCancellationError()
+ }
+ if (errorStatus.isHardwareError()) {
+ faceAuthLogger.hardwareError(errorStatus)
+ handleFaceHardwareError()
}
faceAuthLogger.authenticationError(
errorCode,
@@ -418,6 +419,35 @@ constructor(
}
}
+ private fun handleFaceCancellationError() {
+ cancelNotReceivedHandlerJob?.cancel()
+ applicationScope.launch {
+ faceAuthRequestedWhileCancellation?.let {
+ faceAuthLogger.launchingQueuedFaceAuthRequest(it)
+ authenticate(it)
+ }
+ faceAuthRequestedWhileCancellation = null
+ }
+ }
+
+ private fun handleFaceHardwareError() {
+ if (retryCount < HAL_ERROR_RETRY_MAX) {
+ retryCount++
+ halErrorRetryJob?.cancel()
+ halErrorRetryJob =
+ applicationScope.launch {
+ delay(HAL_ERROR_RETRY_TIMEOUT)
+ if (retryCount < HAL_ERROR_RETRY_MAX) {
+ faceAuthLogger.attemptingRetryAfterHardwareError(retryCount)
+ authenticate(
+ FaceAuthUiEvent.FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE,
+ fallbackToDetection = false
+ )
+ }
+ }
+ }
+ }
+
private fun onFaceAuthRequestCompleted() {
cancellationInProgress = false
_isAuthRunning.value = false
@@ -558,6 +588,12 @@ constructor(
* cancelled.
*/
const val DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000L
+
+ /** Number of allowed retries whenever there is a face hardware error */
+ const val HAL_ERROR_RETRY_MAX = 20
+
+ /** Timeout before retries whenever there is a HAL error. */
+ const val HAL_ERROR_RETRY_TIMEOUT = 500L // ms
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
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 eded9c1454f2..c8bd958615cf 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
@@ -50,6 +50,11 @@ data class ErrorAuthenticationStatus(val msgId: Int, val msg: String?) : Authent
* was cancelled before it completed.
*/
fun isCancellationError() = msgId == FaceManager.FACE_ERROR_CANCELED
+
+ /** Method that checks if [msgId] is a hardware error. */
+ fun isHardwareError() =
+ msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE ||
+ msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS
}
/** Face detection success message. */
diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
index 7f6e4a903d76..efd3ad620de0 100644
--- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
@@ -4,6 +4,7 @@ import android.hardware.face.FaceManager
import android.hardware.face.FaceSensorPropertiesInternal
import com.android.keyguard.FaceAuthUiEvent
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.log.dagger.FaceAuthLog
import com.android.systemui.plugins.log.LogBuffer
@@ -239,4 +240,25 @@ constructor(
{ "Requesting face auth for trigger: $str1" }
)
}
+
+ fun hardwareError(errorStatus: ErrorAuthenticationStatus) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = "${errorStatus.msg}"
+ int1 = errorStatus.msgId
+ },
+ { "Received face hardware error: $str1 , code: $int1" }
+ )
+ }
+
+ fun attemptingRetryAfterHardwareError(retryCount: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = retryCount },
+ { "Attempting face auth again because of HW error: retry attempt $int1" }
+ )
+ }
}
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 fc75d47c01b7..a76d03b8ba93 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
@@ -21,6 +21,7 @@ import android.app.StatusBarManager.SESSION_KEYGUARD
import android.content.pm.UserInfo
import android.content.pm.UserInfo.FLAG_PRIMARY
import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE
import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
import android.hardware.biometrics.ComponentInfoInternal
import android.hardware.face.FaceAuthenticateOptions
@@ -824,6 +825,26 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
verify(faceManager).scheduleWatchdog()
}
+ @Test
+ fun retryFaceIfThereIsAHardwareError() =
+ testScope.runTest {
+ initCollectors()
+ allPreconditionsToRunFaceAuthAreTrue()
+
+ triggerFaceAuth(fallbackToDetect = false)
+ clearInvocations(faceManager)
+
+ authenticationCallback.value.onAuthenticationError(
+ FACE_ERROR_HW_UNAVAILABLE,
+ "HW unavailable"
+ )
+
+ advanceTimeBy(DeviceEntryFaceAuthRepositoryImpl.HAL_ERROR_RETRY_TIMEOUT)
+ runCurrent()
+
+ faceAuthenticateIsCalled()
+ }
+
private suspend fun TestScope.testGatingCheckForFaceAuth(gatingCheckModifier: () -> Unit) {
initCollectors()
allPreconditionsToRunFaceAuthAreTrue()