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

Commit 3576d067 authored by Diya Bera's avatar Diya Bera Committed by Android (Google) Code Review
Browse files

Merge "Mandatory Biometrics - Framework (2/N)" into main

parents a4904439 0fff67fb
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -11074,6 +11074,13 @@ public final class Settings {
         */
        public static final String MANDATORY_BIOMETRICS = "mandatory_biometrics";
        /**
         * Whether or not requirements for mandatory biometrics is satisfied.
         * @hide
         */
        public static final String MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED =
                "mandatory_biometrics_requirements_satisfied";
        /**
         * Whether or not active unlock triggers on wake.
         * @hide
+1 −0
Original line number Diff line number Diff line
@@ -282,5 +282,6 @@ public class SecureSettings {
        Settings.Secure.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS,
        Settings.Secure.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS,
        Settings.Secure.MANDATORY_BIOMETRICS,
        Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
    };
}
+2 −0
Original line number Diff line number Diff line
@@ -441,5 +441,7 @@ public class SecureSettingsValidators {
        VALIDATORS.put(Secure.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS, NONE_NEGATIVE_LONG_VALIDATOR);
        VALIDATORS.put(Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.MANDATORY_BIOMETRICS, new InclusiveIntegerRangeValidator(0, 1));
        VALIDATORS.put(Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
                new InclusiveIntegerRangeValidator(0, 1));
    }
}
+114 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ 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.BIOMETRIC_NO_AUTHENTICATION;
import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;

import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;

@@ -41,6 +42,7 @@ import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
@@ -54,8 +56,12 @@ import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.camera2.CameraManager;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.hardware.security.keymint.HardwareAuthenticatorType;
import android.net.Uri;
import android.os.Binder;
@@ -234,6 +240,8 @@ public class BiometricService extends SystemService {
        private static final boolean DEFAULT_APP_ENABLED = true;
        private static final boolean DEFAULT_ALWAYS_REQUIRE_CONFIRMATION = false;
        private static final boolean DEFAULT_MANDATORY_BIOMETRICS_STATUS = false;
        private static final boolean DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS =
                true;

        // Some devices that shipped before S already have face-specific settings. Instead of
        // migrating, which is complicated, let's just keep using the existing settings.
@@ -256,6 +264,8 @@ public class BiometricService extends SystemService {
                Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_APP_ENABLED);
        private final Uri MANDATORY_BIOMETRICS_ENABLED =
                Settings.Secure.getUriFor(Settings.Secure.MANDATORY_BIOMETRICS);
        private final Uri MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED = Settings.Secure.getUriFor(
                Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED);

        private final ContentResolver mContentResolver;
        private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks;
@@ -264,6 +274,12 @@ public class BiometricService extends SystemService {
        private final Map<Integer, Boolean> mBiometricEnabledForApps = new HashMap<>();
        private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>();
        private final Map<Integer, Boolean> mMandatoryBiometricsEnabled = new HashMap<>();
        private final Map<Integer, Boolean> mMandatoryBiometricsRequirementsSatisfied =
                new HashMap<>();
        private final Map<Integer, Boolean> mFingerprintEnrolledForUser =
                new HashMap<>();
        private final Map<Integer, Boolean> mFaceEnrolledForUser =
                new HashMap<>();

        /**
         * Creates a content observer.
@@ -288,7 +304,13 @@ public class BiometricService extends SystemService {
            mMandatoryBiometricsEnabled.put(context.getUserId(), Settings.Secure.getIntForUser(
                    mContentResolver, Settings.Secure.MANDATORY_BIOMETRICS,
                    DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0, context.getUserId()) != 0);
            mMandatoryBiometricsRequirementsSatisfied.put(context.getUserId(),
                    Settings.Secure.getIntForUser(mContentResolver,
                            Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
                            DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS ? 1 : 0,
                            context.getUserId()) != 0);

            addBiometricListenersForMandatoryBiometrics(context);
            updateContentObserver();
        }

@@ -322,6 +344,10 @@ public class BiometricService extends SystemService {
                    false /* notifyForDescendants */,
                    this /* observer */,
                    UserHandle.USER_ALL);
            mContentResolver.registerContentObserver(MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
                    false /* notifyForDescendants */,
                    this /* observer */,
                    UserHandle.USER_ALL);
        }

        @Override
@@ -370,6 +396,13 @@ public class BiometricService extends SystemService {
                        Settings.Secure.MANDATORY_BIOMETRICS,
                        DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0 /* default */,
                        userId) != 0);
            } else if (MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED.equals(uri)) {
                mMandatoryBiometricsRequirementsSatisfied.put(userId, Settings.Secure.getIntForUser(
                        mContentResolver,
                        Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
                        DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS
                                ? 1 : 0 /* default */,
                        userId) != 0);
            }
        }

@@ -411,9 +444,15 @@ public class BiometricService extends SystemService {
            }
        }

        public boolean getMandatoryBiometricsEnabledForUser(int userId) {
        public boolean getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId) {
            return mMandatoryBiometricsEnabled.getOrDefault(userId,
                    DEFAULT_MANDATORY_BIOMETRICS_STATUS);
                    DEFAULT_MANDATORY_BIOMETRICS_STATUS)
                    && mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
                    DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS)
                    && mBiometricEnabledForApps.getOrDefault(userId, DEFAULT_APP_ENABLED)
                    && getEnabledForApps(userId)
                    && (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */)
                    || mFaceEnrolledForUser.getOrDefault(userId, false /* default */));
        }

        void notifyEnabledOnKeyguardCallbacks(int userId) {
@@ -424,6 +463,79 @@ public class BiometricService extends SystemService {
                        userId);
            }
        }

        private void addBiometricListenersForMandatoryBiometrics(Context context) {
            final FingerprintManager fingerprintManager = context.getSystemService(
                    FingerprintManager.class);
            final FaceManager faceManager = context.getSystemService(FaceManager.class);
            if (fingerprintManager != null) {
                fingerprintManager.addAuthenticatorsRegisteredCallback(
                        new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
                            @Override
                            public void onAllAuthenticatorsRegistered(
                                    List<FingerprintSensorPropertiesInternal> list) {
                                if (list == null || list.isEmpty()) {
                                    Slog.d(TAG, "No fingerprint authenticators registered.");
                                    return;
                                }
                                final FingerprintSensorPropertiesInternal
                                        fingerprintSensorProperties = list.get(0);
                                if (fingerprintSensorProperties.sensorStrength
                                        == STRENGTH_STRONG) {
                                    fingerprintManager.registerBiometricStateListener(
                                            new BiometricStateListener() {
                                                @Override
                                                public void onEnrollmentsChanged(
                                                        int userId,
                                                        int sensorId,
                                                        boolean hasEnrollments
                                                ) {
                                                    if (sensorId == fingerprintSensorProperties
                                                            .sensorId) {
                                                        mFingerprintEnrolledForUser.put(userId,
                                                                hasEnrollments);
                                                    }
                                                }
                                            });
                                }
                            }
                        });
            }
            if (faceManager != null) {
                faceManager.addAuthenticatorsRegisteredCallback(
                        new IFaceAuthenticatorsRegisteredCallback.Stub() {
                            @Override
                            public void onAllAuthenticatorsRegistered(
                                    List<FaceSensorPropertiesInternal> list) {
                                if (list == null || list.isEmpty()) {
                                    Slog.d(TAG, "No face authenticators registered.");
                                    return;
                                }
                                final FaceSensorPropertiesInternal
                                        faceSensorPropertiesInternal = list.get(0);
                                if (faceSensorPropertiesInternal.sensorStrength
                                        == STRENGTH_STRONG) {
                                    faceManager.registerBiometricStateListener(
                                            new BiometricStateListener() {
                                                @Override
                                                public void onEnrollmentsChanged(
                                                        int userId,
                                                        int sensorId,
                                                        boolean hasEnrollments
                                                ) {
                                                    if (sensorId
                                                            == faceSensorPropertiesInternal
                                                            .sensorId) {
                                                        mFaceEnrolledForUser.put(userId,
                                                                hasEnrollments);
                                                    }
                                                }
                                            });
                                }
                            }
                        });
            }
        }
    }

    final class EnabledOnKeyguardCallback implements IBinder.DeathRecipient {
+2 −2
Original line number Diff line number Diff line
@@ -112,8 +112,8 @@ class PreAuthInfo {
                == BiometricManager.Authenticators.MANDATORY_BIOMETRICS;

        if (dropCredentialFallback(promptInfo.getAuthenticators(),
                settingObserver.getMandatoryBiometricsEnabledForUser(userId),
                trustManager)) {
                settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(
                        userId), trustManager)) {
            promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
            promptInfo.setNegativeButtonText(context.getString(R.string.cancel));
        }
Loading