Loading core/java/android/provider/Settings.java +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +1 −0 Original line number Diff line number Diff line Loading @@ -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, }; } packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +2 −0 Original line number Diff line number Diff line Loading @@ -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)); } } services/core/java/com/android/server/biometrics/BiometricService.java +114 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading @@ -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; Loading @@ -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. Loading @@ -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(); } Loading Loading @@ -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 Loading Loading @@ -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); } } Loading Loading @@ -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) { Loading @@ -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 { Loading services/core/java/com/android/server/biometrics/PreAuthInfo.java +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/provider/Settings.java +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +1 −0 Original line number Diff line number Diff line Loading @@ -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, }; }
packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +2 −0 Original line number Diff line number Diff line Loading @@ -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)); } }
services/core/java/com/android/server/biometrics/BiometricService.java +114 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading @@ -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; Loading @@ -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. Loading @@ -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(); } Loading Loading @@ -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 Loading Loading @@ -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); } } Loading Loading @@ -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) { Loading @@ -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 { Loading
services/core/java/com/android/server/biometrics/PreAuthInfo.java +2 −2 Original line number Diff line number Diff line Loading @@ -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