Fix 2332563: Add password-lock support to lockscreen

This commit is contained in:
Jim Miller
2009-12-22 19:04:57 -08:00
parent 8edfd3a76b
commit 00d2476d8f
15 changed files with 1261 additions and 206 deletions

View File

@@ -0,0 +1,232 @@
/*
* 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.
*/
package com.android.settings;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.ChooseLockPattern.LeftButtonMode;
import com.android.settings.ChooseLockPattern.RightButtonMode;
import com.android.settings.ChooseLockPattern.Stage;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ChooseLockPassword extends Activity implements OnClickListener {
private final int digitIds[] = new int[] { R.id.zero, R.id.one, R.id.two, R.id.three,
R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine };
private TextView mPasswordTextView;
private int mPasswordMinLength = 4;
private int mPasswordMaxLength = 8;
private LockPatternUtils mLockPatternUtils;
private int mRequestedMode = LockPatternUtils.MODE_PIN;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private com.android.settings.ChooseLockPassword.Stage mUiStage = Stage.Introduction;
private TextView mHeaderText;
private String mFirstPin;
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();
private static final int CONFIRM_EXISTING_REQUEST = 58;
static final int RESULT_FINISHED = RESULT_FIRST_USER;
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
/**
* Keep track internally of where the user is in choosing a pattern.
*/
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);
/**
* @param headerMessage The message displayed at the top.
*/
Stage(int headerMessage) {
this.headerMessage = headerMessage;
}
final int headerMessage;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getContentResolver());
mRequestedMode = getIntent().getIntExtra("password_mode", mRequestedMode);
mPasswordMinLength = getIntent().getIntExtra("password_min_length", mPasswordMinLength);
mPasswordMaxLength = getIntent().getIntExtra("password_max_length", mPasswordMaxLength);
initViews();
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
if (savedInstanceState == null) {
updateStage(Stage.Introduction);
mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST);
}
}
private void initViews() {
if (LockPatternUtils.MODE_PIN == mRequestedMode
|| LockPatternUtils.MODE_PASSWORD == mRequestedMode) {
setContentView(R.layout.choose_lock_pin);
// TODO: alphanumeric layout
// setContentView(R.layout.choose_lock_password);
for (int i = 0; i < digitIds.length; i++) {
Button button = (Button) findViewById(digitIds[i]);
button.setOnClickListener(this);
button.setText(Integer.toString(i));
}
findViewById(R.id.ok).setOnClickListener(this);
findViewById(R.id.cancel).setOnClickListener(this);
}
findViewById(R.id.backspace).setOnClickListener(this);
mPasswordTextView = (TextView) findViewById(R.id.pinDisplay);
mHeaderText = (TextView) findViewById(R.id.headerText);
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CONFIRM_EXISTING_REQUEST:
if (resultCode != Activity.RESULT_OK) {
setResult(RESULT_FINISHED);
finish();
}
break;
}
}
protected void updateStage(Stage stage) {
mHeaderText.setText(stage.headerMessage);
mPasswordTextView.setText("");
mUiStage = stage;
}
/**
* Validates PIN and returns a message to display if PIN fails test.
* @param pin
* @return message id to display to user
*/
private String validatePassword(String pin) {
if (pin.length() < mPasswordMinLength) {
return getString(R.string.pin_password_too_short, mPasswordMinLength);
}
if (pin.length() > mPasswordMaxLength) {
return getString(R.string.pin_password_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);
}
} 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);
}
}
}
return null;
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.ok:
{
final String pin = mPasswordTextView.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);
finish();
} else {
int msg = R.string.lockpassword_confirm_passwords_dont_match;
errorMsg = getString(msg);
}
}
if (errorMsg != null) {
showError(errorMsg, Stage.Introduction);
}
}
break;
case R.id.backspace:
{
final Editable digits = mPasswordTextView.getEditableText();
final int len = digits.length();
if (len > 0) {
digits.delete(len-1, len);
}
}
break;
case R.id.cancel:
finish();
break;
default:
// Digits
for (int i = 0; i < digitIds.length; i++) {
if (v.getId() == digitIds[i]) {
mPasswordTextView.append(Integer.toString(i));
return;
}
}
break;
}
}
private void showError(String msg, final Stage next) {
mHeaderText.setText(msg);
mPasswordTextView.setText("");
mHandler.postDelayed(new Runnable() {
public void run() {
updateStage(next);
}
}, ERROR_MESSAGE_TIMEOUT);
}
}

View File

@@ -45,7 +45,6 @@ import java.util.List;
* - saves chosen password when confirmed
*/
public class ChooseLockPattern extends Activity implements View.OnClickListener{
/**
* Used by the choose lock pattern wizard to indicate the wizard is
* finished, and each activity in the wizard should finish.
@@ -56,7 +55,9 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
* result.
*/
static final int RESULT_FINISHED = RESULT_FIRST_USER;
public static final int CONFIRM_EXISTING_REQUEST = 55;
// how long after a confirmation message is shown before moving on
static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
@@ -65,29 +66,38 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
private static final int ID_EMPTY_MESSAGE = -1;
protected TextView mHeaderText;
protected LockPatternView mLockPatternView;
protected TextView mFooterText;
private TextView mFooterLeftButton;
private TextView mFooterRightButton;
protected List<LockPatternView.Cell> mChosenPattern = null;
protected LockPatternUtils mLockPatternUtils;
/**
* The patten used during the help screen to show how to draw a pattern.
*/
private final List<LockPatternView.Cell> mAnimatePattern =
Collections.unmodifiableList(
Lists.newArrayList(
LockPatternView.Cell.of(0, 0),
LockPatternView.Cell.of(0, 1),
LockPatternView.Cell.of(1, 1),
LockPatternView.Cell.of(2, 1)
));
Collections.unmodifiableList(Lists.newArrayList(
LockPatternView.Cell.of(0, 0),
LockPatternView.Cell.of(0, 1),
LockPatternView.Cell.of(1, 1),
LockPatternView.Cell.of(2, 1)
));
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CONFIRM_EXISTING_REQUEST:
if (resultCode != Activity.RESULT_OK) {
setResult(RESULT_FINISHED);
finish();
}
updateStage(Stage.Introduction);
break;
}
}
/**
* The pattern listener that responds according to a user choosing a new
@@ -125,7 +135,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
}
}
public void onPatternCellAdded(List<Cell> pattern) {
public void onPatternCellAdded(List<Cell> pattern) {
}
@@ -250,19 +260,19 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
}
};
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private static final String KEY_UI_STAGE = "uiStage";
private static final String KEY_PATTERN_CHOICE = "chosenPattern";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getContentResolver());
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setupViews();
// make it so unhandled touch events within the unlock screen go to the
// lock pattern view.
final LinearLayoutWithDefaultTouchRecepient topLayout
@@ -271,11 +281,12 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
topLayout.setDefaultTouchRecepient(mLockPatternView);
if (savedInstanceState == null) {
// first launch
updateStage(Stage.Introduction);
if (mLockPatternUtils.savedPatternExists()) {
confirmPattern();
}
// first launch. As a security measure, we're in NeedToConfirm mode until we know
// there isn't an existing password or the user confirms their password.
updateStage(Stage.NeedToConfirm);
if (!mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST)) {
updateStage(Stage.Introduction);
}
} else {
// restore from previous state
final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
@@ -285,19 +296,20 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
}
}
/**
* Keep all "find view" related stuff confined to this function since in
* case someone needs to subclass and customize.
*/
protected void setupViews() {
setContentView(R.layout.choose_lock_pattern);
mHeaderText = (TextView) findViewById(R.id.headerText);
mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
mLockPatternView.setTactileFeedbackEnabled(
mChooseLockSettingsHelper.utils().isTactileFeedbackEnabled());
mFooterText = (TextView) findViewById(R.id.footerText);
@@ -364,35 +376,6 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
return super.onKeyDown(keyCode, event);
}
/**
* Launch screen to confirm the existing lock pattern.
* @see #onActivityResult(int, int, android.content.Intent)
*/
protected void confirmPattern() {
final Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
startActivityForResult(intent, 55);
}
/**
* @see #confirmPattern
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != 55) {
return;
}
if (resultCode != Activity.RESULT_OK) {
setResult(RESULT_FINISHED);
finish();
}
updateStage(Stage.Introduction);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -414,7 +397,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
mUiStage = stage;
// header text, footer text, visibility and
// header text, footer text, visibility and
// enabled state all known from the stage
if (stage == Stage.ChoiceTooShort) {
mHeaderText.setText(
@@ -486,16 +469,17 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
}
private void saveChosenPatternAndFinish() {
final boolean lockVirgin = !mLockPatternUtils.isPatternEverChosen();
LockPatternUtils utils = mChooseLockSettingsHelper.utils();
final boolean lockVirgin = !utils.isPatternEverChosen();
mLockPatternUtils.saveLockPattern(mChosenPattern);
mLockPatternUtils.setLockPatternEnabled(true);
utils.saveLockPattern(mChosenPattern);
utils.setLockPatternEnabled(true);
if (lockVirgin) {
mLockPatternUtils.setVisiblePatternEnabled(true);
mLockPatternUtils.setTactileFeedbackEnabled(false);
utils.setVisiblePatternEnabled(true);
utils.setTactileFeedbackEnabled(false);
}
setResult(RESULT_FINISHED);
finish();
}

View File

@@ -0,0 +1,85 @@
/*
* 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.
*/
package com.android.settings;
import android.app.Activity;
import android.content.Intent;
import com.android.internal.widget.LockPatternUtils;
public class ChooseLockSettingsHelper {
private LockPatternUtils mLockPatternUtils;
private Activity mActivity;
public ChooseLockSettingsHelper(Activity activity) {
mActivity = activity;
mLockPatternUtils = new LockPatternUtils(activity.getContentResolver());
}
public LockPatternUtils utils() {
return mLockPatternUtils;
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
* @return true if one exists and we launched an activity to confirm it
* @see #onActivityResult(int, int, android.content.Intent)
*/
protected boolean launchConfirmationActivity(int request) {
boolean launched = false;
switch (mLockPatternUtils.getPasswordMode()) {
case LockPatternUtils.MODE_PATTERN:
launched = confirmPattern(request);
break;
case LockPatternUtils.MODE_PIN:
case LockPatternUtils.MODE_PASSWORD:
launched = confirmPassword(request);
break;
}
return launched;
}
/**
* Launch screen to confirm the existing lock pattern.
* @see #onActivityResult(int, int, android.content.Intent)
* @return true if we launched an activity to confirm pattern
*/
private boolean confirmPattern(int request) {
if (!mLockPatternUtils.isLockPatternEnabled() || !mLockPatternUtils.savedPatternExists()) {
return false;
}
final Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
mActivity.startActivityForResult(intent, request);
return true;
}
/**
* Launch screen to confirm the existing lock password.
* @see #onActivityResult(int, int, android.content.Intent)
* @return true if we launched an activity to confirm password
*/
private boolean confirmPassword(int request) {
if (!mLockPatternUtils.isLockPasswordEnabled()) return false;
final Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPassword");
mActivity.startActivityForResult(intent, request);
return true;
}
}

View File

@@ -0,0 +1,114 @@
/*
* 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.
*/
package com.android.settings;
import com.android.internal.widget.LockPatternUtils;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ConfirmLockPassword extends Activity implements OnClickListener {
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
private final int digitIds[] = new int[] { R.id.zero, R.id.one, R.id.two, R.id.three,
R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine };
private TextView mPasswordTextView;
private LockPatternUtils mLockPatternUtils;
private TextView mHeaderText;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getContentResolver());
initViews();
}
private void initViews() {
int mode = mLockPatternUtils.getPasswordMode();
if (LockPatternUtils.MODE_PIN == mode || LockPatternUtils.MODE_PASSWORD == mode) {
setContentView(R.layout.confirm_lock_pin);
for (int i = 0; i < digitIds.length; i++) {
Button button = (Button) findViewById(digitIds[i]);
button.setOnClickListener(this);
button.setText(Integer.toString(i));
}
findViewById(R.id.ok).setOnClickListener(this);
findViewById(R.id.cancel).setOnClickListener(this);
}
findViewById(R.id.backspace).setOnClickListener(this);
mPasswordTextView = (TextView) findViewById(R.id.pinDisplay);
mHeaderText = (TextView) findViewById(R.id.headerText);
mHeaderText.setText(R.string.lockpassword_confirm_your_password_header);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.ok:
{
final String pin = mPasswordTextView.getText().toString();
if (mLockPatternUtils.checkPassword(pin)) {
setResult(RESULT_OK);
finish();
} else {
showError(R.string.lockpattern_need_to_unlock_wrong);
}
}
break;
case R.id.backspace:
{
final Editable digits = mPasswordTextView.getEditableText();
final int len = digits.length();
if (len > 0) {
digits.delete(len-1, len);
}
}
break;
case R.id.cancel:
setResult(RESULT_CANCELED);
finish();
break;
default:
// Digits
for (int i = 0; i < digitIds.length; i++) {
if (v.getId() == digitIds[i]) {
mPasswordTextView.append(Integer.toString(i));
return;
}
}
break;
}
}
private void showError(int msg) {
mHeaderText.setText(msg);
mPasswordTextView.setText(null);
mHandler.postDelayed(new Runnable() {
public void run() {
mHeaderText.setText(R.string.lockpassword_confirm_your_password_header);
}
}, ERROR_MESSAGE_TIMEOUT);
}
}

View File

@@ -25,7 +25,6 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
@@ -35,10 +34,13 @@ import android.os.ICheckinService;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings;
import android.security.Credentials;
import android.security.KeyStore;
@@ -56,11 +58,18 @@ import com.android.internal.widget.LockPatternUtils;
public class SecuritySettings extends PreferenceActivity {
// Lock Settings
private static final String PACKAGE = "com.android.settings";
private static final String LOCK_PATTERN_TUTORIAL = PACKAGE + ".ChooseLockPatternTutorial";
private static final String ICC_LOCK_SETTINGS = PACKAGE + ".IccLockSettings";
private static final String CHOOSE_LOCK_PATTERN = PACKAGE + ".ChooseLockPattern";
private static final String CHOOSE_LOCK_PIN = PACKAGE + ".ChooseLockPassword";
private static final String KEY_LOCK_ENABLED = "lockenabled";
private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
private static final String KEY_TACTILE_FEEDBACK_ENABLED = "tactilefeedback";
private static final int CONFIRM_PATTERN_THEN_DISABLE_AND_CLEAR_REQUEST_CODE = 55;
private static final String KEY_UNLOCK_METHOD = "unlock_method";
private static final int UPDATE_PASSWORD_REQUEST = 56;
private static final int CONFIRM_EXISTING_REQUEST = 57;
// Encrypted File Systems constants
private static final String PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
@@ -69,11 +78,8 @@ public class SecuritySettings extends PreferenceActivity {
private static final String PREFS_NAME = "location_prefs";
private static final String PREFS_USE_LOCATION = "use_location";
private LockPatternUtils mLockPatternUtils;
private CheckBoxPreference mLockEnabled;
private CheckBoxPreference mVisiblePattern;
private CheckBoxPreference mTactileFeedback;
private Preference mChoosePattern;
private CheckBoxPreference mShowPassword;
@@ -97,6 +103,8 @@ public class SecuritySettings extends PreferenceActivity {
// 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 final class SettingsObserver implements Observer {
public void update(Observable o, Object arg) {
updateToggles();
@@ -108,7 +116,7 @@ public class SecuritySettings extends PreferenceActivity {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.security_settings);
mLockPatternUtils = new LockPatternUtils(getContentResolver());
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
createPreferenceHierarchy();
@@ -131,37 +139,22 @@ public class SecuritySettings extends PreferenceActivity {
// Root
PreferenceScreen root = this.getPreferenceScreen();
// Inline preferences
PreferenceCategory inlinePrefCat = new PreferenceCategory(this);
inlinePrefCat.setTitle(R.string.lock_settings_title);
root.addPreference(inlinePrefCat);
PreferenceManager pm = getPreferenceManager();
// change pattern lock
Intent intent = new Intent();
intent.setClassName("com.android.settings",
"com.android.settings.ChooseLockPatternTutorial");
mChoosePattern = getPreferenceManager().createPreferenceScreen(this);
mChoosePattern.setIntent(intent);
inlinePrefCat.addPreference(mChoosePattern);
// autolock toggle
mLockEnabled = new LockEnabledPref(this);
mLockEnabled.setTitle(R.string.lockpattern_settings_enable_title);
mLockEnabled.setSummary(R.string.lockpattern_settings_enable_summary);
mLockEnabled.setKey(KEY_LOCK_ENABLED);
inlinePrefCat.addPreference(mLockEnabled);
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;
}
});
// visible pattern
mVisiblePattern = new CheckBoxPreference(this);
mVisiblePattern.setKey(KEY_VISIBLE_PATTERN);
mVisiblePattern.setTitle(R.string.lockpattern_settings_enable_visible_pattern_title);
inlinePrefCat.addPreference(mVisiblePattern);
mVisiblePattern = (CheckBoxPreference) pm.findPreference(KEY_VISIBLE_PATTERN);
// tactile feedback
mTactileFeedback = new CheckBoxPreference(this);
mTactileFeedback.setKey(KEY_TACTILE_FEEDBACK_ENABLED);
mTactileFeedback.setTitle(R.string.lockpattern_settings_enable_tactile_feedback_title);
inlinePrefCat.addPreference(mTactileFeedback);
mTactileFeedback = (CheckBoxPreference) pm.findPreference(KEY_TACTILE_FEEDBACK_ENABLED);
int activePhoneType = TelephonyManager.getDefault().getPhoneType();
@@ -172,10 +165,7 @@ public class SecuritySettings extends PreferenceActivity {
.createPreferenceScreen(this);
simLockPreferences.setTitle(R.string.sim_lock_settings_category);
// Intent to launch SIM lock settings
intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.IccLockSettings");
simLockPreferences.setIntent(intent);
simLockPreferences.setIntent(new Intent().setClassName(PACKAGE, ICC_LOCK_SETTINGS));
PreferenceCategory simLockCat = new PreferenceCategory(this);
simLockCat.setTitle(R.string.sim_lock_settings_title);
root.addPreference(simLockCat);
@@ -209,23 +199,41 @@ public class SecuritySettings extends PreferenceActivity {
return root;
}
protected void handleUpdateUnlockMethod(final String value) {
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if ("none".equals(value)) {
mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST);
} else if ("password".equals(value) || "pin".equals(value)) {
final int minLength = 4; // TODO: get from policy store.
final int maxLength = 16;
final int mode = "password".equals(value)
? LockPatternUtils.MODE_PASSWORD : LockPatternUtils.MODE_PIN;
Intent intent = new Intent().setClassName(PACKAGE, CHOOSE_LOCK_PIN);
intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, mode);
intent.putExtra(ChooseLockPassword.PASSWORD_MIN_KEY, minLength);
intent.putExtra(ChooseLockPassword.PASSWORD_MAX_KEY, maxLength);
startActivityForResult(intent, UPDATE_PASSWORD_REQUEST);
} else if ("pattern".equals(value)) {
boolean showTutorial = !lockPatternUtils.isPatternEverChosen();
Intent intent = new Intent();
intent.setClassName(PACKAGE, showTutorial ?
LOCK_PATTERN_TUTORIAL : CHOOSE_LOCK_PATTERN);
intent.putExtra("key_lock_method", value);
startActivityForResult(intent, UPDATE_PASSWORD_REQUEST);
}
}
@Override
protected void onResume() {
super.onResume();
boolean patternExists = mLockPatternUtils.savedPatternExists();
mLockEnabled.setEnabled(patternExists);
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
boolean patternExists = lockPatternUtils.savedPatternExists();
mVisiblePattern.setEnabled(patternExists);
mTactileFeedback.setEnabled(patternExists);
mLockEnabled.setChecked(mLockPatternUtils.isLockPatternEnabled());
mVisiblePattern.setChecked(mLockPatternUtils.isVisiblePatternEnabled());
mTactileFeedback.setChecked(mLockPatternUtils.isTactileFeedbackEnabled());
int chooseStringRes = mLockPatternUtils.savedPatternExists() ?
R.string.lockpattern_settings_change_lock_pattern :
R.string.lockpattern_settings_choose_lock_pattern;
mChoosePattern.setTitle(chooseStringRes);
mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled());
mTactileFeedback.setChecked(lockPatternUtils.isTactileFeedbackEnabled());
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
@@ -238,12 +246,13 @@ public class SecuritySettings extends PreferenceActivity {
Preference preference) {
final String key = preference.getKey();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (KEY_LOCK_ENABLED.equals(key)) {
mLockPatternUtils.setLockPatternEnabled(isToggled(preference));
lockPatternUtils.setLockPatternEnabled(isToggled(preference));
} else if (KEY_VISIBLE_PATTERN.equals(key)) {
mLockPatternUtils.setVisiblePatternEnabled(isToggled(preference));
lockPatternUtils.setVisiblePatternEnabled(isToggled(preference));
} else if (KEY_TACTILE_FEEDBACK_ENABLED.equals(key)) {
mLockPatternUtils.setTactileFeedbackEnabled(isToggled(preference));
lockPatternUtils.setTactileFeedbackEnabled(isToggled(preference));
} else if (preference == mShowPassword) {
Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
mShowPassword.isChecked() ? 1 : 0);
@@ -265,11 +274,6 @@ public class SecuritySettings extends PreferenceActivity {
return false;
}
private void showPrivacyPolicy() {
Intent intent = new Intent("android.settings.TERMS");
startActivity(intent);
}
/*
* Creates toggles for each available location provider
*/
@@ -291,36 +295,6 @@ public class SecuritySettings extends PreferenceActivity {
return ((CheckBoxPreference) pref).isChecked();
}
/**
* For the user to disable keyguard, we first make them verify their
* existing pattern.
*/
private class LockEnabledPref extends CheckBoxPreference {
public LockEnabledPref(Context context) {
super(context);
}
@Override
protected void onClick() {
if (mLockPatternUtils.savedPatternExists() && isChecked()) {
confirmPatternThenDisableAndClear();
} else {
super.onClick();
}
}
}
/**
* Launch screen to confirm the existing lock pattern.
* @see #onActivityResult(int, int, android.content.Intent)
*/
private void confirmPatternThenDisableAndClear() {
final Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
startActivityForResult(intent, CONFIRM_PATTERN_THEN_DISABLE_AND_CLEAR_REQUEST_CODE);
}
/**
* @see #confirmPatternThenDisableAndClear
*/
@@ -330,10 +304,11 @@ public class SecuritySettings extends PreferenceActivity {
final boolean resultOk = resultCode == Activity.RESULT_OK;
if ((requestCode == CONFIRM_PATTERN_THEN_DISABLE_AND_CLEAR_REQUEST_CODE)
&& resultOk) {
mLockPatternUtils.setLockPatternEnabled(false);
mLockPatternUtils.saveLockPattern(null);
LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if ((requestCode == CONFIRM_EXISTING_REQUEST) && resultOk) {
lockPatternUtils.saveLockPassword(null);
lockPatternUtils.setLockPatternEnabled(false);
lockPatternUtils.saveLockPattern(null);
}
}