Merge "Added subscription to binder death which removes dead callbacks"
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
index f854316..2263e80 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
@@ -28,6 +28,7 @@
import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.IBiometricStateListener;
import android.hardware.biometrics.SensorPropertiesInternal;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Slog;
@@ -45,7 +46,8 @@
* @param <P> internal property type
*/
public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
- P extends SensorPropertiesInternal> implements ClientMonitorCallback {
+ P extends SensorPropertiesInternal>
+ implements ClientMonitorCallback, IBinder.DeathRecipient {
private static final String TAG = "BiometricStateCallback";
@@ -161,6 +163,11 @@
@NonNull IBiometricStateListener listener) {
mBiometricStateListeners.add(listener);
broadcastCurrentEnrollmentState(listener);
+ try {
+ listener.asBinder().linkToDeath(this, 0 /* flags */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to link to death", e);
+ }
}
private synchronized void broadcastCurrentEnrollmentState(
@@ -196,4 +203,19 @@
Slog.e(TAG, "Remote exception", e);
}
}
-}
+
+ @Override
+ public void binderDied() {
+ // Do nothing, handled below
+ }
+
+ @Override
+ public void binderDied(IBinder who) {
+ Slog.w(TAG, "Callback binder died: " + who);
+ if (mBiometricStateListeners.removeIf(listener -> listener.asBinder().equals(who))) {
+ Slog.w(TAG, "Removed dead listener for " + who);
+ } else {
+ Slog.w(TAG, "No dead listeners found");
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
index 0e30782..3b66eab 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
@@ -80,6 +80,8 @@
when(mFakeProvider.hasEnrollments(eq(SENSOR_ID), eq(USER_ID))).thenReturn(true);
when(mUserManager.getAliveUsers()).thenReturn(
List.of(new UserInfo(USER_ID, "name", 0)));
+ when(mBiometricStateListener.asBinder()).thenReturn(mBiometricStateListener);
+
mCallback = new BiometricStateCallback<>(mUserManager);
mCallback.registerBiometricStateListener(mBiometricStateListener);
@@ -110,6 +112,14 @@
false /* expectCallback */, false /* expectedCallbackValue */);
}
+ @Test
+ public void testBinderDeath() {
+ mCallback.binderDied(mBiometricStateListener.asBinder());
+
+ testEnrollmentCallback(true /* changed */, false /* isNowEnrolled */,
+ false /* expectCallback */, false /* expectedCallbackValue */);
+ }
+
private void testEnrollmentCallback(boolean changed, boolean isNowEnrolled,
boolean expectCallback, boolean expectedCallbackValue) {
EnrollClient<?> client = mock(EnrollClient.class);