KeyguardPatternView.java revision 2c7bc26a7447e6ac9eadcf328259aa3bb1be2949
1dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller/* 2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project 3dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * 4dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 5dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * you may not use this file except in compliance with the License. 6dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * You may obtain a copy of the License at 7dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * 8dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * http://www.apache.org/licenses/LICENSE-2.0 9dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * 10dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Unless required by applicable law or agreed to in writing, software 11dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 12dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * See the License for the specific language governing permissions and 14dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * limitations under the License. 15dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */ 16dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpackage com.android.internal.policy.impl.keyguard; 17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 18dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.Account; 19dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.AccountManager; 20dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.AccountManagerCallback; 21dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.AccountManagerFuture; 22dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.AuthenticatorException; 23dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.OperationCanceledException; 24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context; 255737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.graphics.Rect; 26dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.Bundle; 27dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.CountDownTimer; 28dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.SystemClock; 292c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasaniimport android.os.UserHandle; 30dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet; 31dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.Log; 32dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.MotionEvent; 33dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View; 34dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.widget.Button; 353af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Millerimport android.widget.LinearLayout; 36dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 37dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternUtils; 38dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternView; 39dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.R; 40dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 41dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport java.io.IOException; 42dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport java.util.List; 43dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 443af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Millerpublic class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView { 45dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 46dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private static final String TAG = "SecurityPatternView"; 47dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private static final boolean DEBUG = false; 48dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 49dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // how long before we clear the wrong pattern 50dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000; 51dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 52dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK 53dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000; 54dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 55dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // how long we stay awake after the user hits the first dot. 56dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000; 57dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 58dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // how many cells the user has to cross before we poke the wakelock 59dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2; 60dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 61dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private int mFailedPatternAttemptsSinceLastTimeout = 0; 62dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private int mTotalFailedPatternAttempts = 0; 63dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private CountDownTimer mCountdownTimer = null; 64dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private LockPatternUtils mLockPatternUtils; 65dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private LockPatternView mLockPatternView; 66dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private Button mForgotPatternButton; 67dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private KeyguardSecurityCallback mCallback; 68dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private boolean mEnableFallback; 69dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 70dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller /** 71dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Keeps track of the last time we poked the wake lock during dispatching of the touch event. 72dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Initialized to something guaranteed to make us poke the wakelock when the user starts 73dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * drawing the pattern. 74dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * @see #dispatchTouchEvent(android.view.MotionEvent) 75dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */ 76dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS; 77dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller /** 79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Useful for clearing out the wrong pattern after a delay 80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */ 81dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private Runnable mCancelPatternRunnable = new Runnable() { 82dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void run() { 83dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.clearPattern(); 84dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 85dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller }; 865737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller private Rect mTempRect = new Rect(); 870ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller private SecurityMessageDisplay mSecurityMessageDisplay; 88dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 89dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller enum FooterMode { 90dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller Normal, 91dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller ForgotLockPattern, 92dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller VerifyUnlocked 93dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 94dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 95dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public KeyguardPatternView(Context context) { 96dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller this(context, null); 97dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public KeyguardPatternView(Context context, AttributeSet attrs) { 100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller super(context, attrs); 101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 102dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void setKeyguardCallback(KeyguardSecurityCallback callback) { 104dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback = callback; 105dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 106dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 107dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void setLockPatternUtils(LockPatternUtils utils) { 108dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = utils; 109dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 110dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 111dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 112dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller protected void onFinishInflate() { 113dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller super.onFinishInflate(); 114dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = mLockPatternUtils == null 115dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller ? new LockPatternUtils(mContext) : mLockPatternUtils; 116dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 117dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView); 118dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setSaveEnabled(false); 119dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setFocusable(false); 120dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setOnPatternListener(new UnlockPatternListener()); 121dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 122dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // stealth mode will be the same for the life of this screen 123dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled()); 124dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 125dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // vibrate mode will be the same for the life of this screen 126dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); 127dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 128dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button); 129dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setText(R.string.kg_forgot_pattern_button_text); 130dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setOnClickListener(new OnClickListener() { 131dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onClick(View v) { 132258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller mCallback.showBackupSecurity(); 133dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 134dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller }); 135dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 136dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller setFocusableInTouchMode(true); 137dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 138dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller maybeEnableFallback(mContext); 1390b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); 140dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 141dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 142dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void updateFooter(FooterMode mode) { 143dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller switch (mode) { 144dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller case Normal: 145dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.d(TAG, "mode normal"); 146dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setVisibility(View.GONE); 147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller break; 148dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller case ForgotLockPattern: 149dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.d(TAG, "mode ForgotLockPattern"); 150dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setVisibility(View.VISIBLE); 151dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller break; 152dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller case VerifyUnlocked: 153dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.d(TAG, "mode VerifyUnlocked"); 154dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setVisibility(View.GONE); 155dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 156dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 157dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 158dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 159d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller public boolean onTouchEvent(MotionEvent ev) { 160d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller boolean result = super.onTouchEvent(ev); 161dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // as long as the user is entering a pattern (i.e sending a touch event that was handled 162dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // by this screen), keep poking the wake lock so that the screen will stay on. 163dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime; 164dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) { 165dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLastPokeTime = SystemClock.elapsedRealtime(); 166dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 1675737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller mTempRect.set(0, 0, 0, 0); 1685737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller offsetRectIntoDescendantCoords(mLockPatternView, mTempRect); 1695737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller ev.offsetLocation(mTempRect.left, mTempRect.top); 1705737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller result = mLockPatternView.dispatchTouchEvent(ev) || result; 1715737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller ev.offsetLocation(-mTempRect.left, -mTempRect.top); 172dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return result; 173dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 174dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 175dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void reset() { 176dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // reset lock pattern 177dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.enableInput(); 178dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setEnabled(true); 179dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.clearPattern(); 180dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 181dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // if the user is currently locked out, enforce it. 182dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); 183dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (deadline != 0) { 184dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller handleAttemptLockout(deadline); 185dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 1861625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett displayDefaultSecurityMessage(); 187dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 188dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 189dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // the footer depends on how many total attempts the user has failed 190dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mCallback.isVerifyUnlockOnly()) { 191dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.VerifyUnlocked); 192dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else if (mEnableFallback && 193dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller (mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { 194dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.ForgotLockPattern); 195dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 196dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.Normal); 197dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 198dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 199dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 200dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 2011625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett private void displayDefaultSecurityMessage() { 2021625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) { 2031625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true); 2041625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett } else { 2051625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false); 2061625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett } 2071625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett } 2081625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett 2096fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen @Override 2106fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen public void showUsabilityHint() { 2116fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen } 2126fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen 213dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller /** TODO: hook this up */ 214dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void cleanUp() { 215dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.v(TAG, "Cleanup() called on " + this); 216dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = null; 217dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setOnPatternListener(null); 218dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 219dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 220dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 221dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onWindowFocusChanged(boolean hasWindowFocus) { 222dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller super.onWindowFocusChanged(hasWindowFocus); 223dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (hasWindowFocus) { 224dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // when timeout dialog closes we want to update our state 225dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller reset(); 226dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 227dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 228dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 229dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private class UnlockPatternListener implements LockPatternView.OnPatternListener { 230dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 231dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternStart() { 232dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.removeCallbacks(mCancelPatternRunnable); 233dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 234dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 235dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternCleared() { 236dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 237dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 238dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternCellAdded(List<LockPatternView.Cell> pattern) { 239dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // To guard against accidental poking of the wakelock, look for 240dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // the user actually trying to draw a pattern of some minimal length. 241dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { 242dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS); 243dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 244dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // Give just a little extra time if they hit one of the first few dots 245dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS); 246dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 247dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 248dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 249dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternDetected(List<LockPatternView.Cell> pattern) { 250dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mLockPatternUtils.checkPattern(pattern)) { 251d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller mCallback.reportSuccessfulUnlockAttempt(); 252dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct); 253258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller mTotalFailedPatternAttempts = 0; 254d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller mCallback.dismiss(true); 255dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 256dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { 257dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS); 258dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 259dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong); 260dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { 261dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mTotalFailedPatternAttempts++; 262dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mFailedPatternAttemptsSinceLastTimeout++; 263dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.reportFailedUnlockAttempt(); 264dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 265dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mFailedPatternAttemptsSinceLastTimeout 266dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { 267dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); 268dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller handleAttemptLockout(deadline); 269dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 2700a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true); 271dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS); 272dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 273dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 274dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 275dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 276dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 277dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void maybeEnableFallback(Context context) { 278dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // Ask the account manager if we have an account that can be used as a 279dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // fallback in case the user forgets his pattern. 280dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context)); 281dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller accountAnalyzer.start(); 282dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 283dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 284dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private class AccountAnalyzer implements AccountManagerCallback<Bundle> { 285dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private final AccountManager mAccountManager; 286dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private final Account[] mAccounts; 287dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private int mAccountIndex; 288dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 289dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private AccountAnalyzer(AccountManager accountManager) { 290dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountManager = accountManager; 2912c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani mAccounts = accountManager.getAccountsByTypeAsUser("com.google", 2922c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani new UserHandle(mLockPatternUtils.getCurrentUser())); 293dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 294dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 295dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void next() { 296dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // if we are ready to enable the fallback or if we depleted the list of accounts 297dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // then finish and get out 2986f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen if (mEnableFallback || mAccountIndex >= mAccounts.length) { 299dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return; 300dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 301dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 302dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // lookup the confirmCredentials intent for the current account 3032c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani mAccountManager.confirmCredentialsAsUser(mAccounts[mAccountIndex], null, null, this, 3042c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani null, new UserHandle(mLockPatternUtils.getCurrentUser())); 305dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 306dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 307dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void start() { 308dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mEnableFallback = false; 309dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountIndex = 0; 310dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller next(); 311dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 312dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 313dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void run(AccountManagerFuture<Bundle> future) { 314dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller try { 315dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller Bundle result = future.getResult(); 316dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (result.getParcelable(AccountManager.KEY_INTENT) != null) { 317dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mEnableFallback = true; 318dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 319dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } catch (OperationCanceledException e) { 320dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // just skip the account if we are unable to query it 321dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } catch (IOException e) { 322dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // just skip the account if we are unable to query it 323dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } catch (AuthenticatorException e) { 324dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // just skip the account if we are unable to query it 325dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } finally { 326dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountIndex++; 327dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller next(); 328dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 329dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 330dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 331dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 332dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void handleAttemptLockout(long elapsedRealtimeDeadline) { 333dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.clearPattern(); 334dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setEnabled(false); 335dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller final long elapsedRealtime = SystemClock.elapsedRealtime(); 3366f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen if (mEnableFallback) { 3376f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen updateFooter(FooterMode.ForgotLockPattern); 3386f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen } 339258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller 340dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) { 341dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 342dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 343dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onTick(long millisUntilFinished) { 344dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller final int secondsRemaining = (int) (millisUntilFinished / 1000); 3450ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller mSecurityMessageDisplay.setMessage( 3460a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining); 347dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 348dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 349dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 350dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onFinish() { 351dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setEnabled(true); 3521625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett displayDefaultSecurityMessage(); 353dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // TODO mUnlockIcon.setVisibility(View.VISIBLE); 354dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mFailedPatternAttemptsSinceLastTimeout = 0; 355dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mEnableFallback) { 356dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.ForgotLockPattern); 357dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 358dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.Normal); 359dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 360dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 361dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 362dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller }.start(); 363dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 364dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 365dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 366dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public boolean needsInput() { 367dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return false; 368dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 369dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 370dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 371dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPause() { 372dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mCountdownTimer != null) { 373dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCountdownTimer.cancel(); 374dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCountdownTimer = null; 375dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 376dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 377dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 378dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 379dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onResume() { 380dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller reset(); 381dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 382dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 383dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 384dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public KeyguardSecurityCallback getCallback() { 385dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return mCallback; 386dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 387dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller} 388dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 389dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 390dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 391