summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Joe Bolinger <jbolinger@google.com> 2022-08-17 18:16:40 +0000
committer Joe Bolinger <jbolinger@google.com> 2022-08-17 18:16:40 +0000
commit8f5bb9d31c36d4528223201db403812a99a01b96 (patch)
tree6e139ae5632db5a5d5f50faf1c7c5939a5a0b655
parent294f4a1e79e5989ba441e88b6f2c2c1bcc9e7a2e (diff)
Revert "Copy startup & callback mechanism from fingerprint to face service."
This reverts commit 294f4a1e79e5989ba441e88b6f2c2c1bcc9e7a2e. Reason for revert: b/242845336 (a few cts tests seem to pass on device locally but fail on cf postsubmit) Change-Id: Icf36d403f96fc7a24d5191e7f43f43354a32b54f
-rw-r--r--core/java/android/hardware/face/FaceManager.java40
-rw-r--r--core/java/android/hardware/face/IFaceAuthenticatorsRegisteredCallback.aidl35
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl9
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java86
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java92
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java61
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java235
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java94
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java221
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java71
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java30
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java373
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java72
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java37
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java165
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java51
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java161
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java41
31 files changed, 605 insertions, 1354 deletions
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 7247ef77afb4..7092e43596ec 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -29,7 +29,6 @@ import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
-import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.CryptoObject;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.os.Binder;
@@ -675,45 +674,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
/**
- * Forwards BiometricStateListener to FaceService.
- *
- * @param listener new BiometricStateListener being added
- * @hide
- */
- public void registerBiometricStateListener(@NonNull BiometricStateListener listener) {
- try {
- mService.registerBiometricStateListener(listener);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Adds a callback that gets called when the service registers all of the face
- * authenticators (HALs).
- *
- * If the face authenticators are already registered when the callback is added, the
- * callback is invoked immediately.
- *
- * The callback is automatically removed after it's invoked.
- *
- * @hide
- */
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
- public void addAuthenticatorsRegisteredCallback(
- IFaceAuthenticatorsRegisteredCallback callback) {
- if (mService != null) {
- try {
- mService.addAuthenticatorsRegisteredCallback(callback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- } else {
- Slog.w(TAG, "addAuthenticatorsRegisteredCallback(): Service not connected!");
- }
- }
-
- /**
* @hide
*/
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
diff --git a/core/java/android/hardware/face/IFaceAuthenticatorsRegisteredCallback.aidl b/core/java/android/hardware/face/IFaceAuthenticatorsRegisteredCallback.aidl
deleted file mode 100644
index 78f978d21ed7..000000000000
--- a/core/java/android/hardware/face/IFaceAuthenticatorsRegisteredCallback.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.face;
-
-import android.hardware.face.FaceSensorPropertiesInternal;
-import java.util.List;
-
-/**
- * Callback to notify FaceManager that FaceService has registered all of the
- * face authenticators (HALs).
- * See {@link android.hardware.face.IFaceService#registerAuthenticators}.
- *
- * @hide
- */
-oneway interface IFaceAuthenticatorsRegisteredCallback {
- /**
- * Notifies FaceManager that all of the face authenticators have been registered.
- *
- * @param sensors A consolidated list of sensor properties for all of the authenticators.
- */
- void onAllAuthenticatorsRegistered(in List<FaceSensorPropertiesInternal> sensors);
-}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 9b56f43a0f22..369248edd580 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -17,11 +17,9 @@ package android.hardware.face;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
-import android.hardware.biometrics.IBiometricStateListener;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.face.IFaceServiceReceiver;
import android.hardware.face.Face;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -165,11 +163,4 @@ interface IFaceService {
// hidlSensors must be non-null and empty. See AuthService.java
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerAuthenticators(in List<FaceSensorPropertiesInternal> hidlSensors);
-
- // Adds a callback which gets called when the service registers all of the face
- // authenticators. The callback is automatically removed after it's invoked.
- void addAuthenticatorsRegisteredCallback(IFaceAuthenticatorsRegisteredCallback callback);
-
- // Registers BiometricStateListener.
- void registerBiometricStateListener(IBiometricStateListener listener);
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 1ba9a0471c88..cc7ed183ed64 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -202,10 +202,8 @@ interface IFingerprintService {
void setSidefpsController(in ISidefpsController controller);
// Registers BiometricStateListener.
- @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerBiometricStateListener(IBiometricStateListener listener);
// Sends a power button pressed event to all listeners.
- @EnforcePermission("USE_BIOMETRIC_INTERNAL")
oneway void onPowerPressed();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index d27b9ced66a7..8b5e3c11b2f6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -54,7 +54,6 @@ import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
-import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
@@ -2020,13 +2019,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// in case authenticators aren't registered yet at this point:
mAuthController.addCallback(new AuthController.Callback() {
@Override
- public void onAllAuthenticatorsRegistered(
- @BiometricAuthenticator.Modality int modality) {
+ public void onAllAuthenticatorsRegistered() {
mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE));
}
@Override
- public void onEnrollmentsChanged(@BiometricAuthenticator.Modality int modality) {
+ public void onEnrollmentsChanged() {
mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE));
}
});
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index d6974dfac570..06e1828ef9f4 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -16,7 +16,6 @@
package com.android.keyguard;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static com.android.keyguard.LockIconView.ICON_FINGERPRINT;
@@ -30,7 +29,6 @@ import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.AnimatedStateListDrawable;
-import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricSourceType;
import android.os.Process;
import android.os.VibrationAttributes;
@@ -703,17 +701,13 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
@Override
- public void onAllAuthenticatorsRegistered(@BiometricAuthenticator.Modality int modality) {
- if (modality == TYPE_FINGERPRINT) {
- updateUdfpsConfig();
- }
+ public void onAllAuthenticatorsRegistered() {
+ updateUdfpsConfig();
}
@Override
- public void onEnrollmentsChanged(@BiometricAuthenticator.Modality int modality) {
- if (modality == TYPE_FINGERPRINT) {
- updateUdfpsConfig();
- }
+ public void onEnrollmentsChanged() {
+ updateUdfpsConfig();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 282f25104c44..47ff59cfc281 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -46,7 +46,6 @@ import android.hardware.biometrics.PromptInfo;
import android.hardware.display.DisplayManager;
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;
@@ -157,6 +156,25 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
};
+ private final IFingerprintAuthenticatorsRegisteredCallback
+ mFingerprintAuthenticatorsRegisteredCallback =
+ new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
+ @Override
+ public void onAllAuthenticatorsRegistered(
+ List<FingerprintSensorPropertiesInternal> sensors) {
+ mHandler.post(() -> handleAllFingerprintAuthenticatorsRegistered(sensors));
+ }
+ };
+
+ private final BiometricStateListener mBiometricStateListener =
+ new BiometricStateListener() {
+ @Override
+ public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
+ mHandler.post(
+ () -> handleEnrollmentsChanged(userId, sensorId, hasEnrollments));
+ }
+ };
+
@VisibleForTesting
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -231,8 +249,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
List<FingerprintSensorPropertiesInternal> sensors) {
mExecution.assertIsMainThread();
if (DEBUG) {
- Log.d(TAG, "handleAllFingerprintAuthenticatorsRegistered | sensors: "
- + Arrays.toString(sensors.toArray()));
+ Log.d(TAG, "handleAllAuthenticatorsRegistered | sensors: " + Arrays.toString(
+ sensors.toArray()));
}
mAllFingerprintAuthenticatorsRegistered = true;
mFpProps = sensors;
@@ -274,42 +292,15 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
mSidefpsController = mSidefpsControllerFactory.get();
}
- mFingerprintManager.registerBiometricStateListener(new BiometricStateListener() {
- @Override
- public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
- mHandler.post(() -> handleEnrollmentsChanged(
- TYPE_FINGERPRINT, userId, sensorId, hasEnrollments));
- }
- });
+ mFingerprintManager.registerBiometricStateListener(mBiometricStateListener);
updateFingerprintLocation();
for (Callback cb : mCallbacks) {
- cb.onAllAuthenticatorsRegistered(TYPE_FINGERPRINT);
+ cb.onAllAuthenticatorsRegistered();
}
}
- private void handleAllFaceAuthenticatorsRegistered(List<FaceSensorPropertiesInternal> sensors) {
- mExecution.assertIsMainThread();
- if (DEBUG) {
- Log.d(TAG, "handleAllFaceAuthenticatorsRegistered | sensors: " + Arrays.toString(
- sensors.toArray()));
- }
-
- mFaceManager.registerBiometricStateListener(new BiometricStateListener() {
- @Override
- public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
- mHandler.post(() -> handleEnrollmentsChanged(
- TYPE_FACE, userId, sensorId, hasEnrollments));
- }
- });
-
- for (Callback cb : mCallbacks) {
- cb.onAllAuthenticatorsRegistered(TYPE_FACE);
- }
- }
-
- private void handleEnrollmentsChanged(@Modality int modality, int userId, int sensorId,
- boolean hasEnrollments) {
+ private void handleEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
mExecution.assertIsMainThread();
Log.d(TAG, "handleEnrollmentsChanged, userId: " + userId + ", sensorId: " + sensorId
+ ", hasEnrollments: " + hasEnrollments);
@@ -323,7 +314,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
}
for (Callback cb : mCallbacks) {
- cb.onEnrollmentsChanged(modality);
+ cb.onEnrollmentsChanged();
}
}
@@ -709,26 +700,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
if (mFingerprintManager != null) {
mFingerprintManager.addAuthenticatorsRegisteredCallback(
- new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FingerprintSensorPropertiesInternal> sensors) {
- mHandler.post(() ->
- handleAllFingerprintAuthenticatorsRegistered(sensors));
- }
- });
- }
- if (mFaceManager != null) {
- mFaceManager.addAuthenticatorsRegisteredCallback(
- new IFaceAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FaceSensorPropertiesInternal> sensors) {
- mHandler.post(() ->
- handleAllFaceAuthenticatorsRegistered(sensors));
- }
- }
- );
+ mFingerprintAuthenticatorsRegisteredCallback);
}
mStableDisplaySize = mDisplayManager.getStableDisplaySize();
@@ -1144,13 +1116,13 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
* Called when authenticators are registered. If authenticators are already
* registered before this call, this callback will never be triggered.
*/
- default void onAllAuthenticatorsRegistered(@Modality int modality) {}
+ default void onAllAuthenticatorsRegistered() {}
/**
- * Called when enrollments have changed. This is called after boot and on changes to
+ * Called when UDFPS enrollments have changed. This is called after boot and on changes to
* enrollment.
*/
- default void onEnrollmentsChanged(@Modality int modality) {}
+ default void onEnrollmentsChanged() {}
/**
* Called when the biometric prompt starts showing.
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index fd3f6007d8a9..38fab8ffbfad 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -308,7 +308,7 @@ class AuthRippleController @Inject constructor(
private val authControllerCallback =
object : AuthController.Callback {
- override fun onAllAuthenticatorsRegistered(modality: Int) {
+ override fun onAllAuthenticatorsRegistered() {
updateUdfpsDependentParams()
updateSensorLocation()
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index 7da2cf150147..a9e310d25f9c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -16,15 +16,12 @@
package com.android.systemui.doze;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
import static com.android.systemui.doze.DozeMachine.State.DOZE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSING;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
-import android.hardware.biometrics.BiometricAuthenticator;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
@@ -235,17 +232,13 @@ public class DozeScreenState implements DozeMachine.Part {
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
@Override
- public void onAllAuthenticatorsRegistered(@BiometricAuthenticator.Modality int modality) {
- if (modality == TYPE_FINGERPRINT) {
- updateUdfpsController();
- }
+ public void onAllAuthenticatorsRegistered() {
+ updateUdfpsController();
}
@Override
- public void onEnrollmentsChanged(@BiometricAuthenticator.Modality int modality) {
- if (modality == TYPE_FINGERPRINT) {
- updateUdfpsController();
- }
+ public void onEnrollmentsChanged() {
+ updateUdfpsController();
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 997a6e554364..da6c163b1eea 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -16,8 +16,6 @@
package com.android.systemui.doze;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
import static com.android.systemui.doze.DozeLog.REASON_SENSOR_QUICK_PICKUP;
import static com.android.systemui.doze.DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_DISPLAY;
@@ -31,7 +29,6 @@ import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
-import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.display.AmbientDisplayConfiguration;
import android.net.Uri;
import android.os.Handler;
@@ -838,17 +835,13 @@ public class DozeSensors {
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
@Override
- public void onAllAuthenticatorsRegistered(@BiometricAuthenticator.Modality int modality) {
- if (modality == TYPE_FINGERPRINT) {
- updateUdfpsEnrolled();
- }
+ public void onAllAuthenticatorsRegistered() {
+ updateUdfpsEnrolled();
}
@Override
- public void onEnrollmentsChanged(@BiometricAuthenticator.Modality int modality) {
- if (modality == TYPE_FINGERPRINT) {
- updateUdfpsEnrolled();
- }
+ public void onEnrollmentsChanged() {
+ updateUdfpsEnrolled();
}
private void updateUdfpsEnrolled() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index cde30af447f6..c67737136b3b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -16,7 +16,6 @@
package com.android.keyguard;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
@@ -1006,7 +1005,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
// WHEN udfps is now enrolled
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true);
- callback.onEnrollmentsChanged(TYPE_FINGERPRINT);
+ callback.onEnrollmentsChanged();
// THEN isUdfspEnrolled is TRUE
assertThat(mKeyguardUpdateMonitor.isUdfpsEnrolled()).isTrue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index e0d1f7a19130..d158892e4ec5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -60,9 +60,6 @@ import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorProperties;
import android.hardware.display.DisplayManager;
import android.hardware.face.FaceManager;
-import android.hardware.face.FaceSensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -157,9 +154,7 @@ public class AuthControllerTest extends SysuiTestCase {
@Mock
private InteractionJankMonitor mInteractionJankMonitor;
@Captor
- ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mFpAuthenticatorsRegisteredCaptor;
- @Captor
- ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mFaceAuthenticatorsRegisteredCaptor;
+ ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
@Captor
ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor;
@Captor
@@ -198,38 +193,25 @@ public class AuthControllerTest extends SysuiTestCase {
when(mDisplayManager.getStableDisplaySize()).thenReturn(new Point());
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
- when(mFaceManager.isHardwareDetected()).thenReturn(true);
-
- final List<ComponentInfoInternal> fpComponentInfo = List.of(
- new ComponentInfoInternal("faceSensor" /* componentId */,
- "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
- "00000001" /* serialNumber */, "" /* softwareVersion */));
- final List<ComponentInfoInternal> faceComponentInfo = List.of(
- new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
- "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
- "vendor/version/revision" /* softwareVersion */));
-
- final List<FingerprintSensorPropertiesInternal> fpProps = List.of(
- new FingerprintSensorPropertiesInternal(
- 1 /* sensorId */,
- SensorProperties.STRENGTH_STRONG,
- 1 /* maxEnrollmentsPerUser */,
- fpComponentInfo,
- FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
- true /* resetLockoutRequireHardwareAuthToken */));
- when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(fpProps);
-
- final List<FaceSensorPropertiesInternal> faceProps = List.of(
- new FaceSensorPropertiesInternal(
- 2 /* sensorId */,
- SensorProperties.STRENGTH_STRONG,
- 1 /* maxEnrollmentsPerUser */,
- fpComponentInfo,
- FaceSensorProperties.TYPE_RGB,
- true /* supportsFaceDetection */,
- true /* supportsSelfIllumination */,
- true /* resetLockoutRequireHardwareAuthToken */));
- when(mFaceManager.getSensorPropertiesInternal()).thenReturn(faceProps);
+
+ final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+ componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+ "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+ "00000001" /* serialNumber */, "" /* softwareVersion */));
+ componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+ "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+ "vendor/version/revision" /* softwareVersion */));
+
+ FingerprintSensorPropertiesInternal prop = new FingerprintSensorPropertiesInternal(
+ 1 /* sensorId */,
+ SensorProperties.STRENGTH_STRONG,
+ 1 /* maxEnrollmentsPerUser */,
+ componentInfo,
+ FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ true /* resetLockoutRequireHardwareAuthToken */);
+ List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+ props.add(prop);
+ when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
mAuthController = new TestableAuthController(mContextSpy, mExecution, mCommandQueue,
mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager,
@@ -237,15 +219,12 @@ public class AuthControllerTest extends SysuiTestCase {
mAuthController.start();
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
- mFpAuthenticatorsRegisteredCaptor.capture());
- verify(mFaceManager).addAuthenticatorsRegisteredCallback(
- mFaceAuthenticatorsRegisteredCaptor.capture());
+ mAuthenticatorsRegisteredCaptor.capture());
when(mStatusBarStateController.isDozing()).thenReturn(false);
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
- mFpAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(fpProps);
- mFaceAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(faceProps);
+ mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(props);
// Ensures that the operations posted on the handler get executed.
mTestableLooper.processAllMessages();
@@ -258,7 +237,6 @@ public class AuthControllerTest extends SysuiTestCase {
throws RemoteException {
// This test is sensitive to prior FingerprintManager interactions.
reset(mFingerprintManager);
- reset(mFaceManager);
// This test requires an uninitialized AuthController.
AuthController authController = new TestableAuthController(mContextSpy, mExecution,
@@ -268,27 +246,21 @@ public class AuthControllerTest extends SysuiTestCase {
authController.start();
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
- mFpAuthenticatorsRegisteredCaptor.capture());
- verify(mFaceManager).addAuthenticatorsRegisteredCallback(
- mFaceAuthenticatorsRegisteredCaptor.capture());
+ mAuthenticatorsRegisteredCaptor.capture());
mTestableLooper.processAllMessages();
verify(mFingerprintManager, never()).registerBiometricStateListener(any());
- verify(mFaceManager, never()).registerBiometricStateListener(any());
- mFpAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(List.of());
- mFaceAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(List.of());
+ mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(new ArrayList<>());
mTestableLooper.processAllMessages();
verify(mFingerprintManager).registerBiometricStateListener(any());
- verify(mFaceManager).registerBiometricStateListener(any());
}
@Test
public void testDoesNotCrash_afterEnrollmentsChangedForUnknownSensor() throws RemoteException {
// This test is sensitive to prior FingerprintManager interactions.
reset(mFingerprintManager);
- reset(mFaceManager);
// This test requires an uninitialized AuthController.
AuthController authController = new TestableAuthController(mContextSpy, mExecution,
@@ -298,25 +270,18 @@ public class AuthControllerTest extends SysuiTestCase {
authController.start();
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
- mFpAuthenticatorsRegisteredCaptor.capture());
- verify(mFaceManager).addAuthenticatorsRegisteredCallback(
- mFaceAuthenticatorsRegisteredCaptor.capture());
+ mAuthenticatorsRegisteredCaptor.capture());
// Emulates a device with no authenticators (empty list).
- mFpAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(List.of());
- mFaceAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(List.of());
+ mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(new ArrayList<>());
mTestableLooper.processAllMessages();
verify(mFingerprintManager).registerBiometricStateListener(
mBiometricStateCaptor.capture());
- verify(mFaceManager).registerBiometricStateListener(
- mBiometricStateCaptor.capture());
// Enrollments changed for an unknown sensor.
- for (BiometricStateListener listener : mBiometricStateCaptor.getAllValues()) {
- listener.onEnrollmentsChanged(0 /* userId */,
- 0xbeef /* sensorId */, true /* hasEnrollments */);
- }
+ mBiometricStateCaptor.getValue().onEnrollmentsChanged(0 /* userId */,
+ 0xbeef /* sensorId */, true /* hasEnrollments */);
mTestableLooper.processAllMessages();
// Nothing should crash.
@@ -862,3 +827,4 @@ public class AuthControllerTest extends SysuiTestCase {
}
}
}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index b33f9a7f3933..9ffc5a57cef6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -16,8 +16,6 @@
package com.android.systemui.doze;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
import static com.android.systemui.doze.DozeLog.REASON_SENSOR_TAP;
import static com.android.systemui.doze.DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN;
@@ -414,7 +412,7 @@ public class DozeSensorsTest extends SysuiTestCase {
// WHEN enrollment changes to TRUE
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true);
- mAuthControllerCallback.onEnrollmentsChanged(TYPE_FINGERPRINT);
+ mAuthControllerCallback.onEnrollmentsChanged();
// THEN mConfigured = TRUE
assertTrue(triggerSensor.mConfigured);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
index 5ec6bdf3c00b..24d051508fde 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
@@ -16,8 +16,6 @@
package com.android.systemui.keyguard;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.keyguard.LockIconView.ICON_LOCK;
import static com.android.keyguard.LockIconView.ICON_UNLOCK;
@@ -221,7 +219,7 @@ public class LockIconViewControllerTest extends SysuiTestCase {
Pair<Float, PointF> udfps = setupUdfps();
// WHEN all authenticators are registered
- mAuthControllerCallback.onAllAuthenticatorsRegistered(TYPE_FINGERPRINT);
+ mAuthControllerCallback.onAllAuthenticatorsRegistered();
mDelayableExecutor.runAllReady();
// THEN lock icon view location is updated with the same coordinates as auth controller vals
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java
deleted file mode 100644
index 0f1fe68ad1d7..000000000000
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-import android.annotation.NonNull;
-import android.hardware.biometrics.SensorPropertiesInternal;
-import android.util.proto.ProtoOutputStream;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-
-/**
- * Common attributes for all biometric service providers.
- *
- * @param <T> Internal settings type.
- */
-public interface BiometricServiceProvider<T extends SensorPropertiesInternal> {
-
- /** Checks if the specified sensor is owned by this provider. */
- boolean containsSensor(int sensorId);
-
- /** All sensor properties. */
- @NonNull
- List<T> getSensorProperties();
-
- /** Properties for the given sensor id. */
- @NonNull
- T getSensorProperties(int sensorId);
-
- boolean isHardwareDetected(int sensorId);
-
- /** If the user has any enrollments for the given sensor. */
- boolean hasEnrollments(int sensorId, int userId);
-
- long getAuthenticatorId(int sensorId, int userId);
-
- @LockoutTracker.LockoutMode
- int getLockoutModeForUser(int sensorId, int userId);
-
- void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
- boolean clearSchedulerBuffer);
-
- void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
-
- void dumpInternal(int sensorId, @NonNull PrintWriter pw);
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java
deleted file mode 100644
index 7574523f0662..000000000000
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.biometrics.IBiometricAuthenticator;
-import android.hardware.biometrics.IBiometricService;
-import android.hardware.biometrics.SensorPropertiesInternal;
-import android.os.Handler;
-import android.os.IInterface;
-import android.os.Process;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.util.Pair;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.ServiceThread;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Supplier;
-
-/**
- * Container for all BiometricServiceProvider implementations.
- *
- * @param <T> The service provider type.
- * @param <P> The internal properties type.
- * @param <C> The registration callback for {@link #invokeRegisteredCallback(IInterface, List)}.
- */
-public abstract class BiometricServiceRegistry<T extends BiometricServiceProvider<P>,
- P extends SensorPropertiesInternal,
- C extends IInterface> {
-
- private static final String TAG = "BiometricServiceRegistry";
-
- // Volatile so they can be read without a lock once all services are registered.
- // But, ideally remove this and provide immutable copies via the callback instead.
- @Nullable
- private volatile List<T> mServiceProviders;
- @Nullable
- private volatile List<P> mAllProps;
-
- @NonNull
- private final Supplier<IBiometricService> mBiometricServiceSupplier;
- @NonNull
- private final RemoteCallbackList<C> mRegisteredCallbacks = new RemoteCallbackList<>();
-
- public BiometricServiceRegistry(@NonNull Supplier<IBiometricService> biometricSupplier) {
- mBiometricServiceSupplier = biometricSupplier;
- }
-
- /**
- * Register an implementation by creating a new authenticator and initializing it via
- * {@link IBiometricService#registerAuthenticator(int, int, int, IBiometricAuthenticator)}
- * using the given properties.
- *
- * @param service service to register with
- * @param props internal properties to initialize the authenticator
- */
- protected abstract void registerService(@NonNull IBiometricService service, @NonNull P props);
-
- /**
- * Invoke the callback to notify clients that all authenticators have been registered.
- *
- * @param callback callback to invoke
- * @param allProps properties of all authenticators
- */
- protected abstract void invokeRegisteredCallback(@NonNull C callback,
- @NonNull List<P> allProps) throws RemoteException;
-
- /**
- * Register all authenticators in a background thread.
- *
- * @param serviceProvider Supplier function that will be invoked on the background thread.
- */
- public void registerAll(Supplier<List<T>> serviceProvider) {
- // Some HAL might not be started before the system service and will cause the code below
- // to wait, and some of the operations below might take a significant amount of time to
- // complete (calls to the HALs). To avoid blocking the rest of system server we put
- // this on a background thread.
- final ServiceThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
- true /* allowIo */);
- thread.start();
- final Handler handler = new Handler(thread.getLooper());
- handler.post(() -> registerAllInBackground(serviceProvider));
- thread.quitSafely();
- }
-
- /** Register authenticators now, only called by {@link #registerAll(Supplier).} */
- @VisibleForTesting
- public void registerAllInBackground(Supplier<List<T>> serviceProvider) {
- List<T> providers = serviceProvider.get();
- if (providers == null) {
- providers = new ArrayList<>();
- }
-
- final IBiometricService biometricService = mBiometricServiceSupplier.get();
- if (biometricService == null) {
- throw new IllegalStateException("biometric service cannot be null");
- }
-
- // Register each sensor individually with BiometricService
- final List<P> allProps = new ArrayList<>();
- for (T provider : providers) {
- final List<P> props = provider.getSensorProperties();
- for (P prop : props) {
- registerService(biometricService, prop);
- }
- allProps.addAll(props);
- }
-
- finishRegistration(providers, allProps);
- }
-
- private synchronized void finishRegistration(
- @NonNull List<T> providers, @NonNull List<P> allProps) {
- mServiceProviders = Collections.unmodifiableList(providers);
- mAllProps = Collections.unmodifiableList(allProps);
- broadcastAllAuthenticatorsRegistered();
- }
-
- /**
- * Add a callback that will be invoked once the work from {@link #registerAll(Supplier)}
- * has finished registering all providers (executes immediately if already done).
- *
- * @param callback registration callback
- */
- public synchronized void addAllRegisteredCallback(@Nullable C callback) {
- if (callback == null) {
- Slog.e(TAG, "addAllRegisteredCallback, callback is null");
- return;
- }
-
- final boolean registered = mRegisteredCallbacks.register(callback);
- final boolean allRegistered = mServiceProviders != null;
- if (registered && allRegistered) {
- broadcastAllAuthenticatorsRegistered();
- } else if (!registered) {
- Slog.e(TAG, "addAllRegisteredCallback failed to register callback");
- }
- }
-
- private synchronized void broadcastAllAuthenticatorsRegistered() {
- final int n = mRegisteredCallbacks.beginBroadcast();
- for (int i = 0; i < n; ++i) {
- final C cb = mRegisteredCallbacks.getBroadcastItem(i);
- try {
- invokeRegisteredCallback(cb, mAllProps);
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception in broadcastAllAuthenticatorsRegistered", e);
- } finally {
- mRegisteredCallbacks.unregister(cb);
- }
- }
- mRegisteredCallbacks.finishBroadcast();
- }
-
- /**
- * Get a list of registered providers.
- *
- * Undefined until {@link #registerAll(Supplier)} has fired the completion callback.
- */
- @NonNull
- public List<T> getProviders() {
- return mServiceProviders != null ? mServiceProviders : Collections.emptyList();
- }
-
- /**
- * Gets the provider for given sensor id or null if not registered.
- *
- * Undefined until {@link #registerAll(Supplier)} has fired the completion callback.
- */
- @Nullable
- public T getProviderForSensor(int sensorId) {
- if (mServiceProviders != null) {
- for (T provider : mServiceProviders) {
- if (provider.containsSensor(sensorId)) {
- return provider;
- }
- }
- }
- return null;
- }
-
- /**
- * For devices with only a single provider, returns that provider.
- * If no providers, or multiple providers exist, returns null.
- *
- * Undefined until {@link #registerAll(Supplier)} has fired the completion callback.
- */
- @Nullable
- public Pair<Integer, T> getSingleProvider() {
- if (mAllProps == null || mAllProps.size() != 1) {
- Slog.e(TAG, "Multiple sensors found: " + mAllProps.size());
- return null;
- }
-
- final int sensorId = mAllProps.get(0).sensorId;
- final T provider = getProviderForSensor(sensorId);
- if (provider != null) {
- return new Pair<>(sensorId, provider);
- }
-
- Slog.e(TAG, "Single sensor, but provider not found");
- return null;
- }
-
- /**
- * Get the properties for all providers.
- *
- * Undefined until {@link #registerAll(Supplier)} has fired the completion callback.
- */
- @NonNull
- public List<P> getAllProperties() {
- return mAllProps != null ? mAllProps : Collections.emptyList();
- }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
index f8543162f95e..0d789f7a1840 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
@@ -23,64 +23,32 @@ import static android.hardware.biometrics.BiometricStateListener.STATE_IDLE;
import static android.hardware.biometrics.BiometricStateListener.STATE_KEYGUARD_AUTH;
import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.IBiometricStateListener;
-import android.hardware.biometrics.SensorPropertiesInternal;
import android.os.RemoteException;
-import android.os.UserManager;
import android.util.Slog;
import com.android.server.biometrics.Utils;
-import java.util.Collections;
-import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* A callback for receiving notifications about biometric sensor state changes.
- *
- * @param <T> service provider type
- * @param <P> internal property type
*/
-public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
- P extends SensorPropertiesInternal> implements ClientMonitorCallback {
+public class BiometricStateCallback implements ClientMonitorCallback {
private static final String TAG = "BiometricStateCallback";
@NonNull
- private final CopyOnWriteArrayList<IBiometricStateListener> mBiometricStateListeners =
- new CopyOnWriteArrayList<>();
- @NonNull
- private final UserManager mUserManager;
- @BiometricStateListener.State
- private int mBiometricState;
- @NonNull
- private List<T> mProviders = List.of();
+ private final CopyOnWriteArrayList<IBiometricStateListener>
+ mBiometricStateListeners = new CopyOnWriteArrayList<>();
- /**
- * Create a new callback that must be {@link #start(List)}ed.
- *
- * @param userManager user manager
- */
- public BiometricStateCallback(@NonNull UserManager userManager) {
- mBiometricState = STATE_IDLE;
- mUserManager = userManager;
- }
+ private @BiometricStateListener.State int mBiometricState;
- /**
- * This should be called when the service has been initialized and all providers are ready.
- *
- * @param allProviders all registered biometric service providers
- */
- public synchronized void start(@NonNull List<T> allProviders) {
- mProviders = Collections.unmodifiableList(allProviders);
- broadcastCurrentEnrollmentState(null /* listener */);
+ public BiometricStateCallback() {
+ mBiometricState = STATE_IDLE;
}
- /** Get the current state. */
- @BiometricStateListener.State
public int getBiometricState() {
return mBiometricState;
}
@@ -152,43 +120,23 @@ public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
}
/**
- * Enables clients to register a BiometricStateListener. For example, this is used to forward
- * fingerprint sensor state changes to SideFpsEventHandler.
- *
- * @param listener listener to register
+ * This should be invoked when:
+ * 1) Enrolled --> None-enrolled
+ * 2) None-enrolled --> enrolled
+ * 3) HAL becomes ready
+ * 4) Listener is registered
*/
- public synchronized void registerBiometricStateListener(
- @NonNull IBiometricStateListener listener) {
- mBiometricStateListeners.add(listener);
- broadcastCurrentEnrollmentState(listener);
- }
-
- private synchronized void broadcastCurrentEnrollmentState(
- @Nullable IBiometricStateListener listener) {
- for (T provider : mProviders) {
- for (SensorPropertiesInternal prop : provider.getSensorProperties()) {
- for (UserInfo userInfo : mUserManager.getAliveUsers()) {
- final boolean enrolled = provider.hasEnrollments(prop.sensorId, userInfo.id);
- if (listener != null) {
- notifyEnrollmentStateChanged(
- listener, userInfo.id, prop.sensorId, enrolled);
- } else {
- notifyAllEnrollmentStateChanged(
- userInfo.id, prop.sensorId, enrolled);
- }
- }
- }
- }
- }
-
- private void notifyAllEnrollmentStateChanged(int userId, int sensorId,
+ public void notifyAllEnrollmentStateChanged(int userId, int sensorId,
boolean hasEnrollments) {
for (IBiometricStateListener listener : mBiometricStateListeners) {
notifyEnrollmentStateChanged(listener, userId, sensorId, hasEnrollments);
}
}
- private void notifyEnrollmentStateChanged(@NonNull IBiometricStateListener listener,
+ /**
+ * Notifies the listener of enrollment state changes.
+ */
+ public void notifyEnrollmentStateChanged(@NonNull IBiometricStateListener listener,
int userId, int sensorId, boolean hasEnrollments) {
try {
listener.onEnrollmentsChanged(userId, sensorId, hasEnrollments);
@@ -196,4 +144,14 @@ public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
Slog.e(TAG, "Remote exception", e);
}
}
+
+ /**
+ * Enables clients to register a BiometricStateListener. For example, this is used to forward
+ * fingerprint sensor state changes to SideFpsEventHandler.
+ *
+ * @param listener
+ */
+ public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+ mBiometricStateListeners.add(listener);
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 271bce9890c6..79e65cc6d2e5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -17,18 +17,20 @@
package com.android.server.biometrics.sensors.face;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.MANAGE_FACE;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
-import android.hardware.biometrics.IBiometricStateListener;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
@@ -37,18 +39,18 @@ import android.hardware.biometrics.face.SensorProps;
import android.hardware.face.Face;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.FaceServiceReceiver;
-import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.face.IFaceService;
import android.hardware.face.IFaceServiceReceiver;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
import android.os.NativeHandle;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.UserHandle;
-import android.os.UserManager;
import android.util.Pair;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -56,10 +58,10 @@ import android.view.Surface;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
+import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -86,10 +88,51 @@ public class FaceService extends SystemService {
private final LockoutResetDispatcher mLockoutResetDispatcher;
private final LockPatternUtils mLockPatternUtils;
@NonNull
- private final FaceServiceRegistry mRegistry;
+ private final List<ServiceProvider> mServiceProviders;
+
+ @Nullable
+ private ServiceProvider getProviderForSensor(int sensorId) {
+ for (ServiceProvider provider : mServiceProviders) {
+ if (provider.containsSensor(sensorId)) {
+ return provider;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * For devices with only a single provider, returns that provider. If no providers, or multiple
+ * providers exist, returns null.
+ */
+ @Nullable
+ private Pair<Integer, ServiceProvider> getSingleProvider() {
+ final List<FaceSensorPropertiesInternal> properties = getSensorProperties();
+ if (properties.size() != 1) {
+ Slog.e(TAG, "Multiple sensors found: " + properties.size());
+ return null;
+ }
+
+ // Theoretically we can just return the first provider, but maybe this is easier to
+ // understand.
+ final int sensorId = properties.get(0).sensorId;
+ for (ServiceProvider provider : mServiceProviders) {
+ if (provider.containsSensor(sensorId)) {
+ return new Pair<>(sensorId, provider);
+ }
+ }
+
+ Slog.e(TAG, "Single sensor, but provider not found");
+ return null;
+ }
+
@NonNull
- private final BiometricStateCallback<ServiceProvider, FaceSensorPropertiesInternal>
- mBiometricStateCallback;
+ private List<FaceSensorPropertiesInternal> getSensorProperties() {
+ final List<FaceSensorPropertiesInternal> properties = new ArrayList<>();
+ for (ServiceProvider provider : mServiceProviders) {
+ properties.addAll(provider.getSensorProperties());
+ }
+ return properties;
+ }
/**
* Receives the incoming binder calls from FaceManager.
@@ -99,7 +142,8 @@ public class FaceService extends SystemService {
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
@@ -112,8 +156,9 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
+
final ProtoOutputStream proto = new ProtoOutputStream();
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider != null) {
provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
}
@@ -125,14 +170,16 @@ public class FaceService extends SystemService {
@Override // Binder call
public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
String opPackageName) {
- return mRegistry.getAllProperties();
+
+ return FaceService.this.getSensorProperties();
}
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public FaceSensorPropertiesInternal getSensorProperties(int sensorId,
@NonNull String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
+ ", caller: " + opPackageName);
@@ -146,7 +193,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void generateChallenge(IBinder token, int sensorId, int userId,
IFaceServiceReceiver receiver, String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
return;
@@ -159,7 +207,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
long challenge) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
return;
@@ -173,7 +222,8 @@ public class FaceService extends SystemService {
public long enroll(int userId, final IBinder token, final byte[] hardwareAuthToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures, Surface previewSurface, boolean debugConsent) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for enroll");
return -1;
@@ -195,7 +245,8 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void cancelEnrollment(final IBinder token, long requestId) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for cancelEnrollment");
return;
@@ -209,6 +260,7 @@ public class FaceService extends SystemService {
public long authenticate(final IBinder token, final long operationId, int userId,
final IFaceServiceReceiver receiver, final String opPackageName,
boolean isKeyguardBypassEnabled) {
+
// TODO(b/152413782): If the sensor supports face detect and the device is encrypted or
// lockdown, something wrong happened. See similar path in FingerprintService.
@@ -221,7 +273,7 @@ public class FaceService extends SystemService {
// permission.
final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for authenticate");
return -1;
@@ -249,7 +301,7 @@ public class FaceService extends SystemService {
return -1;
}
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for detectFace");
return -1;
@@ -266,7 +318,8 @@ public class FaceService extends SystemService {
IBinder token, long operationId, int userId,
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
int cookie, boolean allowBackgroundAuthentication) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for prepareForAuthentication");
return;
@@ -283,7 +336,8 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void startPreparedClient(int sensorId, int cookie) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for startPreparedClient");
return;
@@ -296,7 +350,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void cancelAuthentication(final IBinder token, final String opPackageName,
final long requestId) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for cancelAuthentication");
return;
@@ -315,7 +370,7 @@ public class FaceService extends SystemService {
return;
}
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for cancelFaceDetect");
return;
@@ -328,7 +383,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void cancelAuthenticationFromService(int sensorId, final IBinder token,
final String opPackageName, final long requestId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
return;
@@ -341,7 +397,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void remove(final IBinder token, final int faceId, final int userId,
final IFaceServiceReceiver receiver, final String opPackageName) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for remove");
return;
@@ -355,6 +412,7 @@ public class FaceService extends SystemService {
@Override // Binder call
public void removeAll(final IBinder token, final int userId,
final IFaceServiceReceiver receiver, final String opPackageName) {
+
final FaceServiceReceiver internalReceiver = new FaceServiceReceiver() {
int sensorsFinishedRemoving = 0;
final int numSensors = getSensorPropertiesInternal(
@@ -374,7 +432,7 @@ public class FaceService extends SystemService {
// This effectively iterates through all sensors, but has to do so by finding all
// sensors under each provider.
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
List<FaceSensorPropertiesInternal> props = provider.getSensorProperties();
for (FaceSensorPropertiesInternal prop : props) {
provider.scheduleRemoveAll(prop.sensorId, token, userId, internalReceiver,
@@ -409,27 +467,27 @@ public class FaceService extends SystemService {
try {
if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
provider.dumpProtoState(props.sensorId, proto, false);
}
}
proto.flush();
} else if (args.length > 0 && "--proto".equals(args[0])) {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
provider.dumpProtoMetrics(props.sensorId, fd);
}
}
} else if (args.length > 1 && "--hal".equals(args[0])) {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
provider.dumpHal(props.sensorId, fd,
Arrays.copyOfRange(args, 1, args.length, args.getClass()));
}
}
} else {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
pw.println("Dumping for sensorId: " + props.sensorId
+ ", provider: " + provider.getClass().getSimpleName());
@@ -446,9 +504,10 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public boolean isHardwareDetected(int sensorId, String opPackageName) {
+
final long token = Binder.clearCallingIdentity();
try {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
return false;
@@ -462,11 +521,12 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName) {
+
if (userId != UserHandle.getCallingUserId()) {
Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
}
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for getEnrolledFaces, caller: " + opPackageName);
return Collections.emptyList();
@@ -478,11 +538,12 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName) {
+
if (userId != UserHandle.getCallingUserId()) {
Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
}
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for hasEnrolledFaces, caller: " + opPackageName);
return false;
@@ -494,7 +555,8 @@ public class FaceService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for getLockoutModeForUser");
return LockoutTracker.LOCKOUT_NONE;
@@ -507,7 +569,8 @@ public class FaceService extends SystemService {
@Override
public void invalidateAuthenticatorId(int sensorId, int userId,
IInvalidationCallback callback) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for invalidateAuthenticatorId");
return;
@@ -519,7 +582,7 @@ public class FaceService extends SystemService {
@Override // Binder call
public long getAuthenticatorId(int sensorId, int userId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for getAuthenticatorId");
return 0;
@@ -532,7 +595,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void resetLockout(IBinder token, int sensorId, int userId, byte[] hardwareAuthToken,
String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
return;
@@ -546,7 +610,8 @@ public class FaceService extends SystemService {
public void setFeature(final IBinder token, int userId, int feature, boolean enabled,
final byte[] hardwareAuthToken, IFaceServiceReceiver receiver,
final String opPackageName) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for setFeature");
return;
@@ -560,7 +625,8 @@ public class FaceService extends SystemService {
@Override
public void getFeature(final IBinder token, int userId, int feature,
IFaceServiceReceiver receiver, final String opPackageName) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for getFeature");
return;
@@ -570,14 +636,18 @@ public class FaceService extends SystemService {
new ClientMonitorCallbackConverter(receiver), opPackageName);
}
- private List<ServiceProvider> getAidlProviders() {
- final List<ServiceProvider> providers = new ArrayList<>();
+ private void addHidlProviders(@NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
+ for (FaceSensorPropertiesInternal hidlSensor : hidlSensors) {
+ mServiceProviders.add(
+ Face10.newInstance(getContext(), hidlSensor, mLockoutResetDispatcher));
+ }
+ }
+ private void addAidlProviders() {
final String[] instances = ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR);
if (instances == null || instances.length == 0) {
- return providers;
+ return;
}
-
for (String instance : instances) {
final String fqName = IFace.DESCRIPTOR + "/" + instance;
final IFace face = IFace.Stub.asInterface(
@@ -590,41 +660,53 @@ public class FaceService extends SystemService {
final SensorProps[] props = face.getSensorProps();
final FaceProvider provider = new FaceProvider(getContext(), props, instance,
mLockoutResetDispatcher, BiometricContext.getInstance(getContext()));
- providers.add(provider);
+ mServiceProviders.add(provider);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
}
}
-
- return providers;
}
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void registerAuthenticators(
@NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
- mRegistry.registerAll(() -> {
- final List<ServiceProvider> providers = new ArrayList<>();
- for (FaceSensorPropertiesInternal hidlSensor : hidlSensors) {
- providers.add(
- Face10.newInstance(getContext(), hidlSensor, mLockoutResetDispatcher));
+
+ // Some HAL might not be started before the system service and will cause the code below
+ // to wait, and some of the operations below might take a significant amount of time to
+ // complete (calls to the HALs). To avoid blocking the rest of system server we put
+ // this on a background thread.
+ final ServiceThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
+ true /* allowIo */);
+ thread.start();
+ final Handler handler = new Handler(thread.getLooper());
+
+ handler.post(() -> {
+ addHidlProviders(hidlSensors);
+ addAidlProviders();
+
+ final IBiometricService biometricService = IBiometricService.Stub.asInterface(
+ ServiceManager.getService(Context.BIOMETRIC_SERVICE));
+
+ // Register each sensor individually with BiometricService
+ for (ServiceProvider provider : mServiceProviders) {
+ final List<FaceSensorPropertiesInternal> props = provider.getSensorProperties();
+ for (FaceSensorPropertiesInternal prop : props) {
+ final int sensorId = prop.sensorId;
+ final @BiometricManager.Authenticators.Types int strength =
+ Utils.propertyStrengthToAuthenticatorStrength(prop.sensorStrength);
+ final FaceAuthenticator authenticator = new FaceAuthenticator(
+ mServiceWrapper, sensorId);
+ try {
+ biometricService.registerAuthenticator(sensorId, TYPE_FACE, strength,
+ authenticator);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
+ }
+ }
}
- providers.addAll(getAidlProviders());
- return providers;
});
}
-
- @Override
- public void addAuthenticatorsRegisteredCallback(
- IFaceAuthenticatorsRegisteredCallback callback) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
- mRegistry.addAllRegisteredCallback(callback);
- }
-
- @Override
- public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
- mBiometricStateCallback.registerBiometricStateListener(listener);
- }
}
public FaceService(Context context) {
@@ -632,16 +714,7 @@ public class FaceService extends SystemService {
mServiceWrapper = new FaceServiceWrapper();
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
- mBiometricStateCallback = new BiometricStateCallback<>(UserManager.get(context));
- mRegistry = new FaceServiceRegistry(mServiceWrapper,
- () -> IBiometricService.Stub.asInterface(
- ServiceManager.getService(Context.BIOMETRIC_SERVICE)));
- mRegistry.addAllRegisteredCallback(new IFaceAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(List<FaceSensorPropertiesInternal> sensors) {
- mBiometricStateCallback.start(mRegistry.getProviders());
- }
- });
+ mServiceProviders = new ArrayList<>();
}
@Override
@@ -679,7 +752,7 @@ public class FaceService extends SystemService {
if (Utils.isVirtualEnabled(getContext())) {
Slog.i(TAG, "Sync virtual enrollments");
final int userId = ActivityManager.getCurrentUser();
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
provider.scheduleInternalCleanup(props.sensorId, userId, null /* callback */,
true /* favorHalEnrollments */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java
deleted file mode 100644
index 0f0a81d24473..000000000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.IBiometricService;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
-import android.hardware.face.IFaceService;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.sensors.BiometricServiceRegistry;
-
-import java.util.List;
-import java.util.function.Supplier;
-
-/** Registry for {@link IFaceService} providers. */
-public class FaceServiceRegistry extends BiometricServiceRegistry<ServiceProvider,
- FaceSensorPropertiesInternal, IFaceAuthenticatorsRegisteredCallback> {
-
- private static final String TAG = "FaceServiceRegistry";
-
- @NonNull
- private final IFaceService mService;
-
- /** Creates a new registry tied to the given service. */
- public FaceServiceRegistry(@NonNull IFaceService service,
- @Nullable Supplier<IBiometricService> biometricSupplier) {
- super(biometricSupplier);
- mService = service;
- }
-
- @Override
- protected void registerService(@NonNull IBiometricService service,
- @NonNull FaceSensorPropertiesInternal props) {
- @BiometricManager.Authenticators.Types final int strength =
- Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength);
- try {
- service.registerAuthenticator(props.sensorId, TYPE_FACE, strength,
- new FaceAuthenticator(mService, props.sensorId));
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception when registering sensorId: " + props.sensorId);
- }
- }
-
- @Override
- protected void invokeRegisteredCallback(@NonNull IFaceAuthenticatorsRegisteredCallback callback,
- @NonNull List<FaceSensorPropertiesInternal> allProps) throws RemoteException {
- callback.onAllAuthenticatorsRegistered(allProps);
- }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index 4efaedbd5530..6f98365332e2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -26,13 +26,15 @@ import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceServiceReceiver;
import android.os.IBinder;
+import android.util.proto.ProtoOutputStream;
import android.view.Surface;
-import com.android.server.biometrics.sensors.BiometricServiceProvider;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.LockoutTracker;
import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.List;
/**
@@ -54,11 +56,24 @@ import java.util.List;
* to check (e.g. via {@link FaceManager#getSensorPropertiesInternal()}) that the code path isn't
* taken. ServiceProviders will provide a no-op for unsupported operations to fail safely.
*/
-public interface ServiceProvider extends BiometricServiceProvider<FaceSensorPropertiesInternal> {
+public interface ServiceProvider {
+ /**
+ * Checks if the specified sensor is owned by this provider.
+ */
+ boolean containsSensor(int sensorId);
+
+ @NonNull
+ List<FaceSensorPropertiesInternal> getSensorProperties();
+
+ @NonNull
+ FaceSensorPropertiesInternal getSensorProperties(int sensorId);
@NonNull
List<Face> getEnrolledFaces(int sensorId, int userId);
+ @LockoutTracker.LockoutMode
+ int getLockoutModeForUser(int sensorId, int userId);
+
/**
* Requests for the authenticatorId (whose source of truth is in the TEE or equivalent) to be
* invalidated. See {@link com.android.server.biometrics.sensors.InvalidationRequesterClient}
@@ -69,6 +84,10 @@ public interface ServiceProvider extends BiometricServiceProvider<FaceSensorProp
+ " this method");
}
+ long getAuthenticatorId(int sensorId, int userId);
+
+ boolean isHardwareDetected(int sensorId);
+
void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
@NonNull IFaceServiceReceiver receiver, String opPackageName);
@@ -123,6 +142,13 @@ public interface ServiceProvider extends BiometricServiceProvider<FaceSensorProp
void scheduleInternalCleanup(int sensorId, int userId,
@Nullable ClientMonitorCallback callback, boolean favorHalEnrollments);
+ void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer);
+
+ void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
+
+ void dumpInternal(int sensorId, @NonNull PrintWriter pw);
+
@NonNull
ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 6bff179e8eb7..19d54c84c706 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -285,11 +285,6 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
}
@Override
- public boolean hasEnrollments(int sensorId, int userId) {
- return !getEnrolledFaces(sensorId, userId).isEmpty();
- }
-
- @Override
public void scheduleInvalidateAuthenticatorId(int sensorId, int userId,
@NonNull IInvalidationCallback callback) {
mHandler.post(() -> {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index c0a119ff5f1e..65289122747c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -484,11 +484,6 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
@Override
- public boolean hasEnrollments(int sensorId, int userId) {
- return !getEnrolledFaces(sensorId, userId).isEmpty();
- }
-
- @Override
@LockoutTracker.LockoutMode
public int getLockoutModeForUser(int sensorId, int userId) {
return mLockoutTracker.getLockoutModeForUser(userId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 7e2742edd47a..2ba449ae089e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -17,11 +17,14 @@
package com.android.server.biometrics.sensors.fingerprint;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.MANAGE_FINGERPRINT;
+import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
@@ -33,6 +36,8 @@ import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -60,6 +65,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -73,9 +79,11 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
+import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
@@ -107,32 +115,74 @@ public class FingerprintService extends SystemService {
protected static final String TAG = "FingerprintService";
+ private final Object mLock = new Object();
private final AppOpsManager mAppOps;
private final LockoutResetDispatcher mLockoutResetDispatcher;
private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
private final LockPatternUtils mLockPatternUtils;
- @NonNull
- private final BiometricContext mBiometricContext;
- @NonNull
- private final Supplier<String[]> mAidlInstanceNameSupplier;
- @NonNull
- private final Function<String, IFingerprint> mIFingerprintProvider;
- @NonNull
- private final BiometricStateCallback<ServiceProvider, FingerprintSensorPropertiesInternal>
- mBiometricStateCallback;
- @NonNull
- private final Handler mHandler;
- @NonNull
- private final FingerprintServiceRegistry mRegistry;
+ @NonNull private final List<ServiceProvider> mServiceProviders;
+ @NonNull private final BiometricStateCallback mBiometricStateCallback;
+ @NonNull private final Handler mHandler;
+ @NonNull private final BiometricContext mBiometricContext;
+ @NonNull private final Supplier<IBiometricService> mBiometricServiceSupplier;
+ @NonNull private final Function<String, IFingerprint> mIFingerprintProvider;
+
+ @GuardedBy("mLock")
+ @NonNull private final RemoteCallbackList<IFingerprintAuthenticatorsRegisteredCallback>
+ mAuthenticatorsRegisteredCallbacks;
+
+ @GuardedBy("mLock")
+ @NonNull private final List<FingerprintSensorPropertiesInternal> mSensorProps;
+
+ /**
+ * Registers BiometricStateListener in list stored by FingerprintService
+ * @param listener new BiometricStateListener being added
+ */
+ public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+ mBiometricStateCallback.registerBiometricStateListener(listener);
+ broadcastCurrentEnrollmentState(listener);
+ }
- /** Receives the incoming binder calls from FingerprintManager. */
- @VisibleForTesting
- final IFingerprintService.Stub mServiceWrapper = new IFingerprintService.Stub() {
+ /**
+ * @param listener if non-null, notifies only this listener. if null, notifies all listeners
+ * in {@link BiometricStateCallback}. This is slightly ugly, but reduces
+ * redundant code.
+ */
+ private void broadcastCurrentEnrollmentState(@Nullable IBiometricStateListener listener) {
+ final UserManager um = UserManager.get(getContext());
+ synchronized (mLock) {
+ // Update the new listener with current state of all sensors
+ for (FingerprintSensorPropertiesInternal prop : mSensorProps) {
+ final ServiceProvider provider = getProviderForSensor(prop.sensorId);
+ for (UserInfo userInfo : um.getAliveUsers()) {
+ final boolean enrolled = !provider
+ .getEnrolledFingerprints(prop.sensorId, userInfo.id).isEmpty();
+
+ // Defer this work and allow the loop to release the lock sooner
+ mHandler.post(() -> {
+ if (listener != null) {
+ mBiometricStateCallback.notifyEnrollmentStateChanged(
+ listener, userInfo.id, prop.sensorId, enrolled);
+ } else {
+ mBiometricStateCallback.notifyAllEnrollmentStateChanged(
+ userInfo.id, prop.sensorId, enrolled);
+ }
+ });
+ }
+ }
+ }
+ }
+
+ /**
+ * Receives the incoming binder calls from FingerprintManager.
+ */
+ private final IFingerprintService.Stub mServiceWrapper = new IFingerprintService.Stub() {
@android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
@@ -145,8 +195,9 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
+
final ProtoOutputStream proto = new ProtoOutputStream();
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider != null) {
provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
}
@@ -161,14 +212,16 @@ public class FingerprintService extends SystemService {
!= PackageManager.PERMISSION_GRANTED) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
- return mRegistry.getAllProperties();
+
+ return FingerprintService.this.getSensorProperties();
}
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId,
@NonNull String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
+ ", caller: " + opPackageName);
@@ -181,7 +234,8 @@ public class FingerprintService extends SystemService {
@Override // Binder call
public void generateChallenge(IBinder token, int sensorId, int userId,
IFingerprintServiceReceiver receiver, String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
return;
@@ -194,7 +248,8 @@ public class FingerprintService extends SystemService {
@Override // Binder call
public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
long challenge) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
return;
@@ -209,7 +264,8 @@ public class FingerprintService extends SystemService {
public long enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken,
final int userId, final IFingerprintServiceReceiver receiver,
final String opPackageName, @FingerprintManager.EnrollReason int enrollReason) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for enroll");
return -1;
@@ -222,7 +278,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public void cancelEnrollment(final IBinder token, long requestId) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for cancelEnrollment");
return;
@@ -282,10 +339,10 @@ public class FingerprintService extends SystemService {
final Pair<Integer, ServiceProvider> provider;
if (sensorId == FingerprintManager.SENSOR_ID_ANY) {
- provider = mRegistry.getSingleProvider();
+ provider = getSingleProvider();
} else {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
- provider = new Pair<>(sensorId, mRegistry.getProviderForSensor(sensorId));
+ provider = new Pair<>(sensorId, getProviderForSensor(sensorId));
}
if (provider == null) {
Slog.w(TAG, "Null provider for authenticate");
@@ -317,6 +374,7 @@ public class FingerprintService extends SystemService {
final IFingerprintServiceReceiver receiver,
final String opPackageName,
boolean ignoreEnrollmentState) throws PackageManager.NameNotFoundException {
+
final Context context = getUiContext();
final Context promptContext = context.createPackageContextAsUser(
opPackageName, 0 /* flags */, UserHandle.getUserHandleForUid(uId));
@@ -410,7 +468,7 @@ public class FingerprintService extends SystemService {
return -1;
}
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for detectFingerprint");
return -1;
@@ -426,7 +484,8 @@ public class FingerprintService extends SystemService {
public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
long requestId, int cookie, boolean allowBackgroundAuthentication) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for prepareForAuthentication");
return;
@@ -442,7 +501,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void startPreparedClient(int sensorId, int cookie) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for startPreparedClient");
return;
@@ -472,7 +532,7 @@ public class FingerprintService extends SystemService {
return;
}
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for cancelAuthentication");
return;
@@ -493,7 +553,7 @@ public class FingerprintService extends SystemService {
// For IBiometricsFingerprint2.1, cancelling fingerprint detect is the same as
// cancelling authentication.
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for cancelFingerprintDetect");
return;
@@ -506,9 +566,11 @@ public class FingerprintService extends SystemService {
@Override // Binder call
public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
final String opPackageName, final long requestId) {
+
+
Slog.d(TAG, "cancelAuthenticationFromService, sensorId: " + sensorId);
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
return;
@@ -521,7 +583,8 @@ public class FingerprintService extends SystemService {
@Override // Binder call
public void remove(final IBinder token, final int fingerId, final int userId,
final IFingerprintServiceReceiver receiver, final String opPackageName) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for remove");
return;
@@ -554,7 +617,7 @@ public class FingerprintService extends SystemService {
// This effectively iterates through all sensors, but has to do so by finding all
// sensors under each provider.
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
List<FingerprintSensorPropertiesInternal> props = provider.getSensorProperties();
for (FingerprintSensorPropertiesInternal prop : props) {
provider.scheduleRemoveAll(prop.sensorId, token, internalReceiver, userId,
@@ -589,7 +652,7 @@ public class FingerprintService extends SystemService {
try {
if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FingerprintSensorPropertiesInternal props
: provider.getSensorProperties()) {
provider.dumpProtoState(props.sensorId, proto, false);
@@ -597,14 +660,14 @@ public class FingerprintService extends SystemService {
}
proto.flush();
} else if (args.length > 0 && "--proto".equals(args[0])) {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FingerprintSensorPropertiesInternal props
: provider.getSensorProperties()) {
provider.dumpProtoMetrics(props.sensorId, fd);
}
}
} else {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FingerprintSensorPropertiesInternal props
: provider.getSensorProperties()) {
pw.println("Dumping for sensorId: " + props.sensorId
@@ -635,7 +698,7 @@ public class FingerprintService extends SystemService {
final long token = Binder.clearCallingIdentity();
try {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for isHardwareDetectedDeprecated, caller: "
+ opPackageName);
@@ -650,7 +713,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public boolean isHardwareDetected(int sensorId, String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
return false;
@@ -666,7 +730,7 @@ public class FingerprintService extends SystemService {
return;
}
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for rename");
return;
@@ -717,7 +781,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
public boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for hasEnrolledFingerprints, caller: " + opPackageName);
return false;
@@ -729,7 +794,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for getLockoutModeForUser");
return LockoutTracker.LOCKOUT_NONE;
@@ -741,7 +807,8 @@ public class FingerprintService extends SystemService {
@Override
public void invalidateAuthenticatorId(int sensorId, int userId,
IInvalidationCallback callback) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for invalidateAuthenticatorId");
return;
@@ -752,7 +819,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long getAuthenticatorId(int sensorId, int userId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for getAuthenticatorId");
return 0;
@@ -764,7 +832,8 @@ public class FingerprintService extends SystemService {
@Override // Binder call
public void resetLockout(IBinder token, int sensorId, int userId,
@Nullable byte[] hardwareAuthToken, String opPackageName) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
return;
@@ -795,38 +864,55 @@ public class FingerprintService extends SystemService {
@Override // Binder call
public void registerAuthenticators(
@NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
- mRegistry.registerAll(() -> {
- final List<ServiceProvider> providers = new ArrayList<>();
- providers.addAll(getHidlProviders(hidlSensors));
+
+ // Some HAL might not be started before the system service and will cause the code below
+ // to wait, and some of the operations below might take a significant amount of time to
+ // complete (calls to the HALs). To avoid blocking the rest of system server we put
+ // this on a background thread.
+ final ServiceThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
+ true /* allowIo */);
+ thread.start();
+ final Handler handler = new Handler(thread.getLooper());
+ handler.post(() -> {
List<String> aidlSensors = new ArrayList<>();
- final String[] instances = mAidlInstanceNameSupplier.get();
+ final String[] instances =
+ ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
if (instances != null) {
aidlSensors.addAll(Lists.newArrayList(instances));
}
- providers.addAll(getAidlProviders(
- Utils.filterAvailableHalInstances(getContext(), aidlSensors)));
- return providers;
+ registerAuthenticatorsForService(aidlSensors, hidlSensors);
});
+ thread.quitSafely();
}
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void addAuthenticatorsRegisteredCallback(
IFingerprintAuthenticatorsRegisteredCallback callback) {
- mRegistry.addAllRegisteredCallback(callback);
- }
+ if (callback == null) {
+ Slog.e(TAG, "addAuthenticatorsRegisteredCallback, callback is null");
+ return;
+ }
- @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
- @Override
- public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
- mBiometricStateCallback.registerBiometricStateListener(listener);
+ final boolean registered;
+ final boolean hasSensorProps;
+ synchronized (mLock) {
+ registered = mAuthenticatorsRegisteredCallbacks.register(callback);
+ hasSensorProps = !mSensorProps.isEmpty();
+ }
+ if (registered && hasSensorProps) {
+ broadcastAllAuthenticatorsRegistered();
+ } else if (!registered) {
+ Slog.e(TAG, "addAuthenticatorsRegisteredCallback failed to register callback");
+ }
}
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void onPointerDown(long requestId, int sensorId, int x, int y,
float minor, float major) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching provider for onFingerDown, sensorId: " + sensorId);
return;
@@ -837,7 +923,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void onPointerUp(long requestId, int sensorId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching provider for onFingerUp, sensorId: " + sensorId);
return;
@@ -848,7 +935,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void onUiReady(long requestId, int sensorId) {
- final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
Slog.w(TAG, "No matching provider for onUiReady, sensorId: " + sensorId);
return;
@@ -859,7 +947,8 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+
+ for (ServiceProvider provider : mServiceProviders) {
provider.setUdfpsOverlayController(controller);
}
}
@@ -867,15 +956,22 @@ public class FingerprintService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void setSidefpsController(@NonNull ISidefpsController controller) {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+
+ for (ServiceProvider provider : mServiceProviders) {
provider.setSidefpsController(controller);
}
}
- @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
+ @Override
+ public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+ FingerprintService.this.registerBiometricStateListener(listener);
+ }
+
@Override
public void onPowerPressed() {
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+ for (ServiceProvider provider : mServiceProviders) {
provider.onPowerPressed();
}
}
@@ -885,7 +981,6 @@ public class FingerprintService extends SystemService {
this(context, BiometricContext.getInstance(context),
() -> IBiometricService.Stub.asInterface(
ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
- () -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR),
(fqName) -> IFingerprint.Stub.asInterface(
Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName))));
}
@@ -893,34 +988,61 @@ public class FingerprintService extends SystemService {
@VisibleForTesting
FingerprintService(Context context,
BiometricContext biometricContext,
- Supplier<IBiometricService> biometricServiceSupplier,
- Supplier<String[]> aidlInstanceNameSupplier,
+ Supplier<IBiometricService> biometricServiceProvider,
Function<String, IFingerprint> fingerprintProvider) {
super(context);
mBiometricContext = biometricContext;
- mAidlInstanceNameSupplier = aidlInstanceNameSupplier;
+ mBiometricServiceSupplier = biometricServiceProvider;
mIFingerprintProvider = fingerprintProvider;
mAppOps = context.getSystemService(AppOpsManager.class);
mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
- mBiometricStateCallback = new BiometricStateCallback<>(UserManager.get(context));
+ mServiceProviders = new ArrayList<>();
+ mBiometricStateCallback = new BiometricStateCallback();
+ mAuthenticatorsRegisteredCallbacks = new RemoteCallbackList<>();
+ mSensorProps = new ArrayList<>();
mHandler = new Handler(Looper.getMainLooper());
- mRegistry = new FingerprintServiceRegistry(mServiceWrapper, biometricServiceSupplier);
- mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FingerprintSensorPropertiesInternal> sensors) {
- mBiometricStateCallback.start(mRegistry.getProviders());
- }
- });
}
- @NonNull
- private List<ServiceProvider> getHidlProviders(
+ @VisibleForTesting
+ void registerAuthenticatorsForService(@NonNull List<String> aidlInstanceNames,
@NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
- final List<ServiceProvider> providers = new ArrayList<>();
+ addHidlProviders(hidlSensors);
+ addAidlProviders(Utils.filterAvailableHalInstances(getContext(), aidlInstanceNames));
+
+ final IBiometricService biometricService = mBiometricServiceSupplier.get();
+
+ // Register each sensor individually with BiometricService
+ for (ServiceProvider provider : mServiceProviders) {
+ final List<FingerprintSensorPropertiesInternal> props =
+ provider.getSensorProperties();
+ for (FingerprintSensorPropertiesInternal prop : props) {
+ final int sensorId = prop.sensorId;
+ @BiometricManager.Authenticators.Types final int strength =
+ Utils.propertyStrengthToAuthenticatorStrength(prop.sensorStrength);
+ final FingerprintAuthenticator authenticator = new FingerprintAuthenticator(
+ mServiceWrapper, sensorId);
+ try {
+ biometricService.registerAuthenticator(sensorId, TYPE_FINGERPRINT,
+ strength, authenticator);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
+ }
+ }
+ }
+
+ synchronized (mLock) {
+ for (ServiceProvider provider : mServiceProviders) {
+ mSensorProps.addAll(provider.getSensorProperties());
+ }
+ }
+ broadcastCurrentEnrollmentState(null); // broadcasts to all listeners
+ broadcastAllAuthenticatorsRegistered();
+ }
+
+ private void addHidlProviders(List<FingerprintSensorPropertiesInternal> hidlSensors) {
for (FingerprintSensorPropertiesInternal hidlSensor : hidlSensors) {
final Fingerprint21 fingerprint21;
if ((Build.IS_USERDEBUG || Build.IS_ENG)
@@ -937,16 +1059,11 @@ public class FingerprintService extends SystemService {
mBiometricStateCallback, hidlSensor, mHandler,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
}
- providers.add(fingerprint21);
+ mServiceProviders.add(fingerprint21);
}
-
- return providers;
}
- @NonNull
- private List<ServiceProvider> getAidlProviders(@NonNull List<String> instances) {
- final List<ServiceProvider> providers = new ArrayList<>();
-
+ private void addAidlProviders(List<String> instances) {
for (String instance : instances) {
final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
final IFingerprint fp = mIFingerprintProvider.apply(fqName);
@@ -958,7 +1075,7 @@ public class FingerprintService extends SystemService {
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
mBiometricContext);
Slog.i(TAG, "Adding AIDL provider: " + fqName);
- providers.add(provider);
+ mServiceProviders.add(provider);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
}
@@ -966,8 +1083,38 @@ public class FingerprintService extends SystemService {
Slog.e(TAG, "Unable to get declared service: " + fqName);
}
}
+ }
- return providers;
+ // Notifies the callbacks that all of the authenticators have been registered and removes the
+ // invoked callbacks from the callback list.
+ private void broadcastAllAuthenticatorsRegistered() {
+ // Make a local copy of the data so it can be used outside of the synchronized block when
+ // making Binder calls.
+ final List<IFingerprintAuthenticatorsRegisteredCallback> callbacks = new ArrayList<>();
+ final List<FingerprintSensorPropertiesInternal> props;
+ synchronized (mLock) {
+ if (!mSensorProps.isEmpty()) {
+ props = new ArrayList<>(mSensorProps);
+ } else {
+ Slog.e(TAG, "mSensorProps is empty");
+ return;
+ }
+ final int n = mAuthenticatorsRegisteredCallbacks.beginBroadcast();
+ for (int i = 0; i < n; ++i) {
+ final IFingerprintAuthenticatorsRegisteredCallback cb =
+ mAuthenticatorsRegisteredCallbacks.getBroadcastItem(i);
+ callbacks.add(cb);
+ mAuthenticatorsRegisteredCallbacks.unregister(cb);
+ }
+ mAuthenticatorsRegisteredCallbacks.finishBroadcast();
+ }
+ for (IFingerprintAuthenticatorsRegisteredCallback cb : callbacks) {
+ try {
+ cb.onAllAuthenticatorsRegistered(props);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception in onAllAuthenticatorsRegistered", e);
+ }
+ }
}
@Override
@@ -975,9 +1122,51 @@ public class FingerprintService extends SystemService {
publishBinderService(Context.FINGERPRINT_SERVICE, mServiceWrapper);
}
+ @Nullable
+ private ServiceProvider getProviderForSensor(int sensorId) {
+ for (ServiceProvider provider : mServiceProviders) {
+ if (provider.containsSensor(sensorId)) {
+ return provider;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * For devices with only a single provider, returns that provider. If multiple providers,
+ * returns the first one. If no providers, returns null.
+ */
+ @Nullable
+ private Pair<Integer, ServiceProvider> getSingleProvider() {
+ final List<FingerprintSensorPropertiesInternal> properties = getSensorProperties();
+ if (properties.isEmpty()) {
+ Slog.e(TAG, "No providers found");
+ return null;
+ }
+
+ // Theoretically we can just return the first provider, but maybe this is easier to
+ // understand.
+ final int sensorId = properties.get(0).sensorId;
+ for (ServiceProvider provider : mServiceProviders) {
+ if (provider.containsSensor(sensorId)) {
+ return new Pair<>(sensorId, provider);
+ }
+ }
+
+ Slog.e(TAG, "Provider not found");
+ return null;
+ }
+
+ @NonNull
+ private List<FingerprintSensorPropertiesInternal> getSensorProperties() {
+ synchronized (mLock) {
+ return mSensorProps;
+ }
+ }
+
@NonNull
private List<Fingerprint> getEnrolledFingerprintsDeprecated(int userId, String opPackageName) {
- final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for getEnrolledFingerprintsDeprecated, caller: "
+ opPackageName);
@@ -1040,7 +1229,7 @@ public class FingerprintService extends SystemService {
if (Utils.isVirtualEnabled(getContext())) {
Slog.i(TAG, "Sync virtual enrollments");
final int userId = ActivityManager.getCurrentUser();
- for (ServiceProvider provider : mRegistry.getProviders()) {
+ for (ServiceProvider provider : mServiceProviders) {
for (FingerprintSensorPropertiesInternal props : provider.getSensorProperties()) {
provider.scheduleInternalCleanup(props.sensorId, userId, null /* callback */,
true /* favorHalEnrollments */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java
deleted file mode 100644
index 33810b764f23..000000000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.IBiometricService;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
-import android.hardware.fingerprint.IFingerprintService;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.sensors.BiometricServiceRegistry;
-
-import java.util.List;
-import java.util.function.Supplier;
-
-/** Registry for {@link IFingerprintService} providers. */
-public class FingerprintServiceRegistry extends BiometricServiceRegistry<ServiceProvider,
- FingerprintSensorPropertiesInternal, IFingerprintAuthenticatorsRegisteredCallback> {
-
- private static final String TAG = "FingerprintServiceRegistry";
-
- @NonNull
- private final IFingerprintService mService;
-
- /** Creates a new registry tied to the given service. */
- public FingerprintServiceRegistry(@NonNull IFingerprintService service,
- @Nullable Supplier<IBiometricService> biometricSupplier) {
- super(biometricSupplier);
- mService = service;
- }
-
- @Override
- protected void registerService(@NonNull IBiometricService service,
- @NonNull FingerprintSensorPropertiesInternal props) {
- @BiometricManager.Authenticators.Types final int strength =
- Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength);
- try {
- service.registerAuthenticator(props.sensorId, TYPE_FINGERPRINT, strength,
- new FingerprintAuthenticator(mService, props.sensorId));
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception when registering sensorId: " + props.sensorId);
- }
- }
-
- @Override
- protected void invokeRegisteredCallback(
- @NonNull IFingerprintAuthenticatorsRegisteredCallback callback,
- @NonNull List<FingerprintSensorPropertiesInternal> allProps) throws RemoteException {
- callback.onAllAuthenticatorsRegistered(allProps);
- }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index 9075e7ec2080..275d7e445a75 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -28,11 +28,14 @@ import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder;
+import android.util.proto.ProtoOutputStream;
-import com.android.server.biometrics.sensors.BiometricServiceProvider;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.LockoutTracker;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.List;
/**
@@ -56,8 +59,23 @@ import java.util.List;
* fail safely.
*/
@SuppressWarnings("deprecation")
-public interface ServiceProvider extends
- BiometricServiceProvider<FingerprintSensorPropertiesInternal> {
+public interface ServiceProvider {
+ /**
+ * Checks if the specified sensor is owned by this provider.
+ */
+ boolean containsSensor(int sensorId);
+
+ @NonNull
+ List<FingerprintSensorPropertiesInternal> getSensorProperties();
+
+ /**
+ * Returns the internal properties of the specified sensor, if owned by this provider.
+ *
+ * @param sensorId The ID of a fingerprint sensor, or -1 for any sensor.
+ * @return An object representing the internal properties of the specified sensor.
+ */
+ @Nullable
+ FingerprintSensorPropertiesInternal getSensorProperties(int sensorId);
void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken);
@@ -108,11 +126,16 @@ public interface ServiceProvider extends
void scheduleInternalCleanup(int sensorId, int userId,
@Nullable ClientMonitorCallback callback, boolean favorHalEnrollments);
+ boolean isHardwareDetected(int sensorId);
+
void rename(int sensorId, int fingerId, int userId, @NonNull String name);
@NonNull
List<Fingerprint> getEnrolledFingerprints(int sensorId, int userId);
+ @LockoutTracker.LockoutMode
+ int getLockoutModeForUser(int sensorId, int userId);
+
/**
* Requests for the authenticatorId (whose source of truth is in the TEE or equivalent) to
* be invalidated. See {@link com.android.server.biometrics.sensors.InvalidationRequesterClient}
@@ -120,6 +143,7 @@ public interface ServiceProvider extends
void scheduleInvalidateAuthenticatorId(int sensorId, int userId,
@NonNull IInvalidationCallback callback);
+ long getAuthenticatorId(int sensorId, int userId);
void onPointerDown(long requestId, int sensorId, int x, int y, float minor, float major);
@@ -137,6 +161,13 @@ public interface ServiceProvider extends
*/
void setSidefpsController(@NonNull ISidefpsController controller);
+ void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer);
+
+ void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
+
+ void dumpInternal(int sensorId, @NonNull PrintWriter pw);
+
@NonNull
ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 3fe6332fcaa0..2dc005206b42 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -565,11 +565,6 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
}
@Override
- public boolean hasEnrollments(int sensorId, int userId) {
- return !getEnrolledFingerprints(sensorId, userId).isEmpty();
- }
-
- @Override
public void scheduleInvalidateAuthenticatorId(int sensorId, int userId,
@NonNull IInvalidationCallback callback) {
mHandler.post(() -> {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 0e6df8e0df77..ed482f013869 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -789,11 +789,6 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
}
@Override
- public boolean hasEnrollments(int sensorId, int userId) {
- return !getEnrolledFingerprints(sensorId, userId).isEmpty();
- }
-
- @Override
@LockoutTracker.LockoutMode public int getLockoutModeForUser(int sensorId, int userId) {
return mLockoutTracker.getLockoutModeForUser(userId);
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java
deleted file mode 100644
index 8cd58abcdf0f..000000000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG;
-import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_WEAK;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.hardware.biometrics.IBiometricService;
-import android.hardware.face.FaceSensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
-import android.hardware.face.IFaceService;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Presubmit
-@SmallTest
-public class FaceServiceRegistryTest {
-
- private static final int SENSOR_ID_1 = 1;
- private static final int SENSOR_ID_2 = 2;
-
- @Rule
- public final MockitoRule mockito = MockitoJUnit.rule();
-
- @Mock
- private IBiometricService mBiometricService;
- @Mock
- private IFaceService mFaceService;
- @Mock
- private ServiceProvider mProvider1;
- @Mock
- private ServiceProvider mProvider2;
- @Captor
- private ArgumentCaptor<Integer> mIdCaptor;
- @Captor
- private ArgumentCaptor<Integer> mStrengthCaptor;
-
- private FaceSensorPropertiesInternal mProvider1Props;
- private FaceSensorPropertiesInternal mProvider2Props;
- private FaceServiceRegistry mRegistry;
-
- @Before
- public void setup() {
- mProvider1Props = new FaceSensorPropertiesInternal(SENSOR_ID_1,
- STRENGTH_WEAK, 5 /* maxEnrollmentsPerUser */,
- List.of(), FaceSensorProperties.TYPE_RGB,
- true /* supportsFace Detection */,
- true /* supportsSelfIllumination */,
- false /* resetLockoutRequiresHardwareAuthToken */);
- mProvider2Props = new FaceSensorPropertiesInternal(SENSOR_ID_2,
- STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
- List.of(), FaceSensorProperties.TYPE_IR,
- true /* supportsFace Detection */,
- true /* supportsSelfIllumination */,
- false /* resetLockoutRequiresHardwareAuthToken */);
-
- when(mProvider1.getSensorProperties()).thenReturn(List.of(mProvider1Props));
- when(mProvider1.containsSensor(eq(SENSOR_ID_1))).thenReturn(true);
- when(mProvider2.getSensorProperties()).thenReturn(List.of(mProvider2Props));
- when(mProvider2.containsSensor(eq(SENSOR_ID_2))).thenReturn(true);
- mRegistry = new FaceServiceRegistry(mFaceService, () -> mBiometricService);
- }
-
- @Test
- public void registersAllProviders() throws Exception {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- assertThat(mRegistry.getProviders()).containsExactly(mProvider1, mProvider2);
- assertThat(mRegistry.getAllProperties()).containsExactly(mProvider1Props, mProvider2Props);
- verify(mBiometricService, times(2)).registerAuthenticator(
- mIdCaptor.capture(), eq(TYPE_FACE), mStrengthCaptor.capture(), any());
- assertThat(mIdCaptor.getAllValues()).containsExactly(SENSOR_ID_1, SENSOR_ID_2);
- assertThat(mStrengthCaptor.getAllValues())
- .containsExactly(BIOMETRIC_WEAK, BIOMETRIC_STRONG);
- }
-
- @Test
- public void getsProviderById() {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- assertThat(mRegistry.getProviderForSensor(SENSOR_ID_1)).isSameInstanceAs(mProvider1);
- assertThat(mRegistry.getProviderForSensor(SENSOR_ID_2)).isSameInstanceAs(mProvider2);
- assertThat(mRegistry.getProviderForSensor(500)).isNull();
- }
-
- @Test
- public void getsSingleProvider() {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1));
-
- assertThat(mRegistry.getSingleProvider().second).isSameInstanceAs(mProvider1);
- assertThat(mRegistry.getProviders()).containsExactly(mProvider1);
- assertThat(mRegistry.getProviderForSensor(SENSOR_ID_1)).isSameInstanceAs(mProvider1);
- }
-
- @Test
- public void registersListenerBeforeAllRegistered() {
- final List<FaceSensorPropertiesInternal> all = new ArrayList<>();
- mRegistry.addAllRegisteredCallback(new IFaceAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FaceSensorPropertiesInternal> sensors) {
- all.addAll(sensors);
- }
- });
-
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- assertThat(all).containsExactly(mProvider1Props, mProvider2Props);
- }
-
- @Test
- public void registersListenerAfterAllRegistered() {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- final List<FaceSensorPropertiesInternal> all = new ArrayList<>();
- mRegistry.addAllRegisteredCallback(new IFaceAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FaceSensorPropertiesInternal> sensors) {
- all.addAll(sensors);
- }
- });
-
- assertThat(all).containsExactly(mProvider1Props, mProvider2Props);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
index 0e30782eaece..5f88c99b1d1e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
@@ -16,8 +16,6 @@
package com.android.server.biometrics.sensors.fingerprint;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
-
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -26,70 +24,35 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricStateListener;
-import android.hardware.biometrics.SensorPropertiesInternal;
-import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.BiometricServiceProvider;
import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.EnrollClient;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.List;
+import org.mockito.MockitoAnnotations;
@Presubmit
@SmallTest
public class BiometricStateCallbackTest {
- private static final int USER_ID = 10;
- private static final int SENSOR_ID = 2;
-
- @Rule
- public final MockitoRule mockito = MockitoJUnit.rule();
-
- private BiometricStateCallback<FakeProvider, SensorPropertiesInternal> mCallback;
+ private BiometricStateCallback mCallback;
@Mock
- private UserManager mUserManager;
- @Mock
- private BiometricStateListener mBiometricStateListener;
- @Mock
- private FakeProvider mFakeProvider;
-
- private SensorPropertiesInternal mFakeProviderProps;
+ BiometricStateListener mBiometricStateListener;
@Before
public void setup() {
- mFakeProviderProps = new SensorPropertiesInternal(SENSOR_ID, STRENGTH_STRONG,
- 5 /* maxEnrollmentsPerUser */, List.of(),
- false /* resetLockoutRequiresHardwareAuthToken */,
- false /* resetLockoutRequiresChallenge */);
- when(mFakeProvider.getSensorProperties()).thenReturn(List.of(mFakeProviderProps));
- when(mFakeProvider.getSensorProperties(eq(SENSOR_ID))).thenReturn(mFakeProviderProps);
- when(mFakeProvider.hasEnrollments(eq(SENSOR_ID), eq(USER_ID))).thenReturn(true);
- when(mUserManager.getAliveUsers()).thenReturn(
- List.of(new UserInfo(USER_ID, "name", 0)));
-
- mCallback = new BiometricStateCallback<>(mUserManager);
- mCallback.registerBiometricStateListener(mBiometricStateListener);
- }
-
- @Test
- public void startNotifiesEnrollments() {
- mCallback.start(List.of(mFakeProvider));
+ MockitoAnnotations.initMocks(this);
- verify(mBiometricStateListener).onEnrollmentsChanged(eq(USER_ID), eq(SENSOR_ID), eq(true));
+ mCallback = new BiometricStateCallback();
+ mCallback.registerBiometricStateListener(mBiometricStateListener);
}
@Test
@@ -139,6 +102,4 @@ public class BiometricStateCallbackTest {
verify(mBiometricStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
anyBoolean());
}
-
- private interface FakeProvider extends BiometricServiceProvider<SensorPropertiesInternal> {}
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java
deleted file mode 100644
index 67d94a8f02d8..000000000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG;
-import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_WEAK;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.hardware.biometrics.IBiometricService;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
-import android.hardware.fingerprint.IFingerprintService;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Presubmit
-@SmallTest
-public class FingerprintServiceRegistryTest {
-
- private static final int SENSOR_ID_1 = 1;
- private static final int SENSOR_ID_2 = 2;
-
- @Rule
- public final MockitoRule mockito = MockitoJUnit.rule();
-
- @Mock
- private IBiometricService mBiometricService;
- @Mock
- private IFingerprintService mFingerprintService;
- @Mock
- private ServiceProvider mProvider1;
- @Mock
- private ServiceProvider mProvider2;
- @Captor
- private ArgumentCaptor<Integer> mIdCaptor;
- @Captor
- private ArgumentCaptor<Integer> mStrengthCaptor;
-
- private FingerprintSensorPropertiesInternal mProvider1Props;
- private FingerprintSensorPropertiesInternal mProvider2Props;
- private FingerprintServiceRegistry mRegistry;
-
- @Before
- public void setup() {
- mProvider1Props = new FingerprintSensorPropertiesInternal(SENSOR_ID_1,
- STRENGTH_WEAK, 5 /* maxEnrollmentsPerUser */,
- List.of(), FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
- false /* resetLockoutRequiresHardwareAuthToken */);
- mProvider2Props = new FingerprintSensorPropertiesInternal(SENSOR_ID_2,
- STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
- List.of(), FingerprintSensorProperties.TYPE_UNKNOWN,
- false /* resetLockoutRequiresHardwareAuthToken */);
-
- when(mProvider1.getSensorProperties()).thenReturn(List.of(mProvider1Props));
- when(mProvider1.containsSensor(eq(SENSOR_ID_1))).thenReturn(true);
- when(mProvider2.getSensorProperties()).thenReturn(List.of(mProvider2Props));
- when(mProvider2.containsSensor(eq(SENSOR_ID_2))).thenReturn(true);
- mRegistry = new FingerprintServiceRegistry(mFingerprintService, () -> mBiometricService);
- }
-
- @Test
- public void registersAllProviders() throws Exception {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- assertThat(mRegistry.getProviders()).containsExactly(mProvider1, mProvider2);
- assertThat(mRegistry.getAllProperties()).containsExactly(mProvider1Props, mProvider2Props);
- verify(mBiometricService, times(2)).registerAuthenticator(
- mIdCaptor.capture(), eq(TYPE_FINGERPRINT), mStrengthCaptor.capture(), any());
- assertThat(mIdCaptor.getAllValues()).containsExactly(SENSOR_ID_1, SENSOR_ID_2);
- assertThat(mStrengthCaptor.getAllValues())
- .containsExactly(BIOMETRIC_WEAK, BIOMETRIC_STRONG);
- }
-
- @Test
- public void getsProviderById() {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- assertThat(mRegistry.getProviderForSensor(SENSOR_ID_1)).isSameInstanceAs(mProvider1);
- assertThat(mRegistry.getProviderForSensor(SENSOR_ID_2)).isSameInstanceAs(mProvider2);
- assertThat(mRegistry.getProviderForSensor(500)).isNull();
- }
-
- @Test
- public void getsSingleProvider() {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1));
-
- assertThat(mRegistry.getSingleProvider().second).isSameInstanceAs(mProvider1);
- assertThat(mRegistry.getProviders()).containsExactly(mProvider1);
- assertThat(mRegistry.getProviderForSensor(SENSOR_ID_1)).isSameInstanceAs(mProvider1);
- }
-
- @Test
- public void registersListenerBeforeAllRegistered() {
- final List<FingerprintSensorPropertiesInternal> all = new ArrayList<>();
- mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FingerprintSensorPropertiesInternal> sensors) {
- all.addAll(sensors);
- }
- });
-
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- assertThat(all).containsExactly(mProvider1Props, mProvider2Props);
- }
-
- @Test
- public void registersListenerAfterAllRegistered() {
- mRegistry.registerAllInBackground(() -> List.of(mProvider1, mProvider2));
-
- final List<FingerprintSensorPropertiesInternal> all = new ArrayList<>();
- mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FingerprintSensorPropertiesInternal> sensors) {
- all.addAll(sensors);
- }
- });
-
- assertThat(all).containsExactly(mProvider1Props, mProvider2Props);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
index a4048a27dfb5..ca3677e3b5ff 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -32,8 +32,7 @@ import android.hardware.biometrics.fingerprint.FingerprintSensorType;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorLocation;
import android.hardware.biometrics.fingerprint.SensorProps;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.testing.TestableContext;
@@ -53,8 +52,6 @@ import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
@Presubmit
@SmallTest
@@ -97,12 +94,9 @@ public class FingerprintServiceTest {
mContext.getTestablePermissions().setPermission(
USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_GRANTED);
- }
- private void initServiceWith(String... aidlInstances) {
mService = new FingerprintService(mContext, mBiometricContext,
() -> mIBiometricService,
- () -> aidlInstances,
(fqName) -> {
if (fqName.endsWith(NAME_DEFAULT)) return mIFingerprintDefault;
if (fqName.endsWith(NAME_VIRTUAL)) return mIFingerprintVirtual;
@@ -111,50 +105,29 @@ public class FingerprintServiceTest {
}
@Test
- public void registerAuthenticators_defaultOnly() throws Exception {
- initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
-
- mService.mServiceWrapper.registerAuthenticators(List.of());
- waitForRegistration();
+ public void registerAuthenticators_defaultOnly() throws RemoteException {
+ mService.registerAuthenticatorsForService(List.of(NAME_DEFAULT, NAME_VIRTUAL), List.of());
verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
}
@Test
- public void registerAuthenticators_virtualOnly() throws Exception {
- initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
+ public void registerAuthenticators_virtualOnly() throws RemoteException {
Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
- mService.mServiceWrapper.registerAuthenticators(List.of());
- waitForRegistration();
+ mService.registerAuthenticatorsForService(List.of(NAME_DEFAULT, NAME_VIRTUAL), List.of());
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
}
@Test
- public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception {
- initServiceWith(NAME_VIRTUAL);
-
- mService.mServiceWrapper.registerAuthenticators(List.of());
- waitForRegistration();
+ public void registerAuthenticators_virtualAlwaysWhenNoOther() throws RemoteException {
+ mService.registerAuthenticatorsForService(List.of(NAME_VIRTUAL), List.of());
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
}
- private void waitForRegistration() throws Exception {
- final CountDownLatch latch = new CountDownLatch(1);
- mService.mServiceWrapper.addAuthenticatorsRegisteredCallback(
- new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
- @Override
- public void onAllAuthenticatorsRegistered(
- List<FingerprintSensorPropertiesInternal> sensors) {
- latch.countDown();
- }
- });
- latch.await(5, TimeUnit.SECONDS);
- }
-
private static SensorProps createProps(int id, byte strength, byte type) {
final SensorProps props = new SensorProps();
props.commonProps = new CommonProps();