Fix 2332563: Add password-lock support to lockscreen
This commit is contained in:
232
src/com/android/settings/ChooseLockPassword.java
Normal file
232
src/com/android/settings/ChooseLockPassword.java
Normal 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);
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
|
85
src/com/android/settings/ChooseLockSettingsHelper.java
Normal file
85
src/com/android/settings/ChooseLockSettingsHelper.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
114
src/com/android/settings/ConfirmLockPassword.java
Normal file
114
src/com/android/settings/ConfirmLockPassword.java
Normal 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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user