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

Commit d6cbdb4e authored by Austin Delgado's avatar Austin Delgado Committed by Android (Google) Code Review
Browse files

Merge "Added subscription to binder death which removes dead callbacks"

parents e041b342 47ac1476
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);