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

Commit 80f1ddbb authored by Grace Cheng's avatar Grace Cheng
Browse files

Update auth flags and state across secure lock device progress

Updates StrongAuthFlags PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE and
STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE and state of
whether a user has completed two factor authentication across secure lock
device being enabled, interrupted (e.g. biometric lockout), strong
biometric auth, and disabled

Bug: 401645997
Bug: 396641431
Bug: 396642040
Fixes: 396671635
Flag: android.security.secure_lock_device
Test: atest AuthenticationPolicyServiceTest
Test: atest SecureLockDeviceServiceTest
Change-Id: I9561cb2b482a249c1d8de88e8b83456415fb865f
parent 4798c45a
Loading
Loading
Loading
Loading
+81 −15
Original line number Diff line number Diff line
@@ -20,9 +20,14 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE;
import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
import static android.security.Flags.disableAdaptiveAuthCounterLock;
import static android.security.Flags.failedAuthLockToggle;
import static android.security.Flags.secureLockDevice;
import static android.security.Flags.secureLockdown;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;

import android.annotation.EnforcePermission;
@@ -91,7 +96,9 @@ public class AuthenticationPolicyService extends SystemService {
    static final int MAX_ALLOWED_FAILED_AUTH_ATTEMPTS = 5;
    private static final boolean DEFAULT_DISABLE_ADAPTIVE_AUTH_LIMIT_LOCK = false;
    private static final int MSG_REPORT_PRIMARY_AUTH_ATTEMPT = 1;
    private static final int MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT = 2;
    private static final int MSG_REPORT_BIOMETRIC_AUTH_SUCCESS = 2;
    private static final int MSG_REPORT_BIOMETRIC_AUTH_FAILURE = 3;
    private static final int MSG_REPORT_BIOMETRIC_AUTH_ERROR = 4;
    private static final int AUTH_SUCCESS = 1;
    private static final int AUTH_FAILURE = 0;
    private static final int TYPE_PRIMARY_AUTH = 0;
@@ -125,7 +132,7 @@ public class AuthenticationPolicyService extends SystemService {
        mWindowManager = Objects.requireNonNull(
                LocalServices.getService(WindowManagerInternal.class));
        mUserManager = Objects.requireNonNull(LocalServices.getService(UserManagerInternal.class));
        if (android.security.Flags.secureLockdown()) {
        if (secureLockdown()) {
            mSecureLockDeviceService = Objects.requireNonNull(
                    LocalServices.getService(SecureLockDeviceServiceInternal.class));
        }
@@ -218,13 +225,17 @@ public class AuthenticationPolicyService extends SystemService {
                public void onAuthenticationAcquired(AuthenticationAcquiredInfo authInfo) {}

                @Override
                public void onAuthenticationError(AuthenticationErrorInfo authInfo) {}
                public void onAuthenticationError(AuthenticationErrorInfo authInfo) {
                    Slog.i(TAG, "AuthenticationStateListener#onAuthenticationError");
                    mHandler.obtainMessage(
                            MSG_REPORT_BIOMETRIC_AUTH_ERROR, authInfo).sendToTarget();
                }

                @Override
                public void onAuthenticationFailed(AuthenticationFailedInfo authInfo) {
                    Slog.i(TAG, "AuthenticationStateListener#onAuthenticationFailed");
                    mHandler.obtainMessage(MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT, AUTH_FAILURE,
                            authInfo.getUserId()).sendToTarget();
                    mHandler.obtainMessage(
                            MSG_REPORT_BIOMETRIC_AUTH_FAILURE, authInfo).sendToTarget();
                }

                @Override
@@ -241,8 +252,8 @@ public class AuthenticationPolicyService extends SystemService {
                    if (DEBUG) {
                        Slog.d(TAG, "AuthenticationStateListener#onAuthenticationSucceeded");
                    }
                    mHandler.obtainMessage(MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT, AUTH_SUCCESS,
                            authInfo.getUserId()).sendToTarget();
                    mHandler.obtainMessage(
                            MSG_REPORT_BIOMETRIC_AUTH_SUCCESS, authInfo).sendToTarget();
                }
            };

@@ -253,8 +264,17 @@ public class AuthenticationPolicyService extends SystemService {
                case MSG_REPORT_PRIMARY_AUTH_ATTEMPT:
                    handleReportPrimaryAuthAttempt(msg.arg1 != AUTH_FAILURE, msg.arg2);
                    break;
                case MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT:
                    handleReportBiometricAuthAttempt(msg.arg1 != AUTH_FAILURE, msg.arg2);
                case MSG_REPORT_BIOMETRIC_AUTH_SUCCESS:
                    AuthenticationSucceededInfo successInfo = (AuthenticationSucceededInfo) msg.obj;
                    handleReportBiometricAuthSuccess(successInfo);
                    break;
                case MSG_REPORT_BIOMETRIC_AUTH_FAILURE:
                    AuthenticationFailedInfo failInfo = (AuthenticationFailedInfo) msg.obj;
                    handleReportBiometricAuthFailure(failInfo.getUserId());
                    break;
                case MSG_REPORT_BIOMETRIC_AUTH_ERROR:
                    AuthenticationErrorInfo errorInfo = (AuthenticationErrorInfo) msg.obj;
                    handleReportBiometricAuthError(errorInfo);
                    break;
            }
        }
@@ -268,12 +288,53 @@ public class AuthenticationPolicyService extends SystemService {
        reportAuthAttempt(TYPE_PRIMARY_AUTH, success, userId);
    }

    private void handleReportBiometricAuthAttempt(boolean success, int userId) {
    private void handleReportBiometricAuthSuccess(AuthenticationSucceededInfo successInfo) {
        boolean isStrongBiometric = successInfo.isIsStrongBiometric();
        int userId = successInfo.getUserId();

        if (DEBUG) {
            Slog.d(TAG, "handleReportBiometricAuthAttempt: success=" + success
                    + ", userId=" + userId);
            Slog.d(TAG, "handleReportBiometricAuthSuccess: isStrongBiometric="
                    + isStrongBiometric + ", userId=" + userId);
        }
        if (secureLockDevice() && secureLockdown() && isStrongBiometric
                && mSecureLockDeviceService.isSecureLockDeviceEnabled()) {
            // After successful strong biometric auth during secure lock device, notify
            // SecureLockDeviceService
            mSecureLockDeviceService.onStrongBiometricAuthenticationSuccess(UserHandle.of(userId));
        }
        reportAuthAttempt(TYPE_BIOMETRIC_AUTH, /* success */ true, userId);
    }

    private void handleReportBiometricAuthFailure(int userId) {
        if (DEBUG) {
            Slog.d(TAG, "handleReportBiometricAuthFailure: userId=" + userId);
        }
        reportAuthAttempt(TYPE_BIOMETRIC_AUTH, /* success */ false, userId);
    }

    private void handleReportBiometricAuthError(AuthenticationErrorInfo errorInfo) {
        if (DEBUG) {
            Slog.d(TAG, "handleReportBiometricAuthError: "
                    + "biometricSourceType=" + errorInfo.getBiometricSourceType()  + ", "
                    + "requestReason=" + errorInfo.getRequestReason()  + ", "
                    + "errCode=" + errorInfo.getErrCode()  + ", "
                    + "errString=" + errorInfo.getErrString()
            );
        }

        // BIOMETRIC_ERROR_LOCKOUT == FACE_ERROR_LOCKOUT == FINGERPRINT_ERROR_LOCKOUT
        boolean isLockout = errorInfo.getErrCode() == BIOMETRIC_ERROR_LOCKOUT
                || errorInfo.getErrCode() == BIOMETRIC_ERROR_LOCKOUT_PERMANENT;

        boolean secureLockDeviceEnabled = secureLockDevice() && secureLockdown()
                && mSecureLockDeviceService.isSecureLockDeviceEnabled();
        if (secureLockDeviceEnabled && isLockout) {
            // On biometric lockout when secure lock device is enabled, reset authentication
            // progress and return to step 1 of the two-factor authentication - credential
            // auth on the bouncer
            mLockPatternUtils.requireStrongAuth(PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE,
                    UserHandle.USER_ALL);
        }
        reportAuthAttempt(TYPE_BIOMETRIC_AUTH, success, userId);
    }

    private void reportAuthAttempt(int authType, boolean success, int userId) {
@@ -477,7 +538,12 @@ public class AuthenticationPolicyService extends SystemService {
            // Required for internal service to acquire necessary system permissions
            final long identity = Binder.clearCallingIdentity();
            try {
                return mSecureLockDeviceService.disableSecureLockDevice(user, params);
                boolean authenticationComplete =
                        mSecureLockDeviceService.hasUserCompletedTwoFactorAuthentication(user);
                Slog.d("SecureLockDeviceService", "Disabling secure lock device: "
                        + "user " + user + ", authenticationComplete " + authenticationComplete);
                return mSecureLockDeviceService.disableSecureLockDevice(user, params,
                        /* authenticationComplete = */ authenticationComplete);
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
+126 −12
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ import static android.security.authenticationpolicy.AuthenticationPolicyManager.
import static android.security.authenticationpolicy.AuthenticationPolicyManager.ERROR_UNSUPPORTED;
import static android.security.authenticationpolicy.AuthenticationPolicyManager.SUCCESS;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -63,9 +66,12 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractionManagerService;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.locksettings.LockSettingsInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.security.authenticationpolicy.settings.SecureLockDeviceSettingsManager;
import com.android.server.security.authenticationpolicy.settings.SecureLockDeviceSettingsManagerImpl;
import com.android.server.security.authenticationpolicy.settings.SecureLockDeviceStore;
@@ -96,18 +102,28 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
    @NonNull private final Object mSecureLockDeviceStatusListenerLock = new Object();
    @NonNull private final SecureLockDeviceStore mStore;
    @NonNull private final SecureLockDeviceSettingsManager mSecureLockDeviceSettingsManager;

    private final UserManagerInternal mUserManagerInternal;
    // Lock for concurrent access to mUserAuthenticatedWithStrongBiometric
    private final Object mBiometricAuthStateLock = new Object();
    private final RemoteCallbackList<ISecureLockDeviceStatusListener>
            mSecureLockDeviceStatusListeners = new RemoteCallbackList<>();

    // Not final because initialized after SecureLockDeviceService in SystemServer
    private ActivityManager mActivityManager;
    private LockPatternUtils mLockPatternUtils;
    private LockSettingsInternal mLockSettingsInternal;
    private StrongAuthTracker mStrongAuthTracker;
    private WindowManagerInternal mWindowManagerInternal;

    // Stores the UserHandle of the user who has authenticated with a strong biometric
    // to disable secure lock. Will be null if no user is currently authenticated.
    private UserHandle mUserAuthenticatedWithStrongBiometric = null;

    SecureLockDeviceService(@NonNull Context context,
            @NonNull SecureLockDeviceSettingsManager settingsManager,
            @Nullable BiometricManager biometricManager, @Nullable FaceManager faceManager,
            @Nullable FingerprintManager fingerprintManager, @NonNull PowerManager powerManager) {
            @Nullable BiometricManager biometricManager,
            @Nullable FaceManager faceManager, @Nullable FingerprintManager fingerprintManager,
            @NonNull PowerManager powerManager, @NonNull UserManagerInternal userManagerInternal) {
        mContext = context;
        mBiometricManager = biometricManager;
        mFaceManager = faceManager;
@@ -115,6 +131,7 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
        mPowerManager = powerManager;
        mSecureLockDeviceSettingsManager = settingsManager;
        mSecureLockDeviceSettingsManager.resetManagedSettings();
        mUserManagerInternal = userManagerInternal;
        mStore = new SecureLockDeviceStore(IoThread.getHandler(), mSecureLockDeviceSettingsManager);
    }

@@ -138,7 +155,8 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
                context.getSystemService(BiometricManager.class),
                context.getSystemService(FaceManager.class),
                context.getSystemService(FingerprintManager.class),
                Objects.requireNonNull(context.getSystemService(PowerManager.class))
                Objects.requireNonNull(context.getSystemService(PowerManager.class)),
                LocalServices.getService(UserManagerInternal.class)
        );
    }

@@ -171,7 +189,9 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
        }
        mSecureLockDeviceSettingsManager.enableSecurityFeaturesFromBoot(secureLockDeviceClientId);

        // TODO (b/398058587): Set strong auth flags for user to configure allowed auth types
        synchronized (mBiometricAuthStateLock) {
            mUserAuthenticatedWithStrongBiometric = null;
        }

        mStore.storeSecureLockDeviceEnabled(secureLockDeviceClientId);
        notifyAllSecureLockDeviceListenersEnabledStatusUpdated();
@@ -266,6 +286,25 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
        }
    }

    /**
     * Applies Secure Lock Device strong auth flags for all users when secure lock device is
     * enabled.
     *
     * The StrongAuthFlags are used by keyguard and bouncer to determine allowed authenticators
     * and lockdown state, and to display the correct UI for explaining why the device is locked.
     */
    private void setSecureLockDeviceStrongAuthFlags() {
        // Require primary auth only (biometrics disabled) for the first unlock step of
        // Secure Lock Device.
        for (int userId : mUserManagerInternal.getUserIds()) {
            mLockPatternUtils.requireStrongAuth(
                    PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE, userId);
            // Require strong biometric auth for the second unlock step of Secure Lock Device.
            mLockPatternUtils.requireStrongAuth(
                    STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE, userId);
        }
    }

    /**
     * Sets up references to system services initialized after SecureLockDeviceService in
     * SystemServer, and restores secure lock device after boot if needed.
@@ -276,6 +315,14 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
            Slog.d(TAG, "onLockSettingsReady()");
        }
        mActivityManager = mContext.getSystemService(ActivityManager.class);
        mLockSettingsInternal = LocalServices.getService(LockSettingsInternal.class);
        if (mLockPatternUtils == null) {
            mLockPatternUtils = new LockPatternUtils(mContext);
            if (mStrongAuthTracker == null) {
                mStrongAuthTracker = new StrongAuthTracker(mContext);
            }
            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
        }
        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
    }

@@ -406,7 +453,7 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
            return ERROR_UNKNOWN;
        }

        // TODO (b/398058587): Set strong auth flags for user to configure allowed auth types
        setSecureLockDeviceStrongAuthFlags();

        mPowerManager.goToSleep(SystemClock.uptimeMillis(),
                PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
@@ -415,6 +462,11 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
        int userId = user.getIdentifier();
        mSecureLockDeviceSettingsManager.enableSecurityFeatures(userId);
        mStore.storeSecureLockDeviceEnabled(userId);

        synchronized (mBiometricAuthStateLock) {
            mUserAuthenticatedWithStrongBiometric = null;
        }

        notifyAllSecureLockDeviceListenersEnabledStatusUpdated();
        Slog.d(TAG, "Secure lock device is enabled");

@@ -428,6 +480,9 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
     * @param user   {@link UserHandle} of caller requesting to disable secure lock device
     * @param params {@link DisableSecureLockDeviceParams} for caller to supply params related
     *               to the secure lock device request
     * @param authenticationComplete indicates if secure lock device is being disabled as a result
     *                               of successful two-factor primary and strong biometric
     *                               authentication
     * @return {@link DisableSecureLockDeviceRequestStatus} int indicating the result of the
     * secure lock device request
     * @hide
@@ -435,10 +490,9 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
     */
    @Override
    @DisableSecureLockDeviceRequestStatus
    public int disableSecureLockDevice(UserHandle user, DisableSecureLockDeviceParams params) {
        if (!secureLockdown()) {
            return ERROR_UNSUPPORTED;
        } else if (!isSecureLockDeviceEnabled()) {
    public int disableSecureLockDevice(UserHandle user, DisableSecureLockDeviceParams params,
            boolean authenticationComplete) {
        if (!isSecureLockDeviceEnabled()) {
            if (DEBUG) {
                Slog.d(TAG, "Secure lock device is already disabled.");
            }
@@ -457,17 +511,52 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
            return ERROR_NOT_AUTHORIZED;
        }

        // (1) Call into system_server to reset allowed auth types
        // TODO (b/398058587): Reset strong auth flags for user
        // Clears strong auth flags
        mLockSettingsInternal.disableSecureLockDevice(secureLockDeviceClientId,
                authenticationComplete);
        disableSecurityFeatures(secureLockDeviceClientId);

        mStore.storeSecureLockDeviceDisabled();
        notifyAllSecureLockDeviceListenersEnabledStatusUpdated();
        Slog.d(TAG, "Secure lock device is disabled");

        synchronized (mBiometricAuthStateLock) {
            mUserAuthenticatedWithStrongBiometric = null;
        }
        return SUCCESS;
    }

    /**
     * Updates status on whether the user has completed successful two-factor primary authentication
     * strong biometric authentication, and confirmed the biometric auth when necessary.
     *
     * @param user that performed the successful biometric authentication
     *
     * @hide
     */
    @Override
    public void onStrongBiometricAuthenticationSuccess(UserHandle user) {
        Slog.d(TAG, "Received strong biometric authentication success for user " + user + ", "
                + "awaiting device entry completion to disable secure lock device.");
        synchronized (mBiometricAuthStateLock) {
            mUserAuthenticatedWithStrongBiometric = user;
        }
    }

    /**
     * Returns true if the user has completed successful two-factor primary authentication + strong
     * biometric authentication, false otherwise.
     * @param user to check for two-factor authentication completion
     * @hide
     */
    @Override
    public boolean hasUserCompletedTwoFactorAuthentication(UserHandle user) {
        synchronized (mBiometricAuthStateLock) {
            return mUserAuthenticatedWithStrongBiometric != null
                    && mUserAuthenticatedWithStrongBiometric.equals(user);
        }
    }

    /**
     * @return true if secure lock device is enabled, false otherwise
     * @see AuthenticationPolicyManager#isSecureLockDeviceEnabled()
@@ -649,4 +738,29 @@ public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
            }
        }
    }

    @VisibleForTesting
    protected class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
        StrongAuthTracker(Context context) {
            super(context);
        }

        private boolean containsFlag(int haystack, int needle) {
            return (haystack & needle) != 0;
        }

        @Override
        public synchronized void onStrongAuthRequiredChanged(int userId) {
            if (secureLockDevice() && isSecureLockDeviceEnabled()
                    && containsFlag(getStrongAuthForUser(userId),
                    PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE)
            ) {
                Slog.d(TAG, "Primary auth is required for secure lock device; reset pending "
                        + "biometric auth success state.");
                synchronized (mBiometricAuthStateLock) {
                    mUserAuthenticatedWithStrongBiometric = null;
                }
            }
        }
    }
}
 No newline at end of file
+20 −4
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ public abstract class SecureLockDeviceServiceInternal {

    /**
     * @see AuthenticationPolicyManager#getSecureLockDeviceAvailability()
     * @param user calling {@link UserHandle} to check that secure lock device is available for
     * @param user {@link UserHandle} to check that secure lock device is available for
     * @return {@link GetSecureLockDeviceAvailabilityRequestStatus} int indicating whether secure
     * lock device is available for the calling user
     *
@@ -49,7 +49,7 @@ public abstract class SecureLockDeviceServiceInternal {

    /**
     * @see AuthenticationPolicyManager#enableSecureLockDevice(EnableSecureLockDeviceParams)
     * @param user {@link UserHandle} of caller requesting to enable secure lock device
     * @param user {@link UserHandle} secure lock device is being disabled for
     * @param params {@link EnableSecureLockDeviceParams} for caller to supply params related
     *               to the secure lock request
     * @return {@link EnableSecureLockDeviceRequestStatus} int indicating the result of the
@@ -61,15 +61,31 @@ public abstract class SecureLockDeviceServiceInternal {

    /**
     * @see AuthenticationPolicyManager#disableSecureLockDevice(DisableSecureLockDeviceParams)
     * @param user {@link UserHandle} of caller requesting to disable secure lock device
     * @param user {@link UserHandle} secure lock device is being disabled for
     * @param params {@link DisableSecureLockDeviceParams} for caller to supply params related
     *               to the secure lock device request
     * @param authenticationComplete indicates if secure lock device is being disabled as a result
     *                               of successful two-factor primary and biometric authentication
     * @return {@link DisableSecureLockDeviceRequestStatus} int indicating the result of the
     * secure lock device request
     */
    @DisableSecureLockDeviceRequestStatus
    public abstract int disableSecureLockDevice(UserHandle user,
            DisableSecureLockDeviceParams params);
            DisableSecureLockDeviceParams params, boolean authenticationComplete);

    /**
     * @see SecureLockDeviceService#onStrongBiometricAuthenticationSuccess
     * @param user that performed the successful biometric authentication
     * @hide
     */
    public abstract void onStrongBiometricAuthenticationSuccess(UserHandle user);

    /**
     * @see SecureLockDeviceService#hasUserCompletedTwoFactorAuthentication
     * @param user to check for two-factor authentication completion
     * @hide
     */
    public abstract boolean hasUserCompletedTwoFactorAuthentication(UserHandle user);

    /**
     * @see AuthenticationPolicyManager#isSecureLockDeviceEnabled()
+78 −17

File changed.

Preview size limit exceeded, changes collapsed.

+76 −10

File changed.

Preview size limit exceeded, changes collapsed.