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

Commit 95278e36 authored by Diya Bera's avatar Diya Bera
Browse files

Send cancel error when watchdog triggered

Test: atest BiometricSchedulerOperationTest
Fixes: 328953063
Change-Id: Iccdd7506ec820d9d5979408a4a0430abbba5e563
(cherry picked from commit a6435c22)
parent 55ccc51f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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 */);
            }
+11 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -72,6 +75,8 @@ public class BiometricSchedulerOperationTest {
    @Mock
    private BaseClientMonitor mNonInterruptableClientMonitor;
    @Mock
    private ClientMonitorCallbackConverter mListener;
    @Mock
    private ClientMonitorCallback mClientCallback;
    @Mock
    private ClientMonitorCallback mOnStartCallback;
@@ -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) {
@@ -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();
    }
+30 −21
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ public class BiometricSchedulerTest {
    private ISession mSession;
    @Mock
    private IFingerprint mFingerprint;
    @Mock
    private ClientMonitorCallbackConverter mListener;

    @Before
    public void setUp() {
@@ -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());
@@ -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());
@@ -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);
@@ -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);
@@ -741,7 +743,7 @@ public class BiometricSchedulerTest {
        //Start watchdog
        mScheduler.startWatchdog();
        waitForIdle();
        mScheduler.scheduleClientMonitor(mock(BaseClientMonitor.class),
        mScheduler.scheduleClientMonitor(createBaseClientMonitor(),
                mock(ClientMonitorCallback.class));
        waitForIdle();

@@ -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();

@@ -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);
@@ -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);
@@ -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);

@@ -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);

@@ -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);
@@ -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);
@@ -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);
@@ -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);

@@ -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);
@@ -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);
@@ -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();
    }