Loading services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java +22 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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"); } } } services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java +18 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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(), Loading Loading
services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java +22 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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"); } } }
services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java +18 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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(), Loading