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 6edf40f475218..b6a296aec3617 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 @@ -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 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 0f6d82ed4b5ce..dcd6ac4919c42 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 @@ -63,6 +63,14 @@ 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. */ 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 47c662c3b4b02..a09f7b9e787e6 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 @@ -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 @@ -450,6 +451,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 {