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

Commit 9dd16ebc authored by Adrian Roos's avatar Adrian Roos
Browse files

LockPatternUtils clean up continued

- Deprecate Settings.Secure.LOCK_PATTERN_ENABLED
- Remove unused permanent lock out
- Disallow empty/null arguments to saveLockPattern and saveLockPassword
- Refactor repeated quality checks

Change-Id: I6f369eb60f8f6bb1e33384cd06534c713ab52e79
parent dce0122e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25599,7 +25599,7 @@ package android.provider {
    field public static final int LOCATION_MODE_OFF = 0; // 0x0
    field public static final int LOCATION_MODE_SENSORS_ONLY = 1; // 0x1
    field public static final deprecated java.lang.String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
    field public static final java.lang.String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
    field public static final deprecated java.lang.String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
    field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
    field public static final java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
    field public static final deprecated java.lang.String LOGGING_ID = "logging_id";
+4 −0
Original line number Diff line number Diff line
@@ -3669,7 +3669,11 @@ public final class Settings {

        /**
         * Whether autolock is enabled (0 = false, 1 = true)
         *
         * @deprecated Use {@link android.app.KeyguardManager} to determine the state and security
         *             level of the keyguard.
         */
        @Deprecated
        public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";

        /**
+165 −236
Original line number Diff line number Diff line
@@ -21,11 +21,9 @@ import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.AsyncTask;
@@ -42,13 +40,12 @@ import android.provider.Settings;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.IWindowManager;
import android.view.View;
import android.widget.Button;

import com.android.internal.R;
import com.google.android.collect.Lists;
import java.io.ByteArrayOutputStream;

import java.nio.charset.StandardCharsets;
import libcore.util.HexEncoding;

@@ -109,6 +106,7 @@ public class LockPatternUtils {
     */
    public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE;

    @Deprecated
    public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
    public final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
    public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
@@ -205,7 +203,11 @@ public class LockPatternUtils {
    }

    public int getRequestedPasswordHistoryLength() {
        return getDevicePolicyManager().getPasswordHistoryLength(null, getCurrentOrCallingUserId());
        return getRequestedPasswordHistoryLength(getCurrentOrCallingUserId());
    }

    private int getRequestedPasswordHistoryLength(int userId) {
        return getDevicePolicyManager().getPasswordHistoryLength(null, userId);
    }

    public int getRequestedPasswordMinimumLetters() {
@@ -354,15 +356,7 @@ public class LockPatternUtils {
     * Check to see if the user has stored a lock pattern.
     * @return Whether a saved pattern exists.
     */
    public boolean savedPatternExists() {
        return savedPatternExists(getCurrentOrCallingUserId());
    }

    /**
     * Check to see if the user has stored a lock pattern.
     * @return Whether a saved pattern exists.
     */
    public boolean savedPatternExists(int userId) {
    private boolean savedPatternExists(int userId) {
        try {
            return getLockSettings().havePattern(userId);
        } catch (RemoteException re) {
@@ -374,15 +368,7 @@ public class LockPatternUtils {
     * Check to see if the user has stored a lock pattern.
     * @return Whether a saved pattern exists.
     */
    public boolean savedPasswordExists() {
        return savedPasswordExists(getCurrentOrCallingUserId());
    }

     /**
     * Check to see if the user has stored a lock pattern.
     * @return Whether a saved pattern exists.
     */
    public boolean savedPasswordExists(int userId) {
    private boolean savedPasswordExists(int userId) {
        try {
            return getLockSettings().havePassword(userId);
        } catch (RemoteException re) {
@@ -413,29 +399,17 @@ public class LockPatternUtils {
     * information it has.
     */
    public int getActivePasswordQuality(int userId) {
        int quality = (int) getLong(PASSWORD_TYPE_KEY,
                DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
                userId);
        int quality = getKeyguardStoredPasswordQuality(userId);

        switch (quality) {
            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                if (isLockPatternEnabled(userId)) {
        if (isLockPasswordEnabled(quality, userId)) {
            // Quality is a password and a password exists. Return the quality.
            return quality;
        }
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
                // No biometric weak implementation; fall back to unspecified.
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
                if (isLockPasswordEnabled(userId)) {

        if (isLockPatternEnabled(quality, userId)) {
            // Quality is a pattern and a pattern exists. Return the quality.
            return quality;
        }
                break;
        }

        return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    }
@@ -448,10 +422,23 @@ public class LockPatternUtils {
     * Clear any lock pattern or password.
     */
    public void clearLock(int userHandle) {
        saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userHandle);
        setLockPatternEnabled(false, userHandle);
        saveLockPattern(null, userHandle);
        setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);

        try {
            getLockSettings().setLockPassword(null, userHandle);
            getLockSettings().setLockPattern(null, userHandle);
        } catch (RemoteException e) {
            // well, we tried...
        }

        if (userHandle == UserHandle.USER_OWNER) {
            // Set the encryption password to default.
            updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
        }

        getDevicePolicyManager().setActivePasswordState(
                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle);

        onAfterChangingPassword(userHandle);
    }

@@ -462,7 +449,7 @@ public class LockPatternUtils {
     * @param disable Disables lock screen when true
     */
    public void setLockScreenDisabled(boolean disable) {
        setLong(DISABLE_LOCKSCREEN_KEY, disable ? 1 : 0, getCurrentOrCallingUserId());
        setBoolean(DISABLE_LOCKSCREEN_KEY, disable, getCurrentOrCallingUserId());
    }

    /**
@@ -472,7 +459,7 @@ public class LockPatternUtils {
     * @return true if lock screen is can be disabled
     */
    public boolean isLockScreenDisabled() {
        if (!isSecure() && getLong(DISABLE_LOCKSCREEN_KEY, 0, getCurrentOrCallingUserId()) != 0) {
        if (!isSecure() && getBoolean(DISABLE_LOCKSCREEN_KEY, false, getCurrentOrCallingUserId())) {
            // Check if the number of switchable users forces the lockscreen.
            final List<UserInfo> users = UserManager.get(mContext).getUsers(true);
            final int userCount = users.size();
@@ -502,9 +489,13 @@ public class LockPatternUtils {
     */
    public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) {
        try {
            if (pattern == null) {
                throw new IllegalArgumentException("pattern must not be null");
            }

            getLockSettings().setLockPattern(patternToString(pattern), userId);
            DevicePolicyManager dpm = getDevicePolicyManager();
            if (pattern != null) {

            // Update the device encryption password.
            if (userId == UserHandle.USER_OWNER
                    && LockPatternUtils.isDeviceEncryptionEnabled()) {
@@ -522,23 +513,18 @@ public class LockPatternUtils {
            setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
            dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
                    pattern.size(), 0, 0, 0, 0, 0, 0, userId);
            } else {
                dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
                        0, 0, 0, 0, 0, userId);
            }
            onAfterChangingPassword(userId);
        } catch (RemoteException re) {
            Log.e(TAG, "Couldn't save lock pattern " + re);
        }
    }

    private void updateCryptoUserInfo() {
        int userId = getCurrentOrCallingUserId();
    private void updateCryptoUserInfo(int userId) {
        if (userId != UserHandle.USER_OWNER) {
            return;
        }

        final String ownerInfo = isOwnerInfoEnabled() ? getOwnerInfo(userId) : "";
        final String ownerInfo = isOwnerInfoEnabled(userId) ? getOwnerInfo(userId) : "";

        IBinder service = ServiceManager.getService("mount");
        if (service == null) {
@@ -557,12 +543,13 @@ public class LockPatternUtils {

    public void setOwnerInfo(String info, int userId) {
        setString(LOCK_SCREEN_OWNER_INFO, info, userId);
        updateCryptoUserInfo();
        updateCryptoUserInfo(userId);
    }

    public void setOwnerInfoEnabled(boolean enabled) {
        setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, getCurrentOrCallingUserId());
        updateCryptoUserInfo();
        int userId = getCurrentOrCallingUserId();
        setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
        updateCryptoUserInfo(userId);
    }

    public String getOwnerInfo(int userId) {
@@ -570,7 +557,11 @@ public class LockPatternUtils {
    }

    public boolean isOwnerInfoEnabled() {
        return getBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, false, getCurrentOrCallingUserId());
        return isOwnerInfoEnabled(getCurrentOrCallingUserId());
    }

    private boolean isOwnerInfoEnabled(int userId) {
        return getBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, false, userId);
    }

    /**
@@ -710,7 +701,10 @@ public class LockPatternUtils {
    public void saveLockPassword(String password, int quality, int userHandle) {
        try {
            DevicePolicyManager dpm = getDevicePolicyManager();
            if (!TextUtils.isEmpty(password)) {
            if (TextUtils.isEmpty(password)) {
                throw new IllegalArgumentException("password must not be null nor empty");
            }

            getLockSettings().setLockPassword(password, userHandle);
            int computedQuality = computePasswordQuality(password);

@@ -770,7 +764,7 @@ public class LockPatternUtils {
            if (passwordHistory == null) {
                passwordHistory = "";
            }
                int passwordHistoryLength = getRequestedPasswordHistoryLength();
            int passwordHistoryLength = getRequestedPasswordHistoryLength(userHandle);
            if (passwordHistoryLength == 0) {
                passwordHistory = "";
            } else {
@@ -783,18 +777,6 @@ public class LockPatternUtils {
                        .length()));
            }
            setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
            } else {
                // Empty password
                getLockSettings().setLockPassword(null, userHandle);
                if (userHandle == UserHandle.USER_OWNER) {
                    // Set the encryption password to default.
                    updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
                }

                dpm.setActivePasswordState(
                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0,
                        userHandle);
            }
            onAfterChangingPassword(userHandle);
        } catch (RemoteException re) {
            // Cant do much
@@ -854,9 +836,8 @@ public class LockPatternUtils {
     * @return stored password quality
     */
    public int getKeyguardStoredPasswordQuality(int userHandle) {
        int quality = (int) getLong(PASSWORD_TYPE_KEY,
        return (int) getLong(PASSWORD_TYPE_KEY,
                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);
        return quality;
    }

    /**
@@ -865,6 +846,10 @@ public class LockPatternUtils {
     * @return The pattern.
     */
    public static List<LockPatternView.Cell> stringToPattern(String string) {
        if (string == null) {
            return null;
        }

        List<LockPatternView.Cell> result = Lists.newArrayList();

        final byte[] bytes = string.getBytes();
@@ -967,23 +952,39 @@ public class LockPatternUtils {
    }

    /**
     * @return Whether the lock password is enabled
     * @return Whether the lock screen is secured.
     */
    public boolean isLockPasswordEnabled() {
        return isLockPasswordEnabled(getCurrentOrCallingUserId());
    public boolean isSecure() {
        return isSecure(getCurrentOrCallingUserId());
    }

    /**
     * @param userId the user for which to report the value
     * @return Whether the lock screen is secured.
     */
    public boolean isSecure(int userId) {
        int mode = getKeyguardStoredPasswordQuality(userId);
        return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId);
    }

    /**
     * @return Whether the lock password is enabled
     */
    public boolean isLockPasswordEnabled() {
        return isLockPasswordEnabled(getCurrentOrCallingUserId());
    }

    public boolean isLockPasswordEnabled(int userId) {
        long mode = getLong(PASSWORD_TYPE_KEY, 0, userId);
        return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId);
    }

    private boolean isLockPasswordEnabled(int mode, int userId) {
        final boolean passwordEnabled = mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
                || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
                || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
                || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
        return savedPasswordExists(userId) && passwordEnabled;
        return passwordEnabled && savedPasswordExists(userId);
    }

    /**
@@ -993,27 +994,13 @@ public class LockPatternUtils {
        return isLockPatternEnabled(getCurrentOrCallingUserId());
    }

    /**
     * @return Whether the lock pattern is enabled
     */
    public boolean isLockPatternEnabled(int userId) {
        return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false, userId)
                && getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
                        userId) == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
    }

    /**
     * Set whether the lock pattern is enabled.
     */
    public void setLockPatternEnabled(boolean enabled) {
        setLockPatternEnabled(enabled, getCurrentOrCallingUserId());
        return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId);
    }

    /**
     * Set whether the lock pattern is enabled.
     */
    public void setLockPatternEnabled(boolean enabled, int userHandle) {
        setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, enabled, userHandle);
    private boolean isLockPatternEnabled(int mode, int userId) {
        return mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
                && savedPatternExists(userId);
    }

    /**
@@ -1083,27 +1070,6 @@ public class LockPatternUtils {
        return deadline;
    }

    /**
     * @return Whether the user is permanently locked out until they verify their
     *   credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
     *   attempts.
     */
    public boolean isPermanentlyLocked() {
        return getBoolean(LOCKOUT_PERMANENT_KEY, false, getCurrentOrCallingUserId());
    }

    /**
     * Set the state of whether the device is permanently locked, meaning the user
     * must authenticate via other means.
     *
     * @param locked Whether the user is permanently locked out until they verify their
     *   credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
     *   attempts.
     */
    public void setPermanentlyLocked(boolean locked) {
        setBoolean(LOCKOUT_PERMANENT_KEY, locked, getCurrentOrCallingUserId());
    }

    public boolean isEmergencyCallCapable() {
        return mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_voice_capable);
@@ -1119,15 +1085,6 @@ public class LockPatternUtils {
                com.android.internal.R.bool.config_enable_emergency_call_while_sim_locked);
    }

    /**
     * @return A formatted string of the next alarm (for showing on the lock screen),
     *   or null if there is no next alarm.
     */
    public AlarmManager.AlarmClockInfo getNextAlarm() {
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        return alarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
    }

    private boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) {
        try {
            return getLockSettings().getBoolean(secureSettingKey, defaultValue, userId);
@@ -1179,24 +1136,6 @@ public class LockPatternUtils {
        }
    }

    public boolean isSecure() {
        return isSecure(getCurrentOrCallingUserId());
    }

    public boolean isSecure(int userId) {
        long mode = getKeyguardStoredPasswordQuality(userId);
        final boolean isPattern = mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
        final boolean isPassword = mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
                || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
                || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
                || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
        final boolean secure =
                isPattern && isLockPatternEnabled(userId) && savedPatternExists(userId)
                || isPassword && savedPasswordExists(userId);
        return secure;
    }

    /**
     * Sets the emergency button visibility based on isEmergencyCallCapable().
     *
@@ -1258,16 +1197,6 @@ public class LockPatternUtils {
                getCurrentOrCallingUserId());
    }

    public static boolean isSafeModeEnabled() {
        try {
            return IWindowManager.Stub.asInterface(
                    ServiceManager.getService("window")).isSafeModeEnabled();
        } catch (RemoteException e) {
            // Shouldn't happen!
        }
        return false;
    }

    public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents) {
        setEnabledTrustAgents(activeTrustAgents, getCurrentOrCallingUserId());
    }
+8 −4
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.provider.AlarmClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.AttributeSet;
@@ -42,7 +42,8 @@ public class KeyguardStatusView extends GridLayout {
    private static final boolean DEBUG = KeyguardConstants.DEBUG;
    private static final String TAG = "KeyguardStatusView";

    private LockPatternUtils mLockPatternUtils;
    private final LockPatternUtils mLockPatternUtils;
    private final AlarmManager mAlarmManager;

    private TextView mAlarmStatusView;
    private TextClock mDateView;
@@ -92,6 +93,8 @@ public class KeyguardStatusView extends GridLayout {

    public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        mLockPatternUtils = new LockPatternUtils(getContext());
    }

    private void setEnableMarquee(boolean enabled) {
@@ -109,7 +112,7 @@ public class KeyguardStatusView extends GridLayout {
        mDateView.setShowCurrentUserTime(true);
        mClockView.setShowCurrentUserTime(true);
        mOwnerInfo = (TextView) findViewById(R.id.owner_info);
        mLockPatternUtils = new LockPatternUtils(getContext());

        final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
        setEnableMarquee(screenOn);
        refresh();
@@ -140,7 +143,8 @@ public class KeyguardStatusView extends GridLayout {
    }

    private void refresh() {
        AlarmManager.AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm();
        AlarmManager.AlarmClockInfo nextAlarm =
                mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
        Patterns.update(mContext, nextAlarm != null);

        refreshTime();
+12 −4
Original line number Diff line number Diff line
@@ -263,7 +263,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
        checkReadPermission(key, userId);

        String value = mStorage.readKeyValue(key, null, userId);
        String value = getStringUnchecked(key, null, userId);
        return TextUtils.isEmpty(value) ?
                defaultValue : (value.equals("1") || value.equals("true"));
    }
@@ -272,7 +272,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
        checkReadPermission(key, userId);

        String value = mStorage.readKeyValue(key, null, userId);
        String value = getStringUnchecked(key, null, userId);
        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
    }

@@ -280,6 +280,14 @@ public class LockSettingsService extends ILockSettings.Stub {
    public String getString(String key, String defaultValue, int userId) throws RemoteException {
        checkReadPermission(key, userId);

        return getStringUnchecked(key, defaultValue, userId);
    }

    public String getStringUnchecked(String key, String defaultValue, int userId) {
        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
            return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
        }

        return mStorage.readKeyValue(key, defaultValue, userId);
    }

@@ -402,7 +410,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        }

        try {
            if (mLockPatternUtils.isLockPatternEnabled()) {
            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
                if (checkPattern(password, userId)) {
                    return true;
                }
@@ -411,7 +419,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        }

        try {
            if (mLockPatternUtils.isLockPasswordEnabled()) {
            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
                if (checkPassword(password, userId)) {
                    return true;
                }