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

Commit f9b4040b 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" into tm-qpr-dev

parents 9babfb43 4d81f75c
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.hardware.biometrics.BiometricStateListener.STATE_KEYGUARD_
import android.annotation.NonNull;
import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.IBiometricStateListener;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;

@@ -35,7 +36,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
 * A callback for receiving notifications about biometric sensor state changes.
 */
public class BiometricStateCallback implements ClientMonitorCallback {
public class BiometricStateCallback implements ClientMonitorCallback, IBinder.DeathRecipient {

    private static final String TAG = "BiometricStateCallback";

@@ -153,5 +154,25 @@ public class BiometricStateCallback implements ClientMonitorCallback {
     */
    public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
        mBiometricStateListeners.add(listener);
        try {
            listener.asBinder().linkToDeath(this, 0 /* flags */);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to link to death", 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");
        }
    }
}
+18 −7
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.IBiometricStateListener;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;

import androidx.test.filters.SmallTest;
@@ -45,36 +46,46 @@ public class BiometricStateCallbackTest {
    private BiometricStateCallback mCallback;

    @Mock
    BiometricStateListener mBiometricStateListener;
    private IBiometricStateListener.Stub mBiometricStateListener;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);

        when(mBiometricStateListener.asBinder()).thenReturn(mBiometricStateListener);

        mCallback = new BiometricStateCallback();
        mCallback.registerBiometricStateListener(mBiometricStateListener);
    }

    @Test
    public void testNoEnrollmentsToEnrollments_callbackNotified() {
    public void testNoEnrollmentsToEnrollments_callbackNotified() throws RemoteException {
        testEnrollmentCallback(true /* changed */, true /* isNowEnrolled */,
                true /* expectCallback */, true /* expectedCallbackValue */);
    }

    @Test
    public void testEnrollmentsToNoEnrollments_callbackNotified() {
    public void testEnrollmentsToNoEnrollments_callbackNotified() throws RemoteException {
        testEnrollmentCallback(true /* changed */, false /* isNowEnrolled */,
                true /* expectCallback */, false /* expectedCallbackValue */);
    }

    @Test
    public void testEnrollmentsToEnrollments_callbackNotNotified() {
    public void testEnrollmentsToEnrollments_callbackNotNotified() throws RemoteException {
        testEnrollmentCallback(false /* changed */, true /* isNowEnrolled */,
                false /* expectCallback */, false /* expectedCallbackValue */);
    }

    @Test
    public void testBinderDeath() throws RemoteException {
        mCallback.binderDied(mBiometricStateListener.asBinder());

        testEnrollmentCallback(true /* changed */, false /* isNowEnrolled */,
                false /* expectCallback */, false /* expectedCallbackValue */);
    }

    private void testEnrollmentCallback(boolean changed, boolean isNowEnrolled,
            boolean expectCallback, boolean expectedCallbackValue) {
            boolean expectCallback, boolean expectedCallbackValue) throws RemoteException {
        EnrollClient<?> client = mock(EnrollClient.class);

        final int userId = 10;
@@ -96,7 +107,7 @@ public class BiometricStateCallbackTest {
    }

    @Test
    public void testAuthentication_enrollmentCallbackNeverNotified() {
    public void testAuthentication_enrollmentCallbackNeverNotified() throws RemoteException {
        AuthenticationClient<?> client = mock(AuthenticationClient.class);
        mCallback.onClientFinished(client, true /* success */);
        verify(mBiometricStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),