KeyguardPatternView.java revision c0ae9e67ebe6f1298800feaed1b43e867139a904
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; 26c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wrenimport android.graphics.drawable.Drawable; 27dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.Bundle; 28dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.CountDownTimer; 29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.SystemClock; 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; 88c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren private View mEcaView; 89c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren private Drawable mBouncerFrame; 90dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 91dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller enum FooterMode { 92dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller Normal, 93dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller ForgotLockPattern, 94dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller VerifyUnlocked 95dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 96dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 97dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public KeyguardPatternView(Context context) { 98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller this(context, null); 99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public KeyguardPatternView(Context context, AttributeSet attrs) { 102dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller super(context, attrs); 103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 104dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 105dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void setKeyguardCallback(KeyguardSecurityCallback callback) { 106dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback = callback; 107dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 108dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 109dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void setLockPatternUtils(LockPatternUtils utils) { 110dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = utils; 111dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 112dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 113dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 114dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller protected void onFinishInflate() { 115dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller super.onFinishInflate(); 116dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = mLockPatternUtils == null 117dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller ? new LockPatternUtils(mContext) : mLockPatternUtils; 118dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 119dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView); 120dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setSaveEnabled(false); 121dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setFocusable(false); 122dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setOnPatternListener(new UnlockPatternListener()); 123dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 124dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // stealth mode will be the same for the life of this screen 125dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled()); 126dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 127dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // vibrate mode will be the same for the life of this screen 128dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); 129dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 130dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button); 131dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setText(R.string.kg_forgot_pattern_button_text); 132dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setOnClickListener(new OnClickListener() { 133dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onClick(View v) { 134258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller mCallback.showBackupSecurity(); 135dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 136dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller }); 137dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 138dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller setFocusableInTouchMode(true); 139dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 140dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller maybeEnableFallback(mContext); 1410b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); 142c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren mEcaView = findViewById(R.id.keyguard_selector_fade_container); 143c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame); 144c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren if (bouncerFrameView != null) { 145c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren mBouncerFrame = bouncerFrameView.getBackground(); 146c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren } 147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 148dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 149dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void updateFooter(FooterMode mode) { 150dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller switch (mode) { 151dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller case Normal: 152dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.d(TAG, "mode normal"); 153dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setVisibility(View.GONE); 154dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller break; 155dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller case ForgotLockPattern: 156dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.d(TAG, "mode ForgotLockPattern"); 157dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setVisibility(View.VISIBLE); 158dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller break; 159dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller case VerifyUnlocked: 160dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.d(TAG, "mode VerifyUnlocked"); 161dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mForgotPatternButton.setVisibility(View.GONE); 162dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 163dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 164dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 165dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 166d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller public boolean onTouchEvent(MotionEvent ev) { 167d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller boolean result = super.onTouchEvent(ev); 168dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // as long as the user is entering a pattern (i.e sending a touch event that was handled 169dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // by this screen), keep poking the wake lock so that the screen will stay on. 170dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime; 171dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) { 172dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLastPokeTime = SystemClock.elapsedRealtime(); 173dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 1745737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller mTempRect.set(0, 0, 0, 0); 1755737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller offsetRectIntoDescendantCoords(mLockPatternView, mTempRect); 1765737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller ev.offsetLocation(mTempRect.left, mTempRect.top); 1775737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller result = mLockPatternView.dispatchTouchEvent(ev) || result; 1785737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller ev.offsetLocation(-mTempRect.left, -mTempRect.top); 179dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return result; 180dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 181dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 182dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void reset() { 183dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // reset lock pattern 184dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.enableInput(); 185dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setEnabled(true); 186dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.clearPattern(); 187dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 188dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // if the user is currently locked out, enforce it. 189dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); 190dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (deadline != 0) { 191dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller handleAttemptLockout(deadline); 192dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 1931625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett displayDefaultSecurityMessage(); 194dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 195dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 196dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // the footer depends on how many total attempts the user has failed 197dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mCallback.isVerifyUnlockOnly()) { 198dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.VerifyUnlocked); 199dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else if (mEnableFallback && 200dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller (mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { 201dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.ForgotLockPattern); 202dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 203dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.Normal); 204dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 205dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 206dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 207dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 2081625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett private void displayDefaultSecurityMessage() { 2091625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) { 2101625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true); 2111625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett } else { 2121625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false); 2131625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett } 2141625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett } 2151625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett 2166fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen @Override 2176fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen public void showUsabilityHint() { 2186fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen } 2196fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen 220dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller /** TODO: hook this up */ 221dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void cleanUp() { 222dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (DEBUG) Log.v(TAG, "Cleanup() called on " + this); 223dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = null; 224dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setOnPatternListener(null); 225dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 226dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 227dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 228dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onWindowFocusChanged(boolean hasWindowFocus) { 229dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller super.onWindowFocusChanged(hasWindowFocus); 230dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (hasWindowFocus) { 231dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // when timeout dialog closes we want to update our state 232dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller reset(); 233dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 234dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 235dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 236dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private class UnlockPatternListener implements LockPatternView.OnPatternListener { 237dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 238dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternStart() { 239dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.removeCallbacks(mCancelPatternRunnable); 240dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 241dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 242dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternCleared() { 243dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 244dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 245dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternCellAdded(List<LockPatternView.Cell> pattern) { 246dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // To guard against accidental poking of the wakelock, look for 247dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // the user actually trying to draw a pattern of some minimal length. 248dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { 249dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS); 250dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 251dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // Give just a little extra time if they hit one of the first few dots 252dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS); 253dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 254dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 255dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 256dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPatternDetected(List<LockPatternView.Cell> pattern) { 257dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mLockPatternUtils.checkPattern(pattern)) { 258d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller mCallback.reportSuccessfulUnlockAttempt(); 259dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct); 260258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller mTotalFailedPatternAttempts = 0; 261d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller mCallback.dismiss(true); 262dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 263dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { 264dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS); 265dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 266dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong); 267dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { 268dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mTotalFailedPatternAttempts++; 269dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mFailedPatternAttemptsSinceLastTimeout++; 270dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCallback.reportFailedUnlockAttempt(); 271dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 272dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mFailedPatternAttemptsSinceLastTimeout 273dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { 274dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); 275dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller handleAttemptLockout(deadline); 276dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 2770a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true); 278dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS); 279dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 280dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 281dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 282dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 283dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 284dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void maybeEnableFallback(Context context) { 285dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // Ask the account manager if we have an account that can be used as a 286dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // fallback in case the user forgets his pattern. 287dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context)); 288dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller accountAnalyzer.start(); 289dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 290dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 291dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private class AccountAnalyzer implements AccountManagerCallback<Bundle> { 292dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private final AccountManager mAccountManager; 293dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private final Account[] mAccounts; 294dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private int mAccountIndex; 295dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 296dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private AccountAnalyzer(AccountManager accountManager) { 297dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountManager = accountManager; 298dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccounts = accountManager.getAccountsByType("com.google"); 299dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 300dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 301dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void next() { 302dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // if we are ready to enable the fallback or if we depleted the list of accounts 303dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // then finish and get out 3046f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen if (mEnableFallback || mAccountIndex >= mAccounts.length) { 305dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return; 306dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 307dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 308dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // lookup the confirmCredentials intent for the current account 309dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountManager.confirmCredentials(mAccounts[mAccountIndex], null, null, this, null); 310dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 311dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 312dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void start() { 313dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mEnableFallback = false; 314dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountIndex = 0; 315dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller next(); 316dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 317dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 318dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void run(AccountManagerFuture<Bundle> future) { 319dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller try { 320dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller Bundle result = future.getResult(); 321dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (result.getParcelable(AccountManager.KEY_INTENT) != null) { 322dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mEnableFallback = true; 323dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 324dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } catch (OperationCanceledException e) { 325dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // just skip the account if we are unable to query it 326dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } catch (IOException e) { 327dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // just skip the account if we are unable to query it 328dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } catch (AuthenticatorException e) { 329dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // just skip the account if we are unable to query it 330dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } finally { 331dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mAccountIndex++; 332dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller next(); 333dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 334dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 335dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 336dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 337dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller private void handleAttemptLockout(long elapsedRealtimeDeadline) { 338dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.clearPattern(); 339dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setEnabled(false); 340dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller final long elapsedRealtime = SystemClock.elapsedRealtime(); 3416f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen if (mEnableFallback) { 3426f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen updateFooter(FooterMode.ForgotLockPattern); 3436f131416ba4ff48067dc4e627971391a6b6778c4Adam Cohen } 344258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller 345dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) { 346dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 347dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 348dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onTick(long millisUntilFinished) { 349dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller final int secondsRemaining = (int) (millisUntilFinished / 1000); 3500ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller mSecurityMessageDisplay.setMessage( 3510a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining); 352dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 353dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 354dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 355dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onFinish() { 356dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternView.setEnabled(true); 3571625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett displayDefaultSecurityMessage(); 358dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller // TODO mUnlockIcon.setVisibility(View.VISIBLE); 359dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mFailedPatternAttemptsSinceLastTimeout = 0; 360dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mEnableFallback) { 361dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.ForgotLockPattern); 362dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } else { 363dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller updateFooter(FooterMode.Normal); 364dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 365dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 366dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 367dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller }.start(); 368dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 369dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 370dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 371dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public boolean needsInput() { 372dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return false; 373dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 374dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 375dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 376dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onPause() { 377dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller if (mCountdownTimer != null) { 378dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCountdownTimer.cancel(); 379dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mCountdownTimer = null; 380dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 381dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 382dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 383dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 384dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public void onResume() { 385dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller reset(); 386dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 387dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 388dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller @Override 389dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller public KeyguardSecurityCallback getCallback() { 390dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller return mCallback; 391dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller } 392dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 393c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren @Override 394c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren public void showBouncer(int duration) { 395c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren KeyguardSecurityViewHelper. 396c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); 397c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren } 398dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller 399c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren @Override 400c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren public void hideBouncer(int duration) { 401c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren KeyguardSecurityViewHelper. 402c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); 403c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren } 404c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren} 405