15e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller/* 25e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Copyright (C) 2010 The Android Open Source Project 35e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * 45e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 55e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * you may not use this file except in compliance with the License. 65e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * You may obtain a copy of the License at 75e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * 85e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * http://www.apache.org/licenses/LICENSE-2.0 95e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * 105e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Unless required by applicable law or agreed to in writing, software 115e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * distributed under the License is distributed on an "AS IS" BASIS, 125e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * See the License for the specific language governing permissions and 145e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * limitations under the License. 155e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller */ 165e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpackage com.android.internal.policy.impl.keyguard_obsolete; 185e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 19858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport java.util.List; 20858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 21f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Millerimport android.app.admin.DevicePolicyManager; 225e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.content.Context; 235475906f53e2d79807548932dfabbf9945143740Jim Millerimport android.content.res.Configuration; 24148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Millerimport android.graphics.Rect; 255e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 265e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport com.android.internal.widget.LockPatternUtils; 27a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport com.android.internal.widget.PasswordEntryKeyboardView; 285e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 29f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Millerimport android.os.CountDownTimer; 30f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Millerimport android.os.SystemClock; 31aef555bcf26e770e37f2065913084588fb92c6fbJim Millerimport android.provider.Settings; 325cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstromimport android.security.KeyStore; 338ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Millerimport android.text.Editable; 34da3ae8fba865e4b02016bcb65b87a1fbfa000158Jim Millerimport android.text.InputType; 358ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Millerimport android.text.TextWatcher; 368b9dda28c9850b4a68b6958b8d4f751dd64157adJim Millerimport android.text.method.DigitsKeyListener; 378b9dda28c9850b4a68b6958b8d4f751dd64157adJim Millerimport android.text.method.TextKeyListener; 38d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Millerimport android.view.Gravity; 395e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.view.KeyEvent; 405e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.view.LayoutInflater; 415e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.view.View; 42d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Millerimport android.view.ViewGroup.LayoutParams; 43a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport android.view.inputmethod.EditorInfo; 44858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport android.view.inputmethod.InputMethodInfo; 45858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport android.view.inputmethod.InputMethodManager; 46858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport android.view.inputmethod.InputMethodSubtype; 47a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport android.widget.EditText; 485e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.widget.LinearLayout; 49d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Millerimport android.widget.Space; 505e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.widget.TextView; 51a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport android.widget.TextView.OnEditorActionListener; 52a781d016108d64b2735740d42b5a7c57eb420406Jim Miller 535e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport com.android.internal.R; 54a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport com.android.internal.widget.PasswordEntryKeyboardHelper; 555e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 565e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller/** 575e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Displays a dialer-like interface or alphanumeric (latin-1) key entry for the user to enter 585e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * an unlock password 595e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller */ 605475906f53e2d79807548932dfabbf9945143740Jim Millerpublic class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen, 616b05d58018c2806459c121e507c005639b74aee9Jim Miller OnEditorActionListener { 625e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 638171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung private static final String TAG = "PasswordUnlockScreen"; 645e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller private final KeyguardUpdateMonitor mUpdateMonitor; 655e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller private final KeyguardScreenCallback mCallback; 665e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 6751ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final boolean mIsAlpha; 68f9a166ab8236b5824049f5103c4365e12b52b4acKonstantin Lopyrev 6951ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final EditText mPasswordEntry; 7051ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final LockPatternUtils mLockPatternUtils; 7151ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final PasswordEntryKeyboardView mKeyboardView; 7251ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final PasswordEntryKeyboardHelper mKeyboardHelper; 735e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 7451ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final int mCreationOrientation; 7551ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final int mCreationHardKeyboardHidden; 768171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 7751ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final KeyguardStatusViewManager mStatusViewManager; 7851ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo private final boolean mUseSystemIME = true; // TODO: Make configurable 79dcb9376913a954266d07733e5e33bd846230cff8Jim Miller private boolean mResuming; // used to prevent poking the wakelock during onResume() 805475906f53e2d79807548932dfabbf9945143740Jim Miller 816fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller // To avoid accidental lockout due to events while the device in in the pocket, ignore 826fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller // any passwords with length less than or equal to this length. 836fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller private static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3; 846fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller 855475906f53e2d79807548932dfabbf9945143740Jim Miller public PasswordUnlockScreen(Context context, Configuration configuration, 865475906f53e2d79807548932dfabbf9945143740Jim Miller LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor updateMonitor, 875475906f53e2d79807548932dfabbf9945143740Jim Miller KeyguardScreenCallback callback) { 885e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller super(context); 895475906f53e2d79807548932dfabbf9945143740Jim Miller 905169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller mCreationHardKeyboardHidden = configuration.hardKeyboardHidden; 915475906f53e2d79807548932dfabbf9945143740Jim Miller mCreationOrientation = configuration.orientation; 925e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller mUpdateMonitor = updateMonitor; 935e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller mCallback = callback; 94c23024d32779b170dde32a50fbdd945ce521b874Jim Miller mLockPatternUtils = lockPatternUtils; 955e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 965e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller LayoutInflater layoutInflater = LayoutInflater.from(context); 975475906f53e2d79807548932dfabbf9945143740Jim Miller if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) { 985e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller layoutInflater.inflate(R.layout.keyguard_screen_password_portrait, this, true); 9942b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller } else { 10042b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller layoutInflater.inflate(R.layout.keyguard_screen_password_landscape, this, true); 1015e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 1025e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 1036b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor, mLockPatternUtils, 104ebcd6bb1b9ac5f898621ba25c37f2e3ccd2ff33bAdam Cohen mCallback, true); 1058171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 106f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality(); 107f9a166ab8236b5824049f5103c4365e12b52b4acKonstantin Lopyrev mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality 108a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality 109a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality; 110f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller 111a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard); 112a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mPasswordEntry = (EditText) findViewById(R.id.passwordEntry); 113a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mPasswordEntry.setOnEditorActionListener(this); 1145e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 1158171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false); 1163fb0af38a1de9258cc80b227361c9a8ded88cfefJeff Sharkey mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled()); 117d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller boolean imeOrDeleteButtonVisible = false; 1186b05d58018c2806459c121e507c005639b74aee9Jim Miller if (mIsAlpha) { 1196b05d58018c2806459c121e507c005639b74aee9Jim Miller // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard 1206b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); 1216b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyboardView.setVisibility(View.GONE); 1228171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung } else { 1236b05d58018c2806459c121e507c005639b74aee9Jim Miller // Use lockscreen's numeric keyboard if the physical keyboard isn't showing 1248171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); 1256b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyboardView.setVisibility(mCreationHardKeyboardHidden 1266b05d58018c2806459c121e507c005639b74aee9Jim Miller == Configuration.HARDKEYBOARDHIDDEN_NO ? View.INVISIBLE : View.VISIBLE); 12751ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo 12851ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts, 12951ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo // not a separate view 13051ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo View pinDelete = findViewById(R.id.pinDel); 13151ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo if (pinDelete != null) { 13251ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo pinDelete.setVisibility(View.VISIBLE); 133d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller imeOrDeleteButtonVisible = true; 13451ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo pinDelete.setOnClickListener(new OnClickListener() { 13551ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo @Override 13651ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo public void onClick(View v) { 13751ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo mKeyboardHelper.handleBackspace(); 13851ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo } 13951ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo }); 14051ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo } 1418171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung } 1425e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 143a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mPasswordEntry.requestFocus(); 144966b126ea7f24ae16c6a2aa683072bfd2cae8158Jim Miller 1458ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller // This allows keyboards with overlapping qwerty/numeric keys to choose just numeric keys. 146f9a166ab8236b5824049f5103c4365e12b52b4acKonstantin Lopyrev if (mIsAlpha) { 1478b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller mPasswordEntry.setKeyListener(TextKeyListener.getInstance()); 1488ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT 1498ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller | InputType.TYPE_TEXT_VARIATION_PASSWORD); 1506b05d58018c2806459c121e507c005639b74aee9Jim Miller //mStatusViewManager.setHelpMessage(R.string.keyguard_password_enter_password_code, 1516b05d58018c2806459c121e507c005639b74aee9Jim Miller //KeyguardStatusViewManager.LOCK_ICON); 1528b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller } else { 1538b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance()); 1548ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER 1558ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller | InputType.TYPE_NUMBER_VARIATION_PASSWORD); 1566b05d58018c2806459c121e507c005639b74aee9Jim Miller //mStatusViewManager.setHelpMessage(R.string.keyguard_password_enter_pin_code, 1576b05d58018c2806459c121e507c005639b74aee9Jim Miller //KeyguardStatusViewManager.LOCK_ICON); 1588b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller } 1598b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller 1606b05d58018c2806459c121e507c005639b74aee9Jim Miller // Poke the wakelock any time the text is selected or modified 1616b05d58018c2806459c121e507c005639b74aee9Jim Miller mPasswordEntry.setOnClickListener(new OnClickListener() { 1626b05d58018c2806459c121e507c005639b74aee9Jim Miller public void onClick(View v) { 1636b05d58018c2806459c121e507c005639b74aee9Jim Miller mCallback.pokeWakelock(); 1646b05d58018c2806459c121e507c005639b74aee9Jim Miller } 1656b05d58018c2806459c121e507c005639b74aee9Jim Miller }); 1668ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller mPasswordEntry.addTextChangedListener(new TextWatcher() { 1678ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller public void onTextChanged(CharSequence s, int start, int before, int count) { 1688ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller } 1698ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller 1708ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller public void beforeTextChanged(CharSequence s, int start, int count, int after) { 1718ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller } 1728ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller 1738ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller public void afterTextChanged(Editable s) { 174dcb9376913a954266d07733e5e33bd846230cff8Jim Miller if (!mResuming) { 175dcb9376913a954266d07733e5e33bd846230cff8Jim Miller mCallback.pokeWakelock(); 176dcb9376913a954266d07733e5e33bd846230cff8Jim Miller } 1778ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller } 1788ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller }); 179858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 180858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // If there's more than one IME, enable the IME switcher button 181858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller View switchImeButton = findViewById(R.id.switch_ime_button); 182858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller final InputMethodManager imm = (InputMethodManager) getContext().getSystemService( 183858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller Context.INPUT_METHOD_SERVICE); 184b0166bc62f781c3dd921560c0ebafd965603fb16Jim Miller if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) { 185858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller switchImeButton.setVisibility(View.VISIBLE); 186d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller imeOrDeleteButtonVisible = true; 187858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller switchImeButton.setOnClickListener(new OnClickListener() { 188858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller public void onClick(View v) { 189858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller mCallback.pokeWakelock(); // Leave the screen on a bit longer 190858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller imm.showInputMethodPicker(); 191858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 192858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller }); 193858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 194d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller 195d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller // If no icon is visible, reset the left margin on the password field so the text is 196d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller // still centered. 197d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller if (!imeOrDeleteButtonVisible) { 198d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams(); 199d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller if (params instanceof MarginLayoutParams) { 200d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller ((MarginLayoutParams)params).leftMargin = 0; 201d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller mPasswordEntry.setLayoutParams(params); 202d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller } 203d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller } 204858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 205858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 206858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller /** 207858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller * Method adapted from com.android.inputmethod.latin.Utils 208858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller * 209858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller * @param imm The input method manager 210858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller * @param shouldIncludeAuxiliarySubtypes 211858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller * @return true if we have multiple IMEs to choose from 212858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller */ 213858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm, 214858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller final boolean shouldIncludeAuxiliarySubtypes) { 215858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); 216858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 217858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // Number of the filtered IMEs 218858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller int filteredImisCount = 0; 219858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 220858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller for (InputMethodInfo imi : enabledImis) { 221858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // We can return true immediately after we find two or more filtered IMEs. 222858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller if (filteredImisCount > 1) return true; 223858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller final List<InputMethodSubtype> subtypes = 224858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller imm.getEnabledInputMethodSubtypeList(imi, true); 225858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // IMEs that have no subtypes should be counted. 226858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller if (subtypes.isEmpty()) { 227858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller ++filteredImisCount; 228858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller continue; 229858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 230858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 231858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller int auxCount = 0; 232858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller for (InputMethodSubtype subtype : subtypes) { 233858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller if (subtype.isAuxiliary()) { 234858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller ++auxCount; 235858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 236858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 237858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller final int nonAuxCount = subtypes.size() - auxCount; 238858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 239858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // IMEs that have one or more non-auxiliary subtypes should be counted. 240858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary 241858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // subtypes should be counted as well. 242858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { 243858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller ++filteredImisCount; 244858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller continue; 245858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 246858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller } 247858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller 248858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller return filteredImisCount > 1 249858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled 250858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller // input method subtype (The current IME should be LatinIME.) 251858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1; 2525e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 2535e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 254148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Miller @Override 255148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Miller protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 256148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Miller // send focus to the password field 257148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Miller return mPasswordEntry.requestFocus(direction, previouslyFocusedRect); 258148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Miller } 259148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Miller 2605e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller /** {@inheritDoc} */ 2615e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller public boolean needsInput() { 262da3ae8fba865e4b02016bcb65b87a1fbfa000158Jim Miller return mUseSystemIME && mIsAlpha; 2635e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 2645e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 2655e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller /** {@inheritDoc} */ 2665e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller public void onPause() { 2676b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.onPause(); 2685e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 2695e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 2705e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller /** {@inheritDoc} */ 2715e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller public void onResume() { 272dcb9376913a954266d07733e5e33bd846230cff8Jim Miller mResuming = true; 2738171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung // reset status 2746b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.onResume(); 2758171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 2765e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller // start fresh 277a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mPasswordEntry.setText(""); 278a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mPasswordEntry.requestFocus(); 279f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller 280f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller // if the user is currently locked out, enforce it. 281f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); 282f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller if (deadline != 0) { 283f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller handleAttemptLockout(deadline); 284f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller } 285dcb9376913a954266d07733e5e33bd846230cff8Jim Miller mResuming = false; 2865e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 2875e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 2885e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller /** {@inheritDoc} */ 2895e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller public void cleanUp() { 2905e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller mUpdateMonitor.removeCallback(this); 2915e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 2925e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 2935e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller private void verifyPasswordAndUnlock() { 294a781d016108d64b2735740d42b5a7c57eb420406Jim Miller String entry = mPasswordEntry.getText().toString(); 2955e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller if (mLockPatternUtils.checkPassword(entry)) { 2965e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller mCallback.keyguardDone(true); 2976fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller mCallback.reportSuccessfulUnlockAttempt(); 2986b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.setInstructionText(null); 2995cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom KeyStore.getInstance().password(entry); 3006fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) { 3015e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller // to avoid accidental lockout, only count attempts that are long enough to be a 3025e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller // real password. This may require some tweaking. 3036fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller mCallback.reportFailedUnlockAttempt(); 304f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller if (0 == (mUpdateMonitor.getFailedAttempts() 305f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { 306f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); 307f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller handleAttemptLockout(deadline); 308f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller } 3096b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.setInstructionText( 3106b05d58018c2806459c121e507c005639b74aee9Jim Miller mContext.getString(R.string.lockscreen_password_wrong)); 311f9a166ab8236b5824049f5103c4365e12b52b4acKonstantin Lopyrev } else if (entry.length() > 0) { 3126b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.setInstructionText( 3136b05d58018c2806459c121e507c005639b74aee9Jim Miller mContext.getString(R.string.lockscreen_password_wrong)); 3145e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 315a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mPasswordEntry.setText(""); 3165e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 3175e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 318f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller // Prevent user from using the PIN/Password entry until scheduled deadline. 319f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller private void handleAttemptLockout(long elapsedRealtimeDeadline) { 320f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller mPasswordEntry.setEnabled(false); 321f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller mKeyboardView.setEnabled(false); 322f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller long elapsedRealtime = SystemClock.elapsedRealtime(); 32351ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) { 324f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller 325f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller @Override 326f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller public void onTick(long millisUntilFinished) { 327f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller int secondsRemaining = (int) (millisUntilFinished / 1000); 328f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller String instructions = getContext().getString( 329f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller R.string.lockscreen_too_many_failed_attempts_countdown, 330f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller secondsRemaining); 3316b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.setInstructionText(instructions); 332f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller } 333f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller 334f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller @Override 335f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller public void onFinish() { 336f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller mPasswordEntry.setEnabled(true); 337f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller mKeyboardView.setEnabled(true); 3386b05d58018c2806459c121e507c005639b74aee9Jim Miller mStatusViewManager.resetStatusInfo(); 339f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller } 340f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller }.start(); 341f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller } 342f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Miller 3435e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller @Override 3445e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller public boolean onKeyDown(int keyCode, KeyEvent event) { 345a781d016108d64b2735740d42b5a7c57eb420406Jim Miller mCallback.pokeWakelock(); 3465e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller return false; 3475e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 3485e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 34975787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn @Override 35075787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn protected void onAttachedToWindow() { 35175787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn super.onAttachedToWindow(); 3525169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller Configuration config = getResources().getConfiguration(); 3535169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller if (config.orientation != mCreationOrientation 3545169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller || config.hardKeyboardHidden != mCreationHardKeyboardHidden) { 3555169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller mCallback.recreateMe(config); 35675787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn } 35775787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn } 35875787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn 3595475906f53e2d79807548932dfabbf9945143740Jim Miller /** {@inheritDoc} */ 3605475906f53e2d79807548932dfabbf9945143740Jim Miller @Override 3615475906f53e2d79807548932dfabbf9945143740Jim Miller protected void onConfigurationChanged(Configuration newConfig) { 3625475906f53e2d79807548932dfabbf9945143740Jim Miller super.onConfigurationChanged(newConfig); 3635169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller if (newConfig.orientation != mCreationOrientation 3645169fc57e38cda45d6fda4b47b727167dd937cc8Jim Miller || newConfig.hardKeyboardHidden != mCreationHardKeyboardHidden) { 3655475906f53e2d79807548932dfabbf9945143740Jim Miller mCallback.recreateMe(newConfig); 3665475906f53e2d79807548932dfabbf9945143740Jim Miller } 3675e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 3685e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 3695e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller public void onKeyboardChange(boolean isKeyboardOpen) { 37042b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller // Don't show the soft keyboard when the real keyboard is open 37142b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller mKeyboardView.setVisibility(isKeyboardOpen ? View.INVISIBLE : View.VISIBLE); 3725e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 3735e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller 374a781d016108d64b2735740d42b5a7c57eb420406Jim Miller public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 375a781d016108d64b2735740d42b5a7c57eb420406Jim Miller // Check if this was the result of hitting the enter key 3761c18828d20807342d37000746b18a3c1696f3b2eJim Miller if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE 3771c18828d20807342d37000746b18a3c1696f3b2eJim Miller || actionId == EditorInfo.IME_ACTION_NEXT) { 378a781d016108d64b2735740d42b5a7c57eb420406Jim Miller verifyPasswordAndUnlock(); 379a781d016108d64b2735740d42b5a7c57eb420406Jim Miller return true; 3805e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 381a781d016108d64b2735740d42b5a7c57eb420406Jim Miller return false; 3825e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller } 3835e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller} 384