Loading core/java/android/provider/Settings.java +7 −0 Original line number Diff line number Diff line Loading @@ -9658,6 +9658,13 @@ public final class Settings { public static final String BIOMETRIC_DEBUG_ENABLED = "biometric_debug_enabled"; /** * Whether or not virtual sensors are enabled. * @hide */ @Readable public static final String BIOMETRIC_VIRTUAL_ENABLED = "biometric_virtual_enabled"; /** * Whether or not biometric is allowed on Keyguard. * @hide Loading services/core/java/com/android/server/biometrics/Utils.java +17 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; import android.os.Binder; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading Loading @@ -87,6 +88,13 @@ public class Utils { return true; } /** If virtualized biometrics are supported (requires debug build). */ public static boolean isVirtualEnabled(Context context) { return Build.isDebuggable() && Settings.Secure.getIntForUser(context.getContentResolver(), Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1; } /** * Combines {@link PromptInfo#setDeviceCredentialAllowed(boolean)} with * {@link PromptInfo#setAuthenticators(int)}, as the former is not flexible enough. Loading Loading @@ -374,6 +382,15 @@ public class Utils { return false; } /** Same as checkPermission but also allows shell. */ public static void checkPermissionOrShell(Context context, String permission) { if (Binder.getCallingUid() == Process.SHELL_UID) { return; } checkPermission(context, permission); } public static void checkPermission(Context context, String permission) { context.enforceCallingOrSelfPermission(permission, "Must have " + permission + " permission."); Loading services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java +37 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ package com.android.server.biometrics.sensors; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.os.Build; import android.os.IBinder; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.biometrics.BiometricsProto; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; Loading Loading @@ -65,6 +67,7 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide private final List<S> mEnrolledList; private final boolean mHasEnrollmentsBeforeStarting; private BaseClientMonitor mCurrentTask; private boolean mFavorHalEnrollments = false; private final ClientMonitorCallback mEnumerateCallback = new ClientMonitorCallback() { @Override Loading @@ -86,10 +89,24 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide // No unknown HAL templates. Unknown framework templates are already cleaned up in // InternalEnumerateClient. Finish this client. mCallback.onClientFinished(InternalCleanupClient.this, success); } else { if (mFavorHalEnrollments && Build.isDebuggable()) { // on debug builds, optionally allow the HAL be the source of // truth for enrollments try { for (UserTemplate template : mUnknownHALTemplates) { Slog.i(TAG, "Adding unknown HAL template: " + template.mIdentifier.getBiometricId()); onAddUnknownTemplate(template.mUserId, template.mIdentifier); } } finally { mCallback.onClientFinished(InternalCleanupClient.this, success); } } else { startCleanupUnknownHalTemplates(); } } } }; private final ClientMonitorCallback mRemoveCallback = new ClientMonitorCallback() { Loading Loading @@ -197,8 +214,27 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide ((EnumerateConsumer) mCurrentTask).onEnumerationResult(identifier, remaining); } /** When set unknown templates in the HAL will be added instead of deleted. */ public void setFavorHalEnrollments() { mFavorHalEnrollments = true; } /** Called when an unknown template is found and setFavorHalEnrollments was requested. */ protected void onAddUnknownTemplate(int userId, @NonNull BiometricAuthenticator.Identifier identifier) {} @Override public int getProtoEnum() { return BiometricsProto.CM_INTERNAL_CLEANUP; } @VisibleForTesting public InternalEnumerateClient<T> getCurrentEnumerateClient() { return (InternalEnumerateClient<T>) mCurrentTask; } @VisibleForTesting public RemovalClient<S, T> getCurrentRemoveClient() { return (RemovalClient<S, T>) mCurrentTask; } } services/core/java/com/android/server/biometrics/sensors/RemovalClient.java +0 −2 Original line number Diff line number Diff line Loading @@ -50,8 +50,6 @@ public abstract class RemovalClient<S extends BiometricAuthenticator.Identifier, @NonNull Map<Integer, Long> authenticatorIds) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, logger, biometricContext); //, BiometricsProtoEnums.ACTION_REMOVE, // BiometricsProtoEnums.CLIENT_UNKNOWN); mBiometricUtils = utils; mAuthenticatorIds = authenticatorIds; mHasEnrollmentsBeforeStarting = !utils.getBiometricsForUser(context, userId).isEmpty(); Loading services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java +9 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.biometrics.sensors.face.aidl; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.face.IFace; import android.hardware.face.Face; import android.os.IBinder; Loading @@ -28,6 +29,7 @@ import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.InternalCleanupClient; import com.android.server.biometrics.sensors.InternalEnumerateClient; import com.android.server.biometrics.sensors.RemovalClient; import com.android.server.biometrics.sensors.face.FaceUtils; import java.util.List; import java.util.Map; Loading Loading @@ -68,4 +70,11 @@ class FaceInternalCleanupClient extends InternalCleanupClient<Face, AidlSession> null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner, utils, sensorId, logger, biometricContext, authenticatorIds); } @Override protected void onAddUnknownTemplate(int userId, @NonNull BiometricAuthenticator.Identifier identifier) { FaceUtils.getInstance(getSensorId()).addBiometricForUser( getContext(), getTargetUserId(), (Face) identifier); } } Loading
core/java/android/provider/Settings.java +7 −0 Original line number Diff line number Diff line Loading @@ -9658,6 +9658,13 @@ public final class Settings { public static final String BIOMETRIC_DEBUG_ENABLED = "biometric_debug_enabled"; /** * Whether or not virtual sensors are enabled. * @hide */ @Readable public static final String BIOMETRIC_VIRTUAL_ENABLED = "biometric_virtual_enabled"; /** * Whether or not biometric is allowed on Keyguard. * @hide Loading
services/core/java/com/android/server/biometrics/Utils.java +17 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; import android.os.Binder; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading Loading @@ -87,6 +88,13 @@ public class Utils { return true; } /** If virtualized biometrics are supported (requires debug build). */ public static boolean isVirtualEnabled(Context context) { return Build.isDebuggable() && Settings.Secure.getIntForUser(context.getContentResolver(), Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1; } /** * Combines {@link PromptInfo#setDeviceCredentialAllowed(boolean)} with * {@link PromptInfo#setAuthenticators(int)}, as the former is not flexible enough. Loading Loading @@ -374,6 +382,15 @@ public class Utils { return false; } /** Same as checkPermission but also allows shell. */ public static void checkPermissionOrShell(Context context, String permission) { if (Binder.getCallingUid() == Process.SHELL_UID) { return; } checkPermission(context, permission); } public static void checkPermission(Context context, String permission) { context.enforceCallingOrSelfPermission(permission, "Must have " + permission + " permission."); Loading
services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java +37 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ package com.android.server.biometrics.sensors; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.os.Build; import android.os.IBinder; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.biometrics.BiometricsProto; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; Loading Loading @@ -65,6 +67,7 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide private final List<S> mEnrolledList; private final boolean mHasEnrollmentsBeforeStarting; private BaseClientMonitor mCurrentTask; private boolean mFavorHalEnrollments = false; private final ClientMonitorCallback mEnumerateCallback = new ClientMonitorCallback() { @Override Loading @@ -86,10 +89,24 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide // No unknown HAL templates. Unknown framework templates are already cleaned up in // InternalEnumerateClient. Finish this client. mCallback.onClientFinished(InternalCleanupClient.this, success); } else { if (mFavorHalEnrollments && Build.isDebuggable()) { // on debug builds, optionally allow the HAL be the source of // truth for enrollments try { for (UserTemplate template : mUnknownHALTemplates) { Slog.i(TAG, "Adding unknown HAL template: " + template.mIdentifier.getBiometricId()); onAddUnknownTemplate(template.mUserId, template.mIdentifier); } } finally { mCallback.onClientFinished(InternalCleanupClient.this, success); } } else { startCleanupUnknownHalTemplates(); } } } }; private final ClientMonitorCallback mRemoveCallback = new ClientMonitorCallback() { Loading Loading @@ -197,8 +214,27 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide ((EnumerateConsumer) mCurrentTask).onEnumerationResult(identifier, remaining); } /** When set unknown templates in the HAL will be added instead of deleted. */ public void setFavorHalEnrollments() { mFavorHalEnrollments = true; } /** Called when an unknown template is found and setFavorHalEnrollments was requested. */ protected void onAddUnknownTemplate(int userId, @NonNull BiometricAuthenticator.Identifier identifier) {} @Override public int getProtoEnum() { return BiometricsProto.CM_INTERNAL_CLEANUP; } @VisibleForTesting public InternalEnumerateClient<T> getCurrentEnumerateClient() { return (InternalEnumerateClient<T>) mCurrentTask; } @VisibleForTesting public RemovalClient<S, T> getCurrentRemoveClient() { return (RemovalClient<S, T>) mCurrentTask; } }
services/core/java/com/android/server/biometrics/sensors/RemovalClient.java +0 −2 Original line number Diff line number Diff line Loading @@ -50,8 +50,6 @@ public abstract class RemovalClient<S extends BiometricAuthenticator.Identifier, @NonNull Map<Integer, Long> authenticatorIds) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, logger, biometricContext); //, BiometricsProtoEnums.ACTION_REMOVE, // BiometricsProtoEnums.CLIENT_UNKNOWN); mBiometricUtils = utils; mAuthenticatorIds = authenticatorIds; mHasEnrollmentsBeforeStarting = !utils.getBiometricsForUser(context, userId).isEmpty(); Loading
services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java +9 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.biometrics.sensors.face.aidl; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.face.IFace; import android.hardware.face.Face; import android.os.IBinder; Loading @@ -28,6 +29,7 @@ import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.InternalCleanupClient; import com.android.server.biometrics.sensors.InternalEnumerateClient; import com.android.server.biometrics.sensors.RemovalClient; import com.android.server.biometrics.sensors.face.FaceUtils; import java.util.List; import java.util.Map; Loading Loading @@ -68,4 +70,11 @@ class FaceInternalCleanupClient extends InternalCleanupClient<Face, AidlSession> null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner, utils, sensorId, logger, biometricContext, authenticatorIds); } @Override protected void onAddUnknownTemplate(int userId, @NonNull BiometricAuthenticator.Identifier identifier) { FaceUtils.getInstance(getSensorId()).addBiometricForUser( getContext(), getTargetUserId(), (Face) identifier); } }