From bbb4afa19f75694c585506b0c091372d60e07ca7 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Thu, 8 Apr 2010 19:40:19 -0700 Subject: [PATCH] Fix 2579923: Make changing lock screen method more discoverable. This changes the organization of lock screen security settings to make choosing an alternate unlock method more discoverable. Instead of having to disable the old lock method to use a new one, the user now just has one set/change option in lock settings, with a list of method-specific setting below it. In addition, we ask the user to confirm their old credentials before prompting them to choose a new one, which eliminates one source of confusion. Also, ChooseLockGeneric now shows a UI if quality isn't specified. Any unlock method less secure than minimum specified by DevicePolicyManager (if active) is greyed out. Change-Id: Iecc6f64d4d3368a583f06f8d5fe9655cc3d5bd3b --- AndroidManifest.xml | 9 +- res/values/strings.xml | 44 ++++- res/xml/security_settings_chooser.xml | 18 +- res/xml/security_settings_password.xml | 11 +- res/xml/security_settings_pattern.xml | 11 +- res/xml/security_settings_picker.xml | 49 ++++++ res/xml/security_settings_pin.xml | 11 +- .../android/settings/ChooseLockGeneric.java | 154 ++++++++++++++++-- .../android/settings/ChooseLockPassword.java | 6 +- .../android/settings/ChooseLockPattern.java | 16 +- .../settings/ChooseLockPatternExample.java | 29 ++-- .../settings/ChooseLockPatternTutorial.java | 19 +-- .../android/settings/SecuritySettings.java | 88 +--------- 13 files changed, 283 insertions(+), 182 deletions(-) create mode 100644 res/xml/security_settings_picker.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3499a42f8d2..78c0f5b3540 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -491,8 +491,7 @@ android:theme="@android:style/Theme.NoTitleBar"> - + @@ -500,12 +499,14 @@ + android:label="@string/lockpattern_change_lock_pattern_label" + android:exported="false"> + android:theme="@android:style/Theme.NoTitleBar" + android:exported="false"> Sort by time zone + + Location & security @@ -525,23 +527,49 @@ Passwords + - + + + Screen unlock security - - Set unlock pattern + + + Set up screen lock + + + Lock screen with a pattern, PIN, or password + + + Change screen lock + + + Change or disable pattern, PIN, or password security + + + + None + + Disable screen unlock security + + + Pattern - Must draw pattern to unlock screen + Draw pattern to unlock screen - Set unlock PIN + PIN - Must use a numeric PIN to unlock screen + Enter a numeric PIN to unlock screen - Set unlock password + Password - Must use a password to unlock screen + Enter a password to unlock screen + + + Disable by device policy + Turn off screen lock diff --git a/res/xml/security_settings_chooser.xml b/res/xml/security_settings_chooser.xml index 4f5797f4cd4..095c69f6edf 100644 --- a/res/xml/security_settings_chooser.xml +++ b/res/xml/security_settings_chooser.xml @@ -21,21 +21,9 @@ android:title="@string/lock_settings_title"> - - - - diff --git a/res/xml/security_settings_password.xml b/res/xml/security_settings_password.xml index 9addee4600c..ac067117b59 100644 --- a/res/xml/security_settings_password.xml +++ b/res/xml/security_settings_password.xml @@ -21,14 +21,9 @@ android:title="@string/lock_settings_title"> - - - - + + + + + + + + + + + + + + + + + diff --git a/res/xml/security_settings_pin.xml b/res/xml/security_settings_pin.xml index fb7771483b6..ac067117b59 100644 --- a/res/xml/security_settings_pin.xml +++ b/res/xml/security_settings_pin.xml @@ -21,14 +21,9 @@ android:title="@string/lock_settings_title"> - - = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { int minLength = mDPM.getPasswordMinimumLength(null); - if (minLength < 4) { - minLength = 4; + if (minLength < MIN_PASSWORD_LENGTH) { + minLength = MIN_PASSWORD_LENGTH; } final int maxLength = mDPM.getPasswordMaximumLength(quality); Intent intent = new Intent().setClass(this, ChooseLockPassword.class); intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, quality); intent.putExtra(ChooseLockPassword.PASSWORD_MIN_KEY, minLength); intent.putExtra(ChooseLockPassword.PASSWORD_MAX_KEY, maxLength); + intent.putExtra(CONFIRM_CREDENTIALS, false); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); startActivity(intent); - } else { - boolean showTutorial = !lockPatternUtils.isPatternEverChosen(); + } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { + boolean showTutorial = !mChooseLockSettingsHelper.utils().isPatternEverChosen(); Intent intent = new Intent(); intent.setClass(this, showTutorial ? ChooseLockPatternTutorial.class : ChooseLockPattern.class); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); intent.putExtra("key_lock_method", "pattern"); + intent.putExtra(CONFIRM_CREDENTIALS, false); startActivity(intent); + } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { + mChooseLockSettingsHelper.utils().clearLock(); + setResult(RESULT_OK); } finish(); } diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java index 2271a310ae5..63c789667fc 100644 --- a/src/com/android/settings/ChooseLockPassword.java +++ b/src/com/android/settings/ChooseLockPassword.java @@ -104,6 +104,8 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE mRequestedQuality = getIntent().getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, mRequestedQuality); mPasswordMinLength = getIntent().getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength); mPasswordMaxLength = getIntent().getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength); + + final boolean confirmCredentials = getIntent().getBooleanExtra("confirm_credentials", true); int minMode = mLockPatternUtils.getRequestedPasswordQuality(); if (mRequestedQuality < minMode) { mRequestedQuality = minMode; @@ -116,7 +118,9 @@ public class ChooseLockPassword extends Activity implements OnClickListener, OnE mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this); if (savedInstanceState == null) { updateStage(Stage.Introduction); - mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST); + if (confirmCredentials) { + mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST); + } } } diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java index 859d96b2a52..786d5633bb0 100644 --- a/src/com/android/settings/ChooseLockPattern.java +++ b/src/com/android/settings/ChooseLockPattern.java @@ -280,11 +280,19 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{ R.id.topLayout); topLayout.setDefaultTouchRecepient(mLockPatternView); + final boolean confirmCredentials = getIntent().getBooleanExtra("confirm_credentials", true); + if (savedInstanceState == null) { - // 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)) { + if (confirmCredentials) { + // 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); + boolean launchedConfirmationActivity = + mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST); + if (!launchedConfirmationActivity) { + updateStage(Stage.Introduction); + } + } else { updateStage(Stage.Introduction); } } else { diff --git a/src/com/android/settings/ChooseLockPatternExample.java b/src/com/android/settings/ChooseLockPatternExample.java index 77517b9d3d4..cba88b01cec 100644 --- a/src/com/android/settings/ChooseLockPatternExample.java +++ b/src/com/android/settings/ChooseLockPatternExample.java @@ -25,7 +25,6 @@ import android.view.View; import android.widget.ImageView; public class ChooseLockPatternExample extends Activity implements View.OnClickListener { - private static final int REQUESTCODE_CHOOSE = 1; private static final long START_DELAY = 1000; protected static final String TAG = "Settings"; private View mNextButton; @@ -38,26 +37,26 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi startAnimation(mAnimation); } }; - + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.choose_lock_pattern_example); initViews(); } - + @Override protected void onResume() { super.onResume(); mHandler.postDelayed(mRunnable, START_DELAY); } - + @Override protected void onPause() { super.onPause(); stopAnimation(mAnimation); } - + public void onClick(View v) { if (v == mSkipButton) { // Canceling, so finish all @@ -66,37 +65,31 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi } else if (v == mNextButton) { stopAnimation(mAnimation); Intent intent = new Intent(this, ChooseLockPattern.class); - startActivityForResult(intent, REQUESTCODE_CHOOSE); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUESTCODE_CHOOSE && resultCode == ChooseLockPattern.RESULT_FINISHED) { - setResult(resultCode); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + startActivity(intent); finish(); } } - + private void initViews() { mNextButton = findViewById(R.id.next_button); mNextButton.setOnClickListener(this); - + mSkipButton = findViewById(R.id.skip_button); mSkipButton.setOnClickListener(this); - + mImageView = (ImageView) findViewById(R.id.lock_anim); mImageView.setBackgroundResource(R.drawable.lock_anim); mImageView.setOnClickListener(this); mAnimation = (AnimationDrawable) mImageView.getBackground(); } - + protected void startAnimation(final AnimationDrawable animation) { if (animation != null && !animation.isRunning()) { animation.run(); } } - + protected void stopAnimation(final AnimationDrawable animation) { if (animation != null && animation.isRunning()) animation.stop(); } diff --git a/src/com/android/settings/ChooseLockPatternTutorial.java b/src/com/android/settings/ChooseLockPatternTutorial.java index aa6213e06bb..ee0019f7065 100644 --- a/src/com/android/settings/ChooseLockPatternTutorial.java +++ b/src/com/android/settings/ChooseLockPatternTutorial.java @@ -24,8 +24,6 @@ import android.os.Bundle; import android.view.View; public class ChooseLockPatternTutorial extends Activity implements View.OnClickListener { - private static final int REQUESTCODE_EXAMPLE = 1; - private View mNextButton; private View mSkipButton; @@ -35,8 +33,8 @@ public class ChooseLockPatternTutorial extends Activity implements View.OnClickL // Don't show the tutorial if the user has seen it before. LockPatternUtils lockPatternUtils = new LockPatternUtils(this); if (savedInstanceState == null && lockPatternUtils.isPatternEverChosen()) { - Intent intent = new Intent(); - intent.setClass(this, ChooseLockPattern.class); + Intent intent = new Intent(this, ChooseLockPattern.class); + intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); startActivity(intent); finish(); } else { @@ -58,18 +56,11 @@ public class ChooseLockPatternTutorial extends Activity implements View.OnClickL setResult(ChooseLockPattern.RESULT_FINISHED); finish(); } else if (v == mNextButton) { - startActivityForResult(new Intent(this, ChooseLockPatternExample.class), - REQUESTCODE_EXAMPLE); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUESTCODE_EXAMPLE && resultCode == ChooseLockPattern.RESULT_FINISHED) { - setResult(resultCode); + Intent intent = new Intent(this, ChooseLockPatternExample.class); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + startActivity(intent); finish(); } } - } diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index e5e7918f384..1348d48e51e 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -56,25 +56,15 @@ import com.android.internal.widget.LockPatternUtils; * Gesture lock pattern settings. */ public class SecuritySettings extends PreferenceActivity { + private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change"; - 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"; 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 = "unlock_tactile_feedback"; - 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; private CheckBoxPreference mVisiblePattern; private CheckBoxPreference mTactileFeedback; @@ -82,14 +72,10 @@ public class SecuritySettings extends PreferenceActivity { private CheckBoxPreference mShowPassword; // Location Settings - private static final String LOCATION_CATEGORY = "location_category"; private static final String LOCATION_NETWORK = "location_network"; private static final String LOCATION_GPS = "location_gps"; private static final String ASSISTED_GPS = "assisted_gps"; - - // Default password lengths if device policy isn't in effect. Ignored otherwise. - private static final int PASSWORD_MIN_LENGTH = 4; - private static final int PASSWORD_MAX_LENGTH = 16; + private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123; // Credential storage private CredentialStorage mCredentialStorage = new CredentialStorage(); @@ -106,8 +92,6 @@ public class SecuritySettings extends PreferenceActivity { private ContentQueryMap mContentQueryMap; 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(); @@ -169,11 +153,8 @@ public class SecuritySettings extends PreferenceActivity { } } - // 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); + // set or change current. Should be common to all unlock preference screens + // mSetOrChange = (PreferenceScreen) pm.findPreference(KEY_UNLOCK_SET_OR_CHANGE); // visible pattern mVisiblePattern = (CheckBoxPreference) pm.findPreference(KEY_VISIBLE_PATTERN); @@ -181,7 +162,6 @@ public class SecuritySettings extends PreferenceActivity { // 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 @@ -232,46 +212,6 @@ public class SecuritySettings extends PreferenceActivity { return root; } - protected void handleUpdateUnlockMethod(String value) { - // NULL means update the current password/pattern/pin - if (value == null) { - int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality(); - if (DevicePolicyManager.PASSWORD_QUALITY_SOMETHING == mode) { - value = "pattern"; - } else if (DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mode - || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mode) { - value = "password"; - } else if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC == 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); - } - } else { - int reqMode; - if ("password".equals(value)) { - reqMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; - } else if ( "pin".equals(value)) { - reqMode = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; - } else { - reqMode = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; - } - int minMode = mDPM.getPasswordQuality(null); - if (reqMode < minMode) { - reqMode = minMode; - } - Intent intent = new Intent(); - intent.setClass(this, ChooseLockGeneric.class); - intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, reqMode); - startActivityForResult(intent, UPDATE_PASSWORD_REQUEST); - } - } - @Override protected void onResume() { super.onResume(); @@ -296,16 +236,9 @@ public class SecuritySettings extends PreferenceActivity { final String key = preference.getKey(); final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); - 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); + if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) { + Intent intent = new Intent(this, ChooseLockGeneric.class); + startActivityForResult(intent, SET_OR_CHANGE_LOCK_METHOD_REQUEST); } else if (KEY_LOCK_ENABLED.equals(key)) { lockPatternUtils.setLockPatternEnabled(isToggled(preference)); } else if (KEY_VISIBLE_PATTERN.equals(key)) { @@ -360,13 +293,6 @@ public class SecuritySettings extends PreferenceActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - - final boolean resultOk = resultCode == Activity.RESULT_OK; - - LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); - if ((requestCode == CONFIRM_EXISTING_REQUEST) && resultOk) { - lockPatternUtils.clearLock(); - } createPreferenceHierarchy(); }