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(); } - }