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

Commit af366a3e authored by Jim Miller's avatar Jim Miller
Browse files

Fix 2535700: Add support for enforcing password quality

Change-Id: I908b4229d46061f3d450adec72b04276fe10afc1
parent a6a74e22
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ public class ChooseLockGeneric extends Activity {
        
        int quality = getIntent().getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
        if (quality == -1) {
            quality = lockPatternUtils.getPasswordMode();
            quality = lockPatternUtils.getKeyguardStoredPasswordQuality();
        }
        int minQuality = mDPM.getPasswordQuality(null);
        if (quality < minQuality) {
+45 −30
Original line number Diff line number Diff line
@@ -16,20 +16,13 @@

package com.android.settings;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.PasswordEntryKeyboardHelper;
import com.android.internal.widget.PasswordEntryKeyboardView;
import com.android.settings.ChooseLockPattern.LeftButtonMode;
import com.android.settings.ChooseLockPattern.RightButtonMode;
import com.android.settings.ChooseLockPattern.Stage;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.inputmethodservice.KeyboardView;
import android.os.Bundle;
import android.os.Handler;
@@ -56,7 +49,7 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
    private int mPasswordMinLength = 4;
    private int mPasswordMaxLength = 16;
    private LockPatternUtils mLockPatternUtils;
    private int mRequestedMode = LockPatternUtils.MODE_PIN;
    private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
    private ChooseLockSettingsHelper mChooseLockSettingsHelper;
    private com.android.settings.ChooseLockPassword.Stage mUiStage = Stage.Introduction;
    private TextView mHeaderText;
@@ -108,12 +101,12 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLockPatternUtils = new LockPatternUtils(this);
        mRequestedMode = getIntent().getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, mRequestedMode);
        mRequestedQuality = getIntent().getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, mRequestedQuality);
        mPasswordMinLength = getIntent().getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength);
        mPasswordMaxLength = getIntent().getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength);
        int minMode = mLockPatternUtils.getRequestedPasswordMode();
        if (mRequestedMode < minMode) {
            mRequestedMode = minMode;
        int minMode = mLockPatternUtils.getRequestedPasswordQuality();
        if (mRequestedQuality < minMode) {
            mRequestedQuality = minMode;
        }
        int minLength = mLockPatternUtils.getRequestedMinimumPasswordLength();
        if (mPasswordMinLength < minLength) {
@@ -143,7 +136,8 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
        mPasswordEntry.setOnEditorActionListener(this);
        mPasswordEntry.addTextChangedListener(this);

        mIsAlphaMode = LockPatternUtils.MODE_PASSWORD == mRequestedMode;
        mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mRequestedQuality
            || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mRequestedQuality;
        mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
        mKeyboardHelper.setKeyboardMode(mIsAlphaMode ?
                PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
@@ -199,16 +193,16 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE

    /**
     * Validates PIN and returns a message to display if PIN fails test.
     * @param pin
     * @return message id to display to user
     * @param password the raw password the user typed in
     * @return error message to show to user or null if password is OK
     */
    private String validatePassword(String pin) {
        if (pin.length() < mPasswordMinLength) {
    private String validatePassword(String password) {
        if (password.length() < mPasswordMinLength) {
            return getString(mIsAlphaMode ?
                    R.string.lockpassword_password_too_short
                    : R.string.lockpassword_pin_too_short, mPasswordMinLength);
        }
        if (pin.length() > mPasswordMaxLength) {
        if (password.length() > mPasswordMaxLength) {
            return getString(mIsAlphaMode ?
                    R.string.lockpassword_password_too_long
                    : R.string.lockpassword_pin_too_long, mPasswordMaxLength);
@@ -216,8 +210,8 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
        boolean hasAlpha = false;
        boolean hasDigit = false;
        boolean hasSymbol = false;
        for (int i = 0; i < pin.length(); i++) {
            char c = pin.charAt(i);
        for (int i = 0; i < password.length(); i++) {
            char c = password.charAt(i);
            // allow non white space Latin-1 characters only
            if (c <= 32 || c > 127) {
                return getString(R.string.lockpassword_illegal_character);
@@ -230,12 +224,26 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
                hasSymbol = true;
            }
        }
        if (LockPatternUtils.MODE_PIN == mRequestedMode && (hasAlpha | hasSymbol)) {
        if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC == mRequestedQuality
                && (hasAlpha | hasSymbol)) {
            // This shouldn't be possible unless user finds some way to bring up soft keyboard
            return getString(R.string.lockpassword_pin_contains_non_digits);
        } else if (LockPatternUtils.MODE_PASSWORD == mRequestedMode && !hasAlpha) {
            // require at least 1 alpha character
        } else {
            final boolean alphabetic = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
                    == mRequestedQuality;
            final boolean alphanumeric = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                    == mRequestedQuality;
            final boolean symbolic = false; // not yet
            if ((alphabetic || alphanumeric) && !hasAlpha) {
                return getString(R.string.lockpassword_password_requires_alpha);
            }
            if (alphanumeric && !hasDigit) {
                return getString(R.string.lockpassword_password_requires_digit);
            }
            if (symbolic && !hasSymbol) {
                return getString(R.string.lockpassword_password_requires_symbol);
            }
        }
        return null;
    }

@@ -255,7 +263,7 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
        } else if (mUiStage == Stage.NeedToConfirm) {
            if (mFirstPin.equals(pin)) {
                mLockPatternUtils.clearLock();
                mLockPatternUtils.saveLockPassword(pin, mRequestedMode);
                mLockPatternUtils.saveLockPassword(pin, mRequestedQuality);
                finish();
            } else {
                updateStage(Stage.ConfirmWrong);
@@ -304,17 +312,24 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
     * Update the hint based on current Stage and length of password entry
     */
    private void updateUi() {
        final int length = mPasswordEntry.getText().toString().length();
        String password = mPasswordEntry.getText().toString();
        final int length = password.length();
        if (mUiStage == Stage.Introduction && length > 0) {
            if (length < mPasswordMinLength) {
                String msg = getString(mIsAlphaMode ? R.string.lockpassword_password_too_short
                        : R.string.lockpassword_pin_too_short, mPasswordMinLength);
                mHeaderText.setText(msg);
                mNextButton.setEnabled(false);
            } else {
                String error = validatePassword(password);
                if (error != null) {
                    mHeaderText.setText(error);
                    mNextButton.setEnabled(false);
                } else {
                    mHeaderText.setText(R.string.lockpassword_press_continue);
                    mNextButton.setEnabled(true);
                }
            }
        } else {
            mHeaderText.setText(mIsAlphaMode ? mUiStage.alphaHint : mUiStage.numericHint);
            mNextButton.setEnabled(length > 0);
+5 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.settings;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;

import com.android.internal.widget.LockPatternUtils;
@@ -41,12 +42,12 @@ public class ChooseLockSettingsHelper {
     */
    protected boolean launchConfirmationActivity(int request) {
        boolean launched = false;
        switch (mLockPatternUtils.getPasswordMode()) {
            case LockPatternUtils.MODE_PATTERN:
        switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                launched = confirmPattern(request);
                break;
            case LockPatternUtils.MODE_PIN:
            case LockPatternUtils.MODE_PASSWORD:
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
                launched = confirmPassword(request);
                break;
        }
+4 −3
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.internal.widget.PasswordEntryKeyboardHelper;
import com.android.internal.widget.PasswordEntryKeyboardView;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
@@ -51,7 +52,7 @@ public class ConfirmLockPassword extends Activity implements OnClickListener,
    }

    private void initViews() {
        int mode = mLockPatternUtils.getPasswordMode();
        final int storedQuality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
        setContentView(R.layout.confirm_lock_password);
        // Disable IME on our window since we provide our own keyboard
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
@@ -63,8 +64,8 @@ public class ConfirmLockPassword extends Activity implements OnClickListener,
        mPasswordEntry.setOnEditorActionListener(this);
        mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
        mHeaderText = (TextView) findViewById(R.id.headerText);
        final boolean isAlpha =
                LockPatternUtils.MODE_PASSWORD == mLockPatternUtils.getPasswordMode();
        final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality
                || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality;
        mHeaderText.setText(isAlpha ? R.string.lockpassword_confirm_your_password_header
                : R.string.lockpassword_confirm_your_pin_header);
        mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
+19 −14
Original line number Diff line number Diff line
@@ -162,13 +162,17 @@ public class SecuritySettings extends PreferenceActivity {
        if (!mLockPatternUtils.isSecure()) {
            addPreferencesFromResource(R.xml.security_settings_chooser);
        } else {
            final int currentMode = mLockPatternUtils.getPasswordMode();
            if (currentMode == LockPatternUtils.MODE_PATTERN) {
            switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                    addPreferencesFromResource(R.xml.security_settings_pattern);
            } else if (currentMode == LockPatternUtils.MODE_PIN) {
                    break;
                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
                    addPreferencesFromResource(R.xml.security_settings_pin);
            } else if (currentMode == LockPatternUtils.MODE_PASSWORD) {
                    break;
                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
                    addPreferencesFromResource(R.xml.security_settings_password);
                    break;
            }
        }

@@ -243,12 +247,13 @@ public class SecuritySettings extends PreferenceActivity {
    protected void handleUpdateUnlockMethod(String value) {
        // NULL means update the current password/pattern/pin
        if (value == null) {
            int mode = mLockPatternUtils.getPasswordMode();
            if (LockPatternUtils.MODE_PATTERN == mode) {
            int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
            if (DevicePolicyManager.PASSWORD_QUALITY_SOMETHING == mode) {
                value = "pattern";
            } else if (LockPatternUtils.MODE_PASSWORD == mode) {
            } else if (DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mode
                    || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mode) {
                value = "password";
            } else if (LockPatternUtils.MODE_PIN == mode) {
            } else if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC == mode) {
                value = "pin";
            } else {
                throw new IllegalStateException("Unknown password mode: " + value);
@@ -262,11 +267,11 @@ public class SecuritySettings extends PreferenceActivity {
        } else {
            int reqMode;
            if ("password".equals(value)) {
                reqMode = LockPatternUtils.MODE_PASSWORD;
                reqMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
            } else if ( "pin".equals(value)) {
                reqMode = LockPatternUtils.MODE_PIN;
                reqMode = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
            } else {
                reqMode = LockPatternUtils.MODE_PATTERN;
                reqMode = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
            }
            int minMode = mDPM.getPasswordQuality(null);
            if (reqMode < minMode) {