Merge changes Ia4b541e0,I128b0cd6 into udc-qpr-dev

* changes:
  Resolve face detection related issues
  Repeated calls to cancel should cancel any previously scheduled cancellation timeout jobs
This commit is contained in:
Chandru S
2023-07-19 21:58:16 +00:00
committed by Android (Google) Code Review
4 changed files with 52 additions and 8 deletions

View File

@@ -1496,7 +1496,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onDetectionStatusChanged(@NonNull FaceDetectionStatus status) {
handleFaceAuthenticated(status.getUserId(), status.isStrongBiometric());
handleBiometricDetected(status.getUserId(), FACE, status.isStrongBiometric());
}
};

View File

@@ -545,11 +545,11 @@ constructor(
faceAuthLogger.detectionNotSupported(faceManager, faceManager?.sensorPropertiesInternal)
return
}
if (_isAuthRunning.value || detectCancellationSignal != null) {
if (_isAuthRunning.value) {
faceAuthLogger.skippingDetection(_isAuthRunning.value, detectCancellationSignal != null)
return
}
detectCancellationSignal?.cancel()
detectCancellationSignal = CancellationSignal()
withContext(mainDispatcher) {
// We always want to invoke face detect in the main thread.
@@ -574,6 +574,7 @@ constructor(
if (authCancellationSignal == null) return
authCancellationSignal?.cancel()
cancelNotReceivedHandlerJob?.cancel()
cancelNotReceivedHandlerJob =
applicationScope.launch {
delay(DEFAULT_CANCEL_SIGNAL_TIMEOUT)
@@ -583,6 +584,7 @@ constructor(
cancellationInProgress,
faceAuthRequestedWhileCancellation
)
_authenticationStatus.value = ErrorFaceAuthenticationStatus.cancelNotReceivedError()
onFaceAuthRequestCompleted()
}
cancellationInProgress = true

View File

@@ -23,7 +23,10 @@ import android.os.SystemClock.elapsedRealtime
* Authentication status provided by
* [com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository]
*/
sealed class FaceAuthenticationStatus
sealed class FaceAuthenticationStatus(
// present to break equality check if the same error occurs repeatedly.
val createdAt: Long = elapsedRealtime()
)
/** Success authentication status. */
data class SuccessFaceAuthenticationStatus(val successResult: FaceManager.AuthenticationResult) :
@@ -43,8 +46,6 @@ object FailedFaceAuthenticationStatus : FaceAuthenticationStatus()
data class ErrorFaceAuthenticationStatus(
val msgId: Int,
val msg: String? = null,
// present to break equality check if the same error occurs repeatedly.
val createdAt: Long = elapsedRealtime()
) : FaceAuthenticationStatus() {
/**
* Method that checks if [msgId] is a lockout error. A lockout error means that face
@@ -63,7 +64,21 @@ data class ErrorFaceAuthenticationStatus(
fun isHardwareError() =
msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE ||
msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS
companion object {
/**
* Error message that is created when cancel confirmation is not received from FaceManager
* after we request for a cancellation of face auth.
*/
fun cancelNotReceivedError() = ErrorFaceAuthenticationStatus(-1, "")
}
}
/** Face detection success message. */
data class FaceDetectionStatus(val sensorId: Int, val userId: Int, val isStrongBiometric: Boolean)
data class FaceDetectionStatus(
val sensorId: Int,
val userId: Int,
val isStrongBiometric: Boolean,
// present to break equality check if the same error occurs repeatedly.
val createdAt: Long = elapsedRealtime()
)

View File

@@ -44,6 +44,7 @@ import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepositor
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.dump.DumpManager
import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.flags.FakeFeatureFlags
@@ -385,7 +386,10 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
detectionCallback.value.onFaceDetected(1, 1, true)
assertThat(detectStatus()).isEqualTo(FaceDetectionStatus(1, 1, true))
val status = detectStatus()!!
assertThat(status.sensorId).isEqualTo(1)
assertThat(status.userId).isEqualTo(1)
assertThat(status.isStrongBiometric).isEqualTo(true)
}
@Test
@@ -450,6 +454,29 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
faceAuthenticateIsCalled()
}
@Test
fun multipleCancelCallsShouldNotCauseMultipleCancellationStatusBeingEmitted() =
testScope.runTest {
initCollectors()
allPreconditionsToRunFaceAuthAreTrue()
val emittedValues by collectValues(underTest.authenticationStatus)
underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
underTest.cancel()
advanceTimeBy(100)
underTest.cancel()
advanceTimeBy(DeviceEntryFaceAuthRepositoryImpl.DEFAULT_CANCEL_SIGNAL_TIMEOUT)
runCurrent()
advanceTimeBy(DeviceEntryFaceAuthRepositoryImpl.DEFAULT_CANCEL_SIGNAL_TIMEOUT)
runCurrent()
assertThat(emittedValues.size).isEqualTo(1)
assertThat(emittedValues.first())
.isInstanceOf(ErrorFaceAuthenticationStatus::class.java)
assertThat((emittedValues.first() as ErrorFaceAuthenticationStatus).msgId).isEqualTo(-1)
}
@Test
fun faceHelpMessagesAreIgnoredBasedOnConfig() =
testScope.runTest {