diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java index f1c786b4977cd..46d863d7aaec7 100644 --- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java +++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java @@ -123,7 +123,8 @@ public class ClientMonitorCallbackConverter { } } - void onRemoved(BiometricAuthenticator.Identifier identifier, int remaining) + /** Called when a user has been removed. */ + public void onRemoved(BiometricAuthenticator.Identifier identifier, int remaining) throws RemoteException { if (mFaceServiceReceiver != null) { mFaceServiceReceiver.onRemoved((Face) identifier, remaining); 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 07ce841a7cac8..e0d519469e32d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java @@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; +import android.hardware.biometrics.BiometricConstants; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; @@ -71,6 +72,24 @@ public abstract class RemovalClient mUtils; + @Mock + private BiometricAuthenticator.Identifier mIdentifier; + private Map mAuthenticatorIds = new HashMap(); + + @Before + public void setup() { + when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer( + i -> i.getArgument(0)); + } + + @Test + public void testFaceRemovalClient() throws RemoteException { + final int authenticatorId = 1; + int[] authenticatorIds = new int[]{authenticatorId}; + final FaceRemovalClient client = createClient(1, authenticatorIds); + when(mIdentifier.getBiometricId()).thenReturn(authenticatorId); + client.start(mCallback); + verify(mHal).removeEnrollments(authenticatorIds); + client.onRemoved(mIdentifier, 0 /* remaining */); + verify(mClientMonitorCallbackConverter).onRemoved( + eq(mIdentifier) /* identifier */, eq(0) /* remaining */); + verify(mCallback).onClientFinished(client, true); + } + + @Test + public void clientSendsErrorWhenHALFailsToRemoveEnrollment() throws RemoteException { + final FaceRemovalClient client = createClient(1, new int[0]); + client.start(mCallback); + client.onRemoved(null, 0 /* remaining */); + verify(mClientMonitorCallbackConverter).onError(eq(5) /* sensorId */, anyInt(), + eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_REMOVE), eq(0) /* vendorCode*/); + verify(mCallback).onClientFinished(client, false); + } + + private FaceRemovalClient createClient(int version, int[] biometricIds) throws RemoteException { + when(mHal.getInterfaceVersion()).thenReturn(version); + final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback); + return new FaceRemovalClient(mContext, () -> aidl, mToken, + mClientMonitorCallbackConverter, biometricIds, USER_ID, + "own-it", mUtils /* utils */, 5 /* sensorId */, mBiometricLogger, mBiometricContext, + mAuthenticatorIds); + } +}