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