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

Commit 0cdcacb4 authored by Beverly's avatar Beverly
Browse files

Run fpDetect instead of authenticate if keyguard is dismissible

Guarded behind flag.

If the fingerprintDetect results in device entry, show
the authRipple.

Test: atest KeyguardUpdateMonitorTest
Bug: 311145851
Flag: ACONFIG com.android.systemui.run_fingerprint_detect_on_dismissible_keyguard DEVELOPMENT

Change-Id: I5564786ca1c6461e8bb4f5c9742d3ee2fbd182a5
parent b7456308
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -307,6 +307,13 @@ flag {
    bug: "312784809"
}

flag {
   name: "run_fingerprint_detect_on_dismissible_keyguard"
   namespace: "systemui"
   description: "Run fingerprint detect instead of authenticate if the keyguard is dismissible."
   bug: "311145851"
}

flag {
   name: "bluetooth_qs_tile_dialog_auto_on_toggle"
   namespace: "systemui"
+30 −5
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ import com.android.settingslib.WirelessUtils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dumpable;
import com.android.systemui.Flags;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -373,6 +374,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private List<SubscriptionInfo> mSubscriptionInfo;
    @VisibleForTesting
    protected int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
    private boolean mFingerprintDetectRunning;
    private boolean mIsDreaming;
    private boolean mLogoutEnabled;
    private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -986,6 +988,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        final boolean wasCancellingRestarting = mFingerprintRunningState
                == BIOMETRIC_STATE_CANCELLING_RESTARTING;
        mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
        mFingerprintDetectRunning = false;
        if (wasCancellingRestarting) {
            KeyguardUpdateMonitor.this.updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
        } else {
@@ -1094,6 +1097,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
        boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
        mFingerprintRunningState = fingerprintRunningState;
        if (mFingerprintRunningState == BIOMETRIC_STATE_STOPPED) {
            mFingerprintDetectRunning = false;
        }
        mLogger.logFingerprintRunningState(mFingerprintRunningState);
        // Clients of KeyguardUpdateMonitor don't care about the internal state about the
        // asynchronousness of the cancel cycle. So only notify them if the actually running state
@@ -2066,6 +2072,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    @VisibleForTesting
    void resetBiometricListeningState() {
        mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
        mFingerprintDetectRunning = false;
    }

    @VisibleForTesting
@@ -2504,8 +2511,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            return;
        }
        final boolean shouldListenForFingerprint = shouldListenForFingerprint(isUdfpsSupported());
        final boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
        final boolean running = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
        final boolean runningOrRestarting = running
                || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
        final boolean runDetect = shouldRunFingerprintDetect();
        if (runningOrRestarting && !shouldListenForFingerprint) {
            if (action == BIOMETRIC_ACTION_START) {
                mLogger.v("Ignoring stopListeningForFingerprint()");
@@ -2517,8 +2526,22 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                mLogger.v("Ignoring startListeningForFingerprint()");
                return;
            }
            startListeningForFingerprint();
            startListeningForFingerprint(runDetect);
        } else if (running && runDetect && !mFingerprintDetectRunning) {
            if (action == BIOMETRIC_ACTION_STOP) {
                mLogger.v("Ignoring startListeningForFingerprint(detect)");
                return;
            }
            // stop running authentication and start running fingerprint detection
            stopListeningForFingerprint();
            startListeningForFingerprint(true);
        }
    }

    private boolean shouldRunFingerprintDetect() {
        return !isUnlockingWithFingerprintAllowed()
                || (Flags.runFingerprintDetectOnDismissibleKeyguard()
                && getUserCanSkipBouncer(mSelectedUserInteractor.getSelectedUserId()));
    }

    /**
@@ -2776,7 +2799,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                        && biometricEnabledForUser
                        && !isUserInLockdown(user);
        final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed();
        final boolean isSideFps = isSfpsSupported() && isSfpsEnrolled();
        final boolean shouldListenBouncerState =
                !strongerAuthRequired || !mPrimaryBouncerIsOrWillBeShowing;

@@ -2839,7 +2861,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
    }

    private void startListeningForFingerprint() {
    private void startListeningForFingerprint(boolean runDetect) {
        final int userId = mSelectedUserInteractor.getSelectedUserId();
        final boolean unlockPossible = isUnlockWithFingerprintPossible(userId);
        if (mFingerprintCancelSignal != null) {
@@ -2869,18 +2891,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                        mFingerprintInteractiveToAuthProvider.getVendorExtension(userId));
            }

            if (!isUnlockingWithFingerprintAllowed()) {
            if (runDetect) {
                mLogger.v("startListeningForFingerprint - detect");
                mFpm.detectFingerprint(
                        mFingerprintCancelSignal,
                        mFingerprintDetectionCallback,
                        fingerprintAuthenticateOptions);
                mFingerprintDetectRunning = true;
            } else {
                mLogger.v("startListeningForFingerprint");
                mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal,
                        mFingerprintAuthenticationCallback,
                        null /* handler */,
                        fingerprintAuthenticateOptions);
                mFingerprintDetectRunning = false;
            }
            setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
        }
@@ -3876,6 +3900,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                mSelectedUserInteractor.getSelectedUserId()));
        pw.println("  getUserUnlockedWithBiometric()="
                + getUserUnlockedWithBiometric(mSelectedUserInteractor.getSelectedUserId()));
        pw.println("  mFingerprintDetectRunning=" + mFingerprintDetectRunning);
        pw.println("  SIM States:");
        for (SimData data : mSimDatas.values()) {
            pw.println("    " + data.toString());
+16 −3
Original line number Diff line number Diff line
@@ -32,13 +32,13 @@ import com.android.keyguard.logging.KeyguardLogger
import com.android.settingslib.Utils
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.lightRevealMigration
import com.android.systemui.res.R
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.log.core.LogLevel
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
import com.android.systemui.statusbar.CircleReveal
import com.android.systemui.statusbar.LiftReveal
import com.android.systemui.statusbar.LightRevealEffect
@@ -50,6 +50,7 @@ import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.ViewController
import kotlinx.coroutines.ExperimentalCoroutinesApi
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Provider
@@ -62,6 +63,7 @@ import javax.inject.Provider
 *
 * The ripple uses the accent color of the current theme.
 */
@ExperimentalCoroutinesApi
@SysUISingleton
class AuthRippleController @Inject constructor(
    private val sysuiContext: Context,
@@ -75,7 +77,6 @@ class AuthRippleController @Inject constructor(
    private val udfpsControllerProvider: Provider<UdfpsController>,
    private val statusBarStateController: StatusBarStateController,
    private val displayMetrics: DisplayMetrics,
    private val featureFlags: FeatureFlags,
    private val logger: KeyguardLogger,
    private val biometricUnlockController: BiometricUnlockController,
    private val lightRevealScrim: LightRevealScrim,
@@ -313,6 +314,18 @@ class AuthRippleController @Inject constructor(
                mView.fadeDwellRipple()
            }
        }

        override fun onBiometricDetected(
                userId: Int,
                biometricSourceType: BiometricSourceType,
                isStrongBiometric: Boolean
        ) {
            // TODO (b/309804148): add support detect auth ripple for deviceEntryUdfpsRefactor
            if (!DeviceEntryUdfpsRefactor.isEnabled &&
                    keyguardUpdateMonitor.getUserCanSkipBouncer(userId)) {
                showUnlockRipple(biometricSourceType)
            }
        }
    }

    private val configurationChangedListener =
+45 −4
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated;
import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
@@ -923,8 +924,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    @Test
    public void trustAgentHasTrust() {
        // WHEN user has trust
        mKeyguardUpdateMonitor.onTrustChanged(true, true,
                mSelectedUserInteractor.getSelectedUserId(), 0, null);
        givenSelectedUserCanSkipBouncerFromTrustedState();

        // THEN user is considered as "having trust" and bouncer can be skipped
        Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(
@@ -948,8 +948,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    @Test
    public void trustAgentHasTrust_fingerprintLockout() {
        // GIVEN user has trust
        mKeyguardUpdateMonitor.onTrustChanged(true, true,
                mSelectedUserInteractor.getSelectedUserId(), 0, null);
        givenSelectedUserCanSkipBouncerFromTrustedState();
        Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(
                mSelectedUserInteractor.getSelectedUserId()));

@@ -1991,6 +1990,43 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
                .isEqualTo(BIOMETRIC_STATE_STOPPED);
    }

    @Test
    public void runFpDetectFlagDisabled_sideFps_keyguardDismissible_fingerprintAuthenticateRuns() {
        mSetFlagsRule.disableFlags(Flags.FLAG_RUN_FINGERPRINT_DETECT_ON_DISMISSIBLE_KEYGUARD);

        // Clear invocations, since previous setup (e.g. registering BiometricManager callbacks)
        // will trigger updateBiometricListeningState();
        clearInvocations(mFingerprintManager);
        mKeyguardUpdateMonitor.resetBiometricListeningState();

        // GIVEN the user can skip the bouncer
        givenSelectedUserCanSkipBouncerFromTrustedState();
        when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
        mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
        mTestableLooper.processAllMessages();

        // WHEN verify authenticate runs
        verifyFingerprintAuthenticateCall();
    }

    @Test
    public void sideFps_keyguardDismissible_fingerprintDetectRuns() {
        mSetFlagsRule.enableFlags(Flags.FLAG_RUN_FINGERPRINT_DETECT_ON_DISMISSIBLE_KEYGUARD);
        // Clear invocations, since previous setup (e.g. registering BiometricManager callbacks)
        // will trigger updateBiometricListeningState();
        clearInvocations(mFingerprintManager);
        mKeyguardUpdateMonitor.resetBiometricListeningState();

        // GIVEN the user can skip the bouncer
        givenSelectedUserCanSkipBouncerFromTrustedState();
        when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
        mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
        mTestableLooper.processAllMessages();

        // WHEN verify detect runs
        verifyFingerprintDetectCall();
    }

    @Test
    public void testFingerprintSensorProperties() throws RemoteException {
        mFingerprintAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(
@@ -2096,6 +2132,11 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
        verify(callback).onBiometricEnrollmentStateChanged(BiometricSourceType.FACE);
    }

    private void givenSelectedUserCanSkipBouncerFromTrustedState() {
        mKeyguardUpdateMonitor.onTrustChanged(true, true,
                mSelectedUserInteractor.getSelectedUserId(), 0, null);
    }

    private void verifyFingerprintAuthenticateNeverCalled() {
        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+0 −1
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@ class AuthRippleControllerTest : SysuiTestCase() {
            udfpsControllerProvider,
            statusBarStateController,
            displayMetrics,
            featureFlags,
            KeyguardLogger(logcatLogBuffer(AuthRippleController.TAG)),
            biometricUnlockController,
            lightRevealScrim,