packages/apps/Settings
リビジョン | 756b788b476af6995ffcf82d184af19405dac014 (tree) |
---|---|
日時 | 2014-05-14 17:16:53 |
作者 | Adrian Roos <roosa@goog...> |
コミッター | Chih-Wei Huang |
Add lockout after trying to enter PIN / Password too often
Enforce the same lockout that is already enforced when entering the pattern.
Bug: 13647935
Change-Id: Ia60a2235ad526c293b7a8d5600f406f187004df7
@@ -26,8 +26,10 @@ import android.app.Fragment; | ||
26 | 26 | import android.app.admin.DevicePolicyManager; |
27 | 27 | import android.content.Intent; |
28 | 28 | import android.os.Bundle; |
29 | +import android.os.CountDownTimer; | |
29 | 30 | import android.os.Handler; |
30 | 31 | import android.preference.PreferenceActivity; |
32 | +import android.os.SystemClock; | |
31 | 33 | import android.text.Editable; |
32 | 34 | import android.text.InputType; |
33 | 35 | import android.text.TextWatcher; |
@@ -78,7 +80,9 @@ public class ConfirmLockPassword extends PreferenceActivity { | ||
78 | 80 | private PasswordEntryKeyboardHelper mKeyboardHelper; |
79 | 81 | private PasswordEntryKeyboardView mKeyboardView; |
80 | 82 | private Button mContinueButton; |
81 | - | |
83 | + private int mNumWrongConfirmAttempts; | |
84 | + private CountDownTimer mCountdownTimer; | |
85 | + private boolean mIsAlpha; | |
82 | 86 | |
83 | 87 | // required constructor for fragments |
84 | 88 | public ConfirmLockPasswordFragment() { |
@@ -109,29 +113,27 @@ public class ConfirmLockPassword extends PreferenceActivity { | ||
109 | 113 | |
110 | 114 | mKeyboardView = (PasswordEntryKeyboardView) view.findViewById(R.id.keyboard); |
111 | 115 | mHeaderText = (TextView) view.findViewById(R.id.headerText); |
112 | - final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality | |
116 | + mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality | |
113 | 117 | || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality |
114 | 118 | || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == storedQuality; |
115 | - mHeaderText.setText(isAlpha ? R.string.lockpassword_confirm_your_password_header | |
116 | - : R.string.lockpassword_confirm_your_pin_header); | |
119 | + mHeaderText.setText(getDefaultHeader()); | |
117 | 120 | |
118 | 121 | final Activity activity = getActivity(); |
119 | 122 | mKeyboardHelper = new PasswordEntryKeyboardHelper(activity, |
120 | 123 | mKeyboardView, mPasswordEntry); |
121 | - mKeyboardHelper.setKeyboardMode(isAlpha ? | |
124 | + mKeyboardHelper.setKeyboardMode(mIsAlpha ? | |
122 | 125 | PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA |
123 | 126 | : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); |
124 | 127 | mKeyboardView.requestFocus(); |
125 | 128 | |
126 | 129 | int currentType = mPasswordEntry.getInputType(); |
127 | - mPasswordEntry.setInputType(isAlpha ? currentType | |
130 | + mPasswordEntry.setInputType(mIsAlpha ? currentType | |
128 | 131 | : (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD)); |
129 | 132 | |
130 | 133 | // Update the breadcrumb (title) if this is embedded in a PreferenceActivity |
131 | 134 | if (activity instanceof PreferenceActivity) { |
132 | 135 | final PreferenceActivity preferenceActivity = (PreferenceActivity) activity; |
133 | - int id = isAlpha ? R.string.lockpassword_confirm_your_password_header | |
134 | - : R.string.lockpassword_confirm_your_pin_header; | |
136 | + int id = getDefaultHeader(); | |
135 | 137 | CharSequence title = getText(id); |
136 | 138 | preferenceActivity.showBreadCrumbs(title, title); |
137 | 139 | } |
@@ -139,10 +141,19 @@ public class ConfirmLockPassword extends PreferenceActivity { | ||
139 | 141 | return view; |
140 | 142 | } |
141 | 143 | |
144 | + private int getDefaultHeader() { | |
145 | + return mIsAlpha ? R.string.lockpassword_confirm_your_password_header | |
146 | + : R.string.lockpassword_confirm_your_pin_header; | |
147 | + } | |
148 | + | |
142 | 149 | @Override |
143 | 150 | public void onPause() { |
144 | 151 | super.onPause(); |
145 | 152 | mKeyboardView.requestFocus(); |
153 | + if (mCountdownTimer != null) { | |
154 | + mCountdownTimer.cancel(); | |
155 | + mCountdownTimer = null; | |
156 | + } | |
146 | 157 | } |
147 | 158 | |
148 | 159 | @Override |
@@ -150,6 +161,10 @@ public class ConfirmLockPassword extends PreferenceActivity { | ||
150 | 161 | // TODO Auto-generated method stub |
151 | 162 | super.onResume(); |
152 | 163 | mKeyboardView.requestFocus(); |
164 | + long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); | |
165 | + if (deadline != 0) { | |
166 | + handleAttemptLockout(deadline); | |
167 | + } | |
153 | 168 | } |
154 | 169 | |
155 | 170 | private void handleNext() { |
@@ -162,10 +177,40 @@ public class ConfirmLockPassword extends PreferenceActivity { | ||
162 | 177 | getActivity().setResult(RESULT_OK, intent); |
163 | 178 | getActivity().finish(); |
164 | 179 | } else { |
165 | - showError(R.string.lockpattern_need_to_unlock_wrong); | |
180 | + if (++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { | |
181 | + long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); | |
182 | + handleAttemptLockout(deadline); | |
183 | + } else { | |
184 | + showError(R.string.lockpattern_need_to_unlock_wrong); | |
185 | + } | |
166 | 186 | } |
167 | 187 | } |
168 | 188 | |
189 | + private void handleAttemptLockout(long elapsedRealtimeDeadline) { | |
190 | + long elapsedRealtime = SystemClock.elapsedRealtime(); | |
191 | + showError(R.string.lockpattern_too_many_failed_confirmation_attempts_header, 0); | |
192 | + mPasswordEntry.setEnabled(false); | |
193 | + mCountdownTimer = new CountDownTimer( | |
194 | + elapsedRealtimeDeadline - elapsedRealtime, | |
195 | + LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS) { | |
196 | + | |
197 | + @Override | |
198 | + public void onTick(long millisUntilFinished) { | |
199 | + final int secondsCountdown = (int) (millisUntilFinished / 1000); | |
200 | + mHeaderText.setText(getString( | |
201 | + R.string.lockpattern_too_many_failed_confirmation_attempts_footer, | |
202 | + secondsCountdown)); | |
203 | + } | |
204 | + | |
205 | + @Override | |
206 | + public void onFinish() { | |
207 | + mPasswordEntry.setEnabled(true); | |
208 | + mHeaderText.setText(getDefaultHeader()); | |
209 | + mNumWrongConfirmAttempts = 0; | |
210 | + } | |
211 | + }.start(); | |
212 | + } | |
213 | + | |
169 | 214 | public void onClick(View v) { |
170 | 215 | switch (v.getId()) { |
171 | 216 | case R.id.next_button: |
@@ -180,14 +225,23 @@ public class ConfirmLockPassword extends PreferenceActivity { | ||
180 | 225 | } |
181 | 226 | |
182 | 227 | private void showError(int msg) { |
228 | + showError(msg, ERROR_MESSAGE_TIMEOUT); | |
229 | + } | |
230 | + | |
231 | + private final Runnable mResetErrorRunnable = new Runnable() { | |
232 | + public void run() { | |
233 | + mHeaderText.setText(getDefaultHeader()); | |
234 | + } | |
235 | + }; | |
236 | + | |
237 | + private void showError(int msg, long timeout) { | |
183 | 238 | mHeaderText.setText(msg); |
184 | 239 | mHeaderText.announceForAccessibility(mHeaderText.getText()); |
185 | 240 | mPasswordEntry.setText(null); |
186 | - mHandler.postDelayed(new Runnable() { | |
187 | - public void run() { | |
188 | - mHeaderText.setText(R.string.lockpassword_confirm_your_password_header); | |
189 | - } | |
190 | - }, ERROR_MESSAGE_TIMEOUT); | |
241 | + mHandler.removeCallbacks(mResetErrorRunnable); | |
242 | + if (timeout != 0) { | |
243 | + mHandler.postDelayed(mResetErrorRunnable, timeout); | |
244 | + } | |
191 | 245 | } |
192 | 246 | |
193 | 247 | // {@link OnEditorActionListener} methods. |