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

Commit b51b0141 authored by Shawn Lin's avatar Shawn Lin
Browse files

Fix the ring animation not showing while unfolding device

Starting state: Device is unfolded so SysUI runs face aythentication for
request #1

1. The camera changes shortly afterwards, so
   SystemUIDeviceEntryFaceAuthInteractor calls
   repository.cancel()(cancel request #1) and then runFaceAuth()(request
   #2) when the camera changes in order to restart face auth with new
       camera.(Refer to runFaceAuth with
       uiEvent:FACE_AUTH_CAMERA_AVAILABLE_CHANGED)
2. On repository.cancel (request #1) cancellationInProgress becomes
   true.
3. On runFaceAuth, a pending face auth request (request #2) is
   queued(and won't run until cancellationInProgress becomes false, see
   processPendingAuthRequests())
4. SysUI receives the callback from FingerprintManager indicating that
   request #1's lifecycle is done. In the onFaceAuthRequestCompleted
   method, cancellationInProgress is set to false which immediately
   allows face auth request #2 to start running.

The bug here is that if within onFaceAuthRequestCompleted:
cancellationInProgress is set to false before isAuthRunning is set to
false, so we end up in wrong isAuthRunning state(false instead of true).
Therefore, cancellationInProgress should be updated AFTER isAuthRunning.

Bug: 331306919
Test: atest DeviceEntryFaceAuthRepositoryTest
Flag: NONE
Change-Id: Idcb9495790cf8f8bcf5528c337bfd5ecfa915c29
(cherry picked from commit 2f2a52eb)
parent 0e2a0877
Loading
Loading
Loading
Loading
+19 −0
Original line number Original line Diff line number Diff line
@@ -1070,6 +1070,25 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
            faceAuthenticateIsCalled()
            faceAuthenticateIsCalled()
        }
        }


    @Test
    fun retryFaceAuthAfterCancel() =
        testScope.runTest {
            initCollectors()
            allPreconditionsToRunFaceAuthAreTrue()
            val isAuthRunning by collectLastValue(underTest.isAuthRunning)

            underTest.requestAuthenticate(FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED)
            underTest.cancel()
            clearInvocations(faceManager)
            underTest.requestAuthenticate(FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED)

            advanceTimeBy(DeviceEntryFaceAuthRepositoryImpl.DEFAULT_CANCEL_SIGNAL_TIMEOUT)
            runCurrent()

            assertThat(isAuthRunning).isEqualTo(true)
            faceAuthenticateIsCalled()
        }

    private suspend fun TestScope.testGatingCheckForFaceAuth(
    private suspend fun TestScope.testGatingCheckForFaceAuth(
        gatingCheckModifier: suspend () -> Unit
        gatingCheckModifier: suspend () -> Unit
    ) {
    ) {
+4 −1
Original line number Original line Diff line number Diff line
@@ -517,9 +517,12 @@ constructor(


    private fun onFaceAuthRequestCompleted() {
    private fun onFaceAuthRequestCompleted() {
        cancelNotReceivedHandlerJob?.cancel()
        cancelNotReceivedHandlerJob?.cancel()
        cancellationInProgress.value = false
        _isAuthRunning.value = false
        _isAuthRunning.value = false
        authCancellationSignal = null
        authCancellationSignal = null
        // Updates to "cancellationInProgress" may re-trigger face auth
        // (see processPendingAuthRequests()), so we must update this after setting _isAuthRunning
        // to false.
        cancellationInProgress.value = false
    }
    }


    private val detectionCallback =
    private val detectionCallback =