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

Commit d44c9cec authored by Hao Dong's avatar Hao Dong Committed by Automerger Merge Worker
Browse files

Merge "Do not ignore lockout error from face if it's class3." into udc-dev am: 022e333a

parents dc508b07 022e333a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1970,8 +1970,8 @@
    <string name="face_error_user_canceled">Face Unlock canceled by user</string>
    <!-- Generic error message shown when the face operation fails because too many attempts have been made. [CHAR LIMIT=50] -->
    <string name="face_error_lockout">Too many attempts. Try again later.</string>
    <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=90] -->
    <string name="face_error_lockout_permanent">Too many attempts. Face Unlock disabled.</string>
    <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=100] -->
    <string name="face_error_lockout_permanent">Too many attempts. Face Unlock unavailable.</string>
    <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=90] -->
    <string name="face_error_lockout_screen_lock">Too many attempts. Enter screen lock instead.</string>
    <!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] -->
+16 −1
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.biometrics
import android.content.Context
import android.hardware.biometrics.BiometricAuthenticator.Modality
import android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE
import android.hardware.biometrics.BiometricConstants
import android.hardware.face.FaceManager
import android.util.AttributeSet
import com.android.systemui.R

@@ -27,6 +29,7 @@ class AuthBiometricFingerprintAndFaceView(
    context: Context,
    attrs: AttributeSet?
) : AuthBiometricFingerprintView(context, attrs) {
    var isFaceClass3 = false

    constructor (context: Context) : this(context, null)

@@ -34,10 +37,22 @@ class AuthBiometricFingerprintAndFaceView(

    override fun forceRequireConfirmation(@Modality modality: Int) = modality == TYPE_FACE

    override fun ignoreUnsuccessfulEventsFrom(@Modality modality: Int) = modality == TYPE_FACE
    override fun ignoreUnsuccessfulEventsFrom(@Modality modality: Int, unsuccessfulReason: String) =
        modality == TYPE_FACE && !(isFaceClass3 && isLockoutErrorString(unsuccessfulReason))

    override fun onPointerDown(failedModalities: Set<Int>) = failedModalities.contains(TYPE_FACE)

    override fun createIconController(): AuthIconController =
        AuthBiometricFingerprintAndFaceIconController(mContext, mIconView, mIconViewOverlay)

    private fun isLockoutErrorString(unsuccessfulReason: String) =
        unsuccessfulReason == FaceManager.getErrorString(
            mContext,
            BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
            0 /*vendorCode */
        ) || unsuccessfulReason == FaceManager.getErrorString(
            mContext,
            BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
            0 /*vendorCode */
        )
}
+5 −4
Original line number Diff line number Diff line
@@ -258,7 +258,8 @@ public abstract class AuthBiometricView extends LinearLayout {
    }

    /** Ignore all events from this (secondary) modality except successful authentication. */
    protected boolean ignoreUnsuccessfulEventsFrom(@Modality int modality) {
    protected boolean ignoreUnsuccessfulEventsFrom(@Modality int modality,
            String unsuccessfulReason) {
        return false;
    }

@@ -541,7 +542,7 @@ public abstract class AuthBiometricView extends LinearLayout {
     */
    public void onAuthenticationFailed(
            @Modality int modality, @Nullable String failureReason) {
        if (ignoreUnsuccessfulEventsFrom(modality)) {
        if (ignoreUnsuccessfulEventsFrom(modality, failureReason)) {
            return;
        }

@@ -556,7 +557,7 @@ public abstract class AuthBiometricView extends LinearLayout {
     * @param error message
     */
    public void onError(@Modality int modality, String error) {
        if (ignoreUnsuccessfulEventsFrom(modality)) {
        if (ignoreUnsuccessfulEventsFrom(modality, error)) {
            return;
        }

@@ -586,7 +587,7 @@ public abstract class AuthBiometricView extends LinearLayout {
     * @param help message
     */
    public void onHelp(@Modality int modality, String help) {
        if (ignoreUnsuccessfulEventsFrom(modality)) {
        if (ignoreUnsuccessfulEventsFrom(modality, help)) {
            return;
        }
        if (mSize != AuthDialog.SIZE_MEDIUM) {
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;

import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
import static android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;

import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION;

@@ -383,6 +384,8 @@ public class AuthContainerView extends LinearLayout
                fingerprintAndFaceView.setSensorProperties(fpProperties);
                fingerprintAndFaceView.setScaleFactorProvider(config.mScaleProvider);
                fingerprintAndFaceView.updateOverrideIconLayoutParamsSize();
                fingerprintAndFaceView.setFaceClass3(
                        faceProperties.sensorStrength == STRENGTH_STRONG);
                mBiometricView = fingerprintAndFaceView;
            } else if (fpProperties != null) {
                final AuthBiometricFingerprintView fpView =
+46 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.biometrics

import android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE
import android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT
import android.hardware.biometrics.BiometricConstants
import android.hardware.face.FaceManager
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.view.View
@@ -34,6 +36,7 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.times
import org.mockito.junit.MockitoJUnit


@@ -98,7 +101,7 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
    }

    @Test
    fun ignoresFaceErrors() {
    fun ignoresFaceErrors_faceIsNotClass3_notLockoutError() {
        biometricView.onDialogAnimatedIn()
        biometricView.onError(TYPE_FACE, "not a face")
        waitForIdleSync()
@@ -113,5 +116,47 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
        verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
    }

    @Test
    fun doNotIgnoresFaceErrors_faceIsClass3_notLockoutError() {
        biometricView.isFaceClass3 = true
        biometricView.onDialogAnimatedIn()
        biometricView.onError(TYPE_FACE, "not a face")
        waitForIdleSync()

        assertThat(biometricView.isAuthenticating).isTrue()
        verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_ERROR)

        biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
        TestableLooper.get(this).moveTimeForward(1000)
        waitForIdleSync()

        verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
    }

    @Test
    fun doNotIgnoresFaceErrors_faceIsClass3_lockoutError() {
        biometricView.isFaceClass3 = true
        biometricView.onDialogAnimatedIn()
        biometricView.onError(
            TYPE_FACE,
            FaceManager.getErrorString(
                biometricView.context,
                BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
                0 /*vendorCode */
            )
        )
        waitForIdleSync()

        assertThat(biometricView.isAuthenticating).isTrue()
        verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)

        biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
        TestableLooper.get(this).moveTimeForward(1000)
        waitForIdleSync()

        verify(callback, times(2)).onAction(AuthBiometricView.Callback.ACTION_ERROR)
    }


    override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
}