diff options
39 files changed, 495 insertions, 126 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java index 4ca31050bd52..5b28e0035b09 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 1c3560882f1b..ff1a17e07c11 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<Integer> mTestedUsers; + @NonNull private final ArraySet<Integer> 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<Integer> 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); - - for (int user : mTestedUsers) { - cleanupInternalState(user); + // 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); + } + + 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 0dfd5dbf300e..d8c9dbc849a9 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<SensorPropertiesInternal> getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl index c854ac9847d8..7639c5dd4d16 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 a14a910a9e50..24331863a05f 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<SensorPropertiesInternal> getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl index fa7a62c53531..f8395a119c0b 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 000000000000..3d9517f29548 --- /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/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 886a8c1fdae5..a9bcdeff7e47 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -574,12 +574,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 a3e7e2d2c5cb..6e7c701ef5ff 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); @@ -83,10 +84,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<Face> 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 a614ebfe1793..9d086cf203e2 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(); } @@ -739,11 +740,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 8888247e2823..054c0d0f6513 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); @@ -87,6 +88,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/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index b15a8869b22a..e19745e5c578 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 614c5f1b65bf..00a4e43f347d 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/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java index e0626952fac3..16f82af93856 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<S extends BiometricAuthenticator.Identifier, private static final String TAG = "Biometrics/RemovalClient"; - protected final int mBiometricId; private final BiometricUtils<S> mBiometricUtils; private final Map<Integer, Long> mAuthenticatorIds; public RemovalClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, - int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<S> utils, - int sensorId, @NonNull Map<Integer, Long> authenticatorIds, int statsModality) { + int userId, @NonNull String owner, @NonNull BiometricUtils<S> utils, int sensorId, + @NonNull Map<Integer, Long> 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<S extends BiometricAuthenticator.Identifier, @Override public void onRemoved(@Nullable BiometricAuthenticator.Identifier identifier, int remaining) { + Slog.d(TAG, "onRemoved: " + identifier.getBiometricId() + " remaining: " + remaining); if (identifier != null) { mBiometricUtils.removeBiometricForUser(getContext(), getTargetUserId(), identifier.getBiometricId()); 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 f37cf18a1320..06b049be4501 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 825392762c8c..6dbd590df851 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 @@ -386,7 +388,22 @@ public class FaceService extends SystemService implements BiometricServiceCallba opPackageName); } - @Override + @Override // Binder call + public void removeAll(final IBinder token, final int userId, + final IFaceServiceReceiver receiver, final String opPackageName) { + Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); + + final Pair<Integer, ServiceProvider> 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 cc24b8960e75..88edfbf12df1 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; @@ -109,6 +111,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, @@ -120,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); @@ -130,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 897ebd719da4..a5e6ddb81669 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,6 +21,7 @@ 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; @@ -28,10 +29,12 @@ import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceEnrollFrame; 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; @@ -49,6 +52,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<Integer> mEnrollmentIds; @@ -132,9 +136,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<>(); @@ -224,6 +230,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/FaceInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java index 9680e4e1841e..c6696aed6520 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<Face, ISession> { // 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 1b6b9d70d5ac..1d8f210b394e 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; @@ -468,6 +470,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<Face> 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 +506,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()); @@ -543,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) { @@ -564,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); } @@ -627,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/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java index 1cb5031374ec..48796c173dd8 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<Face, ISession> { private static final String TAG = "FaceRemovalClient"; + final int[] mBiometricIds; + FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, - int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<Face> utils, - int sensorId, @NonNull Map<Integer, Long> authenticatorIds) { - super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, + int[] biometricIds, int userId, @NonNull String owner, + @NonNull BiometricUtils<Face> utils, int sensorId, + @NonNull Map<Integer, Long> 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/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java index 4925ce0bb2b1..3434acbf73cc 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; @@ -459,8 +460,9 @@ public class Sensor { } } - @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 d519d60881c0..e8668ed1b6c5 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,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.face.Face; import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceEnrollFrame; 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; @@ -43,6 +46,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<Integer> mEnrollmentIds; @@ -120,10 +124,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<>(); @@ -201,6 +207,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 e46661a5e985..ee8823e041bc 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, @@ -671,6 +672,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) { @@ -742,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); @@ -750,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 @@ -930,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/face/hidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java index d63791c99dd4..3ae201134deb 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<Face, IBiometricsFace> { private static final String TAG = "FaceRemovalClient"; + private final int mBiometricId; + FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon<IBiometricsFace> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<Face> utils, int sensorId, @NonNull Map<Integer, Long> 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/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java index 34a909908b5a..32e9409de4b2 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 b0e42cd137eb..396dd5f42d4d 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 @@ -499,7 +501,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<Integer, ServiceProvider> 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 f672ae56e020..dfec2e3e308f 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; @@ -98,7 +100,12 @@ public interface ServiceProvider { @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName); - void scheduleInternalCleanup(int sensorId, int userId); + void scheduleRemoveAll(int sensorId, @NonNull IBinder token, + @NonNull IFingerprintServiceReceiver receiver, int userId, + @NonNull String opPackageName); + + void scheduleInternalCleanup(int sensorId, int userId, + @Nullable BaseClientMonitor.Callback callback); boolean isHardwareDetected(int sensorId); @@ -133,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 ea9c709ec79f..20b32543f7a0 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<Integer> 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/FingerprintInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java index 2a0e984e5933..0de3f4f8cce2 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<Fingerprint String owner, BiometricUtils<Fingerprint> utils, int sensorId, Map<Integer, Long> 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 0bd2f241ed8d..598cc8992c2d 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; @@ -490,6 +492,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<Fingerprint> 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 +530,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); @@ -518,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) { @@ -538,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); } @@ -683,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/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java index 4a99a7b29638..c622208262e0 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<Fingerprint, ISession> { private static final String TAG = "FingerprintRemovalClient"; + private final int[] mBiometricIds; + FingerprintRemovalClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token, - @Nullable ClientMonitorCallbackConverter listener, int biometricId, int userId, + @Nullable ClientMonitorCallbackConverter listener, int[] biometricIds, int userId, @NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId, @NonNull Map<Integer, Long> 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/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index c83c0fba0133..a98e7db43f79 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; @@ -439,8 +440,9 @@ class Sensor { } } - @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 312ee0a267ac..766a8829e968 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<Integer> 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 554e3d45a3ca..6e22a797b435 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; @@ -644,7 +645,25 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider }); } - private void scheduleInternalCleanup(int userId) { + @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, + @Nullable BaseClientMonitor.Callback callback) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -654,13 +673,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 @@ -840,8 +860,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/fingerprint/hidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java index f6a22f581f1a..2f360f31a325 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<Fingerprint, IBiometricsFingerprint> { private static final String TAG = "FingerprintRemovalClient"; + private final int mBiometricId; + FingerprintRemovalClient(@NonNull Context context, @NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId, @NonNull Map<Integer, Long> 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/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java index 8e84613b2d64..f44e0691bb9d 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; } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 685e9e6ad420..8da2d67d6691 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -2902,11 +2902,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) { @@ -2920,9 +2917,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) { @@ -2936,10 +2932,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(); } @@ -2955,9 +2949,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 1f66c7c02658..67d69292b476 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 |