From 756b788b476af6995ffcf82d184af19405dac014 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Mon, 31 Mar 2014 21:33:35 +0200 Subject: [PATCH] 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 --- src/com/android/settings/ConfirmLockPassword.java | 82 +++++++++++++++++++---- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java index d7402daff8..38d4a893cf 100644 --- a/src/com/android/settings/ConfirmLockPassword.java +++ b/src/com/android/settings/ConfirmLockPassword.java @@ -26,8 +26,10 @@ import android.app.Fragment; import android.app.admin.DevicePolicyManager; import android.content.Intent; import android.os.Bundle; +import android.os.CountDownTimer; import android.os.Handler; import android.preference.PreferenceActivity; +import android.os.SystemClock; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -78,7 +80,9 @@ public class ConfirmLockPassword extends PreferenceActivity { private PasswordEntryKeyboardHelper mKeyboardHelper; private PasswordEntryKeyboardView mKeyboardView; private Button mContinueButton; - + private int mNumWrongConfirmAttempts; + private CountDownTimer mCountdownTimer; + private boolean mIsAlpha; // required constructor for fragments public ConfirmLockPasswordFragment() { @@ -109,29 +113,27 @@ public class ConfirmLockPassword extends PreferenceActivity { mKeyboardView = (PasswordEntryKeyboardView) view.findViewById(R.id.keyboard); mHeaderText = (TextView) view.findViewById(R.id.headerText); - final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality + mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == storedQuality; - mHeaderText.setText(isAlpha ? R.string.lockpassword_confirm_your_password_header - : R.string.lockpassword_confirm_your_pin_header); + mHeaderText.setText(getDefaultHeader()); final Activity activity = getActivity(); mKeyboardHelper = new PasswordEntryKeyboardHelper(activity, mKeyboardView, mPasswordEntry); - mKeyboardHelper.setKeyboardMode(isAlpha ? + mKeyboardHelper.setKeyboardMode(mIsAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); mKeyboardView.requestFocus(); int currentType = mPasswordEntry.getInputType(); - mPasswordEntry.setInputType(isAlpha ? currentType + mPasswordEntry.setInputType(mIsAlpha ? currentType : (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD)); // Update the breadcrumb (title) if this is embedded in a PreferenceActivity if (activity instanceof PreferenceActivity) { final PreferenceActivity preferenceActivity = (PreferenceActivity) activity; - int id = isAlpha ? R.string.lockpassword_confirm_your_password_header - : R.string.lockpassword_confirm_your_pin_header; + int id = getDefaultHeader(); CharSequence title = getText(id); preferenceActivity.showBreadCrumbs(title, title); } @@ -139,10 +141,19 @@ public class ConfirmLockPassword extends PreferenceActivity { return view; } + private int getDefaultHeader() { + return mIsAlpha ? R.string.lockpassword_confirm_your_password_header + : R.string.lockpassword_confirm_your_pin_header; + } + @Override public void onPause() { super.onPause(); mKeyboardView.requestFocus(); + if (mCountdownTimer != null) { + mCountdownTimer.cancel(); + mCountdownTimer = null; + } } @Override @@ -150,6 +161,10 @@ public class ConfirmLockPassword extends PreferenceActivity { // TODO Auto-generated method stub super.onResume(); mKeyboardView.requestFocus(); + long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); + if (deadline != 0) { + handleAttemptLockout(deadline); + } } private void handleNext() { @@ -162,10 +177,40 @@ public class ConfirmLockPassword extends PreferenceActivity { getActivity().setResult(RESULT_OK, intent); getActivity().finish(); } else { - showError(R.string.lockpattern_need_to_unlock_wrong); + if (++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { + long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); + handleAttemptLockout(deadline); + } else { + showError(R.string.lockpattern_need_to_unlock_wrong); + } } } + private void handleAttemptLockout(long elapsedRealtimeDeadline) { + long elapsedRealtime = SystemClock.elapsedRealtime(); + showError(R.string.lockpattern_too_many_failed_confirmation_attempts_header, 0); + mPasswordEntry.setEnabled(false); + mCountdownTimer = new CountDownTimer( + elapsedRealtimeDeadline - elapsedRealtime, + LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS) { + + @Override + public void onTick(long millisUntilFinished) { + final int secondsCountdown = (int) (millisUntilFinished / 1000); + mHeaderText.setText(getString( + R.string.lockpattern_too_many_failed_confirmation_attempts_footer, + secondsCountdown)); + } + + @Override + public void onFinish() { + mPasswordEntry.setEnabled(true); + mHeaderText.setText(getDefaultHeader()); + mNumWrongConfirmAttempts = 0; + } + }.start(); + } + public void onClick(View v) { switch (v.getId()) { case R.id.next_button: @@ -180,14 +225,23 @@ public class ConfirmLockPassword extends PreferenceActivity { } private void showError(int msg) { + showError(msg, ERROR_MESSAGE_TIMEOUT); + } + + private final Runnable mResetErrorRunnable = new Runnable() { + public void run() { + mHeaderText.setText(getDefaultHeader()); + } + }; + + private void showError(int msg, long timeout) { mHeaderText.setText(msg); mHeaderText.announceForAccessibility(mHeaderText.getText()); mPasswordEntry.setText(null); - mHandler.postDelayed(new Runnable() { - public void run() { - mHeaderText.setText(R.string.lockpassword_confirm_your_password_header); - } - }, ERROR_MESSAGE_TIMEOUT); + mHandler.removeCallbacks(mResetErrorRunnable); + if (timeout != 0) { + mHandler.postDelayed(mResetErrorRunnable, timeout); + } } // {@link OnEditorActionListener} methods. -- 2.11.0