summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
author Hao Dong <spdonghao@google.com> 2025-03-24 11:58:42 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-24 11:58:42 -0700
commit1923213009df454dfd48bd9afa1036e81ad22443 (patch)
tree25cd84dbb66ce64e881a64593a58c4ea5a55c1d3 /services
parent0690b03fd027219694d938494da38b02edd535fc (diff)
parent02adb885fe493c461c35ae085f741e6f7cbb1d95 (diff)
Merge "Add some new modality-specific APIs in BiometricManager." into main
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java50
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java39
2 files changed, 89 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index b6768c9c087a..eede4c9c59d0 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -36,6 +36,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.biometrics.AuthenticationStateListener;
import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricEnrollmentStatus;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IAuthService;
@@ -417,6 +418,55 @@ public class AuthService extends SystemService {
}
@Override
+ public List<BiometricEnrollmentStatus> getEnrollmentStatus(String opPackageName)
+ throws RemoteException {
+ checkBiometricAdvancedPermission();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final int userId = UserHandle.myUserId();
+ final List<BiometricEnrollmentStatus> enrollmentStatusList =
+ new ArrayList<>();
+ final IFingerprintService fingerprintService = mInjector.getFingerprintService();
+ if (fingerprintService != null) {
+ final List<FingerprintSensorPropertiesInternal> fpProps =
+ fingerprintService.getSensorPropertiesInternal(opPackageName);
+ if (!fpProps.isEmpty()) {
+ int fpCount = fingerprintService.getEnrolledFingerprints(userId,
+ opPackageName, getContext().getAttributionTag()).size();
+ enrollmentStatusList.add(
+ new BiometricEnrollmentStatus(
+ BiometricManager.TYPE_FINGERPRINT, fpCount));
+ } else {
+ Slog.e(TAG, "No fingerprint sensors");
+ }
+ } else {
+ Slog.e(TAG, "No fingerprint sensors");
+ }
+
+ final IFaceService faceService = mInjector.getFaceService();
+ if (faceService != null) {
+ final List<FaceSensorPropertiesInternal> faceProps =
+ faceService.getSensorPropertiesInternal(opPackageName);
+ if (!faceProps.isEmpty()) {
+ int faceCount = faceService.getEnrolledFaces(faceProps.getFirst().sensorId,
+ userId, opPackageName).size();
+ enrollmentStatusList.add(
+ new BiometricEnrollmentStatus(
+ BiometricManager.TYPE_FACE, faceCount));
+ } else {
+ Slog.e(TAG, "No face sensors");
+ }
+ } else {
+ Slog.e(TAG, "No face sensors");
+ }
+
+ return enrollmentStatusList;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void registerEnabledOnKeyguardCallback(
IBiometricEnabledOnKeyguardCallback callback) throws RemoteException {
checkInternalPermission();
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index c7efa318af99..cebdce9ed6cc 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -49,11 +49,14 @@ import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.PromptInfo;
+import android.hardware.biometrics.SensorProperties;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.face.FaceSensorConfigurations;
+import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceService;
import android.hardware.fingerprint.FingerprintSensorConfigurations;
+import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintService;
import android.hardware.iris.IIrisService;
@@ -84,6 +87,7 @@ import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Stubber;
+import java.util.ArrayList;
import java.util.List;
@Presubmit
@@ -519,6 +523,41 @@ public class AuthServiceTest {
verify(mBiometricService).getLastAuthenticationTime(eq(mUserId), eq(authenticators));
}
+ @Test
+ public void testGetEnrollmentStatus_callsFingerprintAndFaceService() throws Exception {
+ setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
+ List<FaceSensorPropertiesInternal> faceProps = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ FaceSensorProperties.STRENGTH_STRONG,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ List<FingerprintSensorPropertiesInternal> fpProps = List.of(
+ new FingerprintSensorPropertiesInternal(1 /* id */,
+ SensorProperties.STRENGTH_STRONG,
+ 5 /* maxEnrollmentsPerUser */,
+ new ArrayList<>() /* componentInfo */,
+ FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ false /* resetLockoutRequiresHardwareAuthToken */));
+ when(mFaceService.getSensorPropertiesInternal(eq(TEST_OP_PACKAGE_NAME))).thenReturn(
+ faceProps);
+ when(mFingerprintService.getSensorPropertiesInternal(eq(TEST_OP_PACKAGE_NAME))).thenReturn(
+ fpProps);
+ when(mContext.getAttributionTag()).thenReturn("tag");
+ mAuthService = new AuthService(mContext, mInjector);
+ mAuthService.onStart();
+
+ mAuthService.mImpl.getEnrollmentStatus(TEST_OP_PACKAGE_NAME);
+
+ waitForIdle();
+ verify(mFaceService).getEnrolledFaces(eq(0), eq(mUserId), eq(TEST_OP_PACKAGE_NAME));
+ verify(mFingerprintService).getEnrolledFingerprints(eq(mUserId), eq(TEST_OP_PACKAGE_NAME),
+ eq("tag"));
+ }
+
private static void setInternalAndTestBiometricPermissions(
Context context, boolean hasPermission) {
for (String p : List.of(TEST_BIOMETRIC, MANAGE_BIOMETRIC, USE_BIOMETRIC_INTERNAL)) {