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

Commit df6b8da6 authored by Grace Cheng's avatar Grace Cheng
Browse files

Update BiometricUnlockController for secure lock device

Delays face authenticated signal, because device should not be
considered unlocked until face auth is confirmed by the user on the UI

Flag: android.security.secure_lock_device
Bug: 401645997
Bug: 427071518
Test: atest BiometricsUnlockControllerTest
Change-Id: Iace77ffb5734c99bcd400a9907bfde836b459acd
parent d62e8794
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.statusbar.phone;

import static android.security.Flags.FLAG_SECURE_LOCK_DEVICE;
import static android.service.dreams.Flags.FLAG_DREAMS_V2;

import static com.android.systemui.Flags.FLAG_NEW_DOZING_KEYGUARD_STATES;
@@ -65,9 +66,12 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockSource;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.media.NotificationMediaManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.securelockdevice.data.repository.FakeSecureLockDeviceRepository;
import com.android.systemui.securelockdevice.domain.interactor.SecureLockDeviceInteractor;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -141,6 +145,11 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
    private BiometricUnlockInteractor mBiometricUnlockInteractor;
    @Mock
    private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
    private final SecureLockDeviceInteractor mSecureLockDeviceInteractor =
            mKosmos.getSecureLockDeviceInteractor();
    private final FakeSecureLockDeviceRepository mFakeSecureLockDeviceRepository =
            mKosmos.getFakeSecureLockDeviceRepository();
    private final FakeSystemClock mSystemClock = new FakeSystemClock();
    private BiometricUnlockController mBiometricUnlockController;

@@ -177,7 +186,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
                () -> mSelectedUserInteractor,
                mBiometricUnlockInteractor,
                mock(JavaAdapter.class),
                mKeyguardTransitionInteractor
                mKeyguardTransitionInteractor,
                () -> mSecureLockDeviceInteractor
        );
        biometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
        biometricUnlockController.addListener(mBiometricUnlockEventsListener);
@@ -492,6 +502,22 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
                .isEqualTo(BiometricUnlockController.MODE_ONLY_WAKE);
    }

    @EnableFlags(FLAG_SECURE_LOCK_DEVICE)
    @Test
    public void onFaceAuthenticated_whenSecureLockDeviceEnabled_skipNotifyKeyguardAuthenticated() {
        mFakeSecureLockDeviceRepository.onSecureLockDeviceEnabled();
        mFakeSecureLockDeviceRepository.onSuccessfulPrimaryAuth();

        // the value of isStrongBiometric doesn't matter here since we only care about the returned
        // value of isUnlockingWithBiometricAllowed()
        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                BiometricSourceType.FACE, true /* isStrongBiometric */);

        verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
        assertThat(mBiometricUnlockController.getMode())
                .isEqualTo(BiometricUnlockController.MODE_NONE);
    }

    @Test
    @EnableFlags(FLAG_NEW_DOZING_KEYGUARD_STATES)
    public void onBiometricAuthenticated_whenFaceAndPulsing_alwaysDismissKeyguard() {
+42 −26
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;

import static android.app.StatusBarManager.SESSION_KEYGUARD;
import static android.security.Flags.secureLockDevice;
import static android.service.dreams.Flags.dreamsV2;

import android.annotation.IntDef;
@@ -64,6 +65,7 @@ import com.android.systemui.media.NotificationMediaManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.securelockdevice.domain.interactor.SecureLockDeviceInteractor;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -182,6 +184,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
    private final LatencyTracker mLatencyTracker;
    private final VibratorHelper mVibratorHelper;
    private final BiometricUnlockInteractor mBiometricUnlockInteractor;
    private final Lazy<SecureLockDeviceInteractor> mSecureLockDeviceInteractor;

    private final BiometricUnlockLogger mLogger;
    private final SystemClock mSystemClock;
    private final boolean mOrderUnlockAndWake;
@@ -297,7 +301,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
            Lazy<SelectedUserInteractor> selectedUserInteractor,
            BiometricUnlockInteractor biometricUnlockInteractor,
            JavaAdapter javaAdapter,
            KeyguardTransitionInteractor keyguardTransitionInteractor
            KeyguardTransitionInteractor keyguardTransitionInteractor,
            Lazy<SecureLockDeviceInteractor> secureLockDeviceInteractor
    ) {
        mPowerManager = powerManager;
        mUpdateMonitor = keyguardUpdateMonitor;
@@ -307,6 +312,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
        mWakefulnessLifecycle = wakefulnessLifecycle;
        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
        mBiometricUnlockInteractor = biometricUnlockInteractor;
        mSecureLockDeviceInteractor = secureLockDeviceInteractor;

        mNotificationShadeWindowController = notificationShadeWindowController;
        mDozeScrimController = dozeScrimController;
@@ -426,34 +432,44 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
    @Override
    public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
            boolean isStrongBiometric) {
        Trace.beginSection("BiometricUnlockController#onBiometricUnlocked");
        Trace.beginSection("BiometricUnlockController#onBiometricAuthenticated");
        try {
            if (mUpdateMonitor.isGoingToSleep()) {
                mLogger.deferringAuthenticationDueToSleep(userId,
                        biometricSourceType,
                        mPendingAuthenticated != null);
                mPendingAuthenticated = new PendingAuthenticated(userId, biometricSourceType,
                        isStrongBiometric);
            Trace.endSection();
                return;
            }
            mBiometricType = biometricSourceType;
            mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
                    .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
        Optional.ofNullable(BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
            Optional.ofNullable(
                            BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
                    .ifPresent(event -> UI_EVENT_LOGGER.log(event, getSessionId()));

            boolean unlockAllowed =
                    mKeyguardStateController.isOccluded()
                            || mKeyguardBypassController.onBiometricAuthenticated(
                            biometricSourceType, isStrongBiometric);
        if (unlockAllowed) {

            if (secureLockDevice() && mSecureLockDeviceInteractor.get().isSecureLockDeviceEnabled()
                    .getValue() && biometricSourceType == BiometricSourceType.FACE
            ) {
                mLogger.d("Delaying face authenticated signal until user confirmation on the "
                        + "Secure Lock Device UI.");
                return;
            } else if (unlockAllowed) {
                mKeyguardViewMediator.userActivity();
                startWakeAndUnlock(biometricSourceType, isStrongBiometric);
            } else {
                mLogger.d("onBiometricUnlocked aborted by bypass controller");
            }
        } finally {
            Trace.endSection();
        }
    }

    /**
     * Wake and unlock the device in response to successful authentication using biometrics.