From 47ac14766773b81f636592b71b7817e345b4679b Mon Sep 17 00:00:00 2001 From: Austin Delgado Date: Thu, 11 Aug 2022 18:21:57 +0000 Subject: [PATCH] Added subscription to binder death which removes dead callbacks Test: atest BiometricStateCallbackTest Bug: 237439972 Change-Id: I4fad4c5f1042edb27e20c9f916f999092afed0e0 --- .../sensors/BiometricStateCallback.java | 26 +++++++++++++++++-- .../BiometricStateCallbackTest.java | 10 +++++++ 2 files changed, 34 insertions(+), 2 deletions(-) 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 f8543162f95e7..2263e80039bd4 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.content.pm.UserInfo; 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 @@ import java.util.concurrent.CopyOnWriteArrayList; * @param

internal property type */ public class BiometricStateCallback, - P extends SensorPropertiesInternal> implements ClientMonitorCallback { + P extends SensorPropertiesInternal> + implements ClientMonitorCallback, IBinder.DeathRecipient { private static final String TAG = "BiometricStateCallback"; @@ -161,6 +163,11 @@ public class BiometricStateCallback, @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 @@ public class BiometricStateCallback, 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 0e30782eaece9..3b66eaba6129e 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 @@ public class BiometricStateCallbackTest { 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 @@ public class BiometricStateCallbackTest { 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);