Fix 2332563: Update logic for lockscreen in Settings.
diff --git a/res/layout-land/choose_lock_password.xml b/res/layout-land/choose_lock_password.xml
index eba936a..f2a2f46 100644
--- a/res/layout-land/choose_lock_password.xml
+++ b/res/layout-land/choose_lock_password.xml
@@ -53,6 +53,8 @@
android:gravity="center"
android:layout_gravity="center"
android:textSize="24sp"
+ android:layout_marginTop="5dip"
+ android:layout_marginBottom="5dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:background="@drawable/password_field_default"
android:textColor="#ffffffff"
@@ -77,14 +79,15 @@
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:background="@android:drawable/bottom_bar">
+ android:background="@android:drawable/bottom_bar"
+ android:visibility="gone">
<Button android:id="@+id/cancel_button"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_alignParentLeft="true"
- android:text="@string/password_cancel_button_label"
+ android:text="@string/lockpassword_cancel_label"
/>
<Button android:id="@+id/next_button"
@@ -94,7 +97,7 @@
android:layout_alignParentRight="true"
android:drawableRight="@drawable/ic_btn_next"
android:drawablePadding="10dip"
- android:text="@string/password_ok_button_label"
+ android:text="@string/lockpassword_continue_label"
/>
</RelativeLayout>
diff --git a/res/layout/choose_lock_password.xml b/res/layout/choose_lock_password.xml
index ffef021..3ab1374 100644
--- a/res/layout/choose_lock_password.xml
+++ b/res/layout/choose_lock_password.xml
@@ -84,7 +84,7 @@
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_alignParentLeft="true"
- android:text="@string/password_cancel_button_label"
+ android:text="@string/lockpassword_cancel_label"
/>
<Button android:id="@+id/next_button"
@@ -94,7 +94,7 @@
android:layout_alignParentRight="true"
android:drawableRight="@drawable/ic_btn_next"
android:drawablePadding="10dip"
- android:text="@string/password_ok_button_label"
+ android:text="@string/lockpassword_continue_label"
/>
</RelativeLayout>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 4ac663b..ae0fba8 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -98,22 +98,6 @@
<item>1800000</item>
</string-array>
- <!-- Unlock method in SecuritySettings --><skip/>
- <string-array name="unlock_method_entries">
- <item>Password</item>
- <item>PIN</item>
- <item>Pattern</item>
- <item>None</item>
- </string-array>
-
- <!-- Do not translate. -->
- <string-array name="unlock_method_values" translatable="false">
- <item>password</item>
- <item>pin</item>
- <item>pattern</item>
- <item>none</item>
- </string-array>
-
<!-- TTS settings -->
<!-- Default speech rate choices -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4c960ec..18bac1a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -516,28 +516,81 @@
<string name="cdma_security_settings_summary">Set My Location, screen unlock, credential storage lock</string>
<!-- In the security screen, the header title for settings related to Passwords-->
<string name="security_passwords_title">Passwords</string>
- <!-- Name shown for changing the unlock method -->
- <string name="unlock_method_title">Unlock Method</string>
- <!-- Summary shown for changing the unlock method -->
- <string name="unlock_method_summary">Change the method used to unlock your phone</string>
- <!-- Error shown in popup when PIN is too short -->
- <string name="pin_password_too_short">Password must be at least %d digits</string>
+
+
+ <!-- Unlock settings --><skip />
+
+ <!-- Title for preference that will guide the user through creating an unlock pattern -->
+ <string name="unlock_set_unlock_pattern_title">Set unlock pattern</string>
+ <!-- Summary for preference that guides the user through creating an unlock pattern -->
+ <string name="unlock_set_unlock_pattern_summary">Must draw pattern to unlock screen</string>
+
+ <!-- Title for preference that guides the user through creating an unlock PIN (Personal Identification Number) -->
+ <string name="unlock_set_unlock_pin_title">Set unlock PIN</string>
+ <!-- Summary for preference that guides the user through creating an unlock PIN (Personal Identification Number) -->
+ <string name="unlock_set_unlock_pin_summary">Must use a numeric PIN to unlock screen</string>
+
+ <!-- Title for preference that guides the user through creating an unlock password -->
+ <string name="unlock_set_unlock_password_title">Set unlock password</string>
+ <!-- Title for preference that guides the user through creating an unlock password -->
+ <string name="unlock_set_unlock_password_summary">Must use a password to unlock screen</string>
+
+ <!-- Title for option to turn of password/pin/pattern unlock. -->
+ <string name="unlock_disable_lock_title">Turn off screen lock</string>
+
+ <!-- Summary shown under unlock_disable_lock_title when pattern is in use and can be removed -->
+ <string name="unlock_disable_lock_pattern_summary">Remove unlock pattern</string>
+ <!-- Summary shown under unlock_disable_lock_title when PIN is in use and can be removed -->
+ <string name="unlock_disable_lock_pin_summary">Remove unlock PIN</string>
+ <!-- Summary shown under unlock_disable_lock_title when password is in use and can be removed -->
+ <string name="unlock_disable_lock_password_summary">Remove unlock password</string>
+
+ <!-- Title shown on security settings to allow the user to change their lockscreen pattern -->
+ <string name="unlock_change_lock_pattern_title">Change unlock pattern</string>
+ <!-- Title shown on security settings to allow the user to change their lockscreen PIN -->
+ <string name="unlock_change_lock_pin_title">Change unlock PIN</string>
+ <!-- Title shown on security settings to allow the user to change their lockscreen password -->
+ <string name="unlock_change_lock_password_title">Change unlock password</string>
+
+ <!-- Hint shown in dialog screen when password is too short -->
+ <string name="lockpassword_password_too_short">Password must be at least %d characters</string>
+ <!-- Hint shown in dialog screen when PIN is too short -->
+ <string name="lockpassword_pin_too_short">PIN must be at least %d characters</string>
+
+ <!-- Hint shown after minimum password criteria is met -->
+ <string name="lockpassword_press_continue">Press Continue when done</string>
+
+ <!-- Hint shown after minimum password criteria is met -->
+ <string name="lockpassword_continue_label">Continue</string>
+
+ <!-- Error shown in popup when password is too long -->
+ <string name="lockpassword_password_too_long">PIN can be no longer than %d digits</string>
<!-- Error shown in popup when PIN is too long -->
- <string name="pin_password_too_long">Password can be no longer than %d digits</string>
+ <string name="lockpassword_pin_too_long">PIN can be no longer than %d digits</string>
+
<!-- Error shown when in PIN mode and user enters a non-digit -->
- <string name="pin_password_illegal_character">PIN must contain only digits 0-9</string>
+ <string name="lockpassword_pin_contains_non_digits">PIN must contain only digits 0-9</string>
+
<!-- Error shown when in PASSWORD mode and user enters an invalid character -->
- <string name="pin_password_contains_non_digits">Password contains an illegal character</string>
+ <string name="lockpassword_illegal_character">Password contains an illegal character</string>
+
+ <!-- Error shown when in PASSWORD mode and password is all digits -->
+ <string name="lockpassword_password_requires_alpha">Alpha password must contain at least one letter</string>
+
+ <!-- Label for ChoosePassword/PIN OK button -->
+ <string name="lockpassword_ok_label">OK</string>
+
+ <!-- Label for ChoosePassword/PIN OK button -->
+ <string name="lockpassword_cancel_label">Cancel</string>
+
<!-- In the security screen, the header title for settings related to device admins -->
<string name="device_admin_title">Device administration</string>
+
<!-- Title of preference to manage device admins -->
<string name="manage_device_admin">Select device administrators</string>
+
<!-- Summary of preference to manage device policies -->
<string name="manage_device_admin_summary">Add or remove device administrators</string>
- <!-- Label for ChoosePassword/PIN OK button -->
- <string name="password_ok_button_label">OK</string>
- <!-- Label for ChoosePassword/PIN OK button -->
- <string name="password_cancel_button_label">Cancel</string>
<!-- Bluetooth settings -->
<!-- Bluetooth settings check box title on Main Settings screen -->
@@ -1350,16 +1403,26 @@
<!-- Lock Pattern settings -->
<!-- Header on first screen of choose password/PIN flow -->
<string name="lockpassword_choose_your_password_header">Choose your password</string>
+ <!-- Header on first screen of choose password/PIN flow -->
+ <string name="lockpassword_choose_your_pin_header">Choose your PIN</string>
<!-- Header on password confirm screen -->
- <string name="lockpassword_confirm_your_password_header">Confirm password</string>
+ <string name="lockpassword_confirm_your_password_header">Confirm your password</string>
+ <!-- Header on password confirm screen -->
+ <string name="lockpassword_confirm_your_pin_header">Confirm your PIN</string>
<!-- Header on password confirm screen if second password doesn't match the first. -->
<string name="lockpassword_confirm_passwords_dont_match">Passwords don\'t match</string>
- <!-- Header shown if passwords match -->
- <string name="lockpassword_password_confirmed_header">Password confirmed</string>
+ <!-- Header on pin confirm screen if second pin doesn't match the first. -->
+ <string name="lockpassword_confirm_pins_dont_match">PINs don\'t match</string>
+ <!-- Toast shown if setting password was successful -->
+ <string name="lockpassword_password_set_toast">Password has been set</string>
+ <!-- Toast shown if setting PIN was successful -->
+ <string name="lockpassword_pin_set_toast">PIN has been set</string>
+ <!-- Toast shown if setting pattern was successful -->
+ <string name="lockpassword_pattern_set_toast">Pattern has been set</string>
<!-- Lock Pattern settings -->
<!-- Security & location settings screen, header -->
- <string name="lock_settings_title">Screen unlock pattern</string>
+ <string name="lock_settings_title">Screen unlock</string>
<!-- Security & location settings screen, setting option name -->
<string name="lockpattern_change_lock_pattern_label">Change unlock pattern</string>
<!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern". We first ask the user toe nter the current pattern, and this is the message seen -->
diff --git a/res/xml/security_settings.xml b/res/xml/security_settings.xml
index d1f896a..29244f7 100644
--- a/res/xml/security_settings.xml
+++ b/res/xml/security_settings.xml
@@ -43,26 +43,4 @@
</PreferenceCategory>
- <PreferenceCategory
- android:key="security_category"
- android:title="@string/lock_settings_title">
-
- <ListPreference
- android:key="unlock_method"
- android:title="@string/unlock_method_title"
- android:summary="@string/unlock_method_summary"
- android:persistent="false"
- android:entries="@array/unlock_method_entries"
- android:entryValues="@array/unlock_method_values"/>
-
- <CheckBoxPreference
- android:key="visiblepattern"
- android:title="@string/lockpattern_settings_enable_visible_pattern_title"/>
-
- <CheckBoxPreference
- android:key="tactilefeedback"
- android:title="@string/lockpattern_settings_enable_tactile_feedback_title"/>
-
- </PreferenceCategory>
-
</PreferenceScreen>
diff --git a/res/xml/security_settings_chooser.xml b/res/xml/security_settings_chooser.xml
new file mode 100644
index 0000000..4f5797f4
--- /dev/null
+++ b/res/xml/security_settings_chooser.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:key="security_category"
+ android:title="@string/lock_settings_title">
+
+ <PreferenceScreen
+ android:key="unlock_set_pattern"
+ android:title="@string/unlock_set_unlock_pattern_title"
+ android:summary="@string/unlock_set_unlock_pattern_summary"
+ android:persistent="false"/>
+
+ <PreferenceScreen
+ android:key="unlock_set_pin"
+ android:title="@string/unlock_set_unlock_pin_title"
+ android:summary="@string/unlock_set_unlock_pin_summary"
+ android:persistent="false"/>
+
+ <PreferenceScreen
+ android:key="unlock_set_password"
+ android:title="@string/unlock_set_unlock_password_title"
+ android:summary="@string/unlock_set_unlock_password_summary"
+ android:persistent="false"/>
+
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/security_settings_password.xml b/res/xml/security_settings_password.xml
new file mode 100644
index 0000000..9addee4
--- /dev/null
+++ b/res/xml/security_settings_password.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:key="security_category"
+ android:title="@string/lock_settings_title">
+
+ <PreferenceScreen
+ android:key="unlock_method_disable"
+ android:title="@string/unlock_disable_lock_title"
+ android:summary="@string/unlock_disable_lock_password_summary"
+ android:persistent="false"/>
+
+ <PreferenceScreen
+ android:key="unlock_method_change_current"
+ android:title="@string/unlock_change_lock_password_title"
+ android:persistent="false"/>
+
+ <CheckBoxPreference
+ android:key="unlock_tactile_feedback"
+ android:title="@string/lockpattern_settings_enable_tactile_feedback_title"/>
+
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/security_settings_pattern.xml b/res/xml/security_settings_pattern.xml
new file mode 100644
index 0000000..467fbd7
--- /dev/null
+++ b/res/xml/security_settings_pattern.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:key="security_category"
+ android:title="@string/lock_settings_title">
+
+ <PreferenceScreen
+ android:key="unlock_method_disable"
+ android:title="@string/unlock_disable_lock_title"
+ android:summary="@string/unlock_disable_lock_pattern_summary"
+ android:persistent="false"/>
+
+ <PreferenceScreen
+ android:key="unlock_method_change_current"
+ android:title="@string/unlock_change_lock_pattern_title"
+ android:persistent="false"/>
+
+ <CheckBoxPreference
+ android:key="visiblepattern"
+ android:title="@string/lockpattern_settings_enable_visible_pattern_title"/>
+
+ <CheckBoxPreference
+ android:key="unlock_tactile_feedback"
+ android:title="@string/lockpattern_settings_enable_tactile_feedback_title"/>
+
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/security_settings_pin.xml b/res/xml/security_settings_pin.xml
new file mode 100644
index 0000000..fb77714
--- /dev/null
+++ b/res/xml/security_settings_pin.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:key="security_category"
+ android:title="@string/lock_settings_title">
+
+ <PreferenceScreen
+ android:key="unlock_method_disable"
+ android:title="@string/unlock_disable_lock_title"
+ android:summary="@string/unlock_disable_lock_pin_summary"
+ android:persistent="false"/>
+
+ <PreferenceScreen
+ android:key="unlock_method_change_current"
+ android:title="@string/unlock_change_lock_pin_title"
+ android:persistent="false"/>
+
+ <CheckBoxPreference
+ android:key="unlock_tactile_feedback"
+ android:title="@string/lockpattern_settings_enable_tactile_feedback_title"/>
+
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java
index ed4150a..3e3d848 100644
--- a/src/com/android/settings/ChooseLockPassword.java
+++ b/src/com/android/settings/ChooseLockPassword.java
@@ -34,15 +34,24 @@
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
+import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
-public class ChooseLockPassword extends Activity implements OnClickListener {
+public class ChooseLockPassword extends Activity implements OnClickListener, OnEditorActionListener,
+ TextWatcher {
+ private static final String KEY_FIRST_PIN = "first_pin";
+ private static final String KEY_UI_STAGE = "ui_stage";
private TextView mPasswordEntry;
private int mPasswordMinLength = 4;
private int mPasswordMaxLength = 8;
@@ -54,6 +63,9 @@
private String mFirstPin;
private KeyboardView mKeyboardView;
private PasswordEntryKeyboardHelper mKeyboardHelper;
+ private boolean mIsAlphaMode;
+ private Button mCancelButton;
+ private Button mNextButton;
public static final String PASSWORD_MIN_KEY = "lockscreen.password_min";
public static final String PASSWORD_MAX_KEY = "lockscreen.password_max";
private static Handler mHandler = new Handler();
@@ -66,19 +78,30 @@
*/
protected enum Stage {
- Introduction(R.string.lockpassword_choose_your_password_header),
- NeedToConfirm(R.string.lockpassword_confirm_your_password_header),
- ConfirmWrong(R.string.lockpassword_confirm_passwords_dont_match),
- ChoiceConfirmed(R.string.lockpassword_password_confirmed_header);
+ Introduction(R.string.lockpassword_choose_your_password_header,
+ R.string.lockpassword_choose_your_pin_header,
+ R.string.lockpassword_continue_label),
+
+ NeedToConfirm(R.string.lockpassword_confirm_your_password_header,
+ R.string.lockpassword_confirm_your_pin_header,
+ R.string.lockpassword_ok_label),
+
+ ConfirmWrong(R.string.lockpassword_confirm_passwords_dont_match,
+ R.string.lockpassword_confirm_pins_dont_match,
+ R.string.lockpassword_continue_label);
/**
* @param headerMessage The message displayed at the top.
*/
- Stage(int headerMessage) {
- this.headerMessage = headerMessage;
+ Stage(int hintInAlpha, int hintInNumeric, int nextButtonText) {
+ this.alphaHint = hintInAlpha;
+ this.numericHint = hintInNumeric;
+ this.buttonText = nextButtonText;
}
- final int headerMessage;
+ public final int alphaHint;
+ public final int numericHint;
+ public final int buttonText;
}
@Override
@@ -110,15 +133,20 @@
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- findViewById(R.id.cancel_button).setOnClickListener(this);
- findViewById(R.id.next_button).setOnClickListener(this);
+ mCancelButton = (Button) findViewById(R.id.cancel_button);
+ mCancelButton.setOnClickListener(this);
+ mNextButton = (Button) findViewById(R.id.next_button);
+ mNextButton.setOnClickListener(this);
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
mPasswordEntry = (TextView) findViewById(R.id.password_entry);
+ mPasswordEntry.setOnEditorActionListener(this);
+ mPasswordEntry.addTextChangedListener(this);
- final boolean isAlpha = LockPatternUtils.MODE_PASSWORD == mRequestedMode;
+ mIsAlphaMode = LockPatternUtils.MODE_PASSWORD == mRequestedMode;
mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
- mKeyboardHelper.setKeyboardMode(isAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
+ mKeyboardHelper.setKeyboardMode(mIsAlphaMode ?
+ PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
: PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mHeaderText = (TextView) findViewById(R.id.headerText);
@@ -126,17 +154,28 @@
}
@Override
- protected void onPause() {
- super.onPause();
+ protected void onResume() {
+ super.onResume();
+ updateStage(mUiStage);
mKeyboardView.requestFocus();
}
@Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- updateStage(mUiStage);
- mKeyboardView.requestFocus();
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString(KEY_UI_STAGE, mUiStage.name());
+ outState.putString(KEY_FIRST_PIN, mFirstPin);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ String state = savedInstanceState.getString(KEY_UI_STAGE);
+ mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN);
+ if (state != null) {
+ mUiStage = Stage.valueOf(state);
+ updateStage(mUiStage);
+ }
}
@Override
@@ -154,9 +193,8 @@
}
protected void updateStage(Stage stage) {
- mHeaderText.setText(stage.headerMessage);
- mPasswordEntry.setText("");
mUiStage = stage;
+ updateUi();
}
/**
@@ -166,60 +204,76 @@
*/
private String validatePassword(String pin) {
if (pin.length() < mPasswordMinLength) {
- return getString(R.string.pin_password_too_short, mPasswordMinLength);
+ return getString(mIsAlphaMode ?
+ R.string.lockpassword_password_too_short
+ : R.string.lockpassword_pin_too_short, mPasswordMinLength);
}
if (pin.length() > mPasswordMaxLength) {
- return getString(R.string.pin_password_too_long, mPasswordMaxLength);
+ return getString(mIsAlphaMode ?
+ R.string.lockpassword_password_too_long
+ : R.string.lockpassword_pin_too_long, mPasswordMaxLength);
}
- if (LockPatternUtils.MODE_PIN == mRequestedMode) {
- Pattern p = Pattern.compile("[0-9]+");
- Matcher m = p.matcher(pin);
- if (!m.find()) {
- return getString(R.string.pin_password_contains_non_digits);
+ boolean hasAlpha = false;
+ boolean hasDigit = false;
+ boolean hasSymbol = false;
+ for (int i = 0; i < pin.length(); i++) {
+ char c = pin.charAt(i);
+ // allow non white space Latin-1 characters only
+ if (c <= 32 || c > 127) {
+ return getString(R.string.lockpassword_illegal_character);
}
- } else if (LockPatternUtils.MODE_PASSWORD == mRequestedMode) {
- // allow Latin-1 characters only
- for (int i = 0; i < pin.length(); i++) {
- char c = pin.charAt(i);
- if (c <= 32 || c > 127) {
- return getString(R.string.pin_password_illegal_character);
+ if (c >= '0' && c <= '9') {
+ hasDigit = true;
+ } else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+ hasAlpha = true;
+ } else {
+ hasSymbol = true;
+ }
+ }
+ if (LockPatternUtils.MODE_PIN == mRequestedMode && (hasAlpha | hasSymbol)) {
+ return getString(R.string.lockpassword_pin_contains_non_digits);
+ } else if (LockPatternUtils.MODE_PASSWORD == mRequestedMode && !hasAlpha) {
+ // require at least 1 alpha character
+ return getString(R.string.lockpassword_password_requires_alpha);
+ }
+ return null;
+ }
+
+ private void handleNext() {
+ final String pin = mPasswordEntry.getText().toString();
+ if (TextUtils.isEmpty(pin)) {
+ return;
+ }
+ String errorMsg = null;
+ if (mUiStage == Stage.Introduction) {
+ errorMsg = validatePassword(pin);
+ if (errorMsg == null) {
+ mFirstPin = pin;
+ updateStage(Stage.NeedToConfirm);
+ mPasswordEntry.setText("");
+ }
+ } else if (mUiStage == Stage.NeedToConfirm) {
+ if (mFirstPin.equals(pin)) {
+ mLockPatternUtils.clearLock();
+ mLockPatternUtils.saveLockPassword(pin, mRequestedMode);
+ finish();
+ } else {
+ updateStage(Stage.ConfirmWrong);
+ CharSequence tmp = mPasswordEntry.getText();
+ if (tmp != null) {
+ Selection.setSelection((Spannable) tmp, 0, tmp.length());
}
}
}
- return null;
+ if (errorMsg != null) {
+ showError(errorMsg, mUiStage);
+ }
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.next_button:
- {
- final String pin = mPasswordEntry.getText().toString();
- if (TextUtils.isEmpty(pin)) {
- break;
- }
- String errorMsg = null;
- if (mUiStage == Stage.Introduction) {
- errorMsg = validatePassword(pin);
- if (errorMsg == null) {
- mFirstPin = pin;
- updateStage(Stage.NeedToConfirm);
- }
- } else if (mUiStage == Stage.NeedToConfirm) {
- if (mFirstPin.equals(pin)) {
- // TODO: move these to LockPatternUtils
- mLockPatternUtils.setLockPatternEnabled(false);
- mLockPatternUtils.saveLockPattern(null);
- mLockPatternUtils.saveLockPassword(pin, mRequestedMode);
- finish();
- } else {
- int msg = R.string.lockpassword_confirm_passwords_dont_match;
- errorMsg = getString(msg);
- }
- }
- if (errorMsg != null) {
- showError(errorMsg, Stage.Introduction);
- }
- }
+ handleNext();
break;
case R.id.cancel_button:
@@ -230,11 +284,57 @@
private void showError(String msg, final Stage next) {
mHeaderText.setText(msg);
- mPasswordEntry.setText("");
mHandler.postDelayed(new Runnable() {
public void run() {
updateStage(next);
}
}, ERROR_MESSAGE_TIMEOUT);
}
+
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ // Check if this was the result of hitting the enter key
+ if (actionId == EditorInfo.IME_NULL) {
+ handleNext();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Update the hint based on current Stage and length of password entry
+ */
+ private void updateUi() {
+ final int length = mPasswordEntry.getText().toString().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 {
+ mHeaderText.setText(R.string.lockpassword_press_continue);
+ mNextButton.setEnabled(true);
+ }
+ } else {
+ mHeaderText.setText(mIsAlphaMode ? mUiStage.alphaHint : mUiStage.numericHint);
+ mNextButton.setEnabled(length > 0);
+ }
+ mNextButton.setText(mUiStage.buttonText);
+ }
+
+ public void afterTextChanged(Editable s) {
+ // Changing the text while error displayed resets to NeedToConfirm state
+ if (mUiStage == Stage.ConfirmWrong) {
+ mUiStage = Stage.NeedToConfirm;
+ }
+ updateUi();
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
}
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index 78d6ff1..eedbc28 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -24,13 +24,17 @@
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
+import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
+import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
-public class ConfirmLockPassword extends Activity implements OnClickListener {
+public class ConfirmLockPassword extends Activity implements OnClickListener,
+ OnEditorActionListener {
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
private TextView mPasswordEntry;
private LockPatternUtils mLockPatternUtils;
@@ -56,11 +60,13 @@
findViewById(R.id.cancel_button).setOnClickListener(this);
findViewById(R.id.next_button).setOnClickListener(this);
mPasswordEntry = (TextView) findViewById(R.id.password_entry);
+ mPasswordEntry.setOnEditorActionListener(this);
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
mHeaderText = (TextView) findViewById(R.id.headerText);
- mHeaderText.setText(R.string.lockpassword_confirm_your_password_header);
final boolean isAlpha =
LockPatternUtils.MODE_PASSWORD == mLockPatternUtils.getPasswordMode();
+ mHeaderText.setText(isAlpha ? R.string.lockpassword_confirm_your_password_header
+ : R.string.lockpassword_confirm_your_pin_header);
mKeyboardHelper = new PasswordEntryKeyboardHelper(this, mKeyboardView, mPasswordEntry);
mKeyboardHelper.setKeyboardMode(isAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
: PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
@@ -80,18 +86,20 @@
mKeyboardView.requestFocus();
}
+ private void handleNext() {
+ final String pin = mPasswordEntry.getText().toString();
+ if (mLockPatternUtils.checkPassword(pin)) {
+ setResult(RESULT_OK);
+ finish();
+ } else {
+ showError(R.string.lockpattern_need_to_unlock_wrong);
+ }
+ }
+
public void onClick(View v) {
switch (v.getId()) {
case R.id.next_button:
- {
- final String pin = mPasswordEntry.getText().toString();
- if (mLockPatternUtils.checkPassword(pin)) {
- setResult(RESULT_OK);
- finish();
- } else {
- showError(R.string.lockpattern_need_to_unlock_wrong);
- }
- }
+ handleNext();
break;
case R.id.cancel_button:
@@ -110,4 +118,13 @@
}
}, ERROR_MESSAGE_TIMEOUT);
}
+
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ // Check if this was the result of hitting the enter key
+ if (actionId == EditorInfo.IME_NULL) {
+ handleNext();
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index f646d9d..fb2f6c9 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -57,6 +57,11 @@
*/
public class SecuritySettings extends PreferenceActivity {
+ private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
+ private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
+ private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
+ private static final String KEY_UNLOCK_METHOD_CHANGE_CURRENT = "unlock_method_change_current";
+ private static final String KEY_UNLOCK_METHOD_DISABLE = "unlock_method_disable";
// Lock Settings
private static final String PACKAGE = "com.android.settings";
private static final String LOCK_PATTERN_TUTORIAL = PACKAGE + ".ChooseLockPatternTutorial";
@@ -101,13 +106,15 @@
private CheckBoxPreference mAssistedGps;
DevicePolicyManager mDPM;
-
+
// These provide support for receiving notification when Location Manager settings change.
// This is necessary because the Network Location Provider can change settings
// if the user does not confirm enabling the provider.
private ContentQueryMap mContentQueryMap;
- private ListPreference mUnlockMethod;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
+ private LockPatternUtils mLockPatternUtils;
+ private PreferenceScreen mDisableUnlock;
+ private PreferenceScreen mChangeCurrent;
private final class SettingsObserver implements Observer {
public void update(Observable o, Object arg) {
updateToggles();
@@ -117,18 +124,15 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.security_settings);
+
+ mLockPatternUtils = new LockPatternUtils(this);
mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
-
+
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
createPreferenceHierarchy();
- mNetwork = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_NETWORK);
- mGps = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_GPS);
- mAssistedGps = (CheckBoxPreference) getPreferenceScreen().findPreference(ASSISTED_GPS);
-
updateToggles();
// listen for Location Manager settings changes
@@ -141,26 +145,46 @@
}
private PreferenceScreen createPreferenceHierarchy() {
- // Root
PreferenceScreen root = this.getPreferenceScreen();
+ if (root != null) {
+ root.removeAll();
+ }
+ addPreferencesFromResource(R.xml.security_settings);
+ root = this.getPreferenceScreen();
+
+ mNetwork = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_NETWORK);
+ mGps = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_GPS);
+ mAssistedGps = (CheckBoxPreference) getPreferenceScreen().findPreference(ASSISTED_GPS);
PreferenceManager pm = getPreferenceManager();
- mUnlockMethod = (ListPreference) pm.findPreference(KEY_UNLOCK_METHOD);
- mUnlockMethod.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- String value = (String) newValue;
- handleUpdateUnlockMethod(value);
- return false;
+ // Lock screen
+ if (!mLockPatternUtils.isSecure()) {
+ addPreferencesFromResource(R.xml.security_settings_chooser);
+ } else {
+ final int currentMode = mLockPatternUtils.getPasswordMode();
+ if (currentMode == LockPatternUtils.MODE_PATTERN) {
+ addPreferencesFromResource(R.xml.security_settings_pattern);
+ } else if (currentMode == LockPatternUtils.MODE_PIN) {
+ addPreferencesFromResource(R.xml.security_settings_pin);
+ } else if (currentMode == LockPatternUtils.MODE_PASSWORD) {
+ addPreferencesFromResource(R.xml.security_settings_password);
}
- });
+ }
+
+ // disable current pattern. Should be common to all unlock preference screens.
+ mDisableUnlock = (PreferenceScreen) pm.findPreference(KEY_UNLOCK_METHOD_DISABLE);
+
+ // change current. Should be common to all unlock preference screens
+ mChangeCurrent = (PreferenceScreen) pm.findPreference(KEY_UNLOCK_METHOD_CHANGE_CURRENT);
// visible pattern
mVisiblePattern = (CheckBoxPreference) pm.findPreference(KEY_VISIBLE_PATTERN);
- // tactile feedback
+ // tactile feedback. Should be common to all unlock preference screens.
mTactileFeedback = (CheckBoxPreference) pm.findPreference(KEY_TACTILE_FEEDBACK_ENABLED);
+
int activePhoneType = TelephonyManager.getDefault().getPhoneType();
// do not display SIM lock for CDMA phone
@@ -217,7 +241,21 @@
return root;
}
- protected void handleUpdateUnlockMethod(final String value) {
+ 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) {
+ value = "pattern";
+ } else if (LockPatternUtils.MODE_PASSWORD == mode) {
+ value = "password";
+ } else if (LockPatternUtils.MODE_PIN == mode) {
+ value = "pin";
+ } else {
+ throw new IllegalStateException("Unknown password mode: " + value);
+ }
+ }
+
if ("none".equals(value)) {
if (mDPM.getPasswordQuality(null) == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST);
@@ -248,11 +286,14 @@
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
boolean patternExists = lockPatternUtils.savedPatternExists();
- mVisiblePattern.setEnabled(patternExists);
- mTactileFeedback.setEnabled(patternExists);
-
- mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled());
- mTactileFeedback.setChecked(lockPatternUtils.isTactileFeedbackEnabled());
+ if (mVisiblePattern != null) {
+ mVisiblePattern.setEnabled(patternExists);
+ mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled());
+ }
+ if (mTactileFeedback != null) {
+ mTactileFeedback.setEnabled(patternExists);
+ mTactileFeedback.setChecked(lockPatternUtils.isTactileFeedbackEnabled());
+ }
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
@@ -266,7 +307,17 @@
final String key = preference.getKey();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
- if (KEY_LOCK_ENABLED.equals(key)) {
+ if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
+ handleUpdateUnlockMethod("pattern");
+ } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
+ handleUpdateUnlockMethod("pin");
+ } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
+ handleUpdateUnlockMethod("password");
+ } else if (KEY_UNLOCK_METHOD_DISABLE.equals(key)) {
+ handleUpdateUnlockMethod("none");
+ } else if (KEY_UNLOCK_METHOD_CHANGE_CURRENT.equals(key)) {
+ handleUpdateUnlockMethod(null);
+ } else if (KEY_LOCK_ENABLED.equals(key)) {
lockPatternUtils.setLockPatternEnabled(isToggled(preference));
} else if (KEY_VISIBLE_PATTERN.equals(key)) {
lockPatternUtils.setVisiblePatternEnabled(isToggled(preference));
@@ -327,6 +378,7 @@
if ((requestCode == CONFIRM_EXISTING_REQUEST) && resultOk) {
lockPatternUtils.clearLock();
}
+ createPreferenceHierarchy();
}
private class CredentialStorage implements DialogInterface.OnClickListener,