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

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

Launch multiple biometric enrollment when no biometric is enrolled

When a user clicks the biometric item in the Device unlock page and no
biometric is enrolled:
- Fingerint clicked: Launch fingerprint enroll then face enroll.
- Face clicked: Launch face enroll then fingerprint enroll.

Bug: 370940762
Test: atest FaceSafetySourceTest FingerprintSafetySourceTest
Flag: com.android.settings.flags.biometrics_onboarding_education
Change-Id: I874b96a75ec0c126ae1674bb6ab220a0a8533fcd
parent de3ec7e3
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -19,11 +19,15 @@ package com.android.settings.safetycenter;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.safetycenter.SafetyEvent;
import android.safetycenter.SafetySourceData;
import android.safetycenter.SafetySourceIssue;
import android.safetycenter.SafetySourceStatus;

import com.android.settings.Utils;

/** Static helpers for setting SafetyCenter data for biometric safety sources. */
public final class BiometricSourcesUtils {

@@ -89,6 +93,15 @@ public final class BiometricSourcesUtils {
                .setSafetySourceData(context, safetySourceId, safetySourceData, safetyEvent);
    }

    /** Check whether the multiple biometrics enrollment is needed. */
    public static boolean isMultipleBiometricsEnrollmentNeeded(Context context, int userId) {
        FaceManager faceManager = Utils.getFaceManagerOrNull(context);
        FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
        return Utils.isMultipleBiometricsSupported(context)
                && !faceManager.hasEnrolledTemplates(userId)
                && !fingerprintManager.hasEnrolledFingerprints(userId);
    }

    /** Helper method for creating a pending intent. */
    public static PendingIntent createPendingIntent(
            Context context, Intent intent, int requestCode) {
+14 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settings.safetycenter;

import static com.android.settings.biometrics.BiometricEnrollActivity.EXTRA_LAUNCH_FACE_ENROLL_FIRST;
import static com.android.settings.safetycenter.BiometricSourcesUtils.REQUEST_CODE_FACE_SETTING;

import android.content.Context;
@@ -27,6 +28,7 @@ import android.os.UserManager;
import android.safetycenter.SafetyEvent;

import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.BiometricNavigationUtils;
import com.android.settings.biometrics.face.FaceStatusUtils;
import com.android.settings.flags.Flags;
@@ -73,6 +75,16 @@ public final class FaceSafetySource {
        Context profileParentContext = context.createContextAsUser(profileParentUserHandle, 0);

        if (Utils.hasFaceHardware(context)) {
            boolean isMultipleBiometricsEnrollmentNeeded =
                    BiometricSourcesUtils.isMultipleBiometricsEnrollmentNeeded(context, userId);
            String settingClassName = isMultipleBiometricsEnrollmentNeeded
                    ? BiometricEnrollActivity.class.getName()
                    : faceStatusUtils.getSettingsClassName();
            Bundle bundle = new Bundle();
            if (isMultipleBiometricsEnrollmentNeeded) {
                // Launch face enrollment first then fingerprint enrollment.
                bundle.putBoolean(EXTRA_LAUNCH_FACE_ENROLL_FIRST, true);
            }
            RestrictedLockUtils.EnforcedAdmin disablingAdmin = faceStatusUtils.getDisablingAdmin();
            BiometricSourcesUtils.setBiometricSafetySourceData(
                    SAFETY_SOURCE_ID,
@@ -84,9 +96,9 @@ public final class FaceSafetySource {
                            biometricNavigationUtils
                                    .getBiometricSettingsIntent(
                                            context,
                                            faceStatusUtils.getSettingsClassName(),
                                            settingClassName,
                                            disablingAdmin,
                                            Bundle.EMPTY)
                                            bundle)
                                    .setIdentifier(Integer.toString(userId)),
                            REQUEST_CODE_FACE_SETTING),
                    disablingAdmin == null /* enabled */,
+7 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.UserManager;
import android.safetycenter.SafetyEvent;

import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.BiometricNavigationUtils;
import com.android.settings.biometrics.fingerprint.FingerprintStatusUtils;
import com.android.settings.flags.Flags;
@@ -74,6 +75,11 @@ public final class FingerprintSafetySource {
        Context profileParentContext = context.createContextAsUser(profileParentUserHandle, 0);

        if (Utils.hasFingerprintHardware(context)) {
            boolean isMultipleBiometricsEnrollmentNeeded =
                    BiometricSourcesUtils.isMultipleBiometricsEnrollmentNeeded(context, userId);
            String settingClassName = isMultipleBiometricsEnrollmentNeeded
                            ? BiometricEnrollActivity.class.getName()
                            : fingerprintStatusUtils.getSettingsClassName();
            RestrictedLockUtils.EnforcedAdmin disablingAdmin =
                    fingerprintStatusUtils.getDisablingAdmin();
            BiometricSourcesUtils.setBiometricSafetySourceData(
@@ -86,7 +92,7 @@ public final class FingerprintSafetySource {
                            biometricNavigationUtils
                                    .getBiometricSettingsIntent(
                                            context,
                                            fingerprintStatusUtils.getSettingsClassName(),
                                            settingClassName,
                                            disablingAdmin,
                                            Bundle.EMPTY)
                                    .setIdentifier(Integer.toString(userId)),
+26 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -52,6 +53,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.widget.LockPatternUtils;
import com.android.settings.Settings;
import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal;
import com.android.settings.flags.Flags;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -83,6 +85,7 @@ public class FaceSafetySourceTest {
    @Mock private PackageManager mPackageManager;
    @Mock private DevicePolicyManager mDevicePolicyManager;
    @Mock private FaceManager mFaceManager;
    @Mock private FingerprintManager mFingerprintManager;
    @Mock private LockPatternUtils mLockPatternUtils;
    @Mock private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
    @Mock private SupervisionManager mSupervisionManager;
@@ -97,6 +100,8 @@ public class FaceSafetySourceTest {
        when(mApplicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
                .thenReturn(mDevicePolicyManager);
        when(mApplicationContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mFaceManager);
        when(mApplicationContext.getSystemService(Context.FINGERPRINT_SERVICE))
                .thenReturn(mFingerprintManager);
        when(mApplicationContext.getSystemService(Context.SUPERVISION_SERVICE))
                .thenReturn(mSupervisionManager);
        FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
@@ -210,10 +215,12 @@ public class FaceSafetySourceTest {

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
    public void setSafetySourceData_withFaceNotEnrolled_whenNotDisabledByAdmin_setsData() {
    public void setSafetySourceData_onlyFaceNotEnrolled_whenNotDisabledByAdmin_setsData() {
        when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
        when(mFaceManager.isHardwareDetected()).thenReturn(true);
        when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
        when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(true);
        when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);

        FaceSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
@@ -224,6 +231,24 @@ public class FaceSafetySourceTest {
                FaceEnrollIntroductionInternal.class.getName());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
    public void setSafetySourceData_noBiometricEnrolled_whenNotDisabledByAdmin_setsData() {
        when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
        when(mFaceManager.isHardwareDetected()).thenReturn(true);
        when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
        when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
        when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);

        FaceSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);

        assertSafetySourceEnabledDataSetWithSingularSummary(
                "security_settings_face_preference_title_new",
                "security_settings_face_preference_summary_none_new",
                BiometricEnrollActivity.class.getName());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
    @DisableFlags(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+26 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
@@ -52,6 +53,7 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.widget.LockPatternUtils;
import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.fingerprint.FingerprintSettings;
import com.android.settings.flags.Flags;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -87,6 +89,7 @@ public class FingerprintSafetySourceTest {
    @Mock private PackageManager mPackageManager;
    @Mock private DevicePolicyManager mDevicePolicyManager;
    @Mock private FingerprintManager mFingerprintManager;
    @Mock private FaceManager mFaceManager;
    @Mock private LockPatternUtils mLockPatternUtils;
    @Mock private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
    @Mock private SupervisionManager mSupervisionManager;
@@ -100,6 +103,7 @@ public class FingerprintSafetySourceTest {
        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
        when(mApplicationContext.getSystemService(Context.FINGERPRINT_SERVICE))
                .thenReturn(mFingerprintManager);
        when(mApplicationContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mFaceManager);
        when(mApplicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
                .thenReturn(mDevicePolicyManager);
        when(mApplicationContext.getSystemService(Context.SUPERVISION_SERVICE))
@@ -227,10 +231,12 @@ public class FingerprintSafetySourceTest {

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
    public void setSafetySourceData_withFingerprintNotEnrolled_whenNotDisabledByAdmin_setsData() {
    public void setSafetySourceData_onlyFingerprintNotEnrolled_whenNotDisabledByAdmin_setsData() {
        when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
        when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
        when(mFaceManager.isHardwareDetected()).thenReturn(true);
        when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
        when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);

        FingerprintSafetySource.setSafetySourceData(
@@ -242,6 +248,25 @@ public class FingerprintSafetySourceTest {
                FingerprintSettings.class.getName());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
    public void setSafetySourceData_noBiometricEnrolled_whenNotDisabledByAdmin_setsData() {
        when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
        when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
        when(mFaceManager.isHardwareDetected()).thenReturn(true);
        when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
        when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);

        FingerprintSafetySource.setSafetySourceData(
                mApplicationContext, EVENT_SOURCE_STATE_CHANGED);

        assertSafetySourceEnabledDataSetWithSingularSummary(
                "security_settings_fingerprint",
                "security_settings_fingerprint_preference_summary_none_new",
                BiometricEnrollActivity.class.getName());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
    @DisableFlags(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)