ChooseLockPassword.java revision 2eb170cd6ff43db01dc0ff3c1fcac5ebba4489de
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 172eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lampackage com.android.settings.password; 1800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 19c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lamimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; 20c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lamimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; 21c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lamimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; 22c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lamimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; 23c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lamimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; 24c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lam 2500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.app.Activity; 2617e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.app.Fragment; 27af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Millerimport android.app.admin.DevicePolicyManager; 2827ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scullimport android.app.admin.PasswordMetrics; 290698a216311acd9ab52224602d1a75c08bf89f04Jim Millerimport android.content.Context; 3000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.content.Intent; 3100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.os.Bundle; 329ba765b875ebeb66d8a870a29a00fe53e9da306dTony Makimport android.os.Handler; 339ba765b875ebeb66d8a870a29a00fe53e9da306dTony Makimport android.os.Message; 340bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Makimport android.support.v7.widget.LinearLayoutManager; 350bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Makimport android.support.v7.widget.RecyclerView; 3600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.text.Editable; 372e28acedc623527aa5e84ba66635700d6547569aJim Millerimport android.text.InputType; 38122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.text.Selection; 39122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.text.Spannable; 4000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.text.TextUtils; 41122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.text.TextWatcher; 4291e6c499ca8f33cc093fed4277d2b48ab780b309Andres Moralesimport android.util.Log; 43122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.view.KeyEvent; 4417e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.LayoutInflater; 4500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.view.View; 4600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.view.View.OnClickListener; 4739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.view.ViewGroup; 48c41e408aea1bf2f28160265cdadd7662e626d228Maurice Lamimport android.view.inputmethod.EditorInfo; 4900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.widget.Button; 500bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Makimport android.widget.EditText; 51d189ac52a4e49291b729d817fc903116abc086d0Maurice Lamimport android.widget.LinearLayout; 5200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Millerimport android.widget.TextView; 53122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Millerimport android.widget.TextView.OnEditorActionListener; 5400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 55265d3c2a0c36251bf8a9f571d7239b6dd404d942Tamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent; 5639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternUtils; 5739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternUtils.RequestThrottledException; 5839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.TextViewInputDisabler; 592eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.EncryptionInterstitial; 602eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.R; 612eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.SettingsActivity; 622eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.Utils; 632d0b3447360666847c483e6ce2521846c66c25c1Fan Zhangimport com.android.settings.core.InstrumentedPreferenceFragment; 6439b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.settings.notification.RedactionInterstitial; 65d189ac52a4e49291b729d817fc903116abc086d0Maurice Lamimport com.android.setupwizardlib.GlifLayout; 6639b467482d1bf256a111c757e9b7621c6f523271Jason Monk 670bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Makimport java.util.ArrayList; 680bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Makimport java.util.List; 690bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 70263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Megliopublic class ChooseLockPassword extends SettingsActivity { 7100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller public static final String PASSWORD_MIN_KEY = "lockscreen.password_min"; 7200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller public static final String PASSWORD_MAX_KEY = "lockscreen.password_max"; 7357fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_LETTERS_KEY = "lockscreen.password_min_letters"; 7457fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_LOWERCASE_KEY = "lockscreen.password_min_lowercase"; 7557fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_UPPERCASE_KEY = "lockscreen.password_min_uppercase"; 7657fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_NUMERIC_KEY = "lockscreen.password_min_numeric"; 7757fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev public static final String PASSWORD_MIN_SYMBOLS_KEY = "lockscreen.password_min_symbols"; 782df65e4facac659314c2440d0af6316924166e2bKonstantin Lopyrev public static final String PASSWORD_MIN_NONLETTER_KEY = "lockscreen.password_min_nonletter"; 7900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 8091e6c499ca8f33cc093fed4277d2b48ab780b309Andres Morales private static final String TAG = "ChooseLockPassword"; 8191e6c499ca8f33cc093fed4277d2b48ab780b309Andres Morales 8217e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 8317e9e1933055b207473b488595b2887bfcaea32eJim Miller public Intent getIntent() { 8417e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent modIntent = new Intent(super.getIntent()); 856b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName()); 8617e9e1933055b207473b488595b2887bfcaea32eJim Miller return modIntent; 8717e9e1933055b207473b488595b2887bfcaea32eJim Miller } 88122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 892eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public static class IntentBuilder { 902eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 912eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam private final Intent mIntent; 922eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 932eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public IntentBuilder(Context context) { 942eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent = new Intent(context, ChooseLockPassword.class); 952eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false); 962eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false); 972eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 982eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 992eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public IntentBuilder setPasswordQuality(int quality) { 1002eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, quality); 1012eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam return this; 1022eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 1032eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 1042eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public IntentBuilder setPasswordLengthRange(int min, int max) { 1052eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(PASSWORD_MIN_KEY, min); 1062eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(PASSWORD_MAX_KEY, max); 1072eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam return this; 1082eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 1092eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 1102eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public IntentBuilder setUserId(int userId) { 1112eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(Intent.EXTRA_USER_ID, userId); 1122eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam return this; 1132eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 1142eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 1152eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public IntentBuilder setChallenge(long challenge) { 1162eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); 1172eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); 1182eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam return this; 1192eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 1202eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 1212eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public IntentBuilder setPassword(String password) { 1222eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); 1232eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password); 1242eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam return this; 1252eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 1262eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam 1272eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam public Intent build() { 1282eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam return mIntent; 1292eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam } 130fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri } 131fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri 13217e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 133a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani protected boolean isValidFragment(String fragmentName) { 134a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani if (ChooseLockPasswordFragment.class.getName().equals(fragmentName)) return true; 135a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani return false; 136a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani } 137a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani 1386b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam /* package */ Class<? extends Fragment> getFragmentClass() { 1396b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam return ChooseLockPasswordFragment.class; 1406b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam } 1416b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam 142a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani @Override 14371fde52ae36f134e93835bee53bc4bfe5481bba0Udam Saini protected void onCreate(Bundle savedInstanceState) { 14417e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onCreate(savedInstanceState); 1457da8cae44b622518fbffd6d265f291c39e9fc722Jim Miller CharSequence msg = getText(R.string.lockpassword_choose_your_password_header); 146263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio setTitle(msg); 147d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent); 148d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam layout.setFitsSystemWindows(false); 14917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 150122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 1512d0b3447360666847c483e6ce2521846c66c25c1Fan Zhang public static class ChooseLockPasswordFragment extends InstrumentedPreferenceFragment 1520bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak implements OnClickListener, OnEditorActionListener, TextWatcher, 1533e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia SaveAndFinishWorker.Listener { 15417e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final String KEY_FIRST_PIN = "first_pin"; 15517e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final String KEY_UI_STAGE = "ui_stage"; 156a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales private static final String KEY_CURRENT_PASSWORD = "current_password"; 1573e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker"; 158a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales 159a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales private String mCurrentPassword; 160cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence private String mChosenPassword; 1616609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales private boolean mHasChallenge; 1626609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales private long mChallenge; 1630bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private EditText mPasswordEntry; 164f2c2c19339b5d821cb6196911cee04dc9ac647adXiyuan Xia private TextViewInputDisabler mPasswordEntryInputDisabler; 1654c00a611835e2257502ddcdd26b4e827c5b64f80Adrian Roos private int mPasswordMinLength = LockPatternUtils.MIN_LOCK_PASSWORD_SIZE; 16617e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMaxLength = 16; 16717e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinLetters = 0; 16817e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinUpperCase = 0; 16917e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinLowerCase = 0; 17017e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinSymbols = 0; 17117e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinNumeric = 0; 17217e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mPasswordMinNonLetter = 0; 1739ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak private int mPasswordMinLengthToFulfillAllPolicies = 0; 1740bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private int mUserId; 1750bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private boolean mHideDrawer = false; 1760bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak /** 1770bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * Password requirements that we need to verify. 1780bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak */ 1790bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private int[] mPasswordRequirements; 1800bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 18117e9e1933055b207473b488595b2887bfcaea32eJim Miller private LockPatternUtils mLockPatternUtils; 1823e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia private SaveAndFinishWorker mSaveAndFinishWorker; 18317e9e1933055b207473b488595b2887bfcaea32eJim Miller private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; 18417e9e1933055b207473b488595b2887bfcaea32eJim Miller private ChooseLockSettingsHelper mChooseLockSettingsHelper; 18517e9e1933055b207473b488595b2887bfcaea32eJim Miller private Stage mUiStage = Stage.Introduction; 1860bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private PasswordRequirementAdapter mPasswordRequirementAdapter; 1871f8fb0f8ce1e82266a3a12b3d31b9062cff3fc44Paul Lawrence 18817e9e1933055b207473b488595b2887bfcaea32eJim Miller private TextView mHeaderText; 18917e9e1933055b207473b488595b2887bfcaea32eJim Miller private String mFirstPin; 1900bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private RecyclerView mPasswordRestrictionView; 19117e9e1933055b207473b488595b2887bfcaea32eJim Miller private boolean mIsAlphaMode; 19217e9e1933055b207473b488595b2887bfcaea32eJim Miller private Button mCancelButton; 19317e9e1933055b207473b488595b2887bfcaea32eJim Miller private Button mNextButton; 1940bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 1959ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak private TextChangedHandler mTextChangedHandler; 1969ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak 19717e9e1933055b207473b488595b2887bfcaea32eJim Miller private static final int CONFIRM_EXISTING_REQUEST = 58; 19817e9e1933055b207473b488595b2887bfcaea32eJim Miller static final int RESULT_FINISHED = RESULT_FIRST_USER; 199552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani 2000bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int MIN_LETTER_IN_PASSWORD = 0; 2010bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int MIN_UPPER_LETTERS_IN_PASSWORD = 1; 2020bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int MIN_LOWER_LETTERS_IN_PASSWORD = 2; 2030bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int MIN_SYMBOLS_IN_PASSWORD = 3; 2040bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int MIN_NUMBER_IN_PASSWORD = 4; 2050bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int MIN_NON_LETTER_IN_PASSWORD = 5; 2060bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 2070bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Error code returned from {@link #validatePassword(String)}. 2080bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NO_ERROR = 0; 2090bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int CONTAIN_INVALID_CHARACTERS = 1 << 0; 2100bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int TOO_SHORT = 1 << 1; 2110bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int TOO_LONG = 1 << 2; 2120bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int CONTAIN_NON_DIGITS = 1 << 3; 2130bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int CONTAIN_SEQUENTIAL_DIGITS = 1 << 4; 2140bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int RECENTLY_USED = 1 << 5; 2150bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NOT_ENOUGH_LETTER = 1 << 6; 2160bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NOT_ENOUGH_UPPER_CASE = 1 << 7; 2170bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NOT_ENOUGH_LOWER_CASE = 1 << 8; 2180bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NOT_ENOUGH_DIGITS = 1 << 9; 2190bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NOT_ENOUGH_SYMBOLS = 1 << 10; 2200bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private static final int NOT_ENOUGH_NON_LETTER = 1 << 11; 22100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 22200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller /** 22317e9e1933055b207473b488595b2887bfcaea32eJim Miller * Keep track internally of where the user is in choosing a pattern. 22400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller */ 22517e9e1933055b207473b488595b2887bfcaea32eJim Miller protected enum Stage { 22617e9e1933055b207473b488595b2887bfcaea32eJim Miller 22717e9e1933055b207473b488595b2887bfcaea32eJim Miller Introduction(R.string.lockpassword_choose_your_password_header, 22817e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_choose_your_pin_header, 22917e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_continue_label), 23017e9e1933055b207473b488595b2887bfcaea32eJim Miller 23117e9e1933055b207473b488595b2887bfcaea32eJim Miller NeedToConfirm(R.string.lockpassword_confirm_your_password_header, 23217e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_confirm_your_pin_header, 23317e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_ok_label), 23417e9e1933055b207473b488595b2887bfcaea32eJim Miller 23517e9e1933055b207473b488595b2887bfcaea32eJim Miller ConfirmWrong(R.string.lockpassword_confirm_passwords_dont_match, 23617e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_confirm_pins_dont_match, 23717e9e1933055b207473b488595b2887bfcaea32eJim Miller R.string.lockpassword_continue_label); 23817e9e1933055b207473b488595b2887bfcaea32eJim Miller 23917e9e1933055b207473b488595b2887bfcaea32eJim Miller Stage(int hintInAlpha, int hintInNumeric, int nextButtonText) { 24017e9e1933055b207473b488595b2887bfcaea32eJim Miller this.alphaHint = hintInAlpha; 24117e9e1933055b207473b488595b2887bfcaea32eJim Miller this.numericHint = hintInNumeric; 24217e9e1933055b207473b488595b2887bfcaea32eJim Miller this.buttonText = nextButtonText; 24317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 24417e9e1933055b207473b488595b2887bfcaea32eJim Miller 24517e9e1933055b207473b488595b2887bfcaea32eJim Miller public final int alphaHint; 24617e9e1933055b207473b488595b2887bfcaea32eJim Miller public final int numericHint; 24717e9e1933055b207473b488595b2887bfcaea32eJim Miller public final int buttonText; 24800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 24900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 25017e9e1933055b207473b488595b2887bfcaea32eJim Miller // required constructor for fragments 25117e9e1933055b207473b488595b2887bfcaea32eJim Miller public ChooseLockPasswordFragment() { 25200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 25300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 25400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 25517e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 25617e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onCreate(Bundle savedInstanceState) { 25717e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onCreate(savedInstanceState); 25817e9e1933055b207473b488595b2887bfcaea32eJim Miller mLockPatternUtils = new LockPatternUtils(getActivity()); 25917e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent intent = getActivity().getIntent(); 26066026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani if (!(getActivity() instanceof ChooseLockPassword)) { 26166026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani throw new SecurityException("Fragment contained in wrong activity"); 26266026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani } 263fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri // Only take this argument into account if it belongs to the current profile. 264194300dff340d67255d12762ffb376b7ba201c87Benjamin Franz mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras()); 2650bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak processPasswordRequirements(intent); 26617e9e1933055b207473b488595b2887bfcaea32eJim Miller mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity()); 26792779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false); 26862775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos 26962775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos if (intent.getBooleanExtra( 27062775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) { 27162775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos SaveAndFinishWorker w = new SaveAndFinishWorker(); 27262775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos final boolean required = getActivity().getIntent().getBooleanExtra( 27362775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); 27462775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos String current = intent.getStringExtra( 27562775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 27662775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos w.setBlocking(true); 27762775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos w.setListener(this); 27862775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos w.start(mChooseLockSettingsHelper.utils(), required, 27962775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos false, 0, current, current, mRequestedQuality, mUserId); 28062775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos } 2819ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mTextChangedHandler = new TextChangedHandler(); 28217e9e1933055b207473b488595b2887bfcaea32eJim Miller } 2832f9dbcb49174d85218dd18e3b2097d3b9fc789c7Jim Miller 28417e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 28517e9e1933055b207473b488595b2887bfcaea32eJim Miller public View onCreateView(LayoutInflater inflater, ViewGroup container, 28617e9e1933055b207473b488595b2887bfcaea32eJim Miller Bundle savedInstanceState) { 28744f2736f5453ec3bf1fffd3471ecda24da57a094Maurice Lam return inflater.inflate(R.layout.choose_lock_password, container, false); 2886b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam } 28917e9e1933055b207473b488595b2887bfcaea32eJim Miller 2906b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam @Override 2916b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam public void onViewCreated(View view, Bundle savedInstanceState) { 2926b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam super.onViewCreated(view, savedInstanceState); 29317e9e1933055b207473b488595b2887bfcaea32eJim Miller 29417e9e1933055b207473b488595b2887bfcaea32eJim Miller mCancelButton = (Button) view.findViewById(R.id.cancel_button); 29517e9e1933055b207473b488595b2887bfcaea32eJim Miller mCancelButton.setOnClickListener(this); 29617e9e1933055b207473b488595b2887bfcaea32eJim Miller mNextButton = (Button) view.findViewById(R.id.next_button); 29717e9e1933055b207473b488595b2887bfcaea32eJim Miller mNextButton.setOnClickListener(this); 29817e9e1933055b207473b488595b2887bfcaea32eJim Miller 29917e9e1933055b207473b488595b2887bfcaea32eJim Miller mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mRequestedQuality 30017e9e1933055b207473b488595b2887bfcaea32eJim Miller || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mRequestedQuality 30117e9e1933055b207473b488595b2887bfcaea32eJim Miller || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mRequestedQuality; 3020bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 3030bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak setupPasswordRequirementsView(view); 3040bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 3050bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRestrictionView.setLayoutManager(new LinearLayoutManager(getActivity())); 3060bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordEntry = (EditText) view.findViewById(R.id.password_entry); 30717e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry.setOnEditorActionListener(this); 30817e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry.addTextChangedListener(this); 3099c26c9dba6998fda4b3af27e315220b8bec6e0c5Tony Mak mPasswordEntry.requestFocus(); 310f2c2c19339b5d821cb6196911cee04dc9ac647adXiyuan Xia mPasswordEntryInputDisabler = new TextViewInputDisabler(mPasswordEntry); 31117e9e1933055b207473b488595b2887bfcaea32eJim Miller 3129757e30dfa0ab691c4c15366568367e166071a7dJim Miller final Activity activity = getActivity(); 31317e9e1933055b207473b488595b2887bfcaea32eJim Miller mHeaderText = (TextView) view.findViewById(R.id.headerText); 31417e9e1933055b207473b488595b2887bfcaea32eJim Miller 3152e28acedc623527aa5e84ba66635700d6547569aJim Miller int currentType = mPasswordEntry.getInputType(); 3162e28acedc623527aa5e84ba66635700d6547569aJim Miller mPasswordEntry.setInputType(mIsAlphaMode ? currentType 3173b46f49d2a5abb47c1bdf239f855d2063b60595eJim Miller : (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD)); 3182e28acedc623527aa5e84ba66635700d6547569aJim Miller 31917e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent intent = getActivity().getIntent(); 3206609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales final boolean confirmCredentials = intent.getBooleanExtra( 3216609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales ChooseLockGeneric.CONFIRM_CREDENTIALS, true); 322a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mCurrentPassword = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 3236609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales mHasChallenge = intent.getBooleanExtra( 3246609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); 3256609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); 32617e9e1933055b207473b488595b2887bfcaea32eJim Miller if (savedInstanceState == null) { 32717e9e1933055b207473b488595b2887bfcaea32eJim Miller updateStage(Stage.Introduction); 32817e9e1933055b207473b488595b2887bfcaea32eJim Miller if (confirmCredentials) { 32917e9e1933055b207473b488595b2887bfcaea32eJim Miller mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, 330fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri getString(R.string.unlock_set_unlock_launch_picker_title), true, 331fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri mUserId); 33217e9e1933055b207473b488595b2887bfcaea32eJim Miller } 33317e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 334a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales // restore from previous state 33517e9e1933055b207473b488595b2887bfcaea32eJim Miller mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN); 33617e9e1933055b207473b488595b2887bfcaea32eJim Miller final String state = savedInstanceState.getString(KEY_UI_STAGE); 33717e9e1933055b207473b488595b2887bfcaea32eJim Miller if (state != null) { 33817e9e1933055b207473b488595b2887bfcaea32eJim Miller mUiStage = Stage.valueOf(state); 33917e9e1933055b207473b488595b2887bfcaea32eJim Miller updateStage(mUiStage); 34017e9e1933055b207473b488595b2887bfcaea32eJim Miller } 341a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales 342a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales if (mCurrentPassword == null) { 343a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mCurrentPassword = savedInstanceState.getString(KEY_CURRENT_PASSWORD); 344a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales } 3453e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 3463e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia // Re-attach to the exiting worker if there is one. 3473e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mSaveAndFinishWorker = (SaveAndFinishWorker) getFragmentManager().findFragmentByTag( 3483e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia FRAGMENT_TAG_SAVE_AND_FINISH); 34917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 3500bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 351263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio if (activity instanceof SettingsActivity) { 352263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio final SettingsActivity sa = (SettingsActivity) activity; 353d75905991c5a1783ca27dc188c2d086f8f13ff94Jim Miller int id = mIsAlphaMode ? R.string.lockpassword_choose_your_password_header 354d75905991c5a1783ca27dc188c2d086f8f13ff94Jim Miller : R.string.lockpassword_choose_your_pin_header; 3559757e30dfa0ab691c4c15366568367e166071a7dJim Miller CharSequence title = getText(id); 356263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio sa.setTitle(title); 35744f2736f5453ec3bf1fffd3471ecda24da57a094Maurice Lam ((GlifLayout) view).setHeaderText(title); 3589757e30dfa0ab691c4c15366568367e166071a7dJim Miller } 35917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 360122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 3610bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private void setupPasswordRequirementsView(View view) { 3620bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Construct passwordRequirements and requirementDescriptions. 3630bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak List<Integer> passwordRequirements = new ArrayList<>(); 3640bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak List<String> requirementDescriptions = new ArrayList<>(); 3650bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinUpperCase > 0) { 3660bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak passwordRequirements.add(MIN_UPPER_LETTERS_IN_PASSWORD); 3670bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak requirementDescriptions.add(getResources().getQuantityString( 3680bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_uppercase, mPasswordMinUpperCase, 3690bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinUpperCase)); 3700bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 3710bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinLowerCase > 0) { 3720bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak passwordRequirements.add(MIN_LOWER_LETTERS_IN_PASSWORD); 3730bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak requirementDescriptions.add(getResources().getQuantityString( 3740bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_lowercase, mPasswordMinLowerCase, 3750bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLowerCase)); 3760bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 3770bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinLetters > 0) { 3789ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak if (mPasswordMinLetters > mPasswordMinUpperCase + mPasswordMinLowerCase) { 3799ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak passwordRequirements.add(MIN_LETTER_IN_PASSWORD); 3809ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak requirementDescriptions.add(getResources().getQuantityString( 3819ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak R.plurals.lockpassword_password_requires_letters, mPasswordMinLetters, 3829ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mPasswordMinLetters)); 3839ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 3840bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 3850bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinNumeric > 0) { 3860bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak passwordRequirements.add(MIN_NUMBER_IN_PASSWORD); 3870bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak requirementDescriptions.add(getResources().getQuantityString( 3880bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_numeric, mPasswordMinNumeric, 3890bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNumeric)); 3900bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 3910bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinSymbols > 0) { 3920bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak passwordRequirements.add(MIN_SYMBOLS_IN_PASSWORD); 3930bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak requirementDescriptions.add(getResources().getQuantityString( 3940bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_symbols, mPasswordMinSymbols, 3950bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinSymbols)); 3960bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 3970bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinNonLetter > 0) { 3989ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak if (mPasswordMinNonLetter > mPasswordMinNumeric + mPasswordMinSymbols) { 3999ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak passwordRequirements.add(MIN_NON_LETTER_IN_PASSWORD); 4009ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak requirementDescriptions.add(getResources().getQuantityString( 4019ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak R.plurals.lockpassword_password_requires_nonletter, mPasswordMinNonLetter, 4029ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak 4039ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mPasswordMinNonLetter)); 4049ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 4050bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 4060bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Convert list to array. 4070bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRequirements = passwordRequirements.stream().mapToInt(i -> i).toArray(); 4080bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRestrictionView = 4090bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak (RecyclerView) view.findViewById(R.id.password_requirements_view); 4100bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRestrictionView.setLayoutManager(new LinearLayoutManager(getActivity())); 4110bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRequirementAdapter = new PasswordRequirementAdapter(); 4120bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRestrictionView.setAdapter(mPasswordRequirementAdapter); 4130bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 4140bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 41517e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 4166507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang public int getMetricsCategory() { 4179d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren return MetricsEvent.CHOOSE_LOCK_PASSWORD; 4188a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren } 4198a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren 4208a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren @Override 42117e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onResume() { 42217e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onResume(); 423122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller updateStage(mUiStage); 4243e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (mSaveAndFinishWorker != null) { 4253e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mSaveAndFinishWorker.setListener(this); 4263e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } else { 4279c26c9dba6998fda4b3af27e315220b8bec6e0c5Tony Mak mPasswordEntry.requestFocus(); 4283e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 429122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 430122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 43117e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 432552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani public void onPause() { 4333e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (mSaveAndFinishWorker != null) { 4343e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mSaveAndFinishWorker.setListener(null); 435bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia } 436552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani super.onPause(); 437552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani } 438552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani 439552bc61ae2aaf67fd2f19564ca2ced002e8675e6Amith Yamasani @Override 44017e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onSaveInstanceState(Bundle outState) { 44117e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onSaveInstanceState(outState); 44217e9e1933055b207473b488595b2887bfcaea32eJim Miller outState.putString(KEY_UI_STAGE, mUiStage.name()); 44317e9e1933055b207473b488595b2887bfcaea32eJim Miller outState.putString(KEY_FIRST_PIN, mFirstPin); 444a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales outState.putString(KEY_CURRENT_PASSWORD, mCurrentPassword); 44500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 44600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 44717e9e1933055b207473b488595b2887bfcaea32eJim Miller @Override 44817e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onActivityResult(int requestCode, int resultCode, 44917e9e1933055b207473b488595b2887bfcaea32eJim Miller Intent data) { 45017e9e1933055b207473b488595b2887bfcaea32eJim Miller super.onActivityResult(requestCode, resultCode, data); 45117e9e1933055b207473b488595b2887bfcaea32eJim Miller switch (requestCode) { 45217e9e1933055b207473b488595b2887bfcaea32eJim Miller case CONFIRM_EXISTING_REQUEST: 45317e9e1933055b207473b488595b2887bfcaea32eJim Miller if (resultCode != Activity.RESULT_OK) { 45417e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().setResult(RESULT_FINISHED); 45517e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().finish(); 456a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales } else { 457a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales mCurrentPassword = data.getStringExtra( 458a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 45917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 46017e9e1933055b207473b488595b2887bfcaea32eJim Miller break; 46117e9e1933055b207473b488595b2887bfcaea32eJim Miller } 46200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 46317e9e1933055b207473b488595b2887bfcaea32eJim Miller 464ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam protected Intent getRedactionInterstitialIntent(Context context) { 465f6077f4757183ae8b31af0928c895c806241b593Clara Bayarri return RedactionInterstitial.createStartIntent(context, mUserId); 466ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam } 467ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam 46817e9e1933055b207473b488595b2887bfcaea32eJim Miller protected void updateStage(Stage stage) { 469eef72c39ae83697b1beaa148ec56aced67382fecalanv final Stage previousStage = mUiStage; 47017e9e1933055b207473b488595b2887bfcaea32eJim Miller mUiStage = stage; 47117e9e1933055b207473b488595b2887bfcaea32eJim Miller updateUi(); 472eef72c39ae83697b1beaa148ec56aced67382fecalanv 473eef72c39ae83697b1beaa148ec56aced67382fecalanv // If the stage changed, announce the header for accessibility. This 474eef72c39ae83697b1beaa148ec56aced67382fecalanv // is a no-op when accessibility is disabled. 475eef72c39ae83697b1beaa148ec56aced67382fecalanv if (previousStage != stage) { 476eef72c39ae83697b1beaa148ec56aced67382fecalanv mHeaderText.announceForAccessibility(mHeaderText.getText()); 477eef72c39ae83697b1beaa148ec56aced67382fecalanv } 47800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 47917e9e1933055b207473b488595b2887bfcaea32eJim Miller 48017e9e1933055b207473b488595b2887bfcaea32eJim Miller /** 4810bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * Read the requirements from {@link DevicePolicyManager} and intent and aggregate them. 4820bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * 4830bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * @param intent the incoming intent 4840bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak */ 4850bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private void processPasswordRequirements(Intent intent) { 4860bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak final int dpmPasswordQuality = mLockPatternUtils.getRequestedPasswordQuality(mUserId); 4870bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mRequestedQuality = Math.max(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, 4880bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mRequestedQuality), dpmPasswordQuality); 4890bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLength = Math.max(Math.max( 4900bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak LockPatternUtils.MIN_LOCK_PASSWORD_SIZE, 4910bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak intent.getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength)), 4920bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mLockPatternUtils.getRequestedMinimumPasswordLength(mUserId)); 4930bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMaxLength = intent.getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength); 4940bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLetters = Math.max(intent.getIntExtra(PASSWORD_MIN_LETTERS_KEY, 4950bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLetters), mLockPatternUtils.getRequestedPasswordMinimumLetters( 4960bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mUserId)); 4970bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinUpperCase = Math.max(intent.getIntExtra(PASSWORD_MIN_UPPERCASE_KEY, 4980bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinUpperCase), mLockPatternUtils.getRequestedPasswordMinimumUpperCase( 4990bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mUserId)); 5000bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLowerCase = Math.max(intent.getIntExtra(PASSWORD_MIN_LOWERCASE_KEY, 5010bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLowerCase), mLockPatternUtils.getRequestedPasswordMinimumLowerCase( 5020bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mUserId)); 5030bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNumeric = Math.max(intent.getIntExtra(PASSWORD_MIN_NUMERIC_KEY, 5040bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNumeric), mLockPatternUtils.getRequestedPasswordMinimumNumeric( 5050bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mUserId)); 5060bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinSymbols = Math.max(intent.getIntExtra(PASSWORD_MIN_SYMBOLS_KEY, 5070bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinSymbols), mLockPatternUtils.getRequestedPasswordMinimumSymbols( 5080bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mUserId)); 5090bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNonLetter = Math.max(intent.getIntExtra(PASSWORD_MIN_NONLETTER_KEY, 5100bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNonLetter), mLockPatternUtils.getRequestedPasswordMinimumNonLetter( 5110bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mUserId)); 5120bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 5130bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Modify the value based on dpm policy. 5140bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak switch (dpmPasswordQuality) { 5150bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case PASSWORD_QUALITY_ALPHABETIC: 5160bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinLetters == 0) { 5170bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLetters = 1; 5180bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5190bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 5200bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case PASSWORD_QUALITY_ALPHANUMERIC: 5210bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinLetters == 0) { 5220bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLetters = 1; 5230bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5240bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mPasswordMinNumeric == 0) { 5250bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNumeric = 1; 5260bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5270bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 5280bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case PASSWORD_QUALITY_COMPLEX: 5290bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Reserve all the requirements. 5300bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 5310bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak default: 5320bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNumeric = 0; 5330bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLetters = 0; 5340bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinUpperCase = 0; 5350bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLowerCase = 0; 5360bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinSymbols = 0; 5370bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNonLetter = 0; 5380bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5399ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mPasswordMinLengthToFulfillAllPolicies = getMinLengthToFulfillAllPolicies(); 5400bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5410bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 5420bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak /** 5430bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * Validates PIN and returns the validation result. 5440bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * 54517e9e1933055b207473b488595b2887bfcaea32eJim Miller * @param password the raw password the user typed in 5460bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * @return the validation result. 54717e9e1933055b207473b488595b2887bfcaea32eJim Miller */ 5480bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private int validatePassword(String password) { 5490bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak int errorCode = NO_ERROR; 5500bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 55117e9e1933055b207473b488595b2887bfcaea32eJim Miller if (password.length() < mPasswordMinLength) { 5529ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak if (mPasswordMinLength > mPasswordMinLengthToFulfillAllPolicies) { 5539ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak errorCode |= TOO_SHORT; 5549ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 5550bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } else if (password.length() > mPasswordMaxLength) { 5560bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= TOO_LONG; 5570bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } else { 5580bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // The length requirements are fulfilled. 5590bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mRequestedQuality == PASSWORD_QUALITY_NUMERIC_COMPLEX) { 5600bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Check for repeated characters or sequences (e.g. '1234', '0000', '2468') 56127ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull final int sequence = PasswordMetrics.maxLengthSequence(password); 56227ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (sequence > PasswordMetrics.MAX_ALLOWED_SEQUENCE) { 5630bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= CONTAIN_SEQUENTIAL_DIGITS; 5640bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5650bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 5660bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Is the password recently used? 5670bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mLockPatternUtils.checkPasswordHistory(password, mUserId)) { 5680bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= RECENTLY_USED; 5690bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 57000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 5710bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 57227ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull // Allow non-control Latin-1 characters only. 57317e9e1933055b207473b488595b2887bfcaea32eJim Miller for (int i = 0; i < password.length(); i++) { 57417e9e1933055b207473b488595b2887bfcaea32eJim Miller char c = password.charAt(i); 5757e7912de4fb44481ded8e17d5ac1d7a1c9a0d184Nick Kralevich if (c < 32 || c > 127) { 5760bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= CONTAIN_INVALID_CHARACTERS; 57727ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull break; 57817e9e1933055b207473b488595b2887bfcaea32eJim Miller } 57957fbf694a53afb9c1924d81272179dceb3acfa4dKonstantin Lopyrev } 5800bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 58127ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); 58227ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull 5830bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Ensure no non-digits if we are requesting numbers. This shouldn't be possible unless 5840bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // user finds some way to bring up soft keyboard. 5850bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (mRequestedQuality == PASSWORD_QUALITY_NUMERIC 5860bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak || mRequestedQuality == PASSWORD_QUALITY_NUMERIC_COMPLEX) { 58727ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.letters > 0 || metrics.symbols > 0) { 5880bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= CONTAIN_NON_DIGITS; 58917e9e1933055b207473b488595b2887bfcaea32eJim Miller } 590af366a3ed66dcb3c3ecb1dd101e5d8869b518598Jim Miller } 5918fd852e7c2f488650095024aca9c51f8c7ddc3b3Nicolas Prevot 5920bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Check the requirements one by one. 5930bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak for (int i = 0; i < mPasswordRequirements.length; i++) { 5940bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak int passwordRestriction = mPasswordRequirements[i]; 5950bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak switch (passwordRestriction) { 5960bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case MIN_LETTER_IN_PASSWORD: 59727ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.letters < mPasswordMinLetters) { 5980bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= NOT_ENOUGH_LETTER; 5990bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6000bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 6010bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case MIN_UPPER_LETTERS_IN_PASSWORD: 60227ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.upperCase < mPasswordMinUpperCase) { 6030bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= NOT_ENOUGH_UPPER_CASE; 6040bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6050bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 6060bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case MIN_LOWER_LETTERS_IN_PASSWORD: 60727ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.lowerCase < mPasswordMinLowerCase) { 6080bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= NOT_ENOUGH_LOWER_CASE; 6090bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6100bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 6110bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case MIN_SYMBOLS_IN_PASSWORD: 61227ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.symbols < mPasswordMinSymbols) { 6130bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= NOT_ENOUGH_SYMBOLS; 6140bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6150bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 6160bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case MIN_NUMBER_IN_PASSWORD: 61727ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.numeric < mPasswordMinNumeric) { 6180bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= NOT_ENOUGH_DIGITS; 6190bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6200bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 6210bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak case MIN_NON_LETTER_IN_PASSWORD: 62227ca263b7f6cf64f6a789a052a0f737b18a9aef3Andrew Scull if (metrics.nonLetter < mPasswordMinNonLetter) { 6230bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak errorCode |= NOT_ENOUGH_NON_LETTER; 6240bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6250bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak break; 6260bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6270bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6280bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak return errorCode; 629122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 63000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 631cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence public void handleNext() { 6323e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (mSaveAndFinishWorker != null) return; 633cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence mChosenPassword = mPasswordEntry.getText().toString(); 634cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence if (TextUtils.isEmpty(mChosenPassword)) { 63517e9e1933055b207473b488595b2887bfcaea32eJim Miller return; 636122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 63717e9e1933055b207473b488595b2887bfcaea32eJim Miller if (mUiStage == Stage.Introduction) { 6380bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (validatePassword(mChosenPassword) == NO_ERROR) { 639cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence mFirstPin = mChosenPassword; 64017e9e1933055b207473b488595b2887bfcaea32eJim Miller mPasswordEntry.setText(""); 641eef72c39ae83697b1beaa148ec56aced67382fecalanv updateStage(Stage.NeedToConfirm); 64217e9e1933055b207473b488595b2887bfcaea32eJim Miller } 64317e9e1933055b207473b488595b2887bfcaea32eJim Miller } else if (mUiStage == Stage.NeedToConfirm) { 644cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence if (mFirstPin.equals(mChosenPassword)) { 6453e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia startSaveAndFinish(); 64617e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 64717e9e1933055b207473b488595b2887bfcaea32eJim Miller CharSequence tmp = mPasswordEntry.getText(); 64817e9e1933055b207473b488595b2887bfcaea32eJim Miller if (tmp != null) { 64917e9e1933055b207473b488595b2887bfcaea32eJim Miller Selection.setSelection((Spannable) tmp, 0, tmp.length()); 65017e9e1933055b207473b488595b2887bfcaea32eJim Miller } 651eef72c39ae83697b1beaa148ec56aced67382fecalanv updateStage(Stage.ConfirmWrong); 652122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 653122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 654122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 655122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 656af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam protected void setNextEnabled(boolean enabled) { 657af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam mNextButton.setEnabled(enabled); 658af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam } 659af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam 660af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam protected void setNextText(int text) { 661af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam mNextButton.setText(text); 662af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam } 663af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam 66417e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onClick(View v) { 66517e9e1933055b207473b488595b2887bfcaea32eJim Miller switch (v.getId()) { 66617e9e1933055b207473b488595b2887bfcaea32eJim Miller case R.id.next_button: 66717e9e1933055b207473b488595b2887bfcaea32eJim Miller handleNext(); 66817e9e1933055b207473b488595b2887bfcaea32eJim Miller break; 66900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 67017e9e1933055b207473b488595b2887bfcaea32eJim Miller case R.id.cancel_button: 67117e9e1933055b207473b488595b2887bfcaea32eJim Miller getActivity().finish(); 67217e9e1933055b207473b488595b2887bfcaea32eJim Miller break; 67317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 67400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller } 67500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller 67617e9e1933055b207473b488595b2887bfcaea32eJim Miller public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 67774b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller // Check if this was the result of hitting the enter or "done" key 67874b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller if (actionId == EditorInfo.IME_NULL 67974b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller || actionId == EditorInfo.IME_ACTION_DONE 68074b1e0a7330af195621ad0965748bee66c46f4b6Jim Miller || actionId == EditorInfo.IME_ACTION_NEXT) { 68117e9e1933055b207473b488595b2887bfcaea32eJim Miller handleNext(); 68217e9e1933055b207473b488595b2887bfcaea32eJim Miller return true; 68317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 68417e9e1933055b207473b488595b2887bfcaea32eJim Miller return false; 685122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 686122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 68717e9e1933055b207473b488595b2887bfcaea32eJim Miller /** 6880bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * @param errorCode error code returned from {@link #validatePassword(String)}. 6890bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak * @return an array of messages describing the error, important messages come first. 6900bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak */ 6910bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private String[] convertErrorCodeToMessages(int errorCode) { 6920bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak List<String> messages = new ArrayList<>(); 6930bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & CONTAIN_INVALID_CHARACTERS) > 0) { 6940bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getString(R.string.lockpassword_illegal_character)); 6950bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6960bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & CONTAIN_NON_DIGITS) > 0) { 6970bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getString(R.string.lockpassword_pin_contains_non_digits)); 6980bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 6990bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & NOT_ENOUGH_UPPER_CASE) > 0) { 7000bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getResources().getQuantityString( 7010bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_uppercase, mPasswordMinUpperCase, 7020bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinUpperCase)); 7030bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7040bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & NOT_ENOUGH_LOWER_CASE) > 0) { 7050bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getResources().getQuantityString( 7060bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_lowercase, mPasswordMinLowerCase, 7070bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinLowerCase)); 7080bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7099ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak if ((errorCode & NOT_ENOUGH_LETTER) > 0) { 7109ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak messages.add(getResources().getQuantityString( 7119ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak R.plurals.lockpassword_password_requires_letters, mPasswordMinLetters, 7129ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mPasswordMinLetters)); 7139ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 7140bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & NOT_ENOUGH_DIGITS) > 0) { 7150bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getResources().getQuantityString( 7160bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_numeric, mPasswordMinNumeric, 7170bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNumeric)); 7180bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7190bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & NOT_ENOUGH_SYMBOLS) > 0) { 7200bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getResources().getQuantityString( 7210bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_symbols, mPasswordMinSymbols, 7220bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinSymbols)); 7230bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7240bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & NOT_ENOUGH_NON_LETTER) > 0) { 7250bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getResources().getQuantityString( 7260bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.plurals.lockpassword_password_requires_nonletter, mPasswordMinNonLetter, 7270bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordMinNonLetter)); 7280bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7290bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & TOO_SHORT) > 0) { 7300bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getString(mIsAlphaMode ? 7310bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.string.lockpassword_password_too_short 7320bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak : R.string.lockpassword_pin_too_short, mPasswordMinLength)); 7330bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7340bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & TOO_LONG) > 0) { 7350bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getString(mIsAlphaMode ? 7360bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak R.string.lockpassword_password_too_long 7370bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak : R.string.lockpassword_pin_too_long, mPasswordMaxLength + 1)); 7380bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7390bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & CONTAIN_SEQUENTIAL_DIGITS) > 0) { 7400bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getString(R.string.lockpassword_pin_no_sequential_digits)); 7410bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7420bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if ((errorCode & RECENTLY_USED) > 0) { 7430bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak messages.add(getString((mIsAlphaMode) ? R.string.lockpassword_password_recently_used 7440bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak : R.string.lockpassword_pin_recently_used)); 7450bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7460bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak return messages.toArray(new String[0]); 7470bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7480bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 7499ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak private int getMinLengthToFulfillAllPolicies() { 7509ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak final int minLengthForLetters = Math.max(mPasswordMinLetters, 7519ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mPasswordMinUpperCase + mPasswordMinLowerCase); 7529ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak final int minLengthForNonLetters = Math.max(mPasswordMinNonLetter, 7539ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mPasswordMinSymbols + mPasswordMinNumeric); 7549ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak return minLengthForLetters + minLengthForNonLetters; 7559ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 7569ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak 7570bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak /** 75817e9e1933055b207473b488595b2887bfcaea32eJim Miller * Update the hint based on current Stage and length of password entry 75917e9e1933055b207473b488595b2887bfcaea32eJim Miller */ 76017e9e1933055b207473b488595b2887bfcaea32eJim Miller private void updateUi() { 7613e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia final boolean canInput = mSaveAndFinishWorker == null; 76217e9e1933055b207473b488595b2887bfcaea32eJim Miller String password = mPasswordEntry.getText().toString(); 76317e9e1933055b207473b488595b2887bfcaea32eJim Miller final int length = password.length(); 764163dee9fb78ef7c86929b250d150fa989484c2c7Maurice Lam if (mUiStage == Stage.Introduction) { 7650bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRestrictionView.setVisibility(View.VISIBLE); 7660bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak final int errorCode = validatePassword(password); 7670bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak String[] messages = convertErrorCodeToMessages(errorCode); 7680bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Update the fulfillment of requirements. 7690bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRequirementAdapter.setRequirements(messages); 7700bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Enable/Disable the next button accordingly. 7710bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak setNextEnabled(errorCode == NO_ERROR); 77217e9e1933055b207473b488595b2887bfcaea32eJim Miller } else { 7730bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Hide password requirement view when we are just asking user to confirm the pw. 7740bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mPasswordRestrictionView.setVisibility(View.GONE); 7750bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak setHeaderText(getString( 7760bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mIsAlphaMode ? mUiStage.alphaHint : mUiStage.numericHint)); 7773e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia setNextEnabled(canInput && length > 0); 778122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 779af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam setNextText(mUiStage.buttonText); 7803e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mPasswordEntryInputDisabler.setInputEnabled(canInput); 781122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 782122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 7830bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak private void setHeaderText(String text) { 7840bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak // Only set the text if it is different than the existing one to avoid announcing again. 7850bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak if (!TextUtils.isEmpty(mHeaderText.getText()) 7860bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak && mHeaderText.getText().toString().equals(text)) { 7870bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak return; 7880bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7890bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak mHeaderText.setText(text); 7900bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak } 7910bbcdccdbfa1f8473eb1c14e275c7de6dd43b4d4Tony Mak 79217e9e1933055b207473b488595b2887bfcaea32eJim Miller public void afterTextChanged(Editable s) { 79317e9e1933055b207473b488595b2887bfcaea32eJim Miller // Changing the text while error displayed resets to NeedToConfirm state 79417e9e1933055b207473b488595b2887bfcaea32eJim Miller if (mUiStage == Stage.ConfirmWrong) { 79517e9e1933055b207473b488595b2887bfcaea32eJim Miller mUiStage = Stage.NeedToConfirm; 79617e9e1933055b207473b488595b2887bfcaea32eJim Miller } 7979ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak // Schedule the UI update. 7989ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak mTextChangedHandler.notifyAfterTextChanged(); 799122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 800122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 80117e9e1933055b207473b488595b2887bfcaea32eJim Miller public void beforeTextChanged(CharSequence s, int start, int count, int after) { 802122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 80317e9e1933055b207473b488595b2887bfcaea32eJim Miller } 804122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 80517e9e1933055b207473b488595b2887bfcaea32eJim Miller public void onTextChanged(CharSequence s, int start, int before, int count) { 806122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller 80717e9e1933055b207473b488595b2887bfcaea32eJim Miller } 8083e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8093e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia private void startSaveAndFinish() { 8103e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (mSaveAndFinishWorker != null) { 8113e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia Log.w(TAG, "startSaveAndFinish with an existing SaveAndFinishWorker."); 8123e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia return; 8133e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 8143e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8153e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mPasswordEntryInputDisabler.setInputEnabled(false); 8163e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia setNextEnabled(false); 8173e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8183e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mSaveAndFinishWorker = new SaveAndFinishWorker(); 8195bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee mSaveAndFinishWorker.setListener(this); 8205bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee 8213e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia getFragmentManager().beginTransaction().add(mSaveAndFinishWorker, 8223e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia FRAGMENT_TAG_SAVE_AND_FINISH).commit(); 8235bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee getFragmentManager().executePendingTransactions(); 8243e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8253e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia final boolean required = getActivity().getIntent().getBooleanExtra( 8263e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); 8273e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mSaveAndFinishWorker.start(mLockPatternUtils, required, mHasChallenge, mChallenge, 828fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri mChosenPassword, mCurrentPassword, mRequestedQuality, mUserId); 8293e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 8303e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8313e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia @Override 8323e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) { 8333e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia getActivity().setResult(RESULT_FINISHED, resultData); 8343e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8353e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (!wasSecureBefore) { 8363e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia Intent intent = getRedactionInterstitialIntent(getActivity()); 8373e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (intent != null) { 83892779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer); 8393e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia startActivity(intent); 8403e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 8413e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 842686ae494f485a5025dfa456b4f32427b3715c337Udam Saini getActivity().finish(); 8433e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 8449ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak 8459ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak class TextChangedHandler extends Handler { 8469ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak private static final int ON_TEXT_CHANGED = 1; 8479ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak private static final int DELAY_IN_MILLISECOND = 100; 8489ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak 8499ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak /** 8509ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak * With the introduction of delay, we batch processing the text changed event to reduce 8519ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak * unnecessary UI updates. 8529ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak */ 8539ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak private void notifyAfterTextChanged() { 8549ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak removeMessages(ON_TEXT_CHANGED); 8559ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak sendEmptyMessageDelayed(ON_TEXT_CHANGED, DELAY_IN_MILLISECOND); 8569ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 8579ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak 8589ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak @Override 8599ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak public void handleMessage(Message msg) { 860f958f2e14ee07098543291181113c0afdb3b193fDoris Ling if (getActivity() == null) { 861f958f2e14ee07098543291181113c0afdb3b193fDoris Ling return; 862f958f2e14ee07098543291181113c0afdb3b193fDoris Ling } 8639ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak if (msg.what == ON_TEXT_CHANGED) { 8649ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak updateUi(); 8659ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 8669ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 8679ba765b875ebeb66d8a870a29a00fe53e9da306dTony Mak } 8683e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 8693e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 87077c4345373bdf6d6543bc06a04abc026ce762dbeClara Bayarri public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase { 8713e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8723e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia private String mChosenPassword; 8733e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia private String mCurrentPassword; 8743e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia private int mRequestedQuality; 8753e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8763e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia public void start(LockPatternUtils utils, boolean required, 8773e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia boolean hasChallenge, long challenge, 878fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri String chosenPassword, String currentPassword, int requestedQuality, int userId) { 879b8a22e42d42e6de8fce1a2026c112c12fd0f0f7aClara Bayarri prepare(utils, required, hasChallenge, challenge, userId); 8803e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8813e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mChosenPassword = chosenPassword; 8823e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mCurrentPassword = currentPassword; 8833e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mRequestedQuality = requestedQuality; 884fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri mUserId = userId; 8853e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8863e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia start(); 8873e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 8883e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8893e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia @Override 8903e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia protected Intent saveAndVerifyInBackground() { 8913e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia Intent result = null; 8923e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia mUtils.saveLockPassword(mChosenPassword, mCurrentPassword, mRequestedQuality, 893fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri mUserId); 8943e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 8953e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (mHasChallenge) { 8963e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia byte[] token; 8973e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia try { 898fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri token = mUtils.verifyPassword(mChosenPassword, mChallenge, mUserId); 8993e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } catch (RequestThrottledException e) { 9003e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia token = null; 9013e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 9023e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 9033e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia if (token == null) { 9043e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia Log.e(TAG, "critical: no token returned for known good password."); 9053e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 9063e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 9073e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia result = new Intent(); 9083e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); 9093e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 9103e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia 9113e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia return result; 9123e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia } 913122b6c85a9bc7076eacc388142f8c4fccc5462c9Jim Miller } 91400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller} 915