From b2888343b76985188fa2a02acedebe5dbc8755aa Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 16 Feb 2021 14:46:26 -0800 Subject: [PATCH 1/2] Update RemovalClient to support new biometric AIDL The new AIDL interfaces accept a list of IDs to remove. Note that the new interfaces explicitly do NOT support using "remove(0)" to remove all enrollments. Fixes: 179338634 Test: atest CtsBiometricsTestCases Test: atest com.android.server.biometrics Change-Id: I59f6e607ff876541f049ac70d06046815eba7632 --- .../android/hardware/face/FaceManager.java | 23 ++++++++++++++----- .../android/hardware/face/IFaceService.aidl | 5 +++- .../fingerprint/FingerprintManager.java | 21 +++++++++++++---- .../fingerprint/IFingerprintService.aidl | 3 +++ .../biometrics/sensors/RemovalClient.java | 7 +++--- .../biometrics/sensors/face/FaceService.java | 17 +++++++++++++- .../sensors/face/ServiceProvider.java | 3 +++ .../face/aidl/FaceInternalCleanupClient.java | 4 ++-- .../sensors/face/aidl/FaceProvider.java | 21 ++++++++++++++++- .../sensors/face/aidl/FaceRemovalClient.java | 13 +++++++---- .../biometrics/sensors/face/hidl/Face10.java | 14 +++++++++++ .../sensors/face/hidl/FaceRemovalClient.java | 5 +++- .../fingerprint/FingerprintService.java | 16 ++++++++++++- .../sensors/fingerprint/ServiceProvider.java | 4 ++++ .../FingerprintInternalCleanupClient.java | 4 ++-- .../fingerprint/aidl/FingerprintProvider.java | 23 ++++++++++++++++++- .../aidl/FingerprintRemovalClient.java | 10 ++++---- .../fingerprint/hidl/Fingerprint21.java | 17 ++++++++++++++ .../hidl/FingerprintRemovalClient.java | 5 +++- .../locksettings/LockSettingsService.java | 23 +++++++------------ .../LockSettingsServiceTests.java | 8 +++---- 21 files changed, 192 insertions(+), 54 deletions(-) diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 588bc01d7d420..28bc404efb363 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -562,12 +562,23 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver, mContext.getOpPackageName()); } catch (RemoteException e) { - Slog.w(TAG, "Remote exception in remove: ", e); - if (callback != null) { - callback.onRemovalError(face, FACE_ERROR_HW_UNAVAILABLE, - getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE, - 0 /* vendorCode */)); - } + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Removes all face templates for the given user. + * @hide + */ + @RequiresPermission(MANAGE_BIOMETRIC) + public void removeAll(int userId, @NonNull RemovalCallback callback) { + if (mService != null) { + try { + mRemovalCallback = callback; + mService.removeAll(mToken, userId, mServiceReceiver, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } } diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index a3e7e2d2c5cbc..a2e0b3b1cb411 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -83,10 +83,13 @@ interface IFaceService { // Cancel enrollment in progress void cancelEnrollment(IBinder token); - // Any errors resulting from this call will be returned to the listener + // Removes the specified face enrollment for the specified userId. void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver, String opPackageName); + // Removes all face enrollments for the specified userId. + void removeAll(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName); + // Get the enrolled face for user. List getEnrolledFaces(int sensorId, int userId, String opPackageName); diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index a614ebfe1793a..6df2764d3f8bf 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -739,11 +739,22 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing mService.remove(mToken, fp.getBiometricId(), userId, mServiceReceiver, mContext.getOpPackageName()); } catch (RemoteException e) { - Slog.w(TAG, "Remote exception in remove: ", e); - if (callback != null) { - callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE, - getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE, - 0 /* vendorCode */)); + throw e.rethrowFromSystemServer(); + } + } + + /** + * Removes all face templates for the given user. + * @hide + */ + @RequiresPermission(MANAGE_FINGERPRINT) + public void removeAll(int userId, @NonNull RemovalCallback callback) { + if (mService != null) { + try { + mRemovalCallback = callback; + mService.removeAll(mToken, userId, mServiceReceiver, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } } diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index 8888247e2823f..1694fef0f71bf 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -87,6 +87,9 @@ interface IFingerprintService { void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver, String opPackageName); + // Removes all face enrollments for the specified userId. + void removeAll(IBinder token, int userId, IFingerprintServiceReceiver receiver, String opPackageName); + // Rename the fingerprint specified by fingerId and userId to the given name void rename(int fingerId, int userId, String name); diff --git a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java index e0626952fac3c..16f82af938560 100644 --- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java @@ -37,18 +37,16 @@ public abstract class RemovalClient mBiometricUtils; private final Map mAuthenticatorIds; public RemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, - int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, - int sensorId, @NonNull Map authenticatorIds, int statsModality) { + int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, + @NonNull Map authenticatorIds, int statsModality) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, statsModality, BiometricsProtoEnums.ACTION_REMOVE, BiometricsProtoEnums.CLIENT_UNKNOWN); - mBiometricId = biometricId; mBiometricUtils = utils; mAuthenticatorIds = authenticatorIds; } @@ -68,6 +66,7 @@ public abstract class RemovalClient provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for removeAll"); + return; + } + + provider.second.scheduleRemoveAll(provider.first, token, userId, receiver, + opPackageName); + } + + @Override // Binder call public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback, final String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); 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 cc24b8960e756..0b522efb5bac4 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 @@ -109,6 +109,9 @@ public interface ServiceProvider { void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName); + void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId, + @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName); + void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken); void scheduleSetFeature(int sensorId, @NonNull IBinder token, int userId, int feature, diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java index 9680e4e1841e7..c6696aed6520d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java @@ -61,7 +61,7 @@ class FaceInternalCleanupClient extends InternalCleanupClient { // Internal remove does not need to send results to anyone. Cleanup (enumerate + remove) // is all done internally. return new FaceRemovalClient(context, lazyDaemon, token, - null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils, - sensorId, authenticatorIds); + null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner, + utils, sensorId, authenticatorIds); } } 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 e685ee2899afa..dc2611f006356 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 @@ -468,6 +468,25 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @Override public void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { + scheduleRemoveSpecifiedIds(sensorId, token, new int[] {faceId}, userId, receiver, + opPackageName); + } + + @Override + public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId, + @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { + final List faces = FaceUtils.getInstance(sensorId) + .getBiometricsForUser(mContext, userId); + final int[] faceIds = new int[faces.size()]; + for (int i = 0; i < faces.size(); i++) { + faceIds[i] = faces.get(i).getBiometricId(); + } + + scheduleRemoveSpecifiedIds(sensorId, token, faceIds, userId, receiver, opPackageName); + } + + private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token, int[] faceIds, + int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { mHandler.post(() -> { final IFace daemon = getHalInstance(); if (daemon == null) { @@ -485,7 +504,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { final FaceRemovalClient client = new FaceRemovalClient(mContext, mSensors.get(sensorId).getLazySession(), token, - new ClientMonitorCallbackConverter(receiver), faceId, userId, + new ClientMonitorCallbackConverter(receiver), faceIds, userId, opPackageName, FaceUtils.getInstance(sensorId), sensorId, mSensors.get(sensorId).getAuthenticatorIds()); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java index 1cb5031374ec2..48796c173dd8d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java @@ -38,19 +38,22 @@ import java.util.Map; class FaceRemovalClient extends RemovalClient { private static final String TAG = "FaceRemovalClient"; + final int[] mBiometricIds; + FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, - int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, - int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, + int[] biometricIds, int userId, @NonNull String owner, + @NonNull BiometricUtils utils, int sensorId, + @NonNull Map authenticatorIds) { + super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FACE); + mBiometricIds = biometricIds; } @Override protected void startHalOperation() { try { - final int[] ids = new int[]{mBiometricId}; - getFreshDaemon().removeEnrollments(mSequentialId, ids); + getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting remove", e); mCallback.onClientFinished(this, false /* success */); 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 e46661a5e985f..298950fa325a8 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 @@ -671,6 +671,20 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { }); } + @Override + public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId, + @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { + mHandler.post(() -> { + scheduleUpdateActiveUserWithoutHandler(userId); + + // For IBiometricsFace@1.0, remove(0) means remove all enrollments + final FaceRemovalClient client = new FaceRemovalClient(mContext, mLazyDaemon, token, + new ClientMonitorCallbackConverter(receiver), 0 /* faceId */, userId, + opPackageName, + FaceUtils.getLegacyInstance(mSensorId), mSensorId, mAuthenticatorIds); + mScheduler.scheduleClientMonitor(client); + }); + } @Override public void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken) { diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java index acae89928460f..2b0dd02e283c7 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java @@ -38,12 +38,15 @@ import java.util.Map; class FaceRemovalClient extends RemovalClient { private static final String TAG = "FaceRemovalClient"; + private final int mBiometricId; + FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, + super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FACE); + mBiometricId = biometricId; } @Override 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 b0e42cd137eb5..b302931b99615 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 @@ -499,7 +499,21 @@ public class FingerprintService extends SystemService implements BiometricServic opPackageName); } - @Override + @Override // Binder call + public void removeAll(final IBinder token, final int userId, + final IFingerprintServiceReceiver receiver, final String opPackageName) { + Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); + + final Pair provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for removeAll"); + return; + } + provider.second.scheduleRemoveAll(provider.first, token, receiver, userId, + opPackageName); + } + + @Override // Binder call public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback, final String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); 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 f672ae56e0206..8785070f0afad 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 @@ -98,6 +98,10 @@ public interface ServiceProvider { @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName); + void scheduleRemoveAll(int sensorId, @NonNull IBinder token, + @NonNull IFingerprintServiceReceiver receiver, int userId, + @NonNull String opPackageName); + void scheduleInternalCleanup(int sensorId, int userId); boolean isHardwareDetected(int sensorId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java index 2a0e984e59334..0de3f4f8cce23 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java @@ -60,7 +60,7 @@ class FingerprintInternalCleanupClient extends InternalCleanupClient utils, int sensorId, Map authenticatorIds) { return new FingerprintRemovalClient(context, lazyDaemon, token, - null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils, - sensorId, authenticatorIds); + null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner, + utils, sensorId, authenticatorIds); } } 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 ced46e140c0a8..b53639d558890 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 @@ -490,6 +490,27 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi public void scheduleRemove(int sensorId, @NonNull IBinder token, @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName) { + scheduleRemoveSpecifiedIds(sensorId, token, new int[] {fingerId}, userId, receiver, + opPackageName); + } + + @Override + public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, + @NonNull IFingerprintServiceReceiver receiver, int userId, + @NonNull String opPackageName) { + final List fingers = FingerprintUtils.getInstance(sensorId) + .getBiometricsForUser(mContext, userId); + final int[] fingerIds = new int[fingers.size()]; + for (int i = 0; i < fingers.size(); i++) { + fingerIds[i] = fingers.get(i).getBiometricId(); + } + + scheduleRemoveSpecifiedIds(sensorId, token, fingerIds, userId, receiver, opPackageName); + } + + private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token, + int[] fingerprintIds, int userId, @NonNull IFingerprintServiceReceiver receiver, + @NonNull String opPackageName) { mHandler.post(() -> { final IFingerprint daemon = getHalInstance(); if (daemon == null) { @@ -507,7 +528,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext, mSensors.get(sensorId).getLazySession(), token, - new ClientMonitorCallbackConverter(receiver), fingerId, userId, + new ClientMonitorCallbackConverter(receiver), fingerprintIds, userId, opPackageName, FingerprintUtils.getInstance(sensorId), sensorId, mSensors.get(sensorId).getAuthenticatorIds()); mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java index 4a99a7b29638b..c622208262e01 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java @@ -39,20 +39,22 @@ import java.util.Map; class FingerprintRemovalClient extends RemovalClient { private static final String TAG = "FingerprintRemovalClient"; + private final int[] mBiometricIds; + FingerprintRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, - @Nullable ClientMonitorCallbackConverter listener, int biometricId, int userId, + @Nullable ClientMonitorCallbackConverter listener, int[] biometricIds, int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, + super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT); + mBiometricIds = biometricIds; } @Override protected void startHalOperation() { try { - final int[] ids = new int[] {mBiometricId}; - getFreshDaemon().removeEnrollments(mSequentialId, ids); + getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting remove", e); mCallback.onClientFinished(this, false /* success */); 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 7a74c6a39aa17..453b951e1f3bb 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 @@ -636,6 +636,23 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider }); } + @Override + public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, + @NonNull IFingerprintServiceReceiver receiver, int userId, + @NonNull String opPackageName) { + mHandler.post(() -> { + scheduleUpdateActiveUserWithoutHandler(userId); + + // For IBiometricsFingerprint@2.1, remove(0) means remove all enrollments + final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext, + mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), + 0 /* fingerprintId */, userId, opPackageName, + FingerprintUtils.getLegacyInstance(mSensorId), + mSensorProperties.sensorId, mAuthenticatorIds); + mScheduler.scheduleClientMonitor(client); + }); + } + private void scheduleInternalCleanup(int userId) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java index f6a22f581f1a7..2f360f31a325f 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java @@ -39,13 +39,16 @@ import java.util.Map; class FingerprintRemovalClient extends RemovalClient { private static final String TAG = "FingerprintRemovalClient"; + private final int mBiometricId; + FingerprintRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, + super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT); + mBiometricId = biometricId; } @Override diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 28c90e965e47a..deeac8f131f09 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -2890,11 +2890,8 @@ public class LockSettingsService extends ILockSettings.Stub { FingerprintManager mFingerprintManager = mInjector.getFingerprintManager(); if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) { if (mFingerprintManager.hasEnrolledFingerprints(userId)) { - CountDownLatch latch = new CountDownLatch(1); - // For the purposes of M and N, groupId is the same as userId. - Fingerprint finger = new Fingerprint(null, userId, 0, 0); - mFingerprintManager.remove(finger, userId, - fingerprintManagerRemovalCallback(latch)); + final CountDownLatch latch = new CountDownLatch(1); + mFingerprintManager.removeAll(userId, fingerprintManagerRemovalCallback(latch)); try { latch.await(10000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -2908,9 +2905,8 @@ public class LockSettingsService extends ILockSettings.Stub { FaceManager mFaceManager = mInjector.getFaceManager(); if (mFaceManager != null && mFaceManager.isHardwareDetected()) { if (mFaceManager.hasEnrolledTemplates(userId)) { - CountDownLatch latch = new CountDownLatch(1); - Face face = new Face(null, 0, 0); - mFaceManager.remove(face, userId, faceManagerRemovalCallback(latch)); + final CountDownLatch latch = new CountDownLatch(1); + mFaceManager.removeAll(userId, faceManagerRemovalCallback(latch)); try { latch.await(10000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -2924,10 +2920,8 @@ public class LockSettingsService extends ILockSettings.Stub { CountDownLatch latch) { return new FingerprintManager.RemovalCallback() { @Override - public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence err) { - Slog.e(TAG, String.format( - "Can't remove fingerprint %d in group %d. Reason: %s", - fp.getBiometricId(), fp.getGroupId(), err)); + public void onRemovalError(@Nullable Fingerprint fp, int errMsgId, CharSequence err) { + Slog.e(TAG, "Unable to remove fingerprint, error: " + err); latch.countDown(); } @@ -2943,9 +2937,8 @@ public class LockSettingsService extends ILockSettings.Stub { private FaceManager.RemovalCallback faceManagerRemovalCallback(CountDownLatch latch) { return new FaceManager.RemovalCallback() { @Override - public void onRemovalError(Face face, int errMsgId, CharSequence err) { - Slog.e(TAG, String.format("Can't remove face %d. Reason: %s", - face.getBiometricId(), err)); + public void onRemovalError(@Nullable Face face, int errMsgId, CharSequence err) { + Slog.e(TAG, "Unable to remove face, error: " + err); latch.countDown(); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 1f66c7c02658b..67d69292b476c 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -339,11 +339,11 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { mService.setLockCredential(nonePassword(), newPattern("123654"), PRIMARY_USER_ID); // Verify fingerprint is removed - verify(mFingerprintManager).remove(any(), eq(PRIMARY_USER_ID), any()); - verify(mFaceManager).remove(any(), eq(PRIMARY_USER_ID), any()); + verify(mFingerprintManager).removeAll(eq(PRIMARY_USER_ID), any()); + verify(mFaceManager).removeAll(eq(PRIMARY_USER_ID), any()); - verify(mFingerprintManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any()); - verify(mFaceManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any()); + verify(mFingerprintManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any()); + verify(mFaceManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any()); } @Test From d6d23e13a569d8f5b4ace42fbe249ac2b04e3985 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 16 Feb 2021 18:17:08 -0800 Subject: [PATCH 2/2] Try to ensure tests run sequentially Asynchronous operations that are performed in close() (such as cleanupInternalState()) should complete before close() finishes. Otherwise, we risk subsequent tests starting and causing racey conditions while cleanup has not finished yet. Fixes: 180192766 Test: atest CtsBiometricsTestCases Test: atest com.android.server.biometrics Change-Id: I3fdb3fe0be59e826d0c14e14a2590ccdde568774 --- .../hardware/biometrics/BiometricManager.java | 3 +- .../biometrics/BiometricTestSession.java | 73 +++++++++++++++++-- .../hardware/biometrics/IAuthService.aidl | 3 +- .../biometrics/IBiometricAuthenticator.aidl | 3 +- .../biometrics/IBiometricService.aidl | 3 +- .../hardware/biometrics/ITestSession.aidl | 2 +- .../biometrics/ITestSessionCallback.aidl | 25 +++++++ .../android/hardware/face/IFaceService.aidl | 3 +- .../fingerprint/FingerprintManager.java | 3 +- .../fingerprint/IFingerprintService.aidl | 3 +- .../server/biometrics/AuthService.java | 8 +- .../server/biometrics/BiometricService.java | 7 +- .../sensors/face/FaceAuthenticator.java | 6 +- .../biometrics/sensors/face/FaceService.java | 6 +- .../sensors/face/ServiceProvider.java | 8 +- .../face/aidl/BiometricTestSessionImpl.java | 27 ++++++- .../sensors/face/aidl/FaceProvider.java | 14 ++-- .../biometrics/sensors/face/aidl/Sensor.java | 6 +- .../face/hidl/BiometricTestSessionImpl.java | 29 +++++++- .../biometrics/sensors/face/hidl/Face10.java | 21 ++++-- .../fingerprint/FingerprintAuthenticator.java | 6 +- .../fingerprint/FingerprintService.java | 6 +- .../sensors/fingerprint/ServiceProvider.java | 8 +- .../aidl/BiometricTestSessionImpl.java | 29 +++++++- .../fingerprint/aidl/FingerprintProvider.java | 14 ++-- .../sensors/fingerprint/aidl/Sensor.java | 6 +- .../hidl/BiometricTestSessionImpl.java | 27 ++++++- .../fingerprint/hidl/Fingerprint21.java | 20 +++-- .../sensors/iris/IrisAuthenticator.java | 4 +- 29 files changed, 302 insertions(+), 71 deletions(-) create mode 100644 core/java/android/hardware/biometrics/ITestSessionCallback.aidl diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java index 5f5697a4ed0b7..ab817d1da4d99 100644 --- a/core/java/android/hardware/biometrics/BiometricManager.java +++ b/core/java/android/hardware/biometrics/BiometricManager.java @@ -237,7 +237,8 @@ public class BiometricManager { public BiometricTestSession createTestSession(int sensorId) { try { return new BiometricTestSession(mContext, sensorId, - mService.createTestSession(sensorId, mContext.getOpPackageName())); + (context, sensorId1, callback) -> mService + .createTestSession(sensorId1, callback, context.getOpPackageName())); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/biometrics/BiometricTestSession.java b/core/java/android/hardware/biometrics/BiometricTestSession.java index 1c3560882f1bc..ff1a17e07c113 100644 --- a/core/java/android/hardware/biometrics/BiometricTestSession.java +++ b/core/java/android/hardware/biometrics/BiometricTestSession.java @@ -19,6 +19,7 @@ package android.hardware.biometrics; import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; import android.content.Context; @@ -27,6 +28,9 @@ import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + /** * Common set of interfaces to test biometric-related APIs, including {@link BiometricPrompt} and * {@link android.hardware.fingerprint.FingerprintManager}. @@ -36,22 +40,58 @@ import android.util.Log; public class BiometricTestSession implements AutoCloseable { private static final String TAG = "BiometricTestSession"; + /** + * @hide + */ + public interface TestSessionProvider { + @NonNull + ITestSession createTestSession(@NonNull Context context, int sensorId, + @NonNull ITestSessionCallback callback) throws RemoteException; + } + private final Context mContext; private final int mSensorId; private final ITestSession mTestSession; // Keep track of users that were tested, which need to be cleaned up when finishing. - private final ArraySet mTestedUsers; + @NonNull private final ArraySet mTestedUsers; + + // Track the users currently cleaning up, and provide a latch that gets notified when all + // users have finished cleaning up. This is an imperfect system, as there can technically be + // multiple cleanups per user. Theoretically we should track the cleanup's BaseClientMonitor's + // unique ID, but it's complicated to plumb it through. This should be fine for now. + @Nullable private CountDownLatch mCloseLatch; + @NonNull private final ArraySet mUsersCleaningUp; + + private final ITestSessionCallback mCallback = new ITestSessionCallback.Stub() { + @Override + public void onCleanupStarted(int userId) { + Log.d(TAG, "onCleanupStarted, sensor: " + mSensorId + ", userId: " + userId); + } + + @Override + public void onCleanupFinished(int userId) { + Log.d(TAG, "onCleanupFinished, sensor: " + mSensorId + + ", userId: " + userId + + ", remaining users: " + mUsersCleaningUp.size()); + mUsersCleaningUp.remove(userId); + + if (mUsersCleaningUp.isEmpty() && mCloseLatch != null) { + mCloseLatch.countDown(); + } + } + }; /** * @hide */ public BiometricTestSession(@NonNull Context context, int sensorId, - @NonNull ITestSession testSession) { + @NonNull TestSessionProvider testSessionProvider) throws RemoteException { mContext = context; mSensorId = sensorId; - mTestSession = testSession; + mTestSession = testSessionProvider.createTestSession(context, sensorId, mCallback); mTestedUsers = new ArraySet<>(); + mUsersCleaningUp = new ArraySet<>(); setTestHalEnabled(true); } @@ -176,6 +216,11 @@ public class BiometricTestSession implements AutoCloseable { @RequiresPermission(TEST_BIOMETRIC) public void cleanupInternalState(int userId) { try { + if (mUsersCleaningUp.contains(userId)) { + Log.w(TAG, "Cleanup already in progress for user: " + userId); + } + + mUsersCleaningUp.add(userId); mTestSession.cleanupInternalState(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -185,12 +230,24 @@ public class BiometricTestSession implements AutoCloseable { @Override @RequiresPermission(TEST_BIOMETRIC) public void close() { - // Disable the test HAL first, so that enumerate is run on the real HAL, which should have - // no enrollments. Test-only framework enrollments will be deleted. - setTestHalEnabled(false); + // Cleanup can be performed using the test HAL, since it always responds to enumerate with + // zero enrollments. + if (!mTestedUsers.isEmpty()) { + mCloseLatch = new CountDownLatch(1); + for (int user : mTestedUsers) { + cleanupInternalState(user); + } - for (int user : mTestedUsers) { - cleanupInternalState(user); + try { + Log.d(TAG, "Awaiting latch..."); + mCloseLatch.await(10, TimeUnit.SECONDS); + Log.d(TAG, "Finished awaiting"); + } catch (InterruptedException e) { + Log.e(TAG, "Latch interrupted", e); + } } + + // Disable the test HAL after the sensor becomes idle. + setTestHalEnabled(false); } } diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl index 0dfd5dbf300e9..d8c9dbc849a9b 100644 --- a/core/java/android/hardware/biometrics/IAuthService.aidl +++ b/core/java/android/hardware/biometrics/IAuthService.aidl @@ -20,6 +20,7 @@ import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback; import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; @@ -32,7 +33,7 @@ import android.hardware.biometrics.SensorPropertiesInternal; */ interface IAuthService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, String opPackageName); + ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); // Retrieve static sensor properties for all biometric sensors List getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl index c854ac9847d8c..7639c5dd4d16b 100644 --- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl +++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl @@ -20,6 +20,7 @@ import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.face.IFaceServiceReceiver; import android.hardware.face.Face; @@ -32,7 +33,7 @@ import android.hardware.face.Face; interface IBiometricAuthenticator { // Creates a test session - ITestSession createTestSession(String opPackageName); + ITestSession createTestSession(ITestSessionCallback callback, String opPackageName); // Retrieve static sensor properties SensorPropertiesInternal getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl index a14a910a9e504..24331863a05fc 100644 --- a/core/java/android/hardware/biometrics/IBiometricService.aidl +++ b/core/java/android/hardware/biometrics/IBiometricService.aidl @@ -21,6 +21,7 @@ import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; @@ -30,7 +31,7 @@ import android.hardware.biometrics.SensorPropertiesInternal; */ interface IBiometricService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, String opPackageName); + ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); // Retrieve static sensor properties for all biometric sensors List getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl index fa7a62c53531e..f8395a119c0b4 100644 --- a/core/java/android/hardware/biometrics/ITestSession.aidl +++ b/core/java/android/hardware/biometrics/ITestSession.aidl @@ -18,7 +18,7 @@ package android.hardware.biometrics; import android.hardware.biometrics.SensorPropertiesInternal; /** - * A test service for FingerprintManager and BiometricPrompt. + * A test service for FingerprintManager and BiometricManager. * @hide */ interface ITestSession { diff --git a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl new file mode 100644 index 0000000000000..3d9517f29548f --- /dev/null +++ b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 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.biometrics; + +/** + * ITestSession callback for FingerprintManager and BiometricManager. + * @hide + */ +interface ITestSessionCallback { + void onCleanupStarted(int userId); + void onCleanupFinished(int userId); +} diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index a2e0b3b1cb411..6e7c701ef5ff8 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -19,6 +19,7 @@ import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.face.IFaceServiceReceiver; import android.hardware.face.Face; import android.hardware.face.FaceSensorPropertiesInternal; @@ -32,7 +33,7 @@ import android.view.Surface; interface IFaceService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, String opPackageName); + ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); // Requests a proto dump of the specified sensor byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer); diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 6df2764d3f8bf..9d086cf203e29 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -154,7 +154,8 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing public BiometricTestSession createTestSession(int sensorId) { try { return new BiometricTestSession(mContext, sensorId, - mService.createTestSession(sensorId, mContext.getOpPackageName())); + (context, sensorId1, callback) -> mService + .createTestSession(sensorId1, callback, context.getOpPackageName())); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index 1694fef0f71bf..054c0d0f65132 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -19,6 +19,7 @@ import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.IFingerprintClientActiveCallback; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IUdfpsOverlayController; @@ -33,7 +34,7 @@ import java.util.List; interface IFingerprintService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, String opPackageName); + ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); // Requests a proto dump of the specified sensor byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer); diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index b15a8869b22a4..e19745e5c5780 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -40,6 +40,7 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.face.IFaceService; @@ -144,13 +145,14 @@ public class AuthService extends SystemService { private final class AuthServiceImpl extends IAuthService.Stub { @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) - throws RemoteException { + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) throws RemoteException { Utils.checkPermission(getContext(), TEST_BIOMETRIC); final long identity = Binder.clearCallingIdentity(); try { - return mInjector.getBiometricService().createTestSession(sensorId, opPackageName); + return mInjector.getBiometricService() + .createTestSession(sensorId, callback, opPackageName); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 614c5f1b65bfb..00a4e43f347dc 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -44,6 +44,7 @@ import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.fingerprint.FingerprintManager; @@ -570,13 +571,13 @@ public class BiometricService extends SystemService { */ private final class BiometricServiceWrapper extends IBiometricService.Stub { @Override // Binder call - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) - throws RemoteException { + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) throws RemoteException { checkInternalPermission(); for (BiometricSensor sensor : mSensors) { if (sensor.id == sensorId) { - return sensor.impl.createTestSession(opPackageName); + return sensor.impl.createTestSession(callback, opPackageName); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java index f37cf18a13207..06b049be4501d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java @@ -21,6 +21,7 @@ import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.face.IFaceService; import android.os.IBinder; @@ -41,8 +42,9 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub { } @Override - public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException { - return mFaceService.createTestSession(mSensorId, opPackageName); + public ITestSession createTestSession(@NonNull ITestSessionCallback callback, + @NonNull String opPackageName) throws RemoteException { + return mFaceService.createTestSession(mSensorId, callback, opPackageName); } @Override 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 b0433d67ff32f..6dbd590df8515 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 @@ -31,6 +31,7 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.IFace; import android.hardware.biometrics.face.SensorProps; import android.hardware.face.Face; @@ -133,7 +134,8 @@ public class FaceService extends SystemService implements BiometricServiceCallba */ private final class FaceServiceWrapper extends IFaceService.Stub { @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); final ServiceProvider provider = getProviderForSensor(sensorId); @@ -143,7 +145,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba return null; } - return provider.createTestSession(sensorId, opPackageName); + return provider.createTestSession(sensorId, callback, opPackageName); } @Override 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 0b522efb5bac4..88edfbf12df11 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 @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.face.Face; import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorPropertiesInternal; @@ -28,6 +29,7 @@ import android.os.IBinder; import android.os.NativeHandle; import android.util.proto.ProtoOutputStream; +import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; @@ -123,7 +125,8 @@ public interface ServiceProvider { void startPreparedClient(int sensorId, int cookie); - void scheduleInternalCleanup(int sensorId, int userId); + void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback); void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto, boolean clearSchedulerBuffer); @@ -133,7 +136,8 @@ public interface ServiceProvider { void dumpInternal(int sensorId, @NonNull PrintWriter pw); @NonNull - ITestSession createTestSession(int sensorId, @NonNull String opPackageName); + ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName); void dumpHal(int sensorId, @NonNull FileDescriptor fd, @NonNull String[] args); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java index d2673d2969c91..e886be805b617 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java @@ -21,15 +21,18 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.BaseFrame; import android.hardware.face.Face; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; +import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.face.FaceUtils; import java.util.HashSet; @@ -47,6 +50,7 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; + @NonNull private final ITestSessionCallback mCallback; @NonNull private final FaceProvider mProvider; @NonNull private final Sensor mSensor; @NonNull private final Set mEnrollmentIds; @@ -120,9 +124,11 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { }; BiometricTestSessionImpl(@NonNull Context context, int sensorId, + @NonNull ITestSessionCallback callback, @NonNull FaceProvider provider, @NonNull Sensor sensor) { mContext = context; mSensorId = sensorId; + mCallback = callback; mProvider = provider; mSensor = sensor; mEnrollmentIds = new HashSet<>(); @@ -212,6 +218,25 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mProvider.scheduleInternalCleanup(mSensorId, userId); + mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { + @Override + public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { + try { + mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + + @Override + public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, + boolean success) { + try { + mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + }); } } 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 dc2611f006356..02e8e921ae731 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 @@ -25,6 +25,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.IFace; import android.hardware.biometrics.face.SensorProps; import android.hardware.face.Face; @@ -177,7 +178,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { for (int i = 0; i < mSensors.size(); i++) { final int sensorId = mSensors.keyAt(i); scheduleLoadAuthenticatorIds(sensorId); - scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser()); + scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser(), + null /* callback */); } return mDaemon; @@ -562,7 +564,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { } @Override - public void scheduleInternalCleanup(int sensorId, int userId) { + public void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback) { mHandler.post(() -> { final IFace daemon = getHalInstance(); if (daemon == null) { @@ -583,7 +586,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { FaceUtils.getInstance(sensorId), mSensors.get(sensorId).getAuthenticatorIds()); - mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); + mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e); } @@ -646,8 +649,9 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { - return mSensors.get(sensorId).createTestSession(); + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) { + return mSensors.get(sensorId).createTestSession(callback); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java index 90aa4ad556133..49a4aff7edb14 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; @@ -460,8 +461,9 @@ public class Sensor implements IBinder.DeathRecipient { } } - @NonNull ITestSession createTestSession() { - return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this); + @NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback) { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, + mProvider, this); } void createNewSession(@NonNull IFace daemon, int sensorId, int userId) diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java index 4142a52c9253b..2c7b42d2e3034 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java @@ -21,12 +21,15 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.face.Face; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; +import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.face.FaceUtils; import java.util.ArrayList; @@ -41,6 +44,7 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; + @NonNull private final ITestSessionCallback mCallback; @NonNull private final Face10 mFace10; @NonNull private final Face10.HalResultController mHalResultController; @NonNull private final Set mEnrollmentIds; @@ -108,10 +112,12 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { } }; - BiometricTestSessionImpl(@NonNull Context context, int sensorId, @NonNull Face10 face10, + BiometricTestSessionImpl(@NonNull Context context, int sensorId, + @NonNull ITestSessionCallback callback, @NonNull Face10 face10, @NonNull Face10.HalResultController halResultController) { mContext = context; mSensorId = sensorId; + mCallback = callback; mFace10 = face10; mHalResultController = halResultController; mEnrollmentIds = new HashSet<>(); @@ -189,6 +195,25 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mFace10.scheduleInternalCleanup(mSensorId, userId); + mFace10.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { + @Override + public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { + try { + mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + + @Override + public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, + boolean success) { + try { + mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + }); } } 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 298950fa325a8..ee8823e041bc7 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 @@ -29,6 +29,7 @@ import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.V1_0.IBiometricsFace; import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback; import android.hardware.face.Face; @@ -123,7 +124,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() { @Override public void onUserSwitching(int newUserId) { - scheduleInternalCleanup(newUserId); + scheduleInternalCleanup(newUserId, null /* callback */); scheduleGetFeature(mSensorId, new Binder(), newUserId, BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null, mContext.getOpPackageName()); @@ -437,7 +438,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { Slog.d(TAG, "Face HAL ready, HAL ID: " + halId); if (halId != 0) { scheduleLoadAuthenticatorIds(); - scheduleInternalCleanup(ActivityManager.getCurrentUser()); + scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */); scheduleGetFeature(mSensorId, new Binder(), ActivityManager.getCurrentUser(), BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null, @@ -756,7 +757,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { }); } - private void scheduleInternalCleanup(int userId) { + private void scheduleInternalCleanup(int userId, + @Nullable BaseClientMonitor.Callback callback) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -764,13 +766,14 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext, mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId, enrolledList, FaceUtils.getLegacyInstance(mSensorId), mAuthenticatorIds); - mScheduler.scheduleClientMonitor(client); + mScheduler.scheduleClientMonitor(client, callback); }); } @Override - public void scheduleInternalCleanup(int sensorId, int userId) { - scheduleInternalCleanup(userId); + public void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback) { + scheduleInternalCleanup(userId, callback); } @Override @@ -944,7 +947,9 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { - return new BiometricTestSessionImpl(mContext, mSensorId, this, mHalResultController); + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) { + return new BiometricTestSessionImpl(mContext, mSensorId, callback, this, + mHalResultController); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java index 34a909908b5ab..32e9409de4b2d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java @@ -21,6 +21,7 @@ import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintService; import android.os.IBinder; @@ -42,8 +43,9 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub } @Override - public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException { - return mFingerprintService.createTestSession(mSensorId, opPackageName); + public ITestSession createTestSession(@NonNull ITestSessionCallback callback, + @NonNull String opPackageName) throws RemoteException { + return mFingerprintService.createTestSession(mSensorId, callback, opPackageName); } @Override 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 b302931b99615..396dd5f42d4d8 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 @@ -43,6 +43,7 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.SensorProps; import android.hardware.fingerprint.Fingerprint; @@ -109,7 +110,8 @@ public class FingerprintService extends SystemService implements BiometricServic */ private final class FingerprintServiceWrapper extends IFingerprintService.Stub { @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) { Utils.checkPermission(getContext(), TEST_BIOMETRIC); final ServiceProvider provider = getProviderForSensor(sensorId); @@ -119,7 +121,7 @@ public class FingerprintService extends SystemService implements BiometricServic return null; } - return provider.createTestSession(sensorId, opPackageName); + return provider.createTestSession(sensorId, callback, opPackageName); } @Override 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 8785070f0afad..dfec2e3e308f7 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 @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; @@ -28,6 +29,7 @@ import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.IBinder; import android.util.proto.ProtoOutputStream; +import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; @@ -102,7 +104,8 @@ public interface ServiceProvider { @NonNull IFingerprintServiceReceiver receiver, int userId, @NonNull String opPackageName); - void scheduleInternalCleanup(int sensorId, int userId); + void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback); boolean isHardwareDetected(int sensorId); @@ -137,5 +140,6 @@ public interface ServiceProvider { void dumpInternal(int sensorId, @NonNull PrintWriter pw); @NonNull - ITestSession createTestSession(int sensorId, @NonNull String opPackageName); + ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java index ea9c709ec79f5..20b32543f7a03 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java @@ -21,14 +21,17 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.Binder; +import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import java.util.HashSet; @@ -46,6 +49,7 @@ class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; + @NonNull private final ITestSessionCallback mCallback; @NonNull private final FingerprintProvider mProvider; @NonNull private final Sensor mSensor; @NonNull private final Set mEnrollmentIds; @@ -110,9 +114,11 @@ class BiometricTestSessionImpl extends ITestSession.Stub { }; BiometricTestSessionImpl(@NonNull Context context, int sensorId, - @NonNull FingerprintProvider provider, @NonNull Sensor sensor) { + @NonNull ITestSessionCallback callback, @NonNull FingerprintProvider provider, + @NonNull Sensor sensor) { mContext = context; mSensorId = sensorId; + mCallback = callback; mProvider = provider; mSensor = sensor; mEnrollmentIds = new HashSet<>(); @@ -192,6 +198,25 @@ class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mProvider.scheduleInternalCleanup(mSensorId, userId); + mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { + @Override + public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { + try { + mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + + @Override + public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, + boolean success) { + try { + mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + }); } } 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 b53639d558890..70161d679c1c3 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 @@ -25,6 +25,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.SensorProps; import android.hardware.fingerprint.Fingerprint; @@ -185,7 +186,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi for (int i = 0; i < mSensors.size(); i++) { final int sensorId = mSensors.keyAt(i); scheduleLoadAuthenticatorIds(sensorId); - scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser()); + scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser(), + null /* callback */); } return mDaemon; @@ -539,7 +541,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } @Override - public void scheduleInternalCleanup(int sensorId, int userId) { + public void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback) { mHandler.post(() -> { final IFingerprint daemon = getHalInstance(); if (daemon == null) { @@ -559,7 +562,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi mContext.getOpPackageName(), sensorId, enrolledList, FingerprintUtils.getInstance(sensorId), mSensors.get(sensorId).getAuthenticatorIds()); - mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); + mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e); } @@ -704,8 +707,9 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { - return mSensors.get(sensorId).createTestSession(); + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) { + return mSensors.get(sensorId).createTestSession(callback); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index a4dcac794d35c..238b544e7a424 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.Error; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.ISession; @@ -440,8 +441,9 @@ class Sensor implements IBinder.DeathRecipient { } } - @NonNull ITestSession createTestSession() { - return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this); + @NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback) { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, + mProvider, this); } void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId) diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java index 312ee0a267ac3..766a8829e9682 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java @@ -21,13 +21,16 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.Binder; +import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import java.util.ArrayList; @@ -47,6 +50,7 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; + @NonNull private final ITestSessionCallback mCallback; @NonNull private final Fingerprint21 mFingerprint21; @NonNull private final Fingerprint21.HalResultController mHalResultController; @NonNull private final Set mEnrollmentIds; @@ -111,10 +115,12 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { }; BiometricTestSessionImpl(@NonNull Context context, int sensorId, + @NonNull ITestSessionCallback callback, @NonNull Fingerprint21 fingerprint21, @NonNull Fingerprint21.HalResultController halResultController) { mContext = context; mSensorId = sensorId; + mCallback = callback; mFingerprint21 = fingerprint21; mHalResultController = halResultController; mEnrollmentIds = new HashSet<>(); @@ -191,6 +197,25 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mFingerprint21.scheduleInternalCleanup(mSensorId, userId); + mFingerprint21.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { + @Override + public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { + try { + mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + + @Override + public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, + boolean success) { + try { + mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + } + }); } } 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 453b951e1f3bb..22e7603099661 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 @@ -30,6 +30,7 @@ import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback; import android.hardware.fingerprint.Fingerprint; @@ -158,7 +159,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() { @Override public void onUserSwitching(int newUserId) { - scheduleInternalCleanup(newUserId); + scheduleInternalCleanup(newUserId, null /* callback */); } }; @@ -437,7 +438,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider Slog.d(TAG, "Fingerprint HAL ready, HAL ID: " + halId); if (halId != 0) { scheduleLoadAuthenticatorIds(); - scheduleInternalCleanup(ActivityManager.getCurrentUser()); + scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */); } else { Slog.e(TAG, "Unable to set callback"); mDaemon = null; @@ -653,7 +654,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider }); } - private void scheduleInternalCleanup(int userId) { + private void scheduleInternalCleanup(int userId, + @Nullable BaseClientMonitor.Callback callback) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -663,13 +665,14 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider mContext, mLazyDaemon, userId, mContext.getOpPackageName(), mSensorProperties.sensorId, enrolledList, FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds); - mScheduler.scheduleClientMonitor(client); + mScheduler.scheduleClientMonitor(client, callback); }); } @Override - public void scheduleInternalCleanup(int sensorId, int userId) { - scheduleInternalCleanup(userId); + public void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback) { + scheduleInternalCleanup(userId, callback); } @Override @@ -849,8 +852,9 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { - return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, this, + public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, + @NonNull String opPackageName) { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, this, mHalResultController); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java index 8e84613b2d645..f44e0691bb9d0 100644 --- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java +++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java @@ -21,6 +21,7 @@ import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; +import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.iris.IIrisService; import android.os.IBinder; @@ -39,7 +40,8 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub { } @Override - public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException { + public ITestSession createTestSession(@NonNull ITestSessionCallback callback, + @NonNull String opPackageName) throws RemoteException { return null; }