Loading services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java +9 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.hardware.biometrics.BiometricConstants; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -135,6 +136,14 @@ public class BiometricSchedulerOperation { mCancelWatchdog = () -> { if (!isFinished()) { Slog.e(TAG, "[Watchdog Triggered]: " + this); try { mClientMonitor.getListener().onError(mClientMonitor.getSensorId(), mClientMonitor.getCookie(), BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0 /* vendorCode */); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when trying to send error in cancel " + "watchdog."); } getWrappedCallback(mOnStartCallback) .onClientFinished(mClientMonitor, false /* success */); } Loading services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java +11 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.testing.TestableLooper.RunWithLooper; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.eq; Loading @@ -29,7 +30,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; import android.hardware.biometrics.BiometricConstants; import android.os.Handler; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -72,6 +75,8 @@ public class BiometricSchedulerOperationTest { @Mock private BaseClientMonitor mNonInterruptableClientMonitor; @Mock private ClientMonitorCallbackConverter mListener; @Mock private ClientMonitorCallback mClientCallback; @Mock private ClientMonitorCallback mOnStartCallback; Loading Loading @@ -435,17 +440,18 @@ public class BiometricSchedulerOperationTest { } @Test public void cancelWatchdogWhenStarted() { public void cancelWatchdogWhenStarted() throws RemoteException { cancelWatchdog(true); } @Test public void cancelWatchdogWithoutStarting() { public void cancelWatchdogWithoutStarting() throws RemoteException { cancelWatchdog(false); } private void cancelWatchdog(boolean start) { private void cancelWatchdog(boolean start) throws RemoteException { when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal); when(mInterruptableClientMonitor.getListener()).thenReturn(mListener); mInterruptableOperation.start(mOnStartCallback); if (start) { Loading @@ -461,6 +467,8 @@ public class BiometricSchedulerOperationTest { assertThat(mInterruptableOperation.isFinished()).isTrue(); assertThat(mInterruptableOperation.isCanceling()).isFalse(); verify(mInterruptableClientMonitor.getListener()).onError(anyInt(), anyInt(), eq( BiometricConstants.BIOMETRIC_ERROR_CANCELED), eq(0)); verify(mOnStartCallback).onClientFinished(eq(mInterruptableClientMonitor), eq(false)); verify(mInterruptableClientMonitor).destroy(); } Loading services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +30 −21 Original line number Diff line number Diff line Loading @@ -135,6 +135,8 @@ public class BiometricSchedulerTest { private ISession mSession; @Mock private IFingerprint mFingerprint; @Mock private ClientMonitorCallbackConverter mListener; @Before public void setUp() { Loading Loading @@ -206,7 +208,7 @@ public class BiometricSchedulerTest { // Pretend the scheduler is busy so the first operation doesn't start right away. We want // to pretend like there are two operations in the queue before kicking things off mScheduler.mCurrentOperation = new BiometricSchedulerOperation( mock(BaseClientMonitor.class), mock(ClientMonitorCallback.class)); createBaseClientMonitor(), mock(ClientMonitorCallback.class)); mScheduler.scheduleClientMonitor(client1, callback1); assertEquals(1, mScheduler.mPendingOperations.size()); Loading Loading @@ -244,7 +246,7 @@ public class BiometricSchedulerTest { // Pretend the scheduler is busy so the first operation doesn't start right away. We want // to pretend like there are two operations in the queue before kicking things off mScheduler.mCurrentOperation = new BiometricSchedulerOperation( mock(BaseClientMonitor.class), mock(ClientMonitorCallback.class)); createBaseClientMonitor(), mock(ClientMonitorCallback.class)); mScheduler.scheduleClientMonitor(client1, callback1); assertEquals(1, mScheduler.mPendingOperations.size()); Loading Loading @@ -612,10 +614,10 @@ public class BiometricSchedulerTest { @Test public void testInterruptPrecedingClients_whenExpected() { final BaseClientMonitor interruptableMonitor = mock(BaseClientMonitor.class); final BaseClientMonitor interruptableMonitor = createBaseClientMonitor(); when(interruptableMonitor.isInterruptable()).thenReturn(true); final BaseClientMonitor interrupter = mock(BaseClientMonitor.class); final BaseClientMonitor interrupter = createBaseClientMonitor(); when(interrupter.interruptsPrecedingClients()).thenReturn(true); mScheduler.scheduleClientMonitor(interruptableMonitor); Loading @@ -628,10 +630,10 @@ public class BiometricSchedulerTest { @Test public void testDoesNotInterruptPrecedingClients_whenNotExpected() { final BaseClientMonitor interruptableMonitor = mock(BaseClientMonitor.class); final BaseClientMonitor interruptableMonitor = createBaseClientMonitor(); when(interruptableMonitor.isInterruptable()).thenReturn(true); final BaseClientMonitor interrupter = mock(BaseClientMonitor.class); final BaseClientMonitor interrupter = createBaseClientMonitor(); when(interrupter.interruptsPrecedingClients()).thenReturn(false); mScheduler.scheduleClientMonitor(interruptableMonitor); Loading Loading @@ -741,7 +743,7 @@ public class BiometricSchedulerTest { //Start watchdog mScheduler.startWatchdog(); waitForIdle(); mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class), mScheduler.scheduleClientMonitor(createBaseClientMonitor(), mock(ClientMonitorCallback.class)); waitForIdle(); Loading Loading @@ -775,9 +777,9 @@ public class BiometricSchedulerTest { //Start watchdog mScheduler.startWatchdog(); waitForIdle(); mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class), mScheduler.scheduleClientMonitor(createBaseClientMonitor(), mock(ClientMonitorCallback.class)); mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class), mScheduler.scheduleClientMonitor(createBaseClientMonitor(), mock(ClientMonitorCallback.class)); waitForIdle(); Loading Loading @@ -857,7 +859,7 @@ public class BiometricSchedulerTest { public void testScheduleOperation_whenNoUser() { mCurrentUserId = UserHandle.USER_NULL; final BaseClientMonitor nextClient = mock(BaseClientMonitor.class); final BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(0); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -875,9 +877,9 @@ public class BiometricSchedulerTest { mStartOperationsFinish = false; final BaseClientMonitor[] nextClients = new BaseClientMonitor[]{ mock(BaseClientMonitor.class), mock(BaseClientMonitor.class), mock(BaseClientMonitor.class) createBaseClientMonitor(), createBaseClientMonitor(), createBaseClientMonitor() }; for (BaseClientMonitor client : nextClients) { when(client.getTargetUserId()).thenReturn(5); Loading @@ -899,7 +901,7 @@ public class BiometricSchedulerTest { mCurrentUserId = UserHandle.USER_NULL; mStartOperationsFinish = false; final BaseClientMonitor client = mock(BaseClientMonitor.class); final BaseClientMonitor client = createBaseClientMonitor(); when(client.getTargetUserId()).thenReturn(5); Loading @@ -913,7 +915,7 @@ public class BiometricSchedulerTest { assertThat(mScheduler.mCurrentOperation).isNull(); final BiometricSchedulerOperation fakeOperation = new BiometricSchedulerOperation( mock(BaseClientMonitor.class), new ClientMonitorCallback() {}); createBaseClientMonitor(), new ClientMonitorCallback() {}); mScheduler.mCurrentOperation = fakeOperation; startUserClient.mCallback.onClientFinished(startUserClient, true); Loading @@ -925,7 +927,7 @@ public class BiometricSchedulerTest { public void testScheduleOperation_whenSameUser() { mCurrentUserId = 10; BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(mCurrentUserId); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -943,7 +945,7 @@ public class BiometricSchedulerTest { mCurrentUserId = 10; final int nextUserId = 11; BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(nextUserId); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -963,7 +965,7 @@ public class BiometricSchedulerTest { public void testStartUser_alwaysStartsNextOperation() { mCurrentUserId = UserHandle.USER_NULL; BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(10); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -977,7 +979,7 @@ public class BiometricSchedulerTest { // schedule second operation but swap out the current operation // before it runs so that it's not current when it's completion callback runs nextClient = mock(BaseClientMonitor.class); nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(11); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -994,7 +996,7 @@ public class BiometricSchedulerTest { // When a stop user client fails, check that mStopUserClient // is set to null to prevent the scheduler from getting stuck. BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(10); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -1008,7 +1010,7 @@ public class BiometricSchedulerTest { // schedule second operation but swap out the current operation // before it runs so that it's not current when it's completion callback runs nextClient = mock(BaseClientMonitor.class); nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(11); mShouldFailStopUser = true; mScheduler.scheduleClientMonitor(nextClient); Loading @@ -1023,6 +1025,13 @@ public class BiometricSchedulerTest { return BiometricSchedulerProto.parseFrom(mScheduler.dumpProtoState(clearSchedulerBuffer)); } private BaseClientMonitor createBaseClientMonitor() { BaseClientMonitor client = mock(BaseClientMonitor.class); when(client.getListener()).thenReturn(mListener); return client; } private void waitForIdle() { TestableLooper.get(this).processAllMessages(); } Loading Loading
services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java +9 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.hardware.biometrics.BiometricConstants; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -135,6 +136,14 @@ public class BiometricSchedulerOperation { mCancelWatchdog = () -> { if (!isFinished()) { Slog.e(TAG, "[Watchdog Triggered]: " + this); try { mClientMonitor.getListener().onError(mClientMonitor.getSensorId(), mClientMonitor.getCookie(), BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0 /* vendorCode */); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when trying to send error in cancel " + "watchdog."); } getWrappedCallback(mOnStartCallback) .onClientFinished(mClientMonitor, false /* success */); } Loading
services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java +11 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.testing.TestableLooper.RunWithLooper; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.eq; Loading @@ -29,7 +30,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; import android.hardware.biometrics.BiometricConstants; import android.os.Handler; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -72,6 +75,8 @@ public class BiometricSchedulerOperationTest { @Mock private BaseClientMonitor mNonInterruptableClientMonitor; @Mock private ClientMonitorCallbackConverter mListener; @Mock private ClientMonitorCallback mClientCallback; @Mock private ClientMonitorCallback mOnStartCallback; Loading Loading @@ -435,17 +440,18 @@ public class BiometricSchedulerOperationTest { } @Test public void cancelWatchdogWhenStarted() { public void cancelWatchdogWhenStarted() throws RemoteException { cancelWatchdog(true); } @Test public void cancelWatchdogWithoutStarting() { public void cancelWatchdogWithoutStarting() throws RemoteException { cancelWatchdog(false); } private void cancelWatchdog(boolean start) { private void cancelWatchdog(boolean start) throws RemoteException { when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal); when(mInterruptableClientMonitor.getListener()).thenReturn(mListener); mInterruptableOperation.start(mOnStartCallback); if (start) { Loading @@ -461,6 +467,8 @@ public class BiometricSchedulerOperationTest { assertThat(mInterruptableOperation.isFinished()).isTrue(); assertThat(mInterruptableOperation.isCanceling()).isFalse(); verify(mInterruptableClientMonitor.getListener()).onError(anyInt(), anyInt(), eq( BiometricConstants.BIOMETRIC_ERROR_CANCELED), eq(0)); verify(mOnStartCallback).onClientFinished(eq(mInterruptableClientMonitor), eq(false)); verify(mInterruptableClientMonitor).destroy(); } Loading
services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +30 −21 Original line number Diff line number Diff line Loading @@ -135,6 +135,8 @@ public class BiometricSchedulerTest { private ISession mSession; @Mock private IFingerprint mFingerprint; @Mock private ClientMonitorCallbackConverter mListener; @Before public void setUp() { Loading Loading @@ -206,7 +208,7 @@ public class BiometricSchedulerTest { // Pretend the scheduler is busy so the first operation doesn't start right away. We want // to pretend like there are two operations in the queue before kicking things off mScheduler.mCurrentOperation = new BiometricSchedulerOperation( mock(BaseClientMonitor.class), mock(ClientMonitorCallback.class)); createBaseClientMonitor(), mock(ClientMonitorCallback.class)); mScheduler.scheduleClientMonitor(client1, callback1); assertEquals(1, mScheduler.mPendingOperations.size()); Loading Loading @@ -244,7 +246,7 @@ public class BiometricSchedulerTest { // Pretend the scheduler is busy so the first operation doesn't start right away. We want // to pretend like there are two operations in the queue before kicking things off mScheduler.mCurrentOperation = new BiometricSchedulerOperation( mock(BaseClientMonitor.class), mock(ClientMonitorCallback.class)); createBaseClientMonitor(), mock(ClientMonitorCallback.class)); mScheduler.scheduleClientMonitor(client1, callback1); assertEquals(1, mScheduler.mPendingOperations.size()); Loading Loading @@ -612,10 +614,10 @@ public class BiometricSchedulerTest { @Test public void testInterruptPrecedingClients_whenExpected() { final BaseClientMonitor interruptableMonitor = mock(BaseClientMonitor.class); final BaseClientMonitor interruptableMonitor = createBaseClientMonitor(); when(interruptableMonitor.isInterruptable()).thenReturn(true); final BaseClientMonitor interrupter = mock(BaseClientMonitor.class); final BaseClientMonitor interrupter = createBaseClientMonitor(); when(interrupter.interruptsPrecedingClients()).thenReturn(true); mScheduler.scheduleClientMonitor(interruptableMonitor); Loading @@ -628,10 +630,10 @@ public class BiometricSchedulerTest { @Test public void testDoesNotInterruptPrecedingClients_whenNotExpected() { final BaseClientMonitor interruptableMonitor = mock(BaseClientMonitor.class); final BaseClientMonitor interruptableMonitor = createBaseClientMonitor(); when(interruptableMonitor.isInterruptable()).thenReturn(true); final BaseClientMonitor interrupter = mock(BaseClientMonitor.class); final BaseClientMonitor interrupter = createBaseClientMonitor(); when(interrupter.interruptsPrecedingClients()).thenReturn(false); mScheduler.scheduleClientMonitor(interruptableMonitor); Loading Loading @@ -741,7 +743,7 @@ public class BiometricSchedulerTest { //Start watchdog mScheduler.startWatchdog(); waitForIdle(); mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class), mScheduler.scheduleClientMonitor(createBaseClientMonitor(), mock(ClientMonitorCallback.class)); waitForIdle(); Loading Loading @@ -775,9 +777,9 @@ public class BiometricSchedulerTest { //Start watchdog mScheduler.startWatchdog(); waitForIdle(); mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class), mScheduler.scheduleClientMonitor(createBaseClientMonitor(), mock(ClientMonitorCallback.class)); mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class), mScheduler.scheduleClientMonitor(createBaseClientMonitor(), mock(ClientMonitorCallback.class)); waitForIdle(); Loading Loading @@ -857,7 +859,7 @@ public class BiometricSchedulerTest { public void testScheduleOperation_whenNoUser() { mCurrentUserId = UserHandle.USER_NULL; final BaseClientMonitor nextClient = mock(BaseClientMonitor.class); final BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(0); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -875,9 +877,9 @@ public class BiometricSchedulerTest { mStartOperationsFinish = false; final BaseClientMonitor[] nextClients = new BaseClientMonitor[]{ mock(BaseClientMonitor.class), mock(BaseClientMonitor.class), mock(BaseClientMonitor.class) createBaseClientMonitor(), createBaseClientMonitor(), createBaseClientMonitor() }; for (BaseClientMonitor client : nextClients) { when(client.getTargetUserId()).thenReturn(5); Loading @@ -899,7 +901,7 @@ public class BiometricSchedulerTest { mCurrentUserId = UserHandle.USER_NULL; mStartOperationsFinish = false; final BaseClientMonitor client = mock(BaseClientMonitor.class); final BaseClientMonitor client = createBaseClientMonitor(); when(client.getTargetUserId()).thenReturn(5); Loading @@ -913,7 +915,7 @@ public class BiometricSchedulerTest { assertThat(mScheduler.mCurrentOperation).isNull(); final BiometricSchedulerOperation fakeOperation = new BiometricSchedulerOperation( mock(BaseClientMonitor.class), new ClientMonitorCallback() {}); createBaseClientMonitor(), new ClientMonitorCallback() {}); mScheduler.mCurrentOperation = fakeOperation; startUserClient.mCallback.onClientFinished(startUserClient, true); Loading @@ -925,7 +927,7 @@ public class BiometricSchedulerTest { public void testScheduleOperation_whenSameUser() { mCurrentUserId = 10; BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(mCurrentUserId); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -943,7 +945,7 @@ public class BiometricSchedulerTest { mCurrentUserId = 10; final int nextUserId = 11; BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(nextUserId); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -963,7 +965,7 @@ public class BiometricSchedulerTest { public void testStartUser_alwaysStartsNextOperation() { mCurrentUserId = UserHandle.USER_NULL; BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(10); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -977,7 +979,7 @@ public class BiometricSchedulerTest { // schedule second operation but swap out the current operation // before it runs so that it's not current when it's completion callback runs nextClient = mock(BaseClientMonitor.class); nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(11); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -994,7 +996,7 @@ public class BiometricSchedulerTest { // When a stop user client fails, check that mStopUserClient // is set to null to prevent the scheduler from getting stuck. BaseClientMonitor nextClient = mock(BaseClientMonitor.class); BaseClientMonitor nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(10); mScheduler.scheduleClientMonitor(nextClient); Loading @@ -1008,7 +1010,7 @@ public class BiometricSchedulerTest { // schedule second operation but swap out the current operation // before it runs so that it's not current when it's completion callback runs nextClient = mock(BaseClientMonitor.class); nextClient = createBaseClientMonitor(); when(nextClient.getTargetUserId()).thenReturn(11); mShouldFailStopUser = true; mScheduler.scheduleClientMonitor(nextClient); Loading @@ -1023,6 +1025,13 @@ public class BiometricSchedulerTest { return BiometricSchedulerProto.parseFrom(mScheduler.dumpProtoState(clearSchedulerBuffer)); } private BaseClientMonitor createBaseClientMonitor() { BaseClientMonitor client = mock(BaseClientMonitor.class); when(client.getListener()).thenReturn(mListener); return client; } private void waitForIdle() { TestableLooper.get(this).processAllMessages(); } Loading