Change I546ee2fb: Fix 2677197: Adding minimum complex character support.
Change-Id: I5590ec2743b84e34098871507dbcc2f49e5a4e9f
This commit is contained in:
@@ -620,6 +620,36 @@
|
|||||||
<!-- Error shown when in PASSWORD mode and password doesn't contain any symbols -->
|
<!-- Error shown when in PASSWORD mode and password doesn't contain any symbols -->
|
||||||
<string name="lockpassword_password_requires_symbol">Password must contain at least one symbol</string>
|
<string name="lockpassword_password_requires_symbol">Password must contain at least one symbol</string>
|
||||||
|
|
||||||
|
<!-- Error shown when in PASSWORD mode and password doesn't contain the required number of letters -->
|
||||||
|
<plurals name="lockpassword_password_requires_letters">
|
||||||
|
<item quantity="one">Password must contain at least 1 letter</item>
|
||||||
|
<item quantity="other">Password must contain at least %d letters</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Error shown when in PASSWORD mode and password doesn't contain the required number of lowercase letters -->
|
||||||
|
<plurals name="lockpassword_password_requires_lowercase">
|
||||||
|
<item quantity="one">Password must contain at least 1 lowercase letter</item>
|
||||||
|
<item quantity="other">Password must contain at least %d lowercase letters</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Error shown when in PASSWORD mode and password doesn't contain the required number of uppercase letters -->
|
||||||
|
<plurals name="lockpassword_password_requires_uppercase">
|
||||||
|
<item quantity="one">Password must contain at least 1 uppercase letter</item>
|
||||||
|
<item quantity="other">Password must contain at least %d uppercase letters</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Error shown when in PASSWORD mode and password doesn't contain the required number of numerical digits -->
|
||||||
|
<plurals name="lockpassword_password_requires_numeric">
|
||||||
|
<item quantity="one">Password must contain at least 1 numerical digit</item>
|
||||||
|
<item quantity="other">Password must contain at least %d numerical digits</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Error shown when in PASSWORD mode and password doesn't contain the required number of special symbols -->
|
||||||
|
<plurals name="lockpassword_password_requires_symbols">
|
||||||
|
<item quantity="one">Password must contain at least 1 special symbol</item>
|
||||||
|
<item quantity="other">Password must contain at least %d special symbols</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
<!-- Error shown when in PASSWORD mode and password has been used recently. Please keep this string short! -->
|
<!-- Error shown when in PASSWORD mode and password has been used recently. Please keep this string short! -->
|
||||||
<string name="lockpassword_password_recently_used">Device administrator disallows using a recent password</string>
|
<string name="lockpassword_password_recently_used">Device administrator disallows using a recent password</string>
|
||||||
|
|
||||||
|
@@ -138,7 +138,7 @@ public class ChooseLockGeneric extends PreferenceActivity {
|
|||||||
} else if (KEY_UNLOCK_SET_PIN.equals(key)) {
|
} else if (KEY_UNLOCK_SET_PIN.equals(key)) {
|
||||||
enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
||||||
} else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
|
} else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
|
||||||
enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
|
enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
|
||||||
}
|
}
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
|
pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
|
||||||
|
@@ -48,6 +48,11 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
|
|||||||
private TextView mPasswordEntry;
|
private TextView mPasswordEntry;
|
||||||
private int mPasswordMinLength = 4;
|
private int mPasswordMinLength = 4;
|
||||||
private int mPasswordMaxLength = 16;
|
private int mPasswordMaxLength = 16;
|
||||||
|
private int mPasswordMinLetters = 0;
|
||||||
|
private int mPasswordMinUpperCase = 0;
|
||||||
|
private int mPasswordMinLowerCase = 0;
|
||||||
|
private int mPasswordMinSymbols = 0;
|
||||||
|
private int mPasswordMinNumeric = 0;
|
||||||
private LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
||||||
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
||||||
@@ -61,6 +66,11 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
|
|||||||
private Button mNextButton;
|
private Button mNextButton;
|
||||||
public static final String PASSWORD_MIN_KEY = "lockscreen.password_min";
|
public static final String PASSWORD_MIN_KEY = "lockscreen.password_min";
|
||||||
public static final String PASSWORD_MAX_KEY = "lockscreen.password_max";
|
public static final String PASSWORD_MAX_KEY = "lockscreen.password_max";
|
||||||
|
public static final String PASSWORD_MIN_LETTERS_KEY = "lockscreen.password_min_letters";
|
||||||
|
public static final String PASSWORD_MIN_LOWERCASE_KEY = "lockscreen.password_min_lowercase";
|
||||||
|
public static final String PASSWORD_MIN_UPPERCASE_KEY = "lockscreen.password_min_uppercase";
|
||||||
|
public static final String PASSWORD_MIN_NUMERIC_KEY = "lockscreen.password_min_numeric";
|
||||||
|
public static final String PASSWORD_MIN_SYMBOLS_KEY = "lockscreen.password_min_symbols";
|
||||||
private static Handler mHandler = new Handler();
|
private static Handler mHandler = new Handler();
|
||||||
private static final int CONFIRM_EXISTING_REQUEST = 58;
|
private static final int CONFIRM_EXISTING_REQUEST = 58;
|
||||||
static final int RESULT_FINISHED = RESULT_FIRST_USER;
|
static final int RESULT_FINISHED = RESULT_FIRST_USER;
|
||||||
@@ -101,19 +111,25 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
mLockPatternUtils = new LockPatternUtils(this);
|
mLockPatternUtils = new LockPatternUtils(this);
|
||||||
mRequestedQuality = getIntent().getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, mRequestedQuality);
|
mRequestedQuality = Math.max(getIntent().getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
|
||||||
mPasswordMinLength = getIntent().getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength);
|
mRequestedQuality), mLockPatternUtils.getRequestedPasswordQuality());
|
||||||
|
mPasswordMinLength = Math.max(
|
||||||
|
getIntent().getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength), mLockPatternUtils
|
||||||
|
.getRequestedMinimumPasswordLength());
|
||||||
mPasswordMaxLength = getIntent().getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength);
|
mPasswordMaxLength = getIntent().getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength);
|
||||||
|
mPasswordMinLetters = Math.max(getIntent().getIntExtra(PASSWORD_MIN_LETTERS_KEY,
|
||||||
|
mPasswordMinLetters), mLockPatternUtils.getRequestedPasswordMinimumLetters());
|
||||||
|
mPasswordMinUpperCase = Math.max(getIntent().getIntExtra(PASSWORD_MIN_UPPERCASE_KEY,
|
||||||
|
mPasswordMinUpperCase), mLockPatternUtils.getRequestedPasswordMinimumUpperCase());
|
||||||
|
mPasswordMinLowerCase = Math.max(getIntent().getIntExtra(PASSWORD_MIN_LOWERCASE_KEY,
|
||||||
|
mPasswordMinLowerCase), mLockPatternUtils.getRequestedPasswordMinimumLowerCase());
|
||||||
|
mPasswordMinNumeric = Math.max(getIntent().getIntExtra(PASSWORD_MIN_NUMERIC_KEY,
|
||||||
|
mPasswordMinNumeric), mLockPatternUtils.getRequestedPasswordMinimumNumeric());
|
||||||
|
mPasswordMinSymbols = Math.max(getIntent().getIntExtra(PASSWORD_MIN_SYMBOLS_KEY,
|
||||||
|
mPasswordMinSymbols), mLockPatternUtils.getRequestedPasswordMinimumSymbols());
|
||||||
final boolean confirmCredentials = getIntent().getBooleanExtra("confirm_credentials", true);
|
final boolean confirmCredentials = getIntent().getBooleanExtra("confirm_credentials", true);
|
||||||
int minMode = mLockPatternUtils.getRequestedPasswordQuality();
|
|
||||||
if (mRequestedQuality < minMode) {
|
|
||||||
mRequestedQuality = minMode;
|
|
||||||
}
|
|
||||||
int minLength = mLockPatternUtils.getRequestedMinimumPasswordLength();
|
|
||||||
if (mPasswordMinLength < minLength) {
|
|
||||||
mPasswordMinLength = minLength;
|
|
||||||
}
|
|
||||||
initViews();
|
initViews();
|
||||||
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
|
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
@@ -142,7 +158,8 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
|
|||||||
mPasswordEntry.addTextChangedListener(this);
|
mPasswordEntry.addTextChangedListener(this);
|
||||||
|
|
||||||
mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mRequestedQuality
|
mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mRequestedQuality
|
||||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mRequestedQuality;
|
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mRequestedQuality
|
||||||
|
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mRequestedQuality;
|
||||||
mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
|
mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
|
||||||
mKeyboardHelper.setKeyboardMode(mIsAlphaMode ?
|
mKeyboardHelper.setKeyboardMode(mIsAlphaMode ?
|
||||||
PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
|
PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
|
||||||
@@ -212,9 +229,11 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
|
|||||||
R.string.lockpassword_password_too_long
|
R.string.lockpassword_password_too_long
|
||||||
: R.string.lockpassword_pin_too_long, mPasswordMaxLength);
|
: R.string.lockpassword_pin_too_long, mPasswordMaxLength);
|
||||||
}
|
}
|
||||||
boolean hasAlpha = false;
|
int letters = 0;
|
||||||
boolean hasDigit = false;
|
int numbers = 0;
|
||||||
boolean hasSymbol = false;
|
int lowercase = 0;
|
||||||
|
int symbols = 0;
|
||||||
|
int uppercase = 0;
|
||||||
for (int i = 0; i < password.length(); i++) {
|
for (int i = 0; i < password.length(); i++) {
|
||||||
char c = password.charAt(i);
|
char c = password.charAt(i);
|
||||||
// allow non white space Latin-1 characters only
|
// allow non white space Latin-1 characters only
|
||||||
@@ -222,32 +241,55 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE
|
|||||||
return getString(R.string.lockpassword_illegal_character);
|
return getString(R.string.lockpassword_illegal_character);
|
||||||
}
|
}
|
||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
hasDigit = true;
|
numbers++;
|
||||||
} else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
|
} else if (c >= 'A' && c <= 'Z') {
|
||||||
hasAlpha = true;
|
letters++;
|
||||||
|
uppercase++;
|
||||||
|
} else if (c >= 'a' && c <= 'z') {
|
||||||
|
letters++;
|
||||||
|
lowercase++;
|
||||||
} else {
|
} else {
|
||||||
hasSymbol = true;
|
symbols++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC == mRequestedQuality
|
if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC == mRequestedQuality
|
||||||
&& (hasAlpha | hasSymbol)) {
|
&& (letters > 0 || symbols > 0)) {
|
||||||
// This shouldn't be possible unless user finds some way to bring up soft keyboard
|
// This shouldn't be possible unless user finds some way to bring up
|
||||||
|
// soft keyboard
|
||||||
return getString(R.string.lockpassword_pin_contains_non_digits);
|
return getString(R.string.lockpassword_pin_contains_non_digits);
|
||||||
|
} else if (DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mRequestedQuality) {
|
||||||
|
if (letters < mPasswordMinLetters) {
|
||||||
|
return String.format(getResources().getQuantityString(
|
||||||
|
R.plurals.lockpassword_password_requires_letters, mPasswordMinLetters),
|
||||||
|
mPasswordMinLetters);
|
||||||
|
} else if (numbers < mPasswordMinNumeric) {
|
||||||
|
return String.format(getResources().getQuantityString(
|
||||||
|
R.plurals.lockpassword_password_requires_numeric, mPasswordMinNumeric),
|
||||||
|
mPasswordMinNumeric);
|
||||||
|
} else if (lowercase < mPasswordMinLowerCase) {
|
||||||
|
return String.format(getResources().getQuantityString(
|
||||||
|
R.plurals.lockpassword_password_requires_lowercase, mPasswordMinLowerCase),
|
||||||
|
mPasswordMinLowerCase);
|
||||||
|
} else if (uppercase < mPasswordMinUpperCase) {
|
||||||
|
return String.format(getResources().getQuantityString(
|
||||||
|
R.plurals.lockpassword_password_requires_uppercase, mPasswordMinUpperCase),
|
||||||
|
mPasswordMinUpperCase);
|
||||||
|
} else if (symbols < mPasswordMinSymbols) {
|
||||||
|
return String.format(getResources().getQuantityString(
|
||||||
|
R.plurals.lockpassword_password_requires_symbols, mPasswordMinSymbols),
|
||||||
|
mPasswordMinSymbols);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
final boolean alphabetic = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
|
final boolean alphabetic = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
|
||||||
== mRequestedQuality;
|
== mRequestedQuality;
|
||||||
final boolean alphanumeric = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
|
final boolean alphanumeric = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
|
||||||
== mRequestedQuality;
|
== mRequestedQuality;
|
||||||
final boolean symbolic = false; // not yet
|
if ((alphabetic || alphanumeric) && letters == 0) {
|
||||||
if ((alphabetic || alphanumeric) && !hasAlpha) {
|
|
||||||
return getString(R.string.lockpassword_password_requires_alpha);
|
return getString(R.string.lockpassword_password_requires_alpha);
|
||||||
}
|
}
|
||||||
if (alphanumeric && !hasDigit) {
|
if (alphanumeric && numbers == 0) {
|
||||||
return getString(R.string.lockpassword_password_requires_digit);
|
return getString(R.string.lockpassword_password_requires_digit);
|
||||||
}
|
}
|
||||||
if (symbolic && !hasSymbol) {
|
|
||||||
return getString(R.string.lockpassword_password_requires_symbol);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(mLockPatternUtils.checkPasswordHistory(password)) {
|
if(mLockPatternUtils.checkPasswordHistory(password)) {
|
||||||
return getString(mIsAlphaMode ? R.string.lockpassword_password_recently_used
|
return getString(mIsAlphaMode ? R.string.lockpassword_password_recently_used
|
||||||
|
@@ -52,6 +52,7 @@ public class ChooseLockSettingsHelper {
|
|||||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
||||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
||||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
||||||
|
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
|
||||||
// TODO: update UI layout for ConfirmPassword to show message and details
|
// TODO: update UI layout for ConfirmPassword to show message and details
|
||||||
launched = confirmPassword(request);
|
launched = confirmPassword(request);
|
||||||
break;
|
break;
|
||||||
|
@@ -65,7 +65,8 @@ public class ConfirmLockPassword extends Activity implements OnClickListener,
|
|||||||
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
|
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
|
||||||
mHeaderText = (TextView) findViewById(R.id.headerText);
|
mHeaderText = (TextView) findViewById(R.id.headerText);
|
||||||
final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality
|
final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality
|
||||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality;
|
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality
|
||||||
|
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == storedQuality;
|
||||||
mHeaderText.setText(isAlpha ? R.string.lockpassword_confirm_your_password_header
|
mHeaderText.setText(isAlpha ? R.string.lockpassword_confirm_your_password_header
|
||||||
: R.string.lockpassword_confirm_your_pin_header);
|
: R.string.lockpassword_confirm_your_pin_header);
|
||||||
mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
|
mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
|
||||||
|
@@ -155,6 +155,7 @@ public class SecuritySettings extends PreferenceActivity {
|
|||||||
break;
|
break;
|
||||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
||||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
||||||
|
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
|
||||||
addPreferencesFromResource(R.xml.security_settings_password);
|
addPreferencesFromResource(R.xml.security_settings_password);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user