From 84999d69e0a70f5e510577b09ea1e788142252a8 Mon Sep 17 00:00:00 2001 From: Karl Rosaen Date: Mon, 24 Aug 2009 17:18:02 -0700 Subject: [PATCH] Adjust 'account unlock' scenario to make 'forgot pattern' more forgiving. When a user hits the 'forgot pattern' button, they aren't permanently forced into using the account to unlock the screen; they can get back to the pattern screen by hitting the back key, or by turning off the screen (e.g it's not sticky). Also, show progress dialog while checking account, and make sure we are on the UI thread when doing stuff from the account callback. --- .../policy/impl/AccountUnlockScreen.java | 68 ++++++++++++++++--- .../policy/impl/KeyguardScreenCallback.java | 11 ++- .../policy/impl/LockPatternKeyguardView.java | 17 ++++- .../internal/policy/impl/UnlockScreen.java | 14 +++- 4 files changed, 96 insertions(+), 14 deletions(-) diff --git a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java index e1181453d6195..069f97e6e3c47 100644 --- a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java +++ b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java @@ -35,10 +35,13 @@ import android.text.TextWatcher; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; +import android.view.WindowManager; import android.widget.Button; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.TextView; +import android.app.Dialog; +import android.app.ProgressDialog; import java.io.IOException; @@ -67,12 +70,17 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree private Button mOk; private Button mEmergencyCall; + /** + * Shown while making asynchronous check of password. + */ + private ProgressDialog mCheckingDialog; + /** * AccountUnlockScreen constructor. */ public AccountUnlockScreen(Context context, - KeyguardScreenCallback callback, - LockPatternUtils lockPatternUtils) { + KeyguardScreenCallback callback, + LockPatternUtils lockPatternUtils) { super(context); mCallback = callback; mLockPatternUtils = lockPatternUtils; @@ -81,6 +89,9 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree R.layout.keyguard_screen_glogin_unlock, this, true); mTopHeader = (TextView) findViewById(R.id.topHeader); + mTopHeader.setText(mLockPatternUtils.isPermanentlyLocked() ? + R.string.lockscreen_glogin_too_many_attempts : + R.string.lockscreen_glogin_forgot_pattern); mInstructions = (TextView) findViewById(R.id.instructions); @@ -135,6 +146,9 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree /** {@inheritDoc} */ public void cleanUp() { + if (mCheckingDialog != null) { + mCheckingDialog.hide(); + } } /** {@inheritDoc} */ @@ -149,10 +163,12 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree } } - private void onCheckPasswordResult(boolean flag) { - if (flag) { + private void onCheckPasswordResult(boolean success) { + if (success) { // clear out forgotten password mLockPatternUtils.setPermanentlyLocked(false); + mLockPatternUtils.setLockPatternEnabled(false); + mLockPatternUtils.saveLockPattern(null); // launch the 'choose lock pattern' activity so // the user can pick a new one if they want to @@ -173,7 +189,11 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { - mCallback.goToLockScreen(); + if (mLockPatternUtils.isPermanentlyLocked()) { + mCallback.goToLockScreen(); + } else { + mCallback.forgotPattern(false); + } return true; } return super.dispatchKeyEvent(event); @@ -232,6 +252,7 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree } private void asyncCheckPassword() { + mCallback.pokeWakelock(AWAKE_POKE_MILLIS); final String login = mLogin.getText().toString(); final String password = mPassword.getText().toString(); Account account = findIntendedAccount(login); @@ -239,18 +260,49 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree onCheckPasswordResult(false); return; } + getProgressDialog().show(); AccountManager.get(mContext).confirmPassword( account, password, new AccountManagerCallback() { public void run(AccountManagerFuture future) { - boolean result = false; try { - result = future.getResult(); + mCallback.pokeWakelock(AWAKE_POKE_MILLIS); + final boolean result = future.getResult(); + // ensure on UI thread + mLogin.post(new Runnable() { + public void run() { + onCheckPasswordResult(result); + } + }); } catch (OperationCanceledException e) { + onCheckPasswordResult(false); } catch (IOException e) { + onCheckPasswordResult(false); } catch (AuthenticatorException e) { + onCheckPasswordResult(false); + } finally { + mLogin.post(new Runnable() { + public void run() { + getProgressDialog().hide(); + } + }); } - onCheckPasswordResult(result); } }, null /* handler */); } + + private Dialog getProgressDialog() { + if (mCheckingDialog == null) { + mCheckingDialog = new ProgressDialog(mContext); + mCheckingDialog.setMessage( + mContext.getString(R.string.lockscreen_glogin_checking_password)); + mCheckingDialog.setIndeterminate(true); + mCheckingDialog.setCancelable(false); + mCheckingDialog.getWindow().setType( + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + mCheckingDialog.getWindow().setFlags( + WindowManager.LayoutParams.FLAG_BLUR_BEHIND, + WindowManager.LayoutParams.FLAG_BLUR_BEHIND); + } + return mCheckingDialog; + } } diff --git a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java b/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java index b46b37d04db0c..6bb6a45a7e340 100644 --- a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java +++ b/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java @@ -28,10 +28,19 @@ public interface KeyguardScreenCallback extends KeyguardViewCallback { void goToLockScreen(); /** - * Transitino to th unlock screen. + * Transition to the unlock screen. */ void goToUnlockScreen(); + /** + * The user reported that they forgot their pattern (or not, when they want to back out of the + * forgot pattern screen). + * + * @param isForgotten True if the user hit the forgot pattern, false if they want to back out + * of the account screen. + */ + void forgotPattern(boolean isForgotten); + /** * @return Whether the keyguard requires some sort of PIN. */ diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java index 0c45cd56e4fad..31bfd47af84aa 100644 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -112,10 +112,13 @@ public class LockPatternKeyguardView extends KeyguardViewBase { private Mode mMode = Mode.LockScreen; /** - * Keeps track of what mode the current unlock screen is + * Keeps track of what mode the current unlock screen is (cached from most recent computation in + * {@link #getUnlockMode}). */ private UnlockMode mUnlockScreenMode; + private boolean mForgotPattern; + /** * If true, it means we are in the process of verifying that the user * can get past the lock screen per {@link #verifyUnlock()} @@ -185,6 +188,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase { mKeyguardScreenCallback = new KeyguardScreenCallback() { public void goToLockScreen() { + mForgotPattern = false; if (mIsVerifyUnlockOnly) { // navigating away from unlock screen during verify mode means // we are done and the user failed to authenticate. @@ -209,6 +213,13 @@ public class LockPatternKeyguardView extends KeyguardViewBase { } } + public void forgotPattern(boolean isForgotten) { + if (mEnableFallback) { + mForgotPattern = isForgotten; + updateScreen(Mode.UnlockScreen); + } + } + public boolean isSecure() { return LockPatternKeyguardView.this.isSecure(); } @@ -293,12 +304,14 @@ public class LockPatternKeyguardView extends KeyguardViewBase { @Override public void reset() { mIsVerifyUnlockOnly = false; + mForgotPattern = false; updateScreen(getInitialMode()); } @Override public void onScreenTurnedOff() { mScreenOn = false; + mForgotPattern = false; if (mMode == Mode.LockScreen) { ((KeyguardScreen) mLockScreen).onPause(); } else { @@ -523,7 +536,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase { if (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED) { return UnlockMode.SimPin; } else { - return mLockPatternUtils.isPermanentlyLocked() ? + return (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) ? UnlockMode.Account: UnlockMode.Pattern; } diff --git a/policy/com/android/internal/policy/impl/UnlockScreen.java b/policy/com/android/internal/policy/impl/UnlockScreen.java index 9aedf901d232f..74e03192c0528 100644 --- a/policy/com/android/internal/policy/impl/UnlockScreen.java +++ b/policy/com/android/internal/policy/impl/UnlockScreen.java @@ -104,6 +104,7 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient case ForgotLockPattern: mFooterNormal.setVisibility(View.GONE); mFooterForgotPattern.setVisibility(View.VISIBLE); + mForgotPatternButton.setVisibility(View.VISIBLE); break; case VerifyUnlocked: mFooterNormal.setVisibility(View.GONE); @@ -164,8 +165,7 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient mForgotPatternButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { - mLockPatternUtils.setPermanentlyLocked(true); - mCallback.goToUnlockScreen(); + mCallback.forgotPattern(true); } }); @@ -274,6 +274,15 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient mUpdateMonitor.removeCallback(this); } + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + if (hasWindowFocus) { + // when timeout dialog closes we want to update our state + onResume(); + } + } + private class UnlockPatternListener implements LockPatternView.OnPatternListener { @@ -337,5 +346,4 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient } }.start(); } - }