ChooseLockPassword.java revision 6609b0c22ae89a24d1b07dc3c4143452616d4450
100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller/* 200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * Copyright (C) 2010 The Android Open Source Project 300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * 400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * you may not use this file except in compliance with the License. 600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * You may obtain a copy of the License at 700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * 800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * http://www.apache.org/licenses/LICENSE-2.0 900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * 1000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * Unless required by applicable law or agreed to in writing, software 1100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 1200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * See the License for the specific language governing permissions and 1400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller * limitations under the License. 1500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller */ 1600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 1700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerpackage com.android.settings; 1800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 198a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenimport com.android.internal.logging.MetricsLogger; 2000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport com.android.internal.widget.LockPatternUtils; 212f9dbcb49174d85218dd18e3b2097d3b9fc789c7Jim Millerimport com.android.internal.widget.PasswordEntryKeyboardHelper; 222f9dbcb49174d85218dd18e3b2097d3b9fc789c7Jim Millerimport com.android.internal.widget.PasswordEntryKeyboardView; 236f60f7ed22f94891156115643452a32d0324f65aAdrian Roosimport com.android.settings.notification.RedactionInterstitial; 2400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 2500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.app.Activity; 2617e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.app.Fragment; 27af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Millerimport android.app.admin.DevicePolicyManager; 280698a216311acd9ab52224602d1a75c08bf89f04Jim Millerimport android.content.Context; 2900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.content.Intent; 302f9dbcb49174d85218dd18e3b2097d3b9fc789c7Jim Millerimport android.inputmethodservice.KeyboardView; 3100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.os.Bundle; 3200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.os.Handler; 33552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasaniimport android.os.Message; 3400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.text.Editable; 352e28acedc623527aa5e84ba66635700d6547569aJim Millerimport android.text.InputType; 36122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.text.Selection; 37122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.text.Spannable; 3800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.text.TextUtils; 39122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.text.TextWatcher; 40122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.view.KeyEvent; 4117e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.LayoutInflater; 4200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.view.View; 4317e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.ViewGroup; 4400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.view.View.OnClickListener; 45122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.view.inputmethod.EditorInfo; 4600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.widget.Button; 4700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.widget.TextView; 48122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.widget.TextView.OnEditorActionListener; 4900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 50263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Megliopublic class ChooseLockPassword extends SettingsActivity { 5100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller public static final String PASSWORD_MIN_KEY = "lockscreen.password_min"; 5200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller public static final String PASSWORD_MAX_KEY = "lockscreen.password_max"; 5357fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_LETTERS_KEY = "lockscreen.password_min_letters"; 5457fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_LOWERCASE_KEY = "lockscreen.password_min_lowercase"; 5557fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_UPPERCASE_KEY = "lockscreen.password_min_uppercase"; 5657fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_NUMERIC_KEY = "lockscreen.password_min_numeric"; 5757fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_SYMBOLS_KEY = "lockscreen.password_min_symbols"; 582df65e4facac659314c2440d0af6316924166e2bKonstantin Lopyrev public static final String PASSWORD_MIN_NONLETTER_KEY = "lockscreen.password_min_nonletter"; 5900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 6017e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 6117e9e1933055b207473b488595b2887bfcaea32eJim Miller public Intent getIntent() { 6217e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent modIntent = new Intent(super.getIntent()); 636b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName()); 6417e9e1933055b207473b488595b2887bfcaea32eJim Miller return modIntent; 6517e9e1933055b207473b488595b2887bfcaea32eJim Miller } 66122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 67f788718f2142e5546bbf1b6847793d59ffea898bAdrian Roos public static Intent createIntent(Context context, int quality, 680698a216311acd9ab52224602d1a75c08bf89f04Jim Miller int minLength, final int maxLength, boolean requirePasswordToDecrypt, 690698a216311acd9ab52224602d1a75c08bf89f04Jim Miller boolean confirmCredentials) { 700698a216311acd9ab52224602d1a75c08bf89f04Jim Miller Intent intent = new Intent().setClass(context, ChooseLockPassword.class); 710698a216311acd9ab52224602d1a75c08bf89f04Jim Miller intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, quality); 720698a216311acd9ab52224602d1a75c08bf89f04Jim Miller intent.putExtra(PASSWORD_MIN_KEY, minLength); 730698a216311acd9ab52224602d1a75c08bf89f04Jim Miller intent.putExtra(PASSWORD_MAX_KEY, maxLength); 740698a216311acd9ab52224602d1a75c08bf89f04Jim Miller intent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, confirmCredentials); 750698a216311acd9ab52224602d1a75c08bf89f04Jim Miller intent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, requirePasswordToDecrypt); 760698a216311acd9ab52224602d1a75c08bf89f04Jim Miller return intent; 770698a216311acd9ab52224602d1a75c08bf89f04Jim Miller } 780698a216311acd9ab52224602d1a75c08bf89f04Jim Miller 79a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales public static Intent createIntent(Context context, int quality, 80a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales int minLength, final int maxLength, boolean requirePasswordToDecrypt, String password) { 81a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales Intent intent = createIntent(context, quality, minLength, maxLength, requirePasswordToDecrypt, 82a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales false); 83a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password); 84a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales return intent; 85a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales } 86a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales 876609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales public static Intent createIntent(Context context, int quality, 886609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales int minLength, final int maxLength, boolean requirePasswordToDecrypt, long challenge) { 896609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales Intent intent = createIntent(context, quality, minLength, maxLength, requirePasswordToDecrypt, 906609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales false); 916609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); 926609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); 936609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales return intent; 946609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales } 956609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales 9617e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 97a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani protected boolean isValidFragment(String fragmentName) { 98a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani if (ChooseLockPasswordFragment.class.getName().equals(fragmentName)) return true; 99a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani return false; 100a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani } 101a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani 1026b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam /* package */ Class<? extends Fragment> getFragmentClass() { 1036b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam return ChooseLockPasswordFragment.class; 1046b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam } 1056b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam 106a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani @Override 10717e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onCreate(Bundle savedInstanceState) { 10817e9e1933055b207473b488595b2887bfcaea32eJim Miller // TODO: Fix on phones 10917e9e1933055b207473b488595b2887bfcaea32eJim Miller // Disable IME on our window since we provide our own keyboard 11017e9e1933055b207473b488595b2887bfcaea32eJim Miller //getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 11117e9e1933055b207473b488595b2887bfcaea32eJim Miller //WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 11217e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onCreate(savedInstanceState); 1137da8cae44b622518fbffd6d265f291c39e9fc722Jim Miller CharSequence msg = getText(R.string.lockpassword_choose_your_password_header); 114263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio setTitle(msg); 11517e9e1933055b207473b488595b2887bfcaea32eJim Miller } 116122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 1178a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren public static class ChooseLockPasswordFragment extends InstrumentedFragment 11817e9e1933055b207473b488595b2887bfcaea32eJim Miller implements OnClickListener, OnEditorActionListener, TextWatcher { 11917e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final String KEY_FIRST_PIN = "first_pin"; 12017e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final String KEY_UI_STAGE = "ui_stage"; 121a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales private static final String KEY_CURRENT_PASSWORD = "current_password"; 122a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales 123a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales private String mCurrentPassword; 1246609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales private boolean mHasChallenge; 1256609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales private long mChallenge; 12617e9e1933055b207473b488595b2887bfcaea32eJim Miller private TextView mPasswordEntry; 1274c00a611835e2257502ddcdd26b4e827c5b64f80Adrian Roos private int mPasswordMinLength = LockPatternUtils.MIN_LOCK_PASSWORD_SIZE; 12817e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMaxLength = 16; 12917e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinLetters = 0; 13017e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinUpperCase = 0; 13117e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinLowerCase = 0; 13217e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinSymbols = 0; 13317e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinNumeric = 0; 13417e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinNonLetter = 0; 13517e9e1933055b207473b488595b2887bfcaea32eJim Miller private LockPatternUtils mLockPatternUtils; 13617e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; 13717e9e1933055b207473b488595b2887bfcaea32eJim Miller private ChooseLockSettingsHelper mChooseLockSettingsHelper; 13817e9e1933055b207473b488595b2887bfcaea32eJim Miller private Stage mUiStage = Stage.Introduction; 1396d5c75f6cd928befb348fa283e53edc10716f151Adrian Roos private boolean mDone = false; 14017e9e1933055b207473b488595b2887bfcaea32eJim Miller private TextView mHeaderText; 14117e9e1933055b207473b488595b2887bfcaea32eJim Miller private String mFirstPin; 14217e9e1933055b207473b488595b2887bfcaea32eJim Miller private KeyboardView mKeyboardView; 14317e9e1933055b207473b488595b2887bfcaea32eJim Miller private PasswordEntryKeyboardHelper mKeyboardHelper; 14417e9e1933055b207473b488595b2887bfcaea32eJim Miller private boolean mIsAlphaMode; 14517e9e1933055b207473b488595b2887bfcaea32eJim Miller private Button mCancelButton; 14617e9e1933055b207473b488595b2887bfcaea32eJim Miller private Button mNextButton; 14717e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final int CONFIRM_EXISTING_REQUEST = 58; 14817e9e1933055b207473b488595b2887bfcaea32eJim Miller static final int RESULT_FINISHED = RESULT_FIRST_USER; 14917e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final long ERROR_MESSAGE_TIMEOUT = 3000; 150552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani private static final int MSG_SHOW_ERROR = 1; 151552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani 152552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani private Handler mHandler = new Handler() { 153552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani @Override 154552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani public void handleMessage(Message msg) { 155552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani if (msg.what == MSG_SHOW_ERROR) { 156552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani updateStage((Stage) msg.obj); 157552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani } 158552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani } 159552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani }; 16000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 16100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller /** 16217e9e1933055b207473b488595b2887bfcaea32eJim Miller * Keep track internally of where the user is in choosing a pattern. 16300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller */ 16417e9e1933055b207473b488595b2887bfcaea32eJim Miller protected enum Stage { 16517e9e1933055b207473b488595b2887bfcaea32eJim Miller 16617e9e1933055b207473b488595b2887bfcaea32eJim Miller Introduction(R.string.lockpassword_choose_your_password_header, 16717e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_choose_your_pin_header, 16817e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_continue_label), 16917e9e1933055b207473b488595b2887bfcaea32eJim Miller 17017e9e1933055b207473b488595b2887bfcaea32eJim Miller NeedToConfirm(R.string.lockpassword_confirm_your_password_header, 17117e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_confirm_your_pin_header, 17217e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_ok_label), 17317e9e1933055b207473b488595b2887bfcaea32eJim Miller 17417e9e1933055b207473b488595b2887bfcaea32eJim Miller ConfirmWrong(R.string.lockpassword_confirm_passwords_dont_match, 17517e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_confirm_pins_dont_match, 17617e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_continue_label); 17717e9e1933055b207473b488595b2887bfcaea32eJim Miller 17817e9e1933055b207473b488595b2887bfcaea32eJim Miller Stage(int hintInAlpha, int hintInNumeric, int nextButtonText) { 17917e9e1933055b207473b488595b2887bfcaea32eJim Miller this.alphaHint = hintInAlpha; 18017e9e1933055b207473b488595b2887bfcaea32eJim Miller this.numericHint = hintInNumeric; 18117e9e1933055b207473b488595b2887bfcaea32eJim Miller this.buttonText = nextButtonText; 18217e9e1933055b207473b488595b2887bfcaea32eJim Miller } 18317e9e1933055b207473b488595b2887bfcaea32eJim Miller 18417e9e1933055b207473b488595b2887bfcaea32eJim Miller public final int alphaHint; 18517e9e1933055b207473b488595b2887bfcaea32eJim Miller public final int numericHint; 18617e9e1933055b207473b488595b2887bfcaea32eJim Miller public final int buttonText; 18700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 18800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 18917e9e1933055b207473b488595b2887bfcaea32eJim Miller // required constructor for fragments 19017e9e1933055b207473b488595b2887bfcaea32eJim Miller public ChooseLockPasswordFragment() { 19100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 19200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 19300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 19417e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 19517e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onCreate(Bundle savedInstanceState) { 19617e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onCreate(savedInstanceState); 19717e9e1933055b207473b488595b2887bfcaea32eJim Miller mLockPatternUtils = new LockPatternUtils(getActivity()); 19817e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent intent = getActivity().getIntent(); 19966026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani if (!(getActivity() instanceof ChooseLockPassword)) { 20066026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani throw new SecurityException("Fragment contained in wrong activity"); 20166026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani } 20217e9e1933055b207473b488595b2887bfcaea32eJim Miller mRequestedQuality = Math.max(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, 20317e9e1933055b207473b488595b2887bfcaea32eJim Miller mRequestedQuality), mLockPatternUtils.getRequestedPasswordQuality()); 2044c00a611835e2257502ddcdd26b4e827c5b64f80Adrian Roos mPasswordMinLength = Math.max(Math.max( 2054c00a611835e2257502ddcdd26b4e827c5b64f80Adrian Roos LockPatternUtils.MIN_LOCK_PASSWORD_SIZE, 2064c00a611835e2257502ddcdd26b4e827c5b64f80Adrian Roos intent.getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength)), 2074c00a611835e2257502ddcdd26b4e827c5b64f80Adrian Roos mLockPatternUtils.getRequestedMinimumPasswordLength()); 20817e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMaxLength = intent.getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength); 20917e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinLetters = Math.max(intent.getIntExtra(PASSWORD_MIN_LETTERS_KEY, 21017e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinLetters), mLockPatternUtils.getRequestedPasswordMinimumLetters()); 21117e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinUpperCase = Math.max(intent.getIntExtra(PASSWORD_MIN_UPPERCASE_KEY, 21217e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinUpperCase), mLockPatternUtils.getRequestedPasswordMinimumUpperCase()); 21317e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinLowerCase = Math.max(intent.getIntExtra(PASSWORD_MIN_LOWERCASE_KEY, 21417e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinLowerCase), mLockPatternUtils.getRequestedPasswordMinimumLowerCase()); 21517e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinNumeric = Math.max(intent.getIntExtra(PASSWORD_MIN_NUMERIC_KEY, 21617e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinNumeric), mLockPatternUtils.getRequestedPasswordMinimumNumeric()); 21717e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinSymbols = Math.max(intent.getIntExtra(PASSWORD_MIN_SYMBOLS_KEY, 21817e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinSymbols), mLockPatternUtils.getRequestedPasswordMinimumSymbols()); 21917e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinNonLetter = Math.max(intent.getIntExtra(PASSWORD_MIN_NONLETTER_KEY, 22017e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinNonLetter), mLockPatternUtils.getRequestedPasswordMinimumNonLetter()); 22117e9e1933055b207473b488595b2887bfcaea32eJim Miller 22217e9e1933055b207473b488595b2887bfcaea32eJim Miller mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity()); 22317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 2242f9dbcb49174d85218dd18e3b2097d3b9fc789c7Jim Miller 22517e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 22617e9e1933055b207473b488595b2887bfcaea32eJim Miller public View onCreateView(LayoutInflater inflater, ViewGroup container, 22717e9e1933055b207473b488595b2887bfcaea32eJim Miller Bundle savedInstanceState) { 2286b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam return inflater.inflate(R.layout.choose_lock_password, container, false); 2296b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam } 23017e9e1933055b207473b488595b2887bfcaea32eJim Miller 2316b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam @Override 2326b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam public void onViewCreated(View view, Bundle savedInstanceState) { 2336b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam super.onViewCreated(view, savedInstanceState); 23417e9e1933055b207473b488595b2887bfcaea32eJim Miller 23517e9e1933055b207473b488595b2887bfcaea32eJim Miller mCancelButton = (Button) view.findViewById(R.id.cancel_button); 23617e9e1933055b207473b488595b2887bfcaea32eJim Miller mCancelButton.setOnClickListener(this); 23717e9e1933055b207473b488595b2887bfcaea32eJim Miller mNextButton = (Button) view.findViewById(R.id.next_button); 23817e9e1933055b207473b488595b2887bfcaea32eJim Miller mNextButton.setOnClickListener(this); 23917e9e1933055b207473b488595b2887bfcaea32eJim Miller 24017e9e1933055b207473b488595b2887bfcaea32eJim Miller mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mRequestedQuality 24117e9e1933055b207473b488595b2887bfcaea32eJim Miller || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mRequestedQuality 24217e9e1933055b207473b488595b2887bfcaea32eJim Miller || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mRequestedQuality; 24317e9e1933055b207473b488595b2887bfcaea32eJim Miller mKeyboardView = (PasswordEntryKeyboardView) view.findViewById(R.id.keyboard); 24417e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry = (TextView) view.findViewById(R.id.password_entry); 24517e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry.setOnEditorActionListener(this); 24617e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry.addTextChangedListener(this); 24717e9e1933055b207473b488595b2887bfcaea32eJim Miller 2489757e30dfa0ab691c4c15366568367e166071a7dJim Miller final Activity activity = getActivity(); 2499757e30dfa0ab691c4c15366568367e166071a7dJim Miller mKeyboardHelper = new PasswordEntryKeyboardHelper(activity, 25017e9e1933055b207473b488595b2887bfcaea32eJim Miller mKeyboardView, mPasswordEntry); 25117e9e1933055b207473b488595b2887bfcaea32eJim Miller mKeyboardHelper.setKeyboardMode(mIsAlphaMode ? 25217e9e1933055b207473b488595b2887bfcaea32eJim Miller PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA 25317e9e1933055b207473b488595b2887bfcaea32eJim Miller : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); 25417e9e1933055b207473b488595b2887bfcaea32eJim Miller 25517e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText = (TextView) view.findViewById(R.id.headerText); 25617e9e1933055b207473b488595b2887bfcaea32eJim Miller mKeyboardView.requestFocus(); 25717e9e1933055b207473b488595b2887bfcaea32eJim Miller 2582e28acedc623527aa5e84ba66635700d6547569aJim Miller int currentType = mPasswordEntry.getInputType(); 2592e28acedc623527aa5e84ba66635700d6547569aJim Miller mPasswordEntry.setInputType(mIsAlphaMode ? currentType 2603b46f49d2a5abb47c1bdf239f855d2063b60595eJim Miller : (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD)); 2612e28acedc623527aa5e84ba66635700d6547569aJim Miller 26217e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent intent = getActivity().getIntent(); 2636609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales final boolean confirmCredentials = intent.getBooleanExtra( 2646609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales ChooseLockGeneric.CONFIRM_CREDENTIALS, true); 265a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mCurrentPassword = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 2666609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales mHasChallenge = intent.getBooleanExtra( 2676609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); 2686609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); 26917e9e1933055b207473b488595b2887bfcaea32eJim Miller if (savedInstanceState == null) { 27017e9e1933055b207473b488595b2887bfcaea32eJim Miller updateStage(Stage.Introduction); 27117e9e1933055b207473b488595b2887bfcaea32eJim Miller if (confirmCredentials) { 27217e9e1933055b207473b488595b2887bfcaea32eJim Miller mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, 273a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales getString(R.string.unlock_set_unlock_launch_picker_title), true); 27417e9e1933055b207473b488595b2887bfcaea32eJim Miller } 27517e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 276a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales // restore from previous state 27717e9e1933055b207473b488595b2887bfcaea32eJim Miller mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN); 27817e9e1933055b207473b488595b2887bfcaea32eJim Miller final String state = savedInstanceState.getString(KEY_UI_STAGE); 27917e9e1933055b207473b488595b2887bfcaea32eJim Miller if (state != null) { 28017e9e1933055b207473b488595b2887bfcaea32eJim Miller mUiStage = Stage.valueOf(state); 28117e9e1933055b207473b488595b2887bfcaea32eJim Miller updateStage(mUiStage); 28217e9e1933055b207473b488595b2887bfcaea32eJim Miller } 283a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales 284a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales if (mCurrentPassword == null) { 285a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mCurrentPassword = savedInstanceState.getString(KEY_CURRENT_PASSWORD); 286a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales } 28717e9e1933055b207473b488595b2887bfcaea32eJim Miller } 2886d5c75f6cd928befb348fa283e53edc10716f151Adrian Roos mDone = false; 289263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio if (activity instanceof SettingsActivity) { 290263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio final SettingsActivity sa = (SettingsActivity) activity; 291d75905991c5a1783ca27dc188c2d086f8f13ff94Jim Miller int id = mIsAlphaMode ? R.string.lockpassword_choose_your_password_header 292d75905991c5a1783ca27dc188c2d086f8f13ff94Jim Miller : R.string.lockpassword_choose_your_pin_header; 2939757e30dfa0ab691c4c15366568367e166071a7dJim Miller CharSequence title = getText(id); 294263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio sa.setTitle(title); 2959757e30dfa0ab691c4c15366568367e166071a7dJim Miller } 29617e9e1933055b207473b488595b2887bfcaea32eJim Miller } 297122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 29817e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 2998a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren protected int getMetricsCategory() { 3008a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren return MetricsLogger.CHOOSE_LOCK_PASSWORD; 3018a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren } 3028a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren 3038a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren @Override 30417e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onResume() { 30517e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onResume(); 306122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller updateStage(mUiStage); 30717e9e1933055b207473b488595b2887bfcaea32eJim Miller mKeyboardView.requestFocus(); 308122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 309122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 31017e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 311552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani public void onPause() { 312552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani mHandler.removeMessages(MSG_SHOW_ERROR); 313552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani 314552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani super.onPause(); 315552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani } 316552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani 317552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani @Override 31817e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onSaveInstanceState(Bundle outState) { 31917e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onSaveInstanceState(outState); 32017e9e1933055b207473b488595b2887bfcaea32eJim Miller outState.putString(KEY_UI_STAGE, mUiStage.name()); 32117e9e1933055b207473b488595b2887bfcaea32eJim Miller outState.putString(KEY_FIRST_PIN, mFirstPin); 322a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales outState.putString(KEY_CURRENT_PASSWORD, mCurrentPassword); 32300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 32400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 32517e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 32617e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onActivityResult(int requestCode, int resultCode, 32717e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent data) { 32817e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onActivityResult(requestCode, resultCode, data); 32917e9e1933055b207473b488595b2887bfcaea32eJim Miller switch (requestCode) { 33017e9e1933055b207473b488595b2887bfcaea32eJim Miller case CONFIRM_EXISTING_REQUEST: 33117e9e1933055b207473b488595b2887bfcaea32eJim Miller if (resultCode != Activity.RESULT_OK) { 33217e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().setResult(RESULT_FINISHED); 33317e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().finish(); 334a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales } else { 335a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mCurrentPassword = data.getStringExtra( 336a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 33717e9e1933055b207473b488595b2887bfcaea32eJim Miller } 33817e9e1933055b207473b488595b2887bfcaea32eJim Miller break; 33917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 34000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 34117e9e1933055b207473b488595b2887bfcaea32eJim Miller 342ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam protected Intent getRedactionInterstitialIntent(Context context) { 343ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam return RedactionInterstitial.createStartIntent(context); 344ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam } 345ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam 34617e9e1933055b207473b488595b2887bfcaea32eJim Miller protected void updateStage(Stage stage) { 347eef72c39ae83697b1beaa148ec56aced67382fecalanv final Stage previousStage = mUiStage; 34817e9e1933055b207473b488595b2887bfcaea32eJim Miller mUiStage = stage; 34917e9e1933055b207473b488595b2887bfcaea32eJim Miller updateUi(); 350eef72c39ae83697b1beaa148ec56aced67382fecalanv 351eef72c39ae83697b1beaa148ec56aced67382fecalanv // If the stage changed, announce the header for accessibility. This 352eef72c39ae83697b1beaa148ec56aced67382fecalanv // is a no-op when accessibility is disabled. 353eef72c39ae83697b1beaa148ec56aced67382fecalanv if (previousStage != stage) { 354eef72c39ae83697b1beaa148ec56aced67382fecalanv mHeaderText.announceForAccessibility(mHeaderText.getText()); 355eef72c39ae83697b1beaa148ec56aced67382fecalanv } 35600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 35717e9e1933055b207473b488595b2887bfcaea32eJim Miller 35817e9e1933055b207473b488595b2887bfcaea32eJim Miller /** 35917e9e1933055b207473b488595b2887bfcaea32eJim Miller * Validates PIN and returns a message to display if PIN fails test. 36017e9e1933055b207473b488595b2887bfcaea32eJim Miller * @param password the raw password the user typed in 36117e9e1933055b207473b488595b2887bfcaea32eJim Miller * @return error message to show to user or null if password is OK 36217e9e1933055b207473b488595b2887bfcaea32eJim Miller */ 36317e9e1933055b207473b488595b2887bfcaea32eJim Miller private String validatePassword(String password) { 36417e9e1933055b207473b488595b2887bfcaea32eJim Miller if (password.length() < mPasswordMinLength) { 36517e9e1933055b207473b488595b2887bfcaea32eJim Miller return getString(mIsAlphaMode ? 36617e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_password_too_short 36717e9e1933055b207473b488595b2887bfcaea32eJim Miller : R.string.lockpassword_pin_too_short, mPasswordMinLength); 36800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 36917e9e1933055b207473b488595b2887bfcaea32eJim Miller if (password.length() > mPasswordMaxLength) { 37017e9e1933055b207473b488595b2887bfcaea32eJim Miller return getString(mIsAlphaMode ? 37117e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_password_too_long 3729afb14de3b8bbc8c3905926eb3765a65c414e414Jim Miller : R.string.lockpassword_pin_too_long, mPasswordMaxLength + 1); 37300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 37417e9e1933055b207473b488595b2887bfcaea32eJim Miller int letters = 0; 37517e9e1933055b207473b488595b2887bfcaea32eJim Miller int numbers = 0; 37617e9e1933055b207473b488595b2887bfcaea32eJim Miller int lowercase = 0; 37717e9e1933055b207473b488595b2887bfcaea32eJim Miller int symbols = 0; 37817e9e1933055b207473b488595b2887bfcaea32eJim Miller int uppercase = 0; 37917e9e1933055b207473b488595b2887bfcaea32eJim Miller int nonletter = 0; 38017e9e1933055b207473b488595b2887bfcaea32eJim Miller for (int i = 0; i < password.length(); i++) { 38117e9e1933055b207473b488595b2887bfcaea32eJim Miller char c = password.charAt(i); 3827e7912de4fb44481ded8e17d5ac1d7a1c9a0d184Nick Kralevich // allow non control Latin-1 characters only 3837e7912de4fb44481ded8e17d5ac1d7a1c9a0d184Nick Kralevich if (c < 32 || c > 127) { 38417e9e1933055b207473b488595b2887bfcaea32eJim Miller return getString(R.string.lockpassword_illegal_character); 38517e9e1933055b207473b488595b2887bfcaea32eJim Miller } 38617e9e1933055b207473b488595b2887bfcaea32eJim Miller if (c >= '0' && c <= '9') { 38717e9e1933055b207473b488595b2887bfcaea32eJim Miller numbers++; 38817e9e1933055b207473b488595b2887bfcaea32eJim Miller nonletter++; 38917e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (c >= 'A' && c <= 'Z') { 39017e9e1933055b207473b488595b2887bfcaea32eJim Miller letters++; 39117e9e1933055b207473b488595b2887bfcaea32eJim Miller uppercase++; 39217e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (c >= 'a' && c <= 'z') { 39317e9e1933055b207473b488595b2887bfcaea32eJim Miller letters++; 39417e9e1933055b207473b488595b2887bfcaea32eJim Miller lowercase++; 39517e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 39617e9e1933055b207473b488595b2887bfcaea32eJim Miller symbols++; 39717e9e1933055b207473b488595b2887bfcaea32eJim Miller nonletter++; 39817e9e1933055b207473b488595b2887bfcaea32eJim Miller } 39957fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev } 40017e9e1933055b207473b488595b2887bfcaea32eJim Miller if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC == mRequestedQuality 4018fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot || DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX == mRequestedQuality) { 4028fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot if (letters > 0 || symbols > 0) { 4038fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot // This shouldn't be possible unless user finds some way to bring up 4048fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot // soft keyboard 4058fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot return getString(R.string.lockpassword_pin_contains_non_digits); 4068fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot } 4078fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot // Check for repeated characters or sequences (e.g. '1234', '0000', '2468') 4088fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot final int sequence = LockPatternUtils.maxLengthSequence(password); 4098fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot if (DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX == mRequestedQuality 4108fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot && sequence > LockPatternUtils.MAX_ALLOWED_SEQUENCE) { 4118fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot return getString(R.string.lockpassword_pin_no_sequential_digits); 4128fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot } 41317e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mRequestedQuality) { 41417e9e1933055b207473b488595b2887bfcaea32eJim Miller if (letters < mPasswordMinLetters) { 41517e9e1933055b207473b488595b2887bfcaea32eJim Miller return String.format(getResources().getQuantityString( 41617e9e1933055b207473b488595b2887bfcaea32eJim Miller R.plurals.lockpassword_password_requires_letters, mPasswordMinLetters), 41717e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinLetters); 41817e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (numbers < mPasswordMinNumeric) { 41917e9e1933055b207473b488595b2887bfcaea32eJim Miller return String.format(getResources().getQuantityString( 42017e9e1933055b207473b488595b2887bfcaea32eJim Miller R.plurals.lockpassword_password_requires_numeric, mPasswordMinNumeric), 42117e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinNumeric); 42217e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (lowercase < mPasswordMinLowerCase) { 42317e9e1933055b207473b488595b2887bfcaea32eJim Miller return String.format(getResources().getQuantityString( 42417e9e1933055b207473b488595b2887bfcaea32eJim Miller R.plurals.lockpassword_password_requires_lowercase, mPasswordMinLowerCase), 42517e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinLowerCase); 42617e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (uppercase < mPasswordMinUpperCase) { 42717e9e1933055b207473b488595b2887bfcaea32eJim Miller return String.format(getResources().getQuantityString( 42817e9e1933055b207473b488595b2887bfcaea32eJim Miller R.plurals.lockpassword_password_requires_uppercase, mPasswordMinUpperCase), 42917e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinUpperCase); 43017e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (symbols < mPasswordMinSymbols) { 43117e9e1933055b207473b488595b2887bfcaea32eJim Miller return String.format(getResources().getQuantityString( 43217e9e1933055b207473b488595b2887bfcaea32eJim Miller R.plurals.lockpassword_password_requires_symbols, mPasswordMinSymbols), 43317e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinSymbols); 43417e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (nonletter < mPasswordMinNonLetter) { 43517e9e1933055b207473b488595b2887bfcaea32eJim Miller return String.format(getResources().getQuantityString( 43617e9e1933055b207473b488595b2887bfcaea32eJim Miller R.plurals.lockpassword_password_requires_nonletter, mPasswordMinNonLetter), 43717e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordMinNonLetter); 43817e9e1933055b207473b488595b2887bfcaea32eJim Miller } 43917e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 44017e9e1933055b207473b488595b2887bfcaea32eJim Miller final boolean alphabetic = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC 44117e9e1933055b207473b488595b2887bfcaea32eJim Miller == mRequestedQuality; 44217e9e1933055b207473b488595b2887bfcaea32eJim Miller final boolean alphanumeric = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC 44317e9e1933055b207473b488595b2887bfcaea32eJim Miller == mRequestedQuality; 44417e9e1933055b207473b488595b2887bfcaea32eJim Miller if ((alphabetic || alphanumeric) && letters == 0) { 44517e9e1933055b207473b488595b2887bfcaea32eJim Miller return getString(R.string.lockpassword_password_requires_alpha); 44617e9e1933055b207473b488595b2887bfcaea32eJim Miller } 44717e9e1933055b207473b488595b2887bfcaea32eJim Miller if (alphanumeric && numbers == 0) { 44817e9e1933055b207473b488595b2887bfcaea32eJim Miller return getString(R.string.lockpassword_password_requires_digit); 44917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 450af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Miller } 45117e9e1933055b207473b488595b2887bfcaea32eJim Miller if(mLockPatternUtils.checkPasswordHistory(password)) { 45217e9e1933055b207473b488595b2887bfcaea32eJim Miller return getString(mIsAlphaMode ? R.string.lockpassword_password_recently_used 45317e9e1933055b207473b488595b2887bfcaea32eJim Miller : R.string.lockpassword_pin_recently_used); 454af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Miller } 4558fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot 45617e9e1933055b207473b488595b2887bfcaea32eJim Miller return null; 457122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 45800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 459af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam public void handleNext() { 4606d5c75f6cd928befb348fa283e53edc10716f151Adrian Roos if (mDone) return; 4616d5c75f6cd928befb348fa283e53edc10716f151Adrian Roos 46217e9e1933055b207473b488595b2887bfcaea32eJim Miller final String pin = mPasswordEntry.getText().toString(); 46317e9e1933055b207473b488595b2887bfcaea32eJim Miller if (TextUtils.isEmpty(pin)) { 46417e9e1933055b207473b488595b2887bfcaea32eJim Miller return; 465122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 46617e9e1933055b207473b488595b2887bfcaea32eJim Miller String errorMsg = null; 46717e9e1933055b207473b488595b2887bfcaea32eJim Miller if (mUiStage == Stage.Introduction) { 46817e9e1933055b207473b488595b2887bfcaea32eJim Miller errorMsg = validatePassword(pin); 46917e9e1933055b207473b488595b2887bfcaea32eJim Miller if (errorMsg == null) { 47017e9e1933055b207473b488595b2887bfcaea32eJim Miller mFirstPin = pin; 47117e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry.setText(""); 472eef72c39ae83697b1beaa148ec56aced67382fecalanv updateStage(Stage.NeedToConfirm); 47317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 47417e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (mUiStage == Stage.NeedToConfirm) { 47517e9e1933055b207473b488595b2887bfcaea32eJim Miller if (mFirstPin.equals(pin)) { 47690d6c568cf24178669254964af343f729639b31dAdrian Roos boolean wasSecureBefore = mLockPatternUtils.isSecure(); 4770698a216311acd9ab52224602d1a75c08bf89f04Jim Miller final boolean required = getActivity().getIntent().getBooleanExtra( 4780698a216311acd9ab52224602d1a75c08bf89f04Jim Miller EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); 4790698a216311acd9ab52224602d1a75c08bf89f04Jim Miller mLockPatternUtils.setCredentialRequiredToDecrypt(required); 480a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mLockPatternUtils.saveLockPassword(pin, mCurrentPassword, mRequestedQuality); 4816609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales 4826609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales if (mHasChallenge) { 4836609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales Intent intent = new Intent(); 4846609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales byte[] token = mLockPatternUtils.verifyPassword(pin, mChallenge); 4856609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); 4866609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales getActivity().setResult(RESULT_FINISHED, intent); 4876609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales } else { 4886609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales getActivity().setResult(RESULT_FINISHED); 4896609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales } 49017e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().finish(); 4916d5c75f6cd928befb348fa283e53edc10716f151Adrian Roos mDone = true; 49290d6c568cf24178669254964af343f729639b31dAdrian Roos if (!wasSecureBefore) { 493ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam startActivity(getRedactionInterstitialIntent(getActivity())); 49490d6c568cf24178669254964af343f729639b31dAdrian Roos } 49517e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 49617e9e1933055b207473b488595b2887bfcaea32eJim Miller CharSequence tmp = mPasswordEntry.getText(); 49717e9e1933055b207473b488595b2887bfcaea32eJim Miller if (tmp != null) { 49817e9e1933055b207473b488595b2887bfcaea32eJim Miller Selection.setSelection((Spannable) tmp, 0, tmp.length()); 49917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 500eef72c39ae83697b1beaa148ec56aced67382fecalanv updateStage(Stage.ConfirmWrong); 501122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 502122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 50317e9e1933055b207473b488595b2887bfcaea32eJim Miller if (errorMsg != null) { 50417e9e1933055b207473b488595b2887bfcaea32eJim Miller showError(errorMsg, mUiStage); 50517e9e1933055b207473b488595b2887bfcaea32eJim Miller } 506122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 507122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 508af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam protected void setNextEnabled(boolean enabled) { 509af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam mNextButton.setEnabled(enabled); 510af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam } 511af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam 512af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam protected void setNextText(int text) { 513af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam mNextButton.setText(text); 514af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam } 515af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam 51617e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onClick(View v) { 51717e9e1933055b207473b488595b2887bfcaea32eJim Miller switch (v.getId()) { 51817e9e1933055b207473b488595b2887bfcaea32eJim Miller case R.id.next_button: 51917e9e1933055b207473b488595b2887bfcaea32eJim Miller handleNext(); 52017e9e1933055b207473b488595b2887bfcaea32eJim Miller break; 52100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 52217e9e1933055b207473b488595b2887bfcaea32eJim Miller case R.id.cancel_button: 52317e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().finish(); 52417e9e1933055b207473b488595b2887bfcaea32eJim Miller break; 52517e9e1933055b207473b488595b2887bfcaea32eJim Miller } 52600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 52700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 52817e9e1933055b207473b488595b2887bfcaea32eJim Miller private void showError(String msg, final Stage next) { 52917e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText.setText(msg); 530eef72c39ae83697b1beaa148ec56aced67382fecalanv mHeaderText.announceForAccessibility(mHeaderText.getText()); 531552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani Message mesg = mHandler.obtainMessage(MSG_SHOW_ERROR, next); 532552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani mHandler.removeMessages(MSG_SHOW_ERROR); 533552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani mHandler.sendMessageDelayed(mesg, ERROR_MESSAGE_TIMEOUT); 53417e9e1933055b207473b488595b2887bfcaea32eJim Miller } 535122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 53617e9e1933055b207473b488595b2887bfcaea32eJim Miller public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 53774b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller // Check if this was the result of hitting the enter or "done" key 53874b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller if (actionId == EditorInfo.IME_NULL 53974b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller || actionId == EditorInfo.IME_ACTION_DONE 54074b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller || actionId == EditorInfo.IME_ACTION_NEXT) { 54117e9e1933055b207473b488595b2887bfcaea32eJim Miller handleNext(); 54217e9e1933055b207473b488595b2887bfcaea32eJim Miller return true; 54317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 54417e9e1933055b207473b488595b2887bfcaea32eJim Miller return false; 545122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 546122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 54717e9e1933055b207473b488595b2887bfcaea32eJim Miller /** 54817e9e1933055b207473b488595b2887bfcaea32eJim Miller * Update the hint based on current Stage and length of password entry 54917e9e1933055b207473b488595b2887bfcaea32eJim Miller */ 55017e9e1933055b207473b488595b2887bfcaea32eJim Miller private void updateUi() { 55117e9e1933055b207473b488595b2887bfcaea32eJim Miller String password = mPasswordEntry.getText().toString(); 55217e9e1933055b207473b488595b2887bfcaea32eJim Miller final int length = password.length(); 55317e9e1933055b207473b488595b2887bfcaea32eJim Miller if (mUiStage == Stage.Introduction && length > 0) { 55417e9e1933055b207473b488595b2887bfcaea32eJim Miller if (length < mPasswordMinLength) { 55517e9e1933055b207473b488595b2887bfcaea32eJim Miller String msg = getString(mIsAlphaMode ? R.string.lockpassword_password_too_short 55617e9e1933055b207473b488595b2887bfcaea32eJim Miller : R.string.lockpassword_pin_too_short, mPasswordMinLength); 55717e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText.setText(msg); 558af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam setNextEnabled(false); 559af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Miller } else { 56017e9e1933055b207473b488595b2887bfcaea32eJim Miller String error = validatePassword(password); 56117e9e1933055b207473b488595b2887bfcaea32eJim Miller if (error != null) { 56217e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText.setText(error); 563af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam setNextEnabled(false); 56417e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 56517e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText.setText(R.string.lockpassword_press_continue); 566af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam setNextEnabled(true); 56717e9e1933055b207473b488595b2887bfcaea32eJim Miller } 568af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Miller } 56917e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 57017e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText.setText(mIsAlphaMode ? mUiStage.alphaHint : mUiStage.numericHint); 571af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam setNextEnabled(length > 0); 572122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 573af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam setNextText(mUiStage.buttonText); 574122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 575122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 57617e9e1933055b207473b488595b2887bfcaea32eJim Miller public void afterTextChanged(Editable s) { 57717e9e1933055b207473b488595b2887bfcaea32eJim Miller // Changing the text while error displayed resets to NeedToConfirm state 57817e9e1933055b207473b488595b2887bfcaea32eJim Miller if (mUiStage == Stage.ConfirmWrong) { 57917e9e1933055b207473b488595b2887bfcaea32eJim Miller mUiStage = Stage.NeedToConfirm; 58017e9e1933055b207473b488595b2887bfcaea32eJim Miller } 58117e9e1933055b207473b488595b2887bfcaea32eJim Miller updateUi(); 582122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 583122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 58417e9e1933055b207473b488595b2887bfcaea32eJim Miller public void beforeTextChanged(CharSequence s, int start, int count, int after) { 585122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 58617e9e1933055b207473b488595b2887bfcaea32eJim Miller } 587122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 58817e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onTextChanged(CharSequence s, int start, int before, int count) { 589122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 59017e9e1933055b207473b488595b2887bfcaea32eJim Miller } 591122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 59200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller} 593