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

Commit 824e843a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix biometric scheduler watchdog" into main

parents 3cd31aeb 99b50138
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -41,3 +41,13 @@ flag {
  description: "This flag controls FRR dialog improvement"
  bug: "380800403"
}

flag {
  name: "biometric_scheduler_fix"
  namespace: "biometrics_framework"
  description: "This flag fixes a bug where watchdog is ineffective when user switching is required."
  bug: "420939050"
  metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.expresslog.Counter;
import com.android.server.biometrics.BiometricSchedulerProto;
import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.Flags;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;

import java.io.PrintWriter;
@@ -314,8 +315,11 @@ public class BiometricScheduler<T, U> {

        final int currentUserId = mCurrentUserRetriever.get();
        final int nextUserId = mPendingOperations.getFirst().getTargetUserId();
        final boolean shouldStartNextOperationIfMarkedCancelling =
                Flags.biometricSchedulerFix() && mPendingOperations.getFirst().isMarkedCanceling();

        if (nextUserId == currentUserId || mPendingOperations.getFirst().isStartUserOperation()) {
        if (nextUserId == currentUserId || mPendingOperations.getFirst().isStartUserOperation()
                || shouldStartNextOperationIfMarkedCancelling) {
            startNextOperationIfIdle();
        } else if (currentUserId == UserHandle.USER_NULL && mUserSwitchProvider != null) {
            final BaseClientMonitor startClient =
+48 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
@@ -66,6 +67,7 @@ import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;

import com.android.server.biometrics.Flags;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.nano.BiometricSchedulerProto;
@@ -801,6 +803,46 @@ public class BiometricSchedulerTest {

    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_BIOMETRIC_SCHEDULER_FIX)
    public void testBiometricQueueHung_watchdogTriggered_noUserSwitch() {
        final int currentUserId = mCurrentUserId;
        final int newUserId = 10;

        final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
        final TestHalClientMonitor client1 = new TestHalClientMonitor(mContext, mToken, lazyDaemon1,
                0 /* cookie */, BiometricsProto.CM_UPDATE_ACTIVE_USER, currentUserId);
        final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);

        final TestHalClientMonitor client2 = new TestHalClientMonitor(mContext, mToken, lazyDaemon1,
                0 /* cookie */, BiometricsProto.CM_UPDATE_ACTIVE_USER, newUserId);
        final ClientMonitorCallback callback2 = mock(ClientMonitorCallback.class);

        mScheduler.scheduleClientMonitor(client1, callback1);
        mScheduler.scheduleClientMonitor(client2, callback2);

        waitForIdle();

        assertThat(mScheduler.mPendingOperations.size()).isEqualTo(1);
        assertThat(mScheduler.mCurrentOperation.getClientMonitor()).isEqualTo(client1);
        verify(callback1).onClientStarted(client1);

        mScheduler.startWatchdog();
        waitForIdle();
        mLooper.moveTimeForward(10000);
        waitForIdle();
        // After 10 seconds the HAL has 3 seconds to respond to a cancel
        mLooper.moveTimeForward(3000);
        waitForIdle();


        assertThat(mScheduler.mPendingOperations.size()).isEqualTo(0);
        assertThat(mScheduler.mCurrentOperation).isEqualTo(null);
        assertThat(mCurrentUserId).isEqualTo(currentUserId);
        verify(callback1).onClientFinished(client1, true);
        verify(callback2).onClientFinished(client2, true);
    }

    @Test
    public void testTwoInternalCleanupOps_withFirstFavorHalEnrollment() throws Exception {
        final String owner = "test.owner";
@@ -1182,7 +1224,12 @@ public class BiometricSchedulerTest {

        TestHalClientMonitor(@NonNull Context context, @NonNull IBinder token,
                @NonNull Supplier<Object> lazyDaemon, int cookie, int protoEnum) {
            super(context, lazyDaemon, token /* token */, null /* listener */, 0 /* userId */, TAG,
            this(context, token, lazyDaemon, cookie, protoEnum, 0 /* userId */);
        }

        TestHalClientMonitor(@NonNull Context context, @NonNull IBinder token,
                @NonNull Supplier<Object> lazyDaemon, int cookie, int protoEnum, int userId) {
            super(context, lazyDaemon, token /* token */, null /* listener */, userId, TAG,
                    cookie, TEST_SENSOR_ID, mock(BiometricLogger.class),
                    mock(BiometricContext.class), false /* isMandatoryBiometrics */);
            mProtoEnum = protoEnum;