Call InvalidationCallback#onCompleted when client is cancelled
Fixes: 366384601
Test: atest FingerprintInvalidationClientTest, atest
FaceInvalidationClientTest
Flag: EXEMPT bug fix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:da582a35c9ce60fbdae6360cf042faef7d0bbe8d)
Merged-In: Id5ed4bc5f8e38052b8011528015945ed51639fe9
Change-Id: Id5ed4bc5f8e38052b8011528015945ed51639fe9
diff --git a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
index d5aa5e2..43414c0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
@@ -77,6 +77,16 @@
}
@Override
+ public void cancel() {
+ super.cancel();
+ try {
+ mInvalidationCallback.onCompleted();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to complete invalidation client due to exception: " + e);
+ }
+ }
+
+ @Override
public int getProtoEnum() {
return BiometricsProto.CM_INVALIDATE;
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java
new file mode 100644
index 0000000..405fb44
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.face.aidl;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.biometrics.IInvalidationCallback;
+import android.hardware.biometrics.face.V1_0.IBiometricsFace;
+import android.hardware.biometrics.face.V1_0.OptionalUint64;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.HashMap;
+
+@Presubmit
+@SmallTest
+public class FaceInvalidationClientTest {
+
+ private static final int SENSOR_ID = 4;
+ private static final int USER_ID = 0;
+
+
+ @Rule
+ public final TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock
+ private IBiometricsFace mFace;
+ @Mock
+ private AidlResponseHandler mAidlResponseHandler;
+ @Mock
+ private BiometricLogger mBiometricLogger;
+ @Mock
+ private BiometricContext mBiometricContext;
+ @Mock
+ private IInvalidationCallback mInvalidationCallback;
+ @Mock
+ private ClientMonitorCallback mClientMonitorCallback;
+
+ @Test
+ public void testStartInvalidationClient_whenHalIsHidl() throws RemoteException {
+ final OptionalUint64 halId = new OptionalUint64();
+
+ when(mFace.setCallback(any())).thenReturn(halId);
+
+ final AidlSession aidlSession = new AidlSession(mContext, () -> mFace, USER_ID,
+ mAidlResponseHandler);
+ final FaceInvalidationClient faceInvalidationClient =
+ new FaceInvalidationClient(mContext, () -> aidlSession, USER_ID,
+ SENSOR_ID, mBiometricLogger, mBiometricContext, new HashMap<>(),
+ mInvalidationCallback);
+
+ doAnswer((Answer<Void>) invocationOnMock -> {
+ faceInvalidationClient.cancel();
+ return null;
+ }).when(mAidlResponseHandler).onUnsupportedClientScheduled();
+
+ faceInvalidationClient.start(mClientMonitorCallback);
+
+ verify(mInvalidationCallback).onCompleted();
+ }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java
new file mode 100644
index 0000000..1ee2fd1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.fingerprint.aidl;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.biometrics.IInvalidationCallback;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.HashMap;
+
+@Presubmit
+@SmallTest
+public class FingerprintInvalidationClientTest {
+
+ private static final int SENSOR_ID = 4;
+ private static final int USER_ID = 0;
+
+
+ @Rule
+ public final TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock
+ private IBiometricsFingerprint mFingerprint;
+ @Mock
+ private AidlResponseHandler mAidlResponseHandler;
+ @Mock
+ private BiometricLogger mBiometricLogger;
+ @Mock
+ private BiometricContext mBiometricContext;
+ @Mock
+ private IInvalidationCallback mInvalidationCallback;
+ @Mock
+ private ClientMonitorCallback mClientMonitorCallback;
+
+ @Test
+ public void testStartInvalidationClient_whenHalIsHidl() throws RemoteException {
+ final AidlSession aidlSession = new AidlSession(
+ () -> mFingerprint, USER_ID, mAidlResponseHandler);
+ final FingerprintInvalidationClient fingerprintInvalidationClient =
+ new FingerprintInvalidationClient(mContext, () -> aidlSession, USER_ID,
+ SENSOR_ID, mBiometricLogger, mBiometricContext, new HashMap<>(),
+ mInvalidationCallback);
+
+ doAnswer((Answer<Void>) invocationOnMock -> {
+ fingerprintInvalidationClient.cancel();
+ return null;
+ }).when(mAidlResponseHandler).onUnsupportedClientScheduled(
+ FingerprintInvalidationClient.class);
+
+ fingerprintInvalidationClient.start(mClientMonitorCallback);
+
+ verify(mInvalidationCallback).onCompleted();
+ }
+}