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

Commit 3ae39673 authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Run face auth when bouncer is about to show

There may be a delay in showing the bouncer UI (~500ms)
to give face auth the opportunity to succeed
before showing the full bouncer UI. This CL makes sure
face auth begins before that 500ms delay, not after.

Fixes: 388363324
Flag: EXEMPT bugfix
Test: atest SystemUIDeviceEntryFaceAuthInteractorTest
Change-Id: Icf5c97aa8cadd76e26ea25046222b2aa483d072f
parent 887968cb
Loading
Loading
Loading
Loading
+20 −0
Original line number Original line Diff line number Diff line
@@ -322,6 +322,26 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN, false))
                .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN, false))
        }
        }


    @Test
    fun faceAuthIsRequestedWhenPrimaryBouncerIsAboutToShow() =
        testScope.runTest {
            underTest.start()

            bouncerRepository.setPrimaryShowingSoon(false)
            runCurrent()

            bouncerRepository.setPrimaryShowingSoon(true)

            runCurrent()
            assertThat(faceAuthRepository.runningAuthRequest.value)
                .isEqualTo(
                    Pair(
                        FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN,
                        false,
                    )
                )
        }

    @Test
    @Test
    @EnableSceneContainer
    @EnableSceneContainer
    fun withSceneContainerEnabled_faceAuthIsRequestedWhenPrimaryBouncerIsVisible() =
    fun withSceneContainerEnabled_faceAuthIsRequestedWhenPrimaryBouncerIsVisible() =
+1 −0
Original line number Original line Diff line number Diff line
@@ -96,6 +96,7 @@ constructor(
    val userRequestedBouncerWhenAlreadyAuthenticated: Flow<Int> =
    val userRequestedBouncerWhenAlreadyAuthenticated: Flow<Int> =
        repository.userRequestedBouncerWhenAlreadyAuthenticated.filterNotNull()
        repository.userRequestedBouncerWhenAlreadyAuthenticated.filterNotNull()
    val isShowing: StateFlow<Boolean> = repository.primaryBouncerShow
    val isShowing: StateFlow<Boolean> = repository.primaryBouncerShow
    val isShowingSoon: StateFlow<Boolean> = repository.primaryBouncerShowingSoon
    val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {}
    val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {}
    val isBackButtonEnabled: Flow<Boolean> = repository.isBackButtonEnabled.filterNotNull()
    val isBackButtonEnabled: Flow<Boolean> = repository.isBackButtonEnabled.filterNotNull()
    val showMessage: Flow<BouncerShowMessageModel> = repository.showMessage.filterNotNull()
    val showMessage: Flow<BouncerShowMessageModel> = repository.showMessage.filterNotNull()
+15 −0
Original line number Original line Diff line number Diff line
@@ -127,6 +127,17 @@ constructor(
            }
            }
            .launchIn(applicationScope)
            .launchIn(applicationScope)


        isBouncerShowingSoon
            .whenItFlipsToTrue()
            .onEach {
                faceAuthenticationLogger.bouncerShowingSoon()
                runFaceAuth(
                    FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN,
                    fallbackToDetect = false,
                )
            }
            .launchIn(applicationScope)

        alternateBouncerInteractor.isVisible
        alternateBouncerInteractor.isVisible
            .whenItFlipsToTrue()
            .whenItFlipsToTrue()
            .onEach {
            .onEach {
@@ -254,6 +265,10 @@ constructor(
        }
        }
    }
    }


    private val isBouncerShowingSoon: Flow<Boolean> by lazy {
        primaryBouncerInteractor.get().isShowingSoon
    }

    private suspend fun resetLockedOutState(currentUserId: Int) {
    private suspend fun resetLockedOutState(currentUserId: Int) {
        val lockoutMode = facePropertyRepository.getLockoutMode(currentUserId)
        val lockoutMode = facePropertyRepository.getLockoutMode(currentUserId)
        repository.setLockedOut(
        repository.setLockedOut(
+4 −3
Original line number Original line Diff line number Diff line
@@ -95,7 +95,8 @@ private object InternalFaceAuthReasons {
    const val ALTERNATE_BIOMETRIC_BOUNCER_SHOWN = "Face auth due to alternate bouncer shown."
    const val ALTERNATE_BIOMETRIC_BOUNCER_SHOWN = "Face auth due to alternate bouncer shown."
    const val PRIMARY_BOUNCER_SHOWN = "Face auth started/stopped due to primary bouncer shown."
    const val PRIMARY_BOUNCER_SHOWN = "Face auth started/stopped due to primary bouncer shown."
    const val PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN =
    const val PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN =
        "Face auth started/stopped due to bouncer being shown or will be shown."
        "Face auth started/stopped due to bouncer being shown or will be shown. For example," +
            "the bouncer contents may show with an intentional delay."
    const val TRUST_DISABLED = "Face auth started due to trust disabled."
    const val TRUST_DISABLED = "Face auth started due to trust disabled."
    const val TRUST_ENABLED = "Face auth stopped due to trust enabled."
    const val TRUST_ENABLED = "Face auth stopped due to trust enabled."
    const val KEYGUARD_OCCLUSION_CHANGED =
    const val KEYGUARD_OCCLUSION_CHANGED =
@@ -164,7 +165,7 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
    @UiEvent(doc = PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN)
    @UiEvent(doc = PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN)
    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN(
    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN(
        1197,
        1197,
        PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
        PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN,
    ),
    ),
    @UiEvent(doc = RETRY_AFTER_HW_UNAVAILABLE)
    @UiEvent(doc = RETRY_AFTER_HW_UNAVAILABLE)
    FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE(1156, RETRY_AFTER_HW_UNAVAILABLE),
    FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE(1156, RETRY_AFTER_HW_UNAVAILABLE),
@@ -186,7 +187,7 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
        ReplaceWith(
        ReplaceWith(
            "FACE_AUTH_UPDATED_STARTED_WAKING_UP, " +
            "FACE_AUTH_UPDATED_STARTED_WAKING_UP, " +
                "extraInfo=PowerManager.WAKE_REASON_DREAM_FINISHED"
                "extraInfo=PowerManager.WAKE_REASON_DREAM_FINISHED"
        )
        ),
    )
    )
    @UiEvent(doc = DREAM_STOPPED)
    @UiEvent(doc = DREAM_STOPPED)
    FACE_AUTH_TRIGGERED_DREAM_STOPPED(1162, DREAM_STOPPED),
    FACE_AUTH_TRIGGERED_DREAM_STOPPED(1162, DREAM_STOPPED),
+26 −25
Original line number Original line Diff line number Diff line
@@ -25,11 +25,7 @@ private const val TAG = "DeviceEntryFaceAuthRepositoryLog"
 * ```
 * ```
 */
 */
@SysUISingleton
@SysUISingleton
class FaceAuthenticationLogger
class FaceAuthenticationLogger @Inject constructor(@FaceAuthLog private val logBuffer: LogBuffer) {
@Inject
constructor(
    @FaceAuthLog private val logBuffer: LogBuffer,
) {


    fun ignoredWakeupReason(lastWakeReason: WakeSleepReason) {
    fun ignoredWakeupReason(lastWakeReason: WakeSleepReason) {
        logBuffer.log(
        logBuffer.log(
@@ -39,9 +35,10 @@ constructor(
            {
            {
                "Ignoring off/aod/dozing -> Lockscreen transition " +
                "Ignoring off/aod/dozing -> Lockscreen transition " +
                    "because the last wake up reason is not allow-listed: $str1"
                    "because the last wake up reason is not allow-listed: $str1"
            }
            },
        )
        )
    }
    }

    fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent?, ignoredReason: String) {
    fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent?, ignoredReason: String) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
@@ -50,7 +47,7 @@ constructor(
                str1 = "${uiEvent?.reason}"
                str1 = "${uiEvent?.reason}"
                str2 = ignoredReason
                str2 = ignoredReason
            },
            },
            { "Ignoring trigger because $str2, Trigger reason: $str1" }
            { "Ignoring trigger because $str2, Trigger reason: $str1" },
        )
        )
    }
    }


@@ -60,7 +57,7 @@ constructor(


    fun detectionNotSupported(
    fun detectionNotSupported(
        faceManager: FaceManager?,
        faceManager: FaceManager?,
        sensorPropertiesInternal: MutableList<FaceSensorPropertiesInternal>?
        sensorPropertiesInternal: MutableList<FaceSensorPropertiesInternal>?,
    ) {
    ) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
@@ -75,7 +72,7 @@ constructor(
                    "faceManager isNull: $bool1, " +
                    "faceManager isNull: $bool1, " +
                    "sensorPropertiesInternal isNullOrEmpty: $bool2, " +
                    "sensorPropertiesInternal isNullOrEmpty: $bool2, " +
                    "supportsFaceDetection: $bool3"
                    "supportsFaceDetection: $bool3"
            }
            },
        )
        )
    }
    }


@@ -90,7 +87,7 @@ constructor(
            {
            {
                "Skipping running detection: isAuthRunning: $bool1, " +
                "Skipping running detection: isAuthRunning: $bool1, " +
                    "detectCancellationNotNull: $bool2"
                    "detectCancellationNotNull: $bool2"
            }
            },
        )
        )
    }
    }


@@ -106,7 +103,7 @@ constructor(
        isAuthRunning: Boolean,
        isAuthRunning: Boolean,
        isLockedOut: Boolean,
        isLockedOut: Boolean,
        cancellationInProgress: Boolean,
        cancellationInProgress: Boolean,
        faceAuthRequestedWhileCancellation: FaceAuthUiEvent?
        faceAuthRequestedWhileCancellation: FaceAuthUiEvent?,
    ) {
    ) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
@@ -124,7 +121,7 @@ constructor(
                    "isLockedOut: $bool2, " +
                    "isLockedOut: $bool2, " +
                    "cancellationInProgress: $bool3, " +
                    "cancellationInProgress: $bool3, " +
                    "faceAuthRequestedWhileCancellation: $str1"
                    "faceAuthRequestedWhileCancellation: $str1"
            }
            },
        )
        )
    }
    }


@@ -140,7 +137,7 @@ constructor(
        errorCode: Int,
        errorCode: Int,
        errString: CharSequence?,
        errString: CharSequence?,
        lockoutError: Boolean,
        lockoutError: Boolean,
        cancellationError: Boolean
        cancellationError: Boolean,
    ) {
    ) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
@@ -156,7 +153,7 @@ constructor(
                    "errString: $str1, " +
                    "errString: $str1, " +
                    "isLockoutError: $bool1, " +
                    "isLockoutError: $bool1, " +
                    "isCancellationError: $bool2"
                    "isCancellationError: $bool2"
            }
            },
        )
        )
    }
    }


@@ -168,7 +165,7 @@ constructor(
                int1 = result.userId
                int1 = result.userId
                bool1 = result.isStrongBiometric
                bool1 = result.isStrongBiometric
            },
            },
            { "Face authenticated successfully: userId: $int1, isStrongBiometric: $bool1" }
            { "Face authenticated successfully: userId: $int1, isStrongBiometric: $bool1" },
        )
        )
    }
    }


@@ -188,6 +185,10 @@ constructor(
        logBuffer.log(TAG, DEBUG, "Triggering face auth because primary bouncer is visible")
        logBuffer.log(TAG, DEBUG, "Triggering face auth because primary bouncer is visible")
    }
    }


    fun bouncerShowingSoon() {
        logBuffer.log(TAG, DEBUG, "Triggering face auth because primary bouncer will show soon")
    }

    fun alternateBouncerVisibilityChanged() {
    fun alternateBouncerVisibilityChanged() {
        logBuffer.log(TAG, DEBUG, "Triggering face auth because alternate bouncer is visible")
        logBuffer.log(TAG, DEBUG, "Triggering face auth because alternate bouncer is visible")
    }
    }
@@ -197,7 +198,7 @@ constructor(
            TAG,
            TAG,
            DEBUG,
            DEBUG,
            { str1 = "${wake?.lastWakeReason}" },
            { str1 = "${wake?.lastWakeReason}" },
            { "Triggering face auth because lockscreen became visible due to wake reason: $str1" }
            { "Triggering face auth because lockscreen became visible due to wake reason: $str1" },
        )
        )
    }
    }


@@ -210,7 +211,7 @@ constructor(
            TAG,
            TAG,
            DEBUG,
            DEBUG,
            { str1 = uiEvent.reason },
            { str1 = uiEvent.reason },
            { "Requesting face auth for trigger: $str1" }
            { "Requesting face auth for trigger: $str1" },
        )
        )
    }
    }


@@ -222,7 +223,7 @@ constructor(
                str1 = "${errorStatus.msg}"
                str1 = "${errorStatus.msg}"
                int1 = errorStatus.msgId
                int1 = errorStatus.msgId
            },
            },
            { "Received face hardware error: $str1 , code: $int1" }
            { "Received face hardware error: $str1 , code: $int1" },
        )
        )
    }
    }


@@ -231,7 +232,7 @@ constructor(
            TAG,
            TAG,
            DEBUG,
            DEBUG,
            { int1 = retryCount },
            { int1 = retryCount },
            { "Attempting face auth again because of HW error: retry attempt $int1" }
            { "Attempting face auth again because of HW error: retry attempt $int1" },
        )
        )
    }
    }


@@ -251,7 +252,7 @@ constructor(
                str1 = "$uiEvent"
                str1 = "$uiEvent"
                bool1 = fallbackToDetection
                bool1 = fallbackToDetection
            },
            },
            { "Queueing $str1 request for face auth, fallbackToDetection: $bool1" }
            { "Queueing $str1 request for face auth, fallbackToDetection: $bool1" },
        )
        )
    }
    }


@@ -259,7 +260,7 @@ constructor(
        uiEvent: FaceAuthUiEvent?,
        uiEvent: FaceAuthUiEvent?,
        canRunAuth: Boolean,
        canRunAuth: Boolean,
        canRunDetect: Boolean,
        canRunDetect: Boolean,
        cancelInProgress: Boolean
        cancelInProgress: Boolean,
    ) {
    ) {
        uiEvent?.let {
        uiEvent?.let {
            logBuffer.log(
            logBuffer.log(
@@ -276,7 +277,7 @@ constructor(
                        "canRunAuth: $bool1, " +
                        "canRunAuth: $bool1, " +
                        "canRunDetect: $bool2, " +
                        "canRunDetect: $bool2, " +
                        "cancelInProgress: $bool3"
                        "cancelInProgress: $bool3"
                }
                },
            )
            )
        }
        }
    }
    }
@@ -289,14 +290,14 @@ constructor(
                str1 = "${uiEvent?.reason}"
                str1 = "${uiEvent?.reason}"
                bool1 = fallbackToDetection
                bool1 = fallbackToDetection
            },
            },
            { "Processing face auth request: $str1, fallbackToDetect: $bool1" }
            { "Processing face auth request: $str1, fallbackToDetect: $bool1" },
        )
        )
    }
    }


    fun clearingPendingAuthRequest(
    fun clearingPendingAuthRequest(
        @CompileTimeConstant loggingContext: String,
        @CompileTimeConstant loggingContext: String,
        uiEvent: FaceAuthUiEvent?,
        uiEvent: FaceAuthUiEvent?,
        fallbackToDetection: Boolean?
        fallbackToDetection: Boolean?,
    ) {
    ) {
        uiEvent?.let {
        uiEvent?.let {
            logBuffer.log(
            logBuffer.log(
@@ -311,7 +312,7 @@ constructor(
                    "Clearing pending auth: $str1, " +
                    "Clearing pending auth: $str1, " +
                        "fallbackToDetection: $str2, " +
                        "fallbackToDetection: $str2, " +
                        "reason: $str3"
                        "reason: $str3"
                }
                },
            )
            )
        }
        }
    }
    }