Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47ac1476 authored by Austin Delgado's avatar Austin Delgado
Browse files

Added subscription to binder death which removes dead callbacks

Test: atest BiometricStateCallbackTest
Bug: 237439972
Change-Id: I4fad4c5f1042edb27e20c9f916f999092afed0e0
parent a833d0f2
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -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 <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 @@ public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
            @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<T extends BiometricServiceProvider<P>,
            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
+10 −0
Original line number Diff line number Diff line
@@ -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);