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

Commit c94963fd authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Setting to bypass lock screen upon face unlock

Test: atest BiometricsUnlockControllerTest
Test: adb shell settings put secure face_unlock_dismisses_keyguard 0
Test: adb shell settings put secure face_unlock_dismisses_keyguard 1
Bug: 111414690
Change-Id: Id3b112644017bcacf2529717e1ae4b019b00a822
parent 92ed8d72
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -8010,6 +8010,16 @@ public final class Settings {
        private static final Validator FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR =
        private static final Validator FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR =
                BOOLEAN_VALIDATOR;
                BOOLEAN_VALIDATOR;
        /**
         * Whether or not face unlock dismisses the keyguard.
         * @hide
         */
        public static final String FACE_UNLOCK_DISMISSES_KEYGUARD =
                "face_unlock_dismisses_keyguard";
        private static final Validator FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR =
                BOOLEAN_VALIDATOR;
        /**
        /**
         * Whether or not face unlock is allowed for apps (through BiometricPrompt).
         * Whether or not face unlock is allowed for apps (through BiometricPrompt).
         * @hide
         * @hide
@@ -8684,6 +8694,7 @@ public final class Settings {
            NFC_PAYMENT_DEFAULT_COMPONENT,
            NFC_PAYMENT_DEFAULT_COMPONENT,
            AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
            AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
            FACE_UNLOCK_KEYGUARD_ENABLED,
            FACE_UNLOCK_KEYGUARD_ENABLED,
            FACE_UNLOCK_DISMISSES_KEYGUARD,
            FACE_UNLOCK_APP_ENABLED,
            FACE_UNLOCK_APP_ENABLED,
            FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
            FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
            ASSIST_GESTURE_ENABLED,
            ASSIST_GESTURE_ENABLED,
@@ -8845,6 +8856,8 @@ public final class Settings {
            VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
            VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
                    AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
                    AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
            VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
            VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
            VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD,
                    FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR);
            VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
            VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
            VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
            VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
                    FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR);
                    FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR);
+3 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,9 @@
    <!-- Whether or not we show the number in the bar. -->
    <!-- Whether or not we show the number in the bar. -->
    <bool name="config_statusBarShowNumber">false</bool>
    <bool name="config_statusBarShowNumber">false</bool>


    <!-- If the lock screen should be dismissed after biometric auth. -->
    <bool name="config_faceAuthDismissesKeyguard">false</bool>

    <!-- Vibrator pattern for camera gesture launch. -->
    <!-- Vibrator pattern for camera gesture launch. -->
    <integer-array translatable="false" name="config_cameraLaunchGestureVibePattern">
    <integer-array translatable="false" name="config_cameraLaunchGestureVibePattern">
        <item>0</item>
        <item>0</item>
+52 −5
Original line number Original line Diff line number Diff line
@@ -22,17 +22,21 @@ import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.Trace;
import android.os.Trace;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.LatencyTracker;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dependency;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.tuner.TunerService;


import java.io.PrintWriter;
import java.io.PrintWriter;


@@ -95,6 +99,17 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
     */
     */
    private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
    private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;


    /**
     * If face unlock dismisses the lock screen or keeps user on keyguard by default on this device.
     */
    private final boolean mFaceDismissesKeyguardByDefault;

    /**
     * If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
     */
    @VisibleForTesting
    protected boolean mFaceDismissesKeyguard;

    private final NotificationMediaManager mMediaManager;
    private final NotificationMediaManager mMediaManager;
    private final PowerManager mPowerManager;
    private final PowerManager mPowerManager;
    private final Handler mHandler;
    private final Handler mHandler;
@@ -115,6 +130,16 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
    private boolean mPendingShowBouncer;
    private boolean mPendingShowBouncer;
    private boolean mHasScreenTurnedOnSinceAuthenticating;
    private boolean mHasScreenTurnedOnSinceAuthenticating;


    private final TunerService.Tunable mFaceDismissedKeyguardTunable = new TunerService.Tunable() {
        @Override
        public void onTuningChanged(String key, String newValue) {
            int defaultValue = mFaceDismissesKeyguardByDefault ? 1 : 0;
            mFaceDismissesKeyguard = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                    Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
                    defaultValue, KeyguardUpdateMonitor.getCurrentUser()) != 0;
        }
    };

    public BiometricUnlockController(Context context,
    public BiometricUnlockController(Context context,
            DozeScrimController dozeScrimController,
            DozeScrimController dozeScrimController,
            KeyguardViewMediator keyguardViewMediator,
            KeyguardViewMediator keyguardViewMediator,
@@ -122,7 +147,25 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
            StatusBar statusBar,
            StatusBar statusBar,
            UnlockMethodCache unlockMethodCache, Handler handler,
            UnlockMethodCache unlockMethodCache, Handler handler,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
                                     int wakeUpDelay) {
            TunerService tunerService) {
        this(context, dozeScrimController, keyguardViewMediator, scrimController, statusBar,
                unlockMethodCache, handler, keyguardUpdateMonitor, tunerService,
                context.getResources()
                        .getInteger(com.android.internal.R.integer.config_wakeUpDelayDoze),
                context.getResources().getBoolean(R.bool.config_faceAuthDismissesKeyguard));
    }

    @VisibleForTesting
    protected BiometricUnlockController(Context context,
                                     DozeScrimController dozeScrimController,
                                     KeyguardViewMediator keyguardViewMediator,
                                     ScrimController scrimController,
                                     StatusBar statusBar,
                                     UnlockMethodCache unlockMethodCache, Handler handler,
                                     KeyguardUpdateMonitor keyguardUpdateMonitor,
                                     TunerService tunerService,
                                     int wakeUpDelay,
                                     boolean faceDismissesKeyguard) {
        mContext = context;
        mContext = context;
        mPowerManager = context.getSystemService(PowerManager.class);
        mPowerManager = context.getSystemService(PowerManager.class);
        mUpdateMonitor = keyguardUpdateMonitor;
        mUpdateMonitor = keyguardUpdateMonitor;
@@ -138,6 +181,9 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
        mUnlockMethodCache = unlockMethodCache;
        mUnlockMethodCache = unlockMethodCache;
        mHandler = handler;
        mHandler = handler;
        mWakeUpDelay = wakeUpDelay;
        mWakeUpDelay = wakeUpDelay;
        mFaceDismissesKeyguardByDefault = faceDismissesKeyguard;
        tunerService.addTunable(mFaceDismissedKeyguardTunable,
                Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD);
    }
    }


    public void setStatusBarKeyguardViewManager(
    public void setStatusBarKeyguardViewManager(
@@ -344,27 +390,28 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
    private int calculateMode(BiometricSourceType biometricSourceType) {
    private int calculateMode(BiometricSourceType biometricSourceType) {
        boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
        boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
        boolean deviceDreaming = mUpdateMonitor.isDreaming();
        boolean deviceDreaming = mUpdateMonitor.isDreaming();
        boolean isFace = biometricSourceType == BiometricSourceType.FACE;
        boolean faceStayingOnKeyguard = biometricSourceType == BiometricSourceType.FACE
                && !mFaceDismissesKeyguard;


        if (!mUpdateMonitor.isDeviceInteractive()) {
        if (!mUpdateMonitor.isDeviceInteractive()) {
            if (!mStatusBarKeyguardViewManager.isShowing()) {
            if (!mStatusBarKeyguardViewManager.isShowing()) {
                return MODE_ONLY_WAKE;
                return MODE_ONLY_WAKE;
            } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
            } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
                return isFace ? MODE_NONE : MODE_WAKE_AND_UNLOCK_PULSING;
                return faceStayingOnKeyguard ? MODE_NONE : MODE_WAKE_AND_UNLOCK_PULSING;
            } else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
            } else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
                return MODE_WAKE_AND_UNLOCK;
                return MODE_WAKE_AND_UNLOCK;
            } else {
            } else {
                return MODE_SHOW_BOUNCER;
                return MODE_SHOW_BOUNCER;
            }
            }
        }
        }
        if (unlockingAllowed && deviceDreaming && !isFace) {
        if (unlockingAllowed && deviceDreaming && !faceStayingOnKeyguard) {
            return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
            return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
        }
        }
        if (mStatusBarKeyguardViewManager.isShowing()) {
        if (mStatusBarKeyguardViewManager.isShowing()) {
            if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) {
            if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) {
                return MODE_DISMISS_BOUNCER;
                return MODE_DISMISS_BOUNCER;
            } else if (unlockingAllowed) {
            } else if (unlockingAllowed) {
                return isFace ? MODE_ONLY_WAKE : MODE_UNLOCK;
                return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK;
            } else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
            } else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
                return MODE_SHOW_BOUNCER;
                return MODE_SHOW_BOUNCER;
            }
            }
+2 −2
Original line number Original line Diff line number Diff line
@@ -225,6 +225,7 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.volume.VolumeComponent;


@@ -1208,8 +1209,7 @@ public class StatusBar extends SystemUI implements DemoMode,
        mBiometricUnlockController = new BiometricUnlockController(mContext,
        mBiometricUnlockController = new BiometricUnlockController(mContext,
                mDozeScrimController, keyguardViewMediator,
                mDozeScrimController, keyguardViewMediator,
                mScrimController, this, UnlockMethodCache.getInstance(mContext),
                mScrimController, this, UnlockMethodCache.getInstance(mContext),
                new Handler(), mKeyguardUpdateMonitor, mContext.getResources().getInteger(
                new Handler(), mKeyguardUpdateMonitor, Dependency.get(TunerService.class));
                com.android.internal.R.integer.config_wakeUpDelayDoze));
        mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
        mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                getBouncerContainer(), mNotificationPanel, mBiometricUnlockController);
                getBouncerContainer(), mNotificationPanel, mBiometricUnlockController);
        mKeyguardIndicationController
        mKeyguardIndicationController
+29 −3
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.tuner.TunerService;


import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
@@ -68,6 +69,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
    private StatusBar mStatusBar;
    private StatusBar mStatusBar;
    @Mock
    @Mock
    private UnlockMethodCache mUnlockMethodCache;
    private UnlockMethodCache mUnlockMethodCache;
    @Mock
    private TunerService mTunerService;
    private BiometricUnlockController mBiometricUnlockController;
    private BiometricUnlockController mBiometricUnlockController;


    @Before
    @Before
@@ -79,9 +82,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
        mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
        mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
        mDependency.injectTestDependency(StatusBarWindowController.class,
        mDependency.injectTestDependency(StatusBarWindowController.class,
                mStatusBarWindowController);
                mStatusBarWindowController);
        mBiometricUnlockController = new BiometricUnlockController(mContext, mDozeScrimController,
        mBiometricUnlockController = new TestableBiometricUnlockController(
                mKeyguardViewMediator, mScrimController, mStatusBar, mUnlockMethodCache,
                false /* faceDismissesKeyguard */);
                new Handler(), mUpdateMonitor, 0 /* wakeUpDelay */);
        mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
        mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
    }
    }


@@ -135,6 +137,19 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
        verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
        verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
    }
    }


    @Test
    public void onBiometricAuthenticated_whenFace_dismissingKeyguard() {
        mBiometricUnlockController = new TestableBiometricUnlockController(
                true /* faceDismissesKeyguard */);
        mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);

        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                BiometricSourceType.FACE);

        verify(mStatusBarKeyguardViewManager).animateCollapsePanels(anyFloat());
    }

    @Test
    @Test
    public void onBiometricAuthenticated_whenFaceOnBouncer_dismissBouncer() {
    public void onBiometricAuthenticated_whenFaceOnBouncer_dismissBouncer() {
        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
@@ -156,4 +171,15 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {


        verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
        verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
    }
    }

    private class TestableBiometricUnlockController extends BiometricUnlockController {

        TestableBiometricUnlockController(boolean faceDismissesKeyguard) {
            super(mContext, mDozeScrimController,
                    mKeyguardViewMediator, mScrimController, mStatusBar, mUnlockMethodCache,
                    new Handler(), mUpdateMonitor, mTunerService, 0 /* wakeUpDelay */,
                    faceDismissesKeyguard);
            mFaceDismissesKeyguard = faceDismissesKeyguard;
        }
    }
}
}