11f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/* 21f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 31f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * 41f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 51f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * you may not use this file except in compliance with the License. 61f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * You may obtain a copy of the License at 71f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * 81f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 91f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * 101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * See the License for the specific language governing permissions and 141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * limitations under the License. 151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */ 161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectpackage com.android.internal.policy.impl; 181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context; 205475906f53e2d79807548932dfabbf9945143740Jim Millerimport android.content.res.Configuration; 211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.CountDownTimer; 221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.SystemClock; 235cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstromimport android.security.KeyStore; 241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.LayoutInflater; 251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View; 261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.MotionEvent; 271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.Button; 2816541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandlerimport android.util.Log; 291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.R; 301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient; 311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.widget.LockPatternUtils; 321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.widget.LockPatternView; 3372f230e32ec889607f7d85594396cc3b002bae8cJim Millerimport com.android.internal.widget.LockPatternView.Cell; 341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.List; 361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/** 381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * This is the screen that shows the 9 circle unlock widget and instructs 391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * the user how to unlock their device, or make an emergency call. 401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */ 4142b432d84cd3bf860a03a10e9191738e05f2eaddJim Millerclass PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient 426b05d58018c2806459c121e507c005639b74aee9Jim Miller implements KeyguardScreen { 431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 443421c02956c3231dd2cc514402b5f96b9f288ef5JP Abgrall private static final boolean DEBUG = false; 451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private static final String TAG = "UnlockScreen"; 461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // how long before we clear the wrong pattern 481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000; 491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 506fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK 511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000; 521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 536fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller // how long we stay awake after the user hits the first dot. 546fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000; 556fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller 5672f230e32ec889607f7d85594396cc3b002bae8cJim Miller // how many cells the user has to cross before we poke the wakelock 5772f230e32ec889607f7d85594396cc3b002bae8cJim Miller private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2; 5872f230e32ec889607f7d85594396cc3b002bae8cJim Miller 591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private int mFailedPatternAttemptsSinceLastTimeout = 0; 601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private int mTotalFailedPatternAttempts = 0; 611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private CountDownTimer mCountdownTimer = null; 621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 638b886fab5496b0b1f5193f21855220176deddc37Jim Miller private LockPatternUtils mLockPatternUtils; 648b886fab5496b0b1f5193f21855220176deddc37Jim Miller private KeyguardUpdateMonitor mUpdateMonitor; 658b886fab5496b0b1f5193f21855220176deddc37Jim Miller private KeyguardScreenCallback mCallback; 661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 67d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen /** 68d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen * whether there is a fallback option available when the pattern is forgotten. 69d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen */ 7063b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn private boolean mEnableFallback; 71d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen 726b05d58018c2806459c121e507c005639b74aee9Jim Miller private KeyguardStatusViewManager mKeyguardStatusViewManager; 731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private LockPatternView mLockPatternView; 741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** 761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Keeps track of the last time we poked the wake lock during dispatching 771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * of the touch event, initalized to something gauranteed to make us 781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * poke it when the user starts drawing the pattern. 7947088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller * @see #dispatchTouchEvent(android.view.MotionEvent) 801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */ 811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS; 821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** 841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Useful for clearing out the wrong pattern after a delay 851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */ 861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private Runnable mCancelPatternRunnable = new Runnable() { 871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void run() { 881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.clearPattern(); 891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project }; 911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 920d244193bed0c995e2beaff5e217200457b28b9dJim Miller private final OnClickListener mForgotPatternClick = new OnClickListener() { 930d244193bed0c995e2beaff5e217200457b28b9dJim Miller public void onClick(View v) { 940d244193bed0c995e2beaff5e217200457b28b9dJim Miller mCallback.forgotPattern(true); 950d244193bed0c995e2beaff5e217200457b28b9dJim Miller } 960d244193bed0c995e2beaff5e217200457b28b9dJim Miller }; 970d244193bed0c995e2beaff5e217200457b28b9dJim Miller 981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private Button mForgotPatternButton; 995475906f53e2d79807548932dfabbf9945143740Jim Miller private int mCreationOrientation; 1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project enum FooterMode { 1021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project Normal, 1031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project ForgotLockPattern, 1041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project VerifyUnlocked 1051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 1061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1070d244193bed0c995e2beaff5e217200457b28b9dJim Miller private void hideForgotPatternButton() { 1080d244193bed0c995e2beaff5e217200457b28b9dJim Miller mForgotPatternButton.setVisibility(View.GONE); 1090d244193bed0c995e2beaff5e217200457b28b9dJim Miller } 1100d244193bed0c995e2beaff5e217200457b28b9dJim Miller 1110d244193bed0c995e2beaff5e217200457b28b9dJim Miller private void showForgotPatternButton() { 1120d244193bed0c995e2beaff5e217200457b28b9dJim Miller mForgotPatternButton.setVisibility(View.VISIBLE); 1130d244193bed0c995e2beaff5e217200457b28b9dJim Miller } 1140d244193bed0c995e2beaff5e217200457b28b9dJim Miller 1151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private void updateFooter(FooterMode mode) { 1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project switch (mode) { 1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project case Normal: 1180d244193bed0c995e2beaff5e217200457b28b9dJim Miller if (DEBUG) Log.d(TAG, "mode normal"); 1190d244193bed0c995e2beaff5e217200457b28b9dJim Miller hideForgotPatternButton(); 1201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project break; 1211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project case ForgotLockPattern: 1220d244193bed0c995e2beaff5e217200457b28b9dJim Miller if (DEBUG) Log.d(TAG, "mode ForgotLockPattern"); 1230d244193bed0c995e2beaff5e217200457b28b9dJim Miller showForgotPatternButton(); 1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project break; 1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project case VerifyUnlocked: 1260d244193bed0c995e2beaff5e217200457b28b9dJim Miller if (DEBUG) Log.d(TAG, "mode VerifyUnlocked"); 1270d244193bed0c995e2beaff5e217200457b28b9dJim Miller hideForgotPatternButton(); 1281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 1291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 1301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** 1321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * @param context The context. 1335475906f53e2d79807548932dfabbf9945143740Jim Miller * @param configuration 1341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * @param lockPatternUtils Used to lookup lock pattern settings. 1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * @param updateMonitor Used to lookup state affecting keyguard. 1361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * @param callback Used to notify the manager when we're done, etc. 1371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * @param totalFailedAttempts The current number of failed attempts. 138d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen * @param enableFallback True if a backup unlock option is available when the user has forgotten 139d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen * their pattern (e.g they have a google account so we can show them the account based 140d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen * backup option). 1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */ 14242b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller PatternUnlockScreen(Context context, 1435475906f53e2d79807548932dfabbf9945143740Jim Miller Configuration configuration, LockPatternUtils lockPatternUtils, 144d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen KeyguardUpdateMonitor updateMonitor, 145d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen KeyguardScreenCallback callback, 14663b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn int totalFailedAttempts) { 1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project super(context); 1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternUtils = lockPatternUtils; 1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mUpdateMonitor = updateMonitor; 1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mCallback = callback; 1511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mTotalFailedPatternAttempts = totalFailedAttempts; 1525475906f53e2d79807548932dfabbf9945143740Jim Miller mFailedPatternAttemptsSinceLastTimeout = 1535475906f53e2d79807548932dfabbf9945143740Jim Miller totalFailedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT; 1541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 15516541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler if (DEBUG) Log.d(TAG, 15616541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler "UnlockScreen() ctor: totalFailedAttempts=" 15716541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler + totalFailedAttempts + ", mFailedPat...=" 15847088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller + mFailedPatternAttemptsSinceLastTimeout 15916541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler ); 16016541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler 1615475906f53e2d79807548932dfabbf9945143740Jim Miller mCreationOrientation = configuration.orientation; 1625475906f53e2d79807548932dfabbf9945143740Jim Miller 1635475906f53e2d79807548932dfabbf9945143740Jim Miller LayoutInflater inflater = LayoutInflater.from(context); 1648171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 1655475906f53e2d79807548932dfabbf9945143740Jim Miller if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) { 1668171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung Log.d(TAG, "portrait mode"); 1675475906f53e2d79807548932dfabbf9945143740Jim Miller inflater.inflate(R.layout.keyguard_screen_unlock_portrait, this, true); 1681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } else { 1698171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung Log.d(TAG, "landscape mode"); 1705475906f53e2d79807548932dfabbf9945143740Jim Miller inflater.inflate(R.layout.keyguard_screen_unlock_landscape, this, true); 1711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 1721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1736b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor, 174ebcd6bb1b9ac5f898621ba25c37f2e3ccd2ff33bAdam Cohen mLockPatternUtils, mCallback, true); 1751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 176add3930c01370ac2b5b1e052130e578487b42cdaKarl Rosaen mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern); 1771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1780d244193bed0c995e2beaff5e217200457b28b9dJim Miller mForgotPatternButton = (Button) findViewById(R.id.forgotPatternButton); 1791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mForgotPatternButton.setText(R.string.lockscreen_forgot_pattern_button_text); 1800d244193bed0c995e2beaff5e217200457b28b9dJim Miller mForgotPatternButton.setOnClickListener(mForgotPatternClick); 1811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // make it so unhandled touch events within the unlock screen go to the 1831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // lock pattern view. 1841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project setDefaultTouchRecepient(mLockPatternView); 1851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setSaveEnabled(false); 1871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setFocusable(false); 1881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setOnPatternListener(new UnlockPatternListener()); 1891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // stealth mode will be the same for the life of this screen 1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled()); 1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // vibrate mode will be the same for the life of this screen 1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); 1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // assume normal footer mode for now 1971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project updateFooter(FooterMode.Normal); 1981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 1991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project setFocusableInTouchMode(true); 2001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 20263b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn public void setEnableFallback(boolean state) { 20316541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler if (DEBUG) Log.d(TAG, "setEnableFallback(" + state + ")"); 20463b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn mEnableFallback = state; 20563b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn } 20647088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller 2071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project @Override 2081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 2091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // as long as the user is entering a pattern (i.e sending a touch 2101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // event that was handled by this screen), keep poking the 2111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // wake lock so that the screen will stay on. 2121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project final boolean result = super.dispatchTouchEvent(ev); 2131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project if (result && 2141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project ((SystemClock.elapsedRealtime() - mLastPokeTime) 2151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) { 2161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLastPokeTime = SystemClock.elapsedRealtime(); 2171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project return result; 2191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 22175787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn @Override 22275787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn protected void onAttachedToWindow() { 22375787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn super.onAttachedToWindow(); 22475787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn if (LockPatternKeyguardView.DEBUG_CONFIGURATION) { 22575787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn Log.v(TAG, "***** PATTERN ATTACHED TO WINDOW"); 22675787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn Log.v(TAG, "Cur orient=" + mCreationOrientation 22775787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn + ", new config=" + getResources().getConfiguration()); 22875787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn } 22975787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn if (getResources().getConfiguration().orientation != mCreationOrientation) { 23075787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn mCallback.recreateMe(getResources().getConfiguration()); 23175787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn } 23275787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn } 23375787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn 234bf019065f0ccf7e85cfbbfa5f25b200bf326e0ebKarl Rosaen 2351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** {@inheritDoc} */ 2365475906f53e2d79807548932dfabbf9945143740Jim Miller @Override 2375475906f53e2d79807548932dfabbf9945143740Jim Miller protected void onConfigurationChanged(Configuration newConfig) { 2385475906f53e2d79807548932dfabbf9945143740Jim Miller super.onConfigurationChanged(newConfig); 23975787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn if (LockPatternKeyguardView.DEBUG_CONFIGURATION) { 24075787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn Log.v(TAG, "***** PATTERN CONFIGURATION CHANGED"); 24175787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn Log.v(TAG, "Cur orient=" + mCreationOrientation 24275787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn + ", new config=" + getResources().getConfiguration()); 24375787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn } 2445475906f53e2d79807548932dfabbf9945143740Jim Miller if (newConfig.orientation != mCreationOrientation) { 2455475906f53e2d79807548932dfabbf9945143740Jim Miller mCallback.recreateMe(newConfig); 2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 2491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** {@inheritDoc} */ 2501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onKeyboardChange(boolean isKeyboardOpen) {} 2511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** {@inheritDoc} */ 2531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public boolean needsInput() { 2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project return false; 2551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 25647088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller 2571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** {@inheritDoc} */ 2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onPause() { 2591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project if (mCountdownTimer != null) { 2601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mCountdownTimer.cancel(); 2611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mCountdownTimer = null; 2621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2636b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.onPause(); 2641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 2661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** {@inheritDoc} */ 2671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onResume() { 2688171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung // reset status 2696b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.onResume(); 2701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 2711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // reset lock pattern 2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.enableInput(); 2731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setEnabled(true); 2741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.clearPattern(); 27547088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller 2761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // show "forgot pattern?" button if we have an alternate authentication method 2770d244193bed0c995e2beaff5e217200457b28b9dJim Miller if (mCallback.doesFallbackUnlockScreenExist()) { 2780d244193bed0c995e2beaff5e217200457b28b9dJim Miller showForgotPatternButton(); 2790d244193bed0c995e2beaff5e217200457b28b9dJim Miller } else { 2800d244193bed0c995e2beaff5e217200457b28b9dJim Miller hideForgotPatternButton(); 2810d244193bed0c995e2beaff5e217200457b28b9dJim Miller } 2821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 2831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // if the user is currently locked out, enforce it. 2841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); 2851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project if (deadline != 0) { 2861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project handleAttemptLockout(deadline); 2871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 2881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 2891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project // the footer depends on how many total attempts the user has failed 2901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project if (mCallback.isVerifyUnlockOnly()) { 2911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project updateFooter(FooterMode.VerifyUnlocked); 292d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen } else if (mEnableFallback && 293d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen (mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { 2941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project updateFooter(FooterMode.ForgotLockPattern); 295d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen } else { 296d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen updateFooter(FooterMode.Normal); 2971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 298c23024d32779b170dde32a50fbdd945ce521b874Jim Miller 2991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 3011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project /** {@inheritDoc} */ 3021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void cleanUp() { 30379628c6662b863c220ff68159e4272f45d66cbe8Jim Miller if (DEBUG) Log.v(TAG, "Cleanup() called on " + this); 3041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mUpdateMonitor.removeCallback(this); 3058b886fab5496b0b1f5193f21855220176deddc37Jim Miller mLockPatternUtils = null; 3068b886fab5496b0b1f5193f21855220176deddc37Jim Miller mUpdateMonitor = null; 3078b886fab5496b0b1f5193f21855220176deddc37Jim Miller mCallback = null; 30879628c6662b863c220ff68159e4272f45d66cbe8Jim Miller mLockPatternView.setOnPatternListener(null); 3091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 31184999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen @Override 31284999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen public void onWindowFocusChanged(boolean hasWindowFocus) { 31384999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen super.onWindowFocusChanged(hasWindowFocus); 31484999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen if (hasWindowFocus) { 31584999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen // when timeout dialog closes we want to update our state 31684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen onResume(); 31784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen } 31884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen } 31984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen 3201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private class UnlockPatternListener 3211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project implements LockPatternView.OnPatternListener { 3221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 3231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onPatternStart() { 3241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.removeCallbacks(mCancelPatternRunnable); 3251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 3271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onPatternCleared() { 3281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 33072f230e32ec889607f7d85594396cc3b002bae8cJim Miller public void onPatternCellAdded(List<Cell> pattern) { 33172f230e32ec889607f7d85594396cc3b002bae8cJim Miller // To guard against accidental poking of the wakelock, look for 33247088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller // the user actually trying to draw a pattern of some minimal length. 33372f230e32ec889607f7d85594396cc3b002bae8cJim Miller if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { 33472f230e32ec889607f7d85594396cc3b002bae8cJim Miller mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS); 3356fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller } else { 3366fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller // Give just a little extra time if they hit one of the first few dots 3376fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS); 33872f230e32ec889607f7d85594396cc3b002bae8cJim Miller } 33972f230e32ec889607f7d85594396cc3b002bae8cJim Miller } 34072f230e32ec889607f7d85594396cc3b002bae8cJim Miller 3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onPatternDetected(List<LockPatternView.Cell> pattern) { 3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project if (mLockPatternUtils.checkPattern(pattern)) { 3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView 3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project .setDisplayMode(LockPatternView.DisplayMode.Correct); 3456b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.setInstructionText(""); 3466b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.updateStatusLines(true); 3471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mCallback.keyguardDone(true); 3486fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller mCallback.reportSuccessfulUnlockAttempt(); 3495cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom KeyStore.getInstance().password(LockPatternUtils.patternToString(pattern)); 3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } else { 35179628c6662b863c220ff68159e4272f45d66cbe8Jim Miller boolean reportFailedAttempt = false; 35272f230e32ec889607f7d85594396cc3b002bae8cJim Miller if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { 35372f230e32ec889607f7d85594396cc3b002bae8cJim Miller mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS); 35472f230e32ec889607f7d85594396cc3b002bae8cJim Miller } 3551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong); 3561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { 3571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mTotalFailedPatternAttempts++; 3581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mFailedPatternAttemptsSinceLastTimeout++; 35979628c6662b863c220ff68159e4272f45d66cbe8Jim Miller reportFailedAttempt = true; 3601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 36179628c6662b863c220ff68159e4272f45d66cbe8Jim Miller if (mFailedPatternAttemptsSinceLastTimeout 36279628c6662b863c220ff68159e4272f45d66cbe8Jim Miller >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { 3631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); 3641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project handleAttemptLockout(deadline); 3656fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller } else { 3666fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller // TODO mUnlockIcon.setVisibility(View.VISIBLE); 3676b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.setInstructionText( 3688171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung getContext().getString(R.string.lockscreen_pattern_wrong)); 3696b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.updateStatusLines(true); 3706fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller mLockPatternView.postDelayed( 3716fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller mCancelPatternRunnable, 3726fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller PATTERN_CLEAR_TIMEOUT_MS); 3736fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller } 37479628c6662b863c220ff68159e4272f45d66cbe8Jim Miller 37579628c6662b863c220ff68159e4272f45d66cbe8Jim Miller // Because the following can result in cleanUp() being called on this screen, 37679628c6662b863c220ff68159e4272f45d66cbe8Jim Miller // member variables reset in cleanUp() shouldn't be accessed after this call. 37779628c6662b863c220ff68159e4272f45d66cbe8Jim Miller if (reportFailedAttempt) { 37879628c6662b863c220ff68159e4272f45d66cbe8Jim Miller mCallback.reportFailedUnlockAttempt(); 37979628c6662b863c220ff68159e4272f45d66cbe8Jim Miller } 3801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 3841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project private void handleAttemptLockout(long elapsedRealtimeDeadline) { 3851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.clearPattern(); 3861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setEnabled(false); 3871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project long elapsedRealtime = SystemClock.elapsedRealtime(); 3881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) { 3891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 3901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project @Override 3911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onTick(long millisUntilFinished) { 3921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project int secondsRemaining = (int) (millisUntilFinished / 1000); 3936b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.setInstructionText(getContext().getString( 3941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project R.string.lockscreen_too_many_failed_attempts_countdown, 3958171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung secondsRemaining)); 3966b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.updateStatusLines(true); 3971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 3981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project 3991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project @Override 4001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project public void onFinish() { 4011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mLockPatternView.setEnabled(true); 4026b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.setInstructionText(getContext().getString( 4038171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung R.string.lockscreen_pattern_instructions)); 4046b05d58018c2806459c121e507c005639b74aee9Jim Miller mKeyguardStatusViewManager.updateStatusLines(true); 405bf019065f0ccf7e85cfbbfa5f25b200bf326e0ebKarl Rosaen // TODO mUnlockIcon.setVisibility(View.VISIBLE); 4061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project mFailedPatternAttemptsSinceLastTimeout = 0; 407d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen if (mEnableFallback) { 408d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen updateFooter(FooterMode.ForgotLockPattern); 409d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen } else { 410d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen updateFooter(FooterMode.Normal); 411d322c437fe48dc03f0df94492267b3783e3411cbKarl Rosaen } 4121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project }.start(); 4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project } 415c23024d32779b170dde32a50fbdd945ce521b874Jim Miller 4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project} 417