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

Commit 5e84bc9a authored by Wenhui Yang's avatar Wenhui Yang Committed by Android (Google) Code Review
Browse files

Merge "Update bp subtitle base on modality" into udc-d1-dev

parents 374edfcd b8c9fe83
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -1780,6 +1780,10 @@
    <string name="biometric_dialog_default_title">Verify it\u2019s you</string>
    <string name="biometric_dialog_default_title">Verify it\u2019s you</string>
    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face). [CHAR LIMIT=70] -->
    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face). [CHAR LIMIT=70] -->
    <string name="biometric_dialog_default_subtitle">Use your biometric to continue</string>
    <string name="biometric_dialog_default_subtitle">Use your biometric to continue</string>
    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with fingerprint. [CHAR LIMIT=70] -->
    <string name="biometric_dialog_fingerprint_subtitle">Use your fingerprint to continue</string>
    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with face. [CHAR LIMIT=70] -->
    <string name="biometric_dialog_face_subtitle">Use your face to continue</string>
    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face) or their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face) or their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
    <string name="biometric_or_screen_lock_dialog_default_subtitle">Use your biometric or screen lock to continue</string>
    <string name="biometric_or_screen_lock_dialog_default_subtitle">Use your biometric or screen lock to continue</string>


+2 −0
Original line number Original line Diff line number Diff line
@@ -2566,6 +2566,8 @@
  <java-symbol type="string" name="biometric_or_screen_lock_app_setting_name" />
  <java-symbol type="string" name="biometric_or_screen_lock_app_setting_name" />
  <java-symbol type="string" name="biometric_dialog_default_title" />
  <java-symbol type="string" name="biometric_dialog_default_title" />
  <java-symbol type="string" name="biometric_dialog_default_subtitle" />
  <java-symbol type="string" name="biometric_dialog_default_subtitle" />
  <java-symbol type="string" name="biometric_dialog_face_subtitle" />
  <java-symbol type="string" name="biometric_dialog_fingerprint_subtitle" />
  <java-symbol type="string" name="biometric_or_screen_lock_dialog_default_subtitle" />
  <java-symbol type="string" name="biometric_or_screen_lock_dialog_default_subtitle" />
  <java-symbol type="string" name="biometric_error_hw_unavailable" />
  <java-symbol type="string" name="biometric_error_hw_unavailable" />
  <java-symbol type="string" name="biometric_error_user_canceled" />
  <java-symbol type="string" name="biometric_error_user_canceled" />
+30 −17
Original line number Original line Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.server.biometrics;
package com.android.server.biometrics;


import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.hardware.biometrics.BiometricManager.Authenticators;


import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;
import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;
@@ -369,7 +371,7 @@ public class BiometricService extends SystemService {
        public boolean getConfirmationAlwaysRequired(@BiometricAuthenticator.Modality int modality,
        public boolean getConfirmationAlwaysRequired(@BiometricAuthenticator.Modality int modality,
                int userId) {
                int userId) {
            switch (modality) {
            switch (modality) {
                case BiometricAuthenticator.TYPE_FACE:
                case TYPE_FACE:
                    if (!mFaceAlwaysRequireConfirmation.containsKey(userId)) {
                    if (!mFaceAlwaysRequireConfirmation.containsKey(userId)) {
                        onChange(true /* selfChange */,
                        onChange(true /* selfChange */,
                                FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
                                FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
@@ -567,22 +569,6 @@ public class BiometricService extends SystemService {


            Utils.combineAuthenticatorBundles(promptInfo);
            Utils.combineAuthenticatorBundles(promptInfo);


            // Set the default title if necessary.
            if (promptInfo.isUseDefaultTitle()) {
                if (TextUtils.isEmpty(promptInfo.getTitle())) {
                    promptInfo.setTitle(getContext()
                            .getString(R.string.biometric_dialog_default_title));
                }
            }

            // Set the default subtitle if necessary.
            if (promptInfo.isUseDefaultSubtitle()) {
                if (TextUtils.isEmpty(promptInfo.getSubtitle())) {
                    promptInfo.setSubtitle(getContext()
                            .getString(R.string.biometric_dialog_default_subtitle));
                }
            }

            final long requestId = mRequestCounter.get();
            final long requestId = mRequestCounter.get();
            mHandler.post(() -> handleAuthenticate(
            mHandler.post(() -> handleAuthenticate(
                    token, requestId, operationId, userId, receiver, opPackageName, promptInfo));
                    token, requestId, operationId, userId, receiver, opPackageName, promptInfo));
@@ -1302,6 +1288,33 @@ public class BiometricService extends SystemService {
                        opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(),
                        opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(),
                        getContext(), mBiometricCameraManager);
                        getContext(), mBiometricCameraManager);


                // Set the default title if necessary.
                if (promptInfo.isUseDefaultTitle()) {
                    if (TextUtils.isEmpty(promptInfo.getTitle())) {
                        promptInfo.setTitle(getContext()
                                .getString(R.string.biometric_dialog_default_title));
                    }
                }

                final int eligible = preAuthInfo.getEligibleModalities();
                final boolean hasEligibleFingerprintSensor =
                        (eligible & TYPE_FINGERPRINT) == TYPE_FINGERPRINT;
                final boolean hasEligibleFaceSensor = (eligible & TYPE_FACE) == TYPE_FACE;

                // Set the subtitle according to the modality.
                if (promptInfo.isUseDefaultSubtitle()) {
                    if (hasEligibleFingerprintSensor && hasEligibleFaceSensor) {
                        promptInfo.setSubtitle(getContext()
                                .getString(R.string.biometric_dialog_default_subtitle));
                    } else if (hasEligibleFingerprintSensor) {
                        promptInfo.setSubtitle(getContext()
                                .getString(R.string.biometric_dialog_fingerprint_subtitle));
                    } else if (hasEligibleFaceSensor) {
                        promptInfo.setSubtitle(getContext()
                                .getString(R.string.biometric_dialog_face_subtitle));
                    }
                }

                final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus();
                final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus();


                Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first
                Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first
+84 −25
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.biometrics;
package com.android.server.biometrics;


import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
@@ -113,6 +114,10 @@ public class BiometricServiceTest {
    private static final String ERROR_UNABLE_TO_PROCESS = "error_unable_to_process";
    private static final String ERROR_UNABLE_TO_PROCESS = "error_unable_to_process";
    private static final String ERROR_USER_CANCELED = "error_user_canceled";
    private static final String ERROR_USER_CANCELED = "error_user_canceled";
    private static final String ERROR_LOCKOUT = "error_lockout";
    private static final String ERROR_LOCKOUT = "error_lockout";
    private static final String FACE_SUBTITLE = "face_subtitle";
    private static final String FINGERPRINT_SUBTITLE = "fingerprint_subtitle";
    private static final String DEFAULT_SUBTITLE = "default_subtitle";



    private static final String FINGERPRINT_ACQUIRED_SENSOR_DIRTY = "sensor_dirty";
    private static final String FINGERPRINT_ACQUIRED_SENSOR_DIRTY = "sensor_dirty";


@@ -191,6 +196,12 @@ public class BiometricServiceTest {
                .thenReturn(ERROR_NOT_RECOGNIZED);
                .thenReturn(ERROR_NOT_RECOGNIZED);
        when(mResources.getString(R.string.biometric_error_user_canceled))
        when(mResources.getString(R.string.biometric_error_user_canceled))
                .thenReturn(ERROR_USER_CANCELED);
                .thenReturn(ERROR_USER_CANCELED);
        when(mContext.getString(R.string.biometric_dialog_face_subtitle))
                .thenReturn(FACE_SUBTITLE);
        when(mContext.getString(R.string.biometric_dialog_fingerprint_subtitle))
                .thenReturn(FINGERPRINT_SUBTITLE);
        when(mContext.getString(R.string.biometric_dialog_default_subtitle))
                .thenReturn(DEFAULT_SUBTITLE);


        when(mWindowManager.getDefaultDisplay()).thenReturn(
        when(mWindowManager.getDefaultDisplay()).thenReturn(
                new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
                new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
@@ -211,7 +222,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testClientBinderDied_whenPaused() throws Exception {
    public void testClientBinderDied_whenPaused() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);


        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                true /* requireConfirmation */, null /* authenticators */);
                true /* requireConfirmation */, null /* authenticators */);
@@ -238,7 +249,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testClientBinderDied_whenAuthenticating() throws Exception {
    public void testClientBinderDied_whenAuthenticating() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);


        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                true /* requireConfirmation */, null /* authenticators */);
                true /* requireConfirmation */, null /* authenticators */);
@@ -374,7 +385,7 @@ public class BiometricServiceTest {


        final int[] modalities = new int[] {
        final int[] modalities = new int[] {
                TYPE_FINGERPRINT,
                TYPE_FINGERPRINT,
                BiometricAuthenticator.TYPE_FACE,
                TYPE_FACE,
        };
        };


        final int[] strengths = new int[] {
        final int[] strengths = new int[] {
@@ -426,10 +437,57 @@ public class BiometricServiceTest {
                eq(0 /* vendorCode */));
                eq(0 /* vendorCode */));
    }
    }


    @Test
    public void testAuthenticateFace_shouldShowSubtitleForFace() throws Exception {
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);

        invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */,
                null);
        waitForIdle();

        assertEquals(FACE_SUBTITLE, mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
    }

    @Test
    public void testAuthenticateFingerprint_shouldShowSubtitleForFingerprint() throws Exception {
        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);

        invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */,
                null);
        waitForIdle();

        assertEquals(FINGERPRINT_SUBTITLE,
                mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
    }

    @Test
    public void testAuthenticateBothFpAndFace_shouldShowDefaultSubtitle() throws Exception {
        final int[] modalities = new int[] {
                TYPE_FINGERPRINT,
                TYPE_FACE,
        };

        final int[] strengths = new int[] {
                Authenticators.BIOMETRIC_WEAK,
                Authenticators.BIOMETRIC_STRONG,
        };

        setupAuthForMultiple(modalities, strengths);

        invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */,
                null);
        waitForIdle();

        assertEquals(DEFAULT_SUBTITLE, mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
    }

    @Test
    @Test
    public void testAuthenticateFace_respectsUserSetting()
    public void testAuthenticateFace_respectsUserSetting()
            throws Exception {
            throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);


        // Disabled in user settings receives onError
        // Disabled in user settings receives onError
        when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
        when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
@@ -568,7 +626,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testAuthenticate_noBiometrics_credentialAllowed() throws Exception {
    public void testAuthenticate_noBiometrics_credentialAllowed() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
        when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
                .thenReturn(true);
                .thenReturn(true);
@@ -595,13 +653,13 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testAuthenticate_happyPathWithConfirmation_strongBiometric() throws Exception {
    public void testAuthenticate_happyPathWithConfirmation_strongBiometric() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        testAuthenticate_happyPathWithConfirmation(true /* isStrongBiometric */);
        testAuthenticate_happyPathWithConfirmation(true /* isStrongBiometric */);
    }
    }


    @Test
    @Test
    public void testAuthenticate_happyPathWithConfirmation_weakBiometric() throws Exception {
    public void testAuthenticate_happyPathWithConfirmation_weakBiometric() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_WEAK);
        testAuthenticate_happyPathWithConfirmation(false /* isStrongBiometric */);
        testAuthenticate_happyPathWithConfirmation(false /* isStrongBiometric */);
    }
    }


@@ -637,7 +695,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testAuthenticate_no_Biometrics_noCredential() throws Exception {
    public void testAuthenticate_no_Biometrics_noCredential() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
        when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
                .thenReturn(false);
                .thenReturn(false);
@@ -655,7 +713,7 @@ public class BiometricServiceTest {
    @Test
    @Test
    public void testRejectFace_whenAuthenticating_notifiesSystemUIAndClient_thenPaused()
    public void testRejectFace_whenAuthenticating_notifiesSystemUIAndClient_thenPaused()
            throws Exception {
            throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */, null /* authenticators */);
                false /* requireConfirmation */, null /* authenticators */);


@@ -663,7 +721,7 @@ public class BiometricServiceTest {
        waitForIdle();
        waitForIdle();


        verify(mBiometricService.mStatusBarService).onBiometricError(
        verify(mBiometricService.mStatusBarService).onBiometricError(
                eq(BiometricAuthenticator.TYPE_FACE),
                eq(TYPE_FACE),
                eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
                eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
                eq(0 /* vendorCode */));
                eq(0 /* vendorCode */));
        verify(mReceiver1).onAuthenticationFailed();
        verify(mReceiver1).onAuthenticationFailed();
@@ -691,7 +749,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testRequestAuthentication_whenAlreadyAuthenticating() throws Exception {
    public void testRequestAuthentication_whenAlreadyAuthenticating() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */, null /* authenticators */);
                false /* requireConfirmation */, null /* authenticators */);


@@ -700,7 +758,7 @@ public class BiometricServiceTest {
        waitForIdle();
        waitForIdle();


        verify(mReceiver1).onError(
        verify(mReceiver1).onError(
                eq(BiometricAuthenticator.TYPE_FACE),
                eq(TYPE_FACE),
                eq(BiometricPrompt.BIOMETRIC_ERROR_CANCELED),
                eq(BiometricPrompt.BIOMETRIC_ERROR_CANCELED),
                eq(0) /* vendorCode */);
                eq(0) /* vendorCode */);
        verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
        verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
@@ -710,7 +768,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testErrorHalTimeout_whenAuthenticating_entersPausedState() throws Exception {
    public void testErrorHalTimeout_whenAuthenticating_entersPausedState() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */, null /* authenticators */);
                false /* requireConfirmation */, null /* authenticators */);


@@ -723,7 +781,7 @@ public class BiometricServiceTest {


        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
        verify(mBiometricService.mStatusBarService).onBiometricError(
        verify(mBiometricService.mStatusBarService).onBiometricError(
                eq(BiometricAuthenticator.TYPE_FACE),
                eq(TYPE_FACE),
                eq(BiometricConstants.BIOMETRIC_ERROR_TIMEOUT),
                eq(BiometricConstants.BIOMETRIC_ERROR_TIMEOUT),
                eq(0 /* vendorCode */));
                eq(0 /* vendorCode */));
        // Timeout does not count as fail as per BiometricPrompt documentation.
        // Timeout does not count as fail as per BiometricPrompt documentation.
@@ -759,7 +817,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testErrorFromHal_whenPaused_notifiesSystemUIAndClient() throws Exception {
    public void testErrorFromHal_whenPaused_notifiesSystemUIAndClient() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */, null /* authenticators */);
                false /* requireConfirmation */, null /* authenticators */);


@@ -777,7 +835,7 @@ public class BiometricServiceTest {


        // Client receives error immediately
        // Client receives error immediately
        verify(mReceiver1).onError(
        verify(mReceiver1).onError(
                eq(BiometricAuthenticator.TYPE_FACE),
                eq(TYPE_FACE),
                eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
                eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
                eq(0 /* vendorCode */));
                eq(0 /* vendorCode */));
        // Dialog is hidden immediately
        // Dialog is hidden immediately
@@ -926,7 +984,7 @@ public class BiometricServiceTest {
            int biometricPromptError) throws Exception {
            int biometricPromptError) throws Exception {
        final int[] modalities = new int[] {
        final int[] modalities = new int[] {
                TYPE_FINGERPRINT,
                TYPE_FINGERPRINT,
                BiometricAuthenticator.TYPE_FACE,
                TYPE_FACE,
        };
        };


        final int[] strengths = new int[] {
        final int[] strengths = new int[] {
@@ -1123,7 +1181,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testDismissedReasonNegative_whilePaused_invokeHalCancel() throws Exception {
    public void testDismissedReasonNegative_whilePaused_invokeHalCancel() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */, null /* authenticators */);
                false /* requireConfirmation */, null /* authenticators */);


@@ -1142,7 +1200,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testDismissedReasonUserCancel_whilePaused_invokesHalCancel() throws Exception {
    public void testDismissedReasonUserCancel_whilePaused_invokesHalCancel() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                false /* requireConfirmation */, null /* authenticators */);
                false /* requireConfirmation */, null /* authenticators */);


@@ -1161,7 +1219,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testDismissedReasonUserCancel_whenPendingConfirmation() throws Exception {
    public void testDismissedReasonUserCancel_whenPendingConfirmation() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
        invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                true /* requireConfirmation */, null /* authenticators */);
                true /* requireConfirmation */, null /* authenticators */);


@@ -1175,7 +1233,7 @@ public class BiometricServiceTest {
        verify(mBiometricService.mSensors.get(0).impl)
        verify(mBiometricService.mSensors.get(0).impl)
                .cancelAuthenticationFromService(any(), any(), anyLong());
                .cancelAuthenticationFromService(any(), any(), anyLong());
        verify(mReceiver1).onError(
        verify(mReceiver1).onError(
                eq(BiometricAuthenticator.TYPE_FACE),
                eq(TYPE_FACE),
                eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
                eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
                eq(0 /* vendorCode */));
                eq(0 /* vendorCode */));
        verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
        verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
@@ -1296,7 +1354,7 @@ public class BiometricServiceTest {


    @Test
    @Test
    public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
    public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
        when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
                .thenReturn(true);
                .thenReturn(true);
@@ -1590,7 +1648,7 @@ public class BiometricServiceTest {
    @Test
    @Test
    public void testWorkAuthentication_faceWorksIfNotDisabledByDevicePolicyManager()
    public void testWorkAuthentication_faceWorksIfNotDisabledByDevicePolicyManager()
            throws Exception {
            throws Exception {
        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        when(mDevicePolicyManager
        when(mDevicePolicyManager
                .getKeyguardDisabledFeatures(any() /* admin*/, anyInt() /* userHandle */))
                .getKeyguardDisabledFeatures(any() /* admin*/, anyInt() /* userHandle */))
                .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FACE);
                .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FACE);
@@ -1683,7 +1741,7 @@ public class BiometricServiceTest {
                    mFingerprintAuthenticator);
                    mFingerprintAuthenticator);
        }
        }


        if ((modality & BiometricAuthenticator.TYPE_FACE) != 0) {
        if ((modality & TYPE_FACE) != 0) {
            when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(enrolled);
            when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(enrolled);
            when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
            when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
            when(mFaceAuthenticator.getLockoutModeForUser(anyInt()))
            when(mFaceAuthenticator.getLockoutModeForUser(anyInt()))
@@ -1715,7 +1773,7 @@ public class BiometricServiceTest {
                        strength, mFingerprintAuthenticator);
                        strength, mFingerprintAuthenticator);
            }
            }


            if ((modality & BiometricAuthenticator.TYPE_FACE) != 0) {
            if ((modality & TYPE_FACE) != 0) {
                when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
                when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
                when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
                when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
                mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality,
                mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality,
@@ -1798,6 +1856,7 @@ public class BiometricServiceTest {
            boolean checkDevicePolicy) {
            boolean checkDevicePolicy) {
        final PromptInfo promptInfo = new PromptInfo();
        final PromptInfo promptInfo = new PromptInfo();
        promptInfo.setConfirmationRequested(requireConfirmation);
        promptInfo.setConfirmationRequested(requireConfirmation);
        promptInfo.setUseDefaultSubtitle(true);


        if (authenticators != null) {
        if (authenticators != null) {
            promptInfo.setAuthenticators(authenticators);
            promptInfo.setAuthenticators(authenticators);