1/* 2 * Copyright (C) 2007 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 */ 16 17package com.android.internal.policy.impl; 18 19import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 20 21import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl; 22import com.android.internal.telephony.IccCard; 23import com.android.internal.widget.LockPatternUtils; 24 25import android.app.ActivityManagerNative; 26import android.app.AlarmManager; 27import android.app.PendingIntent; 28import android.app.StatusBarManager; 29import android.content.BroadcastReceiver; 30import android.content.ContentResolver; 31import android.content.Context; 32import android.content.Intent; 33import android.content.IntentFilter; 34import android.media.AudioManager; 35import android.media.SoundPool; 36import android.os.Handler; 37import android.os.LocalPowerManager; 38import android.os.Message; 39import android.os.PowerManager; 40import android.os.RemoteException; 41import android.os.SystemClock; 42import android.os.SystemProperties; 43import android.provider.Settings; 44import android.telephony.TelephonyManager; 45import android.util.EventLog; 46import android.util.Log; 47import android.view.KeyEvent; 48import android.view.WindowManagerImpl; 49import android.view.WindowManagerPolicy; 50 51 52/** 53 * Mediates requests related to the keyguard. This includes queries about the 54 * state of the keyguard, power management events that effect whether the keyguard 55 * should be shown or reset, callbacks to the phone window manager to notify 56 * it of when the keyguard is showing, and events from the keyguard view itself 57 * stating that the keyguard was succesfully unlocked. 58 * 59 * Note that the keyguard view is shown when the screen is off (as appropriate) 60 * so that once the screen comes on, it will be ready immediately. 61 * 62 * Example queries about the keyguard: 63 * - is {movement, key} one that should wake the keygaurd? 64 * - is the keyguard showing? 65 * - are input events restricted due to the state of the keyguard? 66 * 67 * Callbacks to the phone window manager: 68 * - the keyguard is showing 69 * 70 * Example external events that translate to keyguard view changes: 71 * - screen turned off -> reset the keyguard, and show it so it will be ready 72 * next time the screen turns on 73 * - keyboard is slid open -> if the keyguard is not secure, hide it 74 * 75 * Events from the keyguard view: 76 * - user succesfully unlocked keyguard -> hide keyguard view, and no longer 77 * restrict input events. 78 * 79 * Note: in addition to normal power managment events that effect the state of 80 * whether the keyguard should be showing, external apps and services may request 81 * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}. When 82 * false, this will override all other conditions for turning on the keyguard. 83 * 84 * Threading and synchronization: 85 * This class is created by the initialization routine of the {@link WindowManagerPolicy}, 86 * and runs on its thread. The keyguard UI is created from that thread in the 87 * constructor of this class. The apis may be called from other threads, including the 88 * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s. 89 * Therefore, methods on this class are synchronized, and any action that is pointed 90 * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI 91 * thread of the keyguard. 92 */ 93public class KeyguardViewMediator implements KeyguardViewCallback, 94 KeyguardUpdateMonitor.SimStateCallback { 95 private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000; 96 private final static boolean DEBUG = false; 97 private final static boolean DBG_WAKE = false; 98 99 private final static String TAG = "KeyguardViewMediator"; 100 101 private static final String DELAYED_KEYGUARD_ACTION = 102 "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"; 103 104 // used for handler messages 105 private static final int TIMEOUT = 1; 106 private static final int SHOW = 2; 107 private static final int HIDE = 3; 108 private static final int RESET = 4; 109 private static final int VERIFY_UNLOCK = 5; 110 private static final int NOTIFY_SCREEN_OFF = 6; 111 private static final int NOTIFY_SCREEN_ON = 7; 112 private static final int WAKE_WHEN_READY = 8; 113 private static final int KEYGUARD_DONE = 9; 114 private static final int KEYGUARD_DONE_DRAWING = 10; 115 private static final int KEYGUARD_DONE_AUTHENTICATING = 11; 116 private static final int SET_HIDDEN = 12; 117 private static final int KEYGUARD_TIMEOUT = 13; 118 119 /** 120 * The default amount of time we stay awake (used for all key input) 121 */ 122 protected static final int AWAKE_INTERVAL_DEFAULT_MS = 10000; 123 124 /** 125 * How long to wait after the screen turns off due to timeout before 126 * turning on the keyguard (i.e, the user has this much time to turn 127 * the screen back on without having to face the keyguard). 128 */ 129 private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000; 130 131 /** 132 * How long we'll wait for the {@link KeyguardViewCallback#keyguardDoneDrawing()} 133 * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)} 134 * that is reenabling the keyguard. 135 */ 136 private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000; 137 138 /** 139 * Allow the user to expand the status bar when the keyguard is engaged 140 * (without a pattern or password). 141 */ 142 private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true; 143 144 /** The stream type that the lock sounds are tied to. */ 145 private int mMasterStreamType; 146 147 private Context mContext; 148 private AlarmManager mAlarmManager; 149 private AudioManager mAudioManager; 150 private StatusBarManager mStatusBarManager; 151 private boolean mShowLockIcon; 152 private boolean mShowingLockIcon; 153 154 private boolean mSystemReady; 155 156 // Whether the next call to playSounds() should be skipped. Defaults to 157 // true because the first lock (on boot) should be silent. 158 private boolean mSuppressNextLockSound = true; 159 160 161 /** Low level access to the power manager for enableUserActivity. Having this 162 * requires that we run in the system process. */ 163 LocalPowerManager mRealPowerManager; 164 165 /** High level access to the power manager for WakeLocks */ 166 private PowerManager mPM; 167 168 /** 169 * Used to keep the device awake while the keyguard is showing, i.e for 170 * calls to {@link #pokeWakelock()} 171 */ 172 private PowerManager.WakeLock mWakeLock; 173 174 /** 175 * Used to keep the device awake while to ensure the keyguard finishes opening before 176 * we sleep. 177 */ 178 private PowerManager.WakeLock mShowKeyguardWakeLock; 179 180 /** 181 * Does not turn on screen, held while a call to {@link KeyguardViewManager#wakeWhenReadyTq(int)} 182 * is called to make sure the device doesn't sleep before it has a chance to poke 183 * the wake lock. 184 * @see #wakeWhenReadyLocked(int) 185 */ 186 private PowerManager.WakeLock mWakeAndHandOff; 187 188 private KeyguardViewManager mKeyguardViewManager; 189 190 // these are protected by synchronized (this) 191 192 /** 193 * External apps (like the phone app) can tell us to disable the keygaurd. 194 */ 195 private boolean mExternallyEnabled = true; 196 197 /** 198 * Remember if an external call to {@link #setKeyguardEnabled} with value 199 * false caused us to hide the keyguard, so that we need to reshow it once 200 * the keygaurd is reenabled with another call with value true. 201 */ 202 private boolean mNeedToReshowWhenReenabled = false; 203 204 // cached value of whether we are showing (need to know this to quickly 205 // answer whether the input should be restricted) 206 private boolean mShowing = false; 207 208 // true if the keyguard is hidden by another window 209 private boolean mHidden = false; 210 211 /** 212 * Helps remember whether the screen has turned on since the last time 213 * it turned off due to timeout. see {@link #onScreenTurnedOff(int)} 214 */ 215 private int mDelayedShowingSequence; 216 217 private int mWakelockSequence; 218 219 private PhoneWindowManager mCallback; 220 221 /** 222 * If the user has disabled the keyguard, then requests to exit, this is 223 * how we'll ultimately let them know whether it was successful. We use this 224 * var being non-null as an indicator that there is an in progress request. 225 */ 226 private WindowManagerPolicy.OnKeyguardExitResult mExitSecureCallback; 227 228 // the properties of the keyguard 229 private KeyguardViewProperties mKeyguardViewProperties; 230 231 private KeyguardUpdateMonitor mUpdateMonitor; 232 233 private boolean mScreenOn = false; 234 235 // last known state of the cellular connection 236 private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE; 237 238 /** 239 * we send this intent when the keyguard is dismissed. 240 */ 241 private Intent mUserPresentIntent; 242 243 /** 244 * {@link #setKeyguardEnabled} waits on this condition when it reenables 245 * the keyguard. 246 */ 247 private boolean mWaitingUntilKeyguardVisible = false; 248 private LockPatternUtils mLockPatternUtils; 249 250 private SoundPool mLockSounds; 251 private int mLockSoundId; 252 private int mUnlockSoundId; 253 private int mLockSoundStreamId; 254 255 /** 256 * The volume applied to the lock/unlock sounds. 257 */ 258 private final float mLockSoundVolume; 259 260 InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() { 261 262 @Override 263 public void onClockVisibilityChanged() { 264 adjustStatusBarLocked(); 265 } 266 267 @Override 268 public void onDeviceProvisioned() { 269 mContext.sendBroadcast(mUserPresentIntent); 270 } 271 272 }; 273 274 public KeyguardViewMediator(Context context, PhoneWindowManager callback, 275 LocalPowerManager powerManager) { 276 mContext = context; 277 278 mRealPowerManager = powerManager; 279 mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 280 mWakeLock = mPM.newWakeLock( 281 PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 282 "keyguard"); 283 mWakeLock.setReferenceCounted(false); 284 mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard"); 285 mShowKeyguardWakeLock.setReferenceCounted(false); 286 287 mWakeAndHandOff = mPM.newWakeLock( 288 PowerManager.PARTIAL_WAKE_LOCK, 289 "keyguardWakeAndHandOff"); 290 mWakeAndHandOff.setReferenceCounted(false); 291 292 IntentFilter filter = new IntentFilter(); 293 filter.addAction(DELAYED_KEYGUARD_ACTION); 294 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 295 context.registerReceiver(mBroadCastReceiver, filter); 296 mAlarmManager = (AlarmManager) context 297 .getSystemService(Context.ALARM_SERVICE); 298 mCallback = callback; 299 300 mUpdateMonitor = new KeyguardUpdateMonitor(context); 301 302 mUpdateMonitor.registerInfoCallback(mInfoCallback); 303 304 mUpdateMonitor.registerSimStateCallback(this); 305 306 mLockPatternUtils = new LockPatternUtils(mContext); 307 mKeyguardViewProperties 308 = new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor); 309 310 mKeyguardViewManager = new KeyguardViewManager( 311 context, WindowManagerImpl.getDefault(), this, 312 mKeyguardViewProperties, mUpdateMonitor); 313 314 mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT); 315 mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 316 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 317 318 final ContentResolver cr = mContext.getContentResolver(); 319 mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1); 320 321 mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0); 322 String soundPath = Settings.System.getString(cr, Settings.System.LOCK_SOUND); 323 if (soundPath != null) { 324 mLockSoundId = mLockSounds.load(soundPath, 1); 325 } 326 if (soundPath == null || mLockSoundId == 0) { 327 if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath); 328 } 329 soundPath = Settings.System.getString(cr, Settings.System.UNLOCK_SOUND); 330 if (soundPath != null) { 331 mUnlockSoundId = mLockSounds.load(soundPath, 1); 332 } 333 if (soundPath == null || mUnlockSoundId == 0) { 334 if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath); 335 } 336 int lockSoundDefaultAttenuation = context.getResources().getInteger( 337 com.android.internal.R.integer.config_lockSoundVolumeDb); 338 mLockSoundVolume = (float)Math.pow(10, lockSoundDefaultAttenuation/20); 339 IntentFilter userFilter = new IntentFilter(); 340 userFilter.addAction(Intent.ACTION_USER_SWITCHED); 341 userFilter.addAction(Intent.ACTION_USER_REMOVED); 342 mContext.registerReceiver(mUserChangeReceiver, userFilter); 343 } 344 345 /** 346 * Let us know that the system is ready after startup. 347 */ 348 public void onSystemReady() { 349 synchronized (this) { 350 if (DEBUG) Log.d(TAG, "onSystemReady"); 351 mSystemReady = true; 352 doKeyguardLocked(); 353 } 354 } 355 356 /** 357 * Called to let us know the screen was turned off. 358 * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, 359 * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or 360 * {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}. 361 */ 362 public void onScreenTurnedOff(int why) { 363 synchronized (this) { 364 mScreenOn = false; 365 if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")"); 366 367 // Lock immediately based on setting if secure (user has a pin/pattern/password). 368 // This also "locks" the device when not secure to provide easy access to the 369 // camera while preventing unwanted input. 370 final boolean lockImmediately = 371 mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure(); 372 373 if (mExitSecureCallback != null) { 374 if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled"); 375 mExitSecureCallback.onKeyguardExitResult(false); 376 mExitSecureCallback = null; 377 if (!mExternallyEnabled) { 378 hideLocked(); 379 } 380 } else if (mShowing) { 381 notifyScreenOffLocked(); 382 resetStateLocked(); 383 } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT 384 || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) { 385 // if the screen turned off because of timeout or the user hit the power button 386 // and we don't need to lock immediately, set an alarm 387 // to enable it a little bit later (i.e, give the user a chance 388 // to turn the screen back on within a certain window without 389 // having to unlock the screen) 390 final ContentResolver cr = mContext.getContentResolver(); 391 392 // From DisplaySettings 393 long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT, 394 KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT); 395 396 // From SecuritySettings 397 final long lockAfterTimeout = Settings.Secure.getInt(cr, 398 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 399 KEYGUARD_LOCK_AFTER_DELAY_DEFAULT); 400 401 // From DevicePolicyAdmin 402 final long policyTimeout = mLockPatternUtils.getDevicePolicyManager() 403 .getMaximumTimeToLock(null); 404 405 long timeout; 406 if (policyTimeout > 0) { 407 // policy in effect. Make sure we don't go beyond policy limit. 408 displayTimeout = Math.max(displayTimeout, 0); // ignore negative values 409 timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout); 410 } else { 411 timeout = lockAfterTimeout; 412 } 413 414 if (timeout <= 0) { 415 // Lock now 416 mSuppressNextLockSound = true; 417 doKeyguardLocked(); 418 } else { 419 // Lock in the future 420 long when = SystemClock.elapsedRealtime() + timeout; 421 Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); 422 intent.putExtra("seq", mDelayedShowingSequence); 423 PendingIntent sender = PendingIntent.getBroadcast(mContext, 424 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); 425 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender); 426 if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " 427 + mDelayedShowingSequence); 428 } 429 } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) { 430 // Do not enable the keyguard if the prox sensor forced the screen off. 431 } else { 432 doKeyguardLocked(); 433 } 434 } 435 } 436 437 /** 438 * Let's us know the screen was turned on. 439 */ 440 public void onScreenTurnedOn(KeyguardViewManager.ShowListener showListener) { 441 synchronized (this) { 442 mScreenOn = true; 443 mDelayedShowingSequence++; 444 if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence); 445 if (showListener != null) { 446 notifyScreenOnLocked(showListener); 447 } 448 } 449 } 450 451 /** 452 * Same semantics as {@link WindowManagerPolicy#enableKeyguard}; provide 453 * a way for external stuff to override normal keyguard behavior. For instance 454 * the phone app disables the keyguard when it receives incoming calls. 455 */ 456 public void setKeyguardEnabled(boolean enabled) { 457 synchronized (this) { 458 if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")"); 459 460 461 mExternallyEnabled = enabled; 462 463 if (!enabled && mShowing) { 464 if (mExitSecureCallback != null) { 465 if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring"); 466 // we're in the process of handling a request to verify the user 467 // can get past the keyguard. ignore extraneous requests to disable / reenable 468 return; 469 } 470 471 // hiding keyguard that is showing, remember to reshow later 472 if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, " 473 + "disabling status bar expansion"); 474 mNeedToReshowWhenReenabled = true; 475 hideLocked(); 476 } else if (enabled && mNeedToReshowWhenReenabled) { 477 // reenabled after previously hidden, reshow 478 if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling " 479 + "status bar expansion"); 480 mNeedToReshowWhenReenabled = false; 481 482 if (mExitSecureCallback != null) { 483 if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting"); 484 mExitSecureCallback.onKeyguardExitResult(false); 485 mExitSecureCallback = null; 486 resetStateLocked(); 487 } else { 488 showLocked(); 489 490 // block until we know the keygaurd is done drawing (and post a message 491 // to unblock us after a timeout so we don't risk blocking too long 492 // and causing an ANR). 493 mWaitingUntilKeyguardVisible = true; 494 mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS); 495 if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false"); 496 while (mWaitingUntilKeyguardVisible) { 497 try { 498 wait(); 499 } catch (InterruptedException e) { 500 Thread.currentThread().interrupt(); 501 } 502 } 503 if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible"); 504 } 505 } 506 } 507 } 508 509 /** 510 * @see android.app.KeyguardManager#exitKeyguardSecurely 511 */ 512 public void verifyUnlock(WindowManagerPolicy.OnKeyguardExitResult callback) { 513 synchronized (this) { 514 if (DEBUG) Log.d(TAG, "verifyUnlock"); 515 if (!mUpdateMonitor.isDeviceProvisioned()) { 516 // don't allow this api when the device isn't provisioned 517 if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned"); 518 callback.onKeyguardExitResult(false); 519 } else if (mExternallyEnabled) { 520 // this only applies when the user has externally disabled the 521 // keyguard. this is unexpected and means the user is not 522 // using the api properly. 523 Log.w(TAG, "verifyUnlock called when not externally disabled"); 524 callback.onKeyguardExitResult(false); 525 } else if (mExitSecureCallback != null) { 526 // already in progress with someone else 527 callback.onKeyguardExitResult(false); 528 } else { 529 mExitSecureCallback = callback; 530 verifyUnlockLocked(); 531 } 532 } 533 } 534 535 /** 536 * Is the keyguard currently showing? 537 */ 538 public boolean isShowing() { 539 return mShowing; 540 } 541 542 /** 543 * Is the keyguard currently showing and not being force hidden? 544 */ 545 public boolean isShowingAndNotHidden() { 546 return mShowing && !mHidden; 547 } 548 549 /** 550 * Notify us when the keyguard is hidden by another window 551 */ 552 public void setHidden(boolean isHidden) { 553 if (DEBUG) Log.d(TAG, "setHidden " + isHidden); 554 mHandler.removeMessages(SET_HIDDEN); 555 Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0); 556 mHandler.sendMessage(msg); 557 } 558 559 /** 560 * Handles SET_HIDDEN message sent by setHidden() 561 */ 562 private void handleSetHidden(boolean isHidden) { 563 synchronized (KeyguardViewMediator.this) { 564 if (mHidden != isHidden) { 565 mHidden = isHidden; 566 updateActivityLockScreenState(); 567 adjustUserActivityLocked(); 568 adjustStatusBarLocked(); 569 } 570 } 571 } 572 573 /** 574 * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout. 575 * This must be safe to call from any thread and with any window manager locks held. 576 */ 577 public void doKeyguardTimeout() { 578 mHandler.removeMessages(KEYGUARD_TIMEOUT); 579 Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT); 580 mHandler.sendMessage(msg); 581 } 582 583 /** 584 * Given the state of the keyguard, is the input restricted? 585 * Input is restricted when the keyguard is showing, or when the keyguard 586 * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet. 587 */ 588 public boolean isInputRestricted() { 589 return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned(); 590 } 591 592 /** 593 * Enable the keyguard if the settings are appropriate. Return true if all 594 * work that will happen is done; returns false if the caller can wait for 595 * the keyguard to be shown. 596 */ 597 private void doKeyguardLocked() { 598 // if another app is disabling us, don't show 599 if (!mExternallyEnabled) { 600 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); 601 602 // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes 603 // for an occasional ugly flicker in this situation: 604 // 1) receive a call with the screen on (no keyguard) or make a call 605 // 2) screen times out 606 // 3) user hits key to turn screen back on 607 // instead, we reenable the keyguard when we know the screen is off and the call 608 // ends (see the broadcast receiver below) 609 // TODO: clean this up when we have better support at the window manager level 610 // for apps that wish to be on top of the keyguard 611 return; 612 } 613 614 // if the keyguard is already showing, don't bother 615 if (mKeyguardViewManager.isShowing()) { 616 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); 617 return; 618 } 619 620 // if the setup wizard hasn't run yet, don't show 621 final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", 622 false); 623 final boolean provisioned = mUpdateMonitor.isDeviceProvisioned(); 624 final IccCard.State state = mUpdateMonitor.getSimState(); 625 final boolean lockedOrMissing = state.isPinLocked() 626 || ((state == IccCard.State.ABSENT 627 || state == IccCard.State.PERM_DISABLED) 628 && requireSim); 629 630 if (!lockedOrMissing && !provisioned) { 631 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned" 632 + " and the sim is not locked or missing"); 633 return; 634 } 635 636 if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) { 637 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off"); 638 return; 639 } 640 641 if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen"); 642 showLocked(); 643 } 644 645 /** 646 * Send message to keyguard telling it to reset its state. 647 * @see #handleReset() 648 */ 649 private void resetStateLocked() { 650 if (DEBUG) Log.d(TAG, "resetStateLocked"); 651 Message msg = mHandler.obtainMessage(RESET); 652 mHandler.sendMessage(msg); 653 } 654 655 /** 656 * Send message to keyguard telling it to verify unlock 657 * @see #handleVerifyUnlock() 658 */ 659 private void verifyUnlockLocked() { 660 if (DEBUG) Log.d(TAG, "verifyUnlockLocked"); 661 mHandler.sendEmptyMessage(VERIFY_UNLOCK); 662 } 663 664 665 /** 666 * Send a message to keyguard telling it the screen just turned on. 667 * @see #onScreenTurnedOff(int) 668 * @see #handleNotifyScreenOff 669 */ 670 private void notifyScreenOffLocked() { 671 if (DEBUG) Log.d(TAG, "notifyScreenOffLocked"); 672 mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF); 673 } 674 675 /** 676 * Send a message to keyguard telling it the screen just turned on. 677 * @see #onScreenTurnedOn() 678 * @see #handleNotifyScreenOn 679 */ 680 private void notifyScreenOnLocked(KeyguardViewManager.ShowListener showListener) { 681 if (DEBUG) Log.d(TAG, "notifyScreenOnLocked"); 682 Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, showListener); 683 mHandler.sendMessage(msg); 684 } 685 686 /** 687 * Send message to keyguard telling it about a wake key so it can adjust 688 * its state accordingly and then poke the wake lock when it is ready. 689 * @param keyCode The wake key. 690 * @see #handleWakeWhenReady 691 * @see #onWakeKeyWhenKeyguardShowingTq(int) 692 */ 693 private void wakeWhenReadyLocked(int keyCode) { 694 if (DBG_WAKE) Log.d(TAG, "wakeWhenReadyLocked(" + keyCode + ")"); 695 696 /** 697 * acquire the handoff lock that will keep the cpu running. this will 698 * be released once the keyguard has set itself up and poked the other wakelock 699 * in {@link #handleWakeWhenReady(int)} 700 */ 701 mWakeAndHandOff.acquire(); 702 703 Message msg = mHandler.obtainMessage(WAKE_WHEN_READY, keyCode, 0); 704 mHandler.sendMessage(msg); 705 } 706 707 /** 708 * Send message to keyguard telling it to show itself 709 * @see #handleShow() 710 */ 711 private void showLocked() { 712 if (DEBUG) Log.d(TAG, "showLocked"); 713 // ensure we stay awake until we are finished displaying the keyguard 714 mShowKeyguardWakeLock.acquire(); 715 Message msg = mHandler.obtainMessage(SHOW); 716 mHandler.sendMessage(msg); 717 } 718 719 /** 720 * Send message to keyguard telling it to hide itself 721 * @see #handleHide() 722 */ 723 private void hideLocked() { 724 if (DEBUG) Log.d(TAG, "hideLocked"); 725 Message msg = mHandler.obtainMessage(HIDE); 726 mHandler.sendMessage(msg); 727 } 728 729 /** {@inheritDoc} */ 730 public void onSimStateChanged(IccCard.State simState) { 731 if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState); 732 733 switch (simState) { 734 case ABSENT: 735 // only force lock screen in case of missing sim if user hasn't 736 // gone through setup wizard 737 synchronized (this) { 738 if (!mUpdateMonitor.isDeviceProvisioned()) { 739 if (!isShowing()) { 740 if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing," 741 + " we need to show the keyguard since the " 742 + "device isn't provisioned yet."); 743 doKeyguardLocked(); 744 } else { 745 resetStateLocked(); 746 } 747 } 748 } 749 break; 750 case PIN_REQUIRED: 751 case PUK_REQUIRED: 752 synchronized (this) { 753 if (!isShowing()) { 754 if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't showing, " 755 + "we need to show keyguard so user can enter their sim pin"); 756 doKeyguardLocked(); 757 } else { 758 resetStateLocked(); 759 } 760 } 761 break; 762 case PERM_DISABLED: 763 synchronized (this) { 764 if (!isShowing()) { 765 if (DEBUG) Log.d(TAG, "PERM_DISABLED and " 766 + "keygaurd isn't showing."); 767 doKeyguardLocked(); 768 } else { 769 if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to" 770 + "show permanently disabled message in lockscreen."); 771 resetStateLocked(); 772 } 773 } 774 break; 775 case READY: 776 synchronized (this) { 777 if (isShowing()) { 778 resetStateLocked(); 779 } 780 } 781 break; 782 } 783 } 784 785 public boolean isSecure() { 786 return mKeyguardViewProperties.isSecure(); 787 } 788 789 private void onUserSwitched(int userId) { 790 mLockPatternUtils.setCurrentUser(userId); 791 synchronized (KeyguardViewMediator.this) { 792 resetStateLocked(); 793 } 794 } 795 796 private void onUserRemoved(int userId) { 797 mLockPatternUtils.removeUser(userId); 798 } 799 800 private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() { 801 @Override 802 public void onReceive(Context context, Intent intent) { 803 String action = intent.getAction(); 804 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 805 onUserSwitched(intent.getIntExtra(Intent.EXTRA_USERID, 0)); 806 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 807 onUserRemoved(intent.getIntExtra(Intent.EXTRA_USERID, 0)); 808 } 809 } 810 }; 811 812 private BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() { 813 @Override 814 public void onReceive(Context context, Intent intent) { 815 final String action = intent.getAction(); 816 if (action.equals(DELAYED_KEYGUARD_ACTION)) { 817 818 int sequence = intent.getIntExtra("seq", 0); 819 820 if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = " 821 + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence); 822 823 synchronized (KeyguardViewMediator.this) { 824 if (mDelayedShowingSequence == sequence) { 825 // Don't play lockscreen SFX if the screen went off due to 826 // timeout. 827 mSuppressNextLockSound = true; 828 829 doKeyguardLocked(); 830 } 831 } 832 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { 833 mPhoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 834 835 synchronized (KeyguardViewMediator.this) { 836 if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState) // call ending 837 && !mScreenOn // screen off 838 && mExternallyEnabled) { // not disabled by any app 839 840 // note: this is a way to gracefully reenable the keyguard when the call 841 // ends and the screen is off without always reenabling the keyguard 842 // each time the screen turns off while in call (and having an occasional ugly 843 // flicker while turning back on the screen and disabling the keyguard again). 844 if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the " 845 + "keyguard is showing"); 846 doKeyguardLocked(); 847 } 848 } 849 } 850 } 851 }; 852 853 854 /** 855 * When a key is received when the screen is off and the keyguard is showing, 856 * we need to decide whether to actually turn on the screen, and if so, tell 857 * the keyguard to prepare itself and poke the wake lock when it is ready. 858 * 859 * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}. 860 * Be sure not to take any action that takes a long time; any significant 861 * action should be posted to a handler. 862 * 863 * @param keyCode The keycode of the key that woke the device 864 * @param isDocked True if the device is in the dock 865 * @return Whether we poked the wake lock (and turned the screen on) 866 */ 867 public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode, boolean isDocked) { 868 if (DEBUG) Log.d(TAG, "onWakeKeyWhenKeyguardShowing(" + keyCode + ")"); 869 870 if (isWakeKeyWhenKeyguardShowing(keyCode, isDocked)) { 871 // give the keyguard view manager a chance to adjust the state of the 872 // keyguard based on the key that woke the device before poking 873 // the wake lock 874 wakeWhenReadyLocked(keyCode); 875 return true; 876 } else { 877 return false; 878 } 879 } 880 881 /** 882 * When the keyguard is showing we ignore some keys that might otherwise typically 883 * be considered wake keys. We filter them out here. 884 * 885 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it 886 * is always considered a wake key. 887 */ 888 private boolean isWakeKeyWhenKeyguardShowing(int keyCode, boolean isDocked) { 889 switch (keyCode) { 890 // ignore volume keys unless docked 891 case KeyEvent.KEYCODE_VOLUME_UP: 892 case KeyEvent.KEYCODE_VOLUME_DOWN: 893 case KeyEvent.KEYCODE_VOLUME_MUTE: 894 return isDocked; 895 896 // ignore media and camera keys 897 case KeyEvent.KEYCODE_MUTE: 898 case KeyEvent.KEYCODE_HEADSETHOOK: 899 case KeyEvent.KEYCODE_MEDIA_PLAY: 900 case KeyEvent.KEYCODE_MEDIA_PAUSE: 901 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 902 case KeyEvent.KEYCODE_MEDIA_STOP: 903 case KeyEvent.KEYCODE_MEDIA_NEXT: 904 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 905 case KeyEvent.KEYCODE_MEDIA_REWIND: 906 case KeyEvent.KEYCODE_MEDIA_RECORD: 907 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 908 case KeyEvent.KEYCODE_CAMERA: 909 return false; 910 } 911 return true; 912 } 913 914 /** 915 * When a wake motion such as an external mouse movement is received when the screen 916 * is off and the keyguard is showing, we need to decide whether to actually turn 917 * on the screen, and if so, tell the keyguard to prepare itself and poke the wake 918 * lock when it is ready. 919 * 920 * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}. 921 * Be sure not to take any action that takes a long time; any significant 922 * action should be posted to a handler. 923 * 924 * @return Whether we poked the wake lock (and turned the screen on) 925 */ 926 public boolean onWakeMotionWhenKeyguardShowingTq() { 927 if (DEBUG) Log.d(TAG, "onWakeMotionWhenKeyguardShowing()"); 928 929 // give the keyguard view manager a chance to adjust the state of the 930 // keyguard based on the key that woke the device before poking 931 // the wake lock 932 wakeWhenReadyLocked(KeyEvent.KEYCODE_UNKNOWN); 933 return true; 934 } 935 936 /** 937 * Callbacks from {@link KeyguardViewManager}. 938 */ 939 940 /** {@inheritDoc} */ 941 public void pokeWakelock() { 942 pokeWakelock(AWAKE_INTERVAL_DEFAULT_MS); 943 } 944 945 /** {@inheritDoc} */ 946 public void pokeWakelock(int holdMs) { 947 synchronized (this) { 948 if (DBG_WAKE) Log.d(TAG, "pokeWakelock(" + holdMs + ")"); 949 mWakeLock.acquire(); 950 mHandler.removeMessages(TIMEOUT); 951 mWakelockSequence++; 952 Message msg = mHandler.obtainMessage(TIMEOUT, mWakelockSequence, 0); 953 mHandler.sendMessageDelayed(msg, holdMs); 954 } 955 } 956 957 /** 958 * {@inheritDoc} 959 * 960 * @see #handleKeyguardDone 961 */ 962 public void keyguardDone(boolean authenticated) { 963 keyguardDone(authenticated, true); 964 } 965 966 public void keyguardDone(boolean authenticated, boolean wakeup) { 967 synchronized (this) { 968 EventLog.writeEvent(70000, 2); 969 if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")"); 970 Message msg = mHandler.obtainMessage(KEYGUARD_DONE); 971 msg.arg1 = wakeup ? 1 : 0; 972 mHandler.sendMessage(msg); 973 974 if (authenticated) { 975 mUpdateMonitor.clearFailedAttempts(); 976 } 977 978 if (mExitSecureCallback != null) { 979 mExitSecureCallback.onKeyguardExitResult(authenticated); 980 mExitSecureCallback = null; 981 982 if (authenticated) { 983 // after succesfully exiting securely, no need to reshow 984 // the keyguard when they've released the lock 985 mExternallyEnabled = true; 986 mNeedToReshowWhenReenabled = false; 987 } 988 } 989 } 990 } 991 992 /** 993 * {@inheritDoc} 994 * 995 * @see #handleKeyguardDoneDrawing 996 */ 997 public void keyguardDoneDrawing() { 998 mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING); 999 } 1000 1001 /** 1002 * This handler will be associated with the policy thread, which will also 1003 * be the UI thread of the keyguard. Since the apis of the policy, and therefore 1004 * this class, can be called by other threads, any action that directly 1005 * interacts with the keyguard ui should be posted to this handler, rather 1006 * than called directly. 1007 */ 1008 private Handler mHandler = new Handler() { 1009 @Override 1010 public void handleMessage(Message msg) { 1011 switch (msg.what) { 1012 case TIMEOUT: 1013 handleTimeout(msg.arg1); 1014 return ; 1015 case SHOW: 1016 handleShow(); 1017 return ; 1018 case HIDE: 1019 handleHide(); 1020 return ; 1021 case RESET: 1022 handleReset(); 1023 return ; 1024 case VERIFY_UNLOCK: 1025 handleVerifyUnlock(); 1026 return; 1027 case NOTIFY_SCREEN_OFF: 1028 handleNotifyScreenOff(); 1029 return; 1030 case NOTIFY_SCREEN_ON: 1031 handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj); 1032 return; 1033 case WAKE_WHEN_READY: 1034 handleWakeWhenReady(msg.arg1); 1035 return; 1036 case KEYGUARD_DONE: 1037 handleKeyguardDone(msg.arg1 != 0); 1038 return; 1039 case KEYGUARD_DONE_DRAWING: 1040 handleKeyguardDoneDrawing(); 1041 return; 1042 case KEYGUARD_DONE_AUTHENTICATING: 1043 keyguardDone(true); 1044 return; 1045 case SET_HIDDEN: 1046 handleSetHidden(msg.arg1 != 0); 1047 break; 1048 case KEYGUARD_TIMEOUT: 1049 synchronized (KeyguardViewMediator.this) { 1050 doKeyguardLocked(); 1051 } 1052 break; 1053 } 1054 } 1055 }; 1056 1057 /** 1058 * @see #keyguardDone 1059 * @see #KEYGUARD_DONE 1060 */ 1061 private void handleKeyguardDone(boolean wakeup) { 1062 if (DEBUG) Log.d(TAG, "handleKeyguardDone"); 1063 handleHide(); 1064 if (wakeup) { 1065 mPM.userActivity(SystemClock.uptimeMillis(), true); 1066 } 1067 mWakeLock.release(); 1068 mContext.sendBroadcast(mUserPresentIntent); 1069 } 1070 1071 /** 1072 * @see #keyguardDoneDrawing 1073 * @see #KEYGUARD_DONE_DRAWING 1074 */ 1075 private void handleKeyguardDoneDrawing() { 1076 synchronized(this) { 1077 if (false) Log.d(TAG, "handleKeyguardDoneDrawing"); 1078 if (mWaitingUntilKeyguardVisible) { 1079 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible"); 1080 mWaitingUntilKeyguardVisible = false; 1081 notifyAll(); 1082 1083 // there will usually be two of these sent, one as a timeout, and one 1084 // as a result of the callback, so remove any remaining messages from 1085 // the queue 1086 mHandler.removeMessages(KEYGUARD_DONE_DRAWING); 1087 } 1088 } 1089 } 1090 1091 /** 1092 * Handles the message sent by {@link #pokeWakelock} 1093 * @param seq used to determine if anything has changed since the message 1094 * was sent. 1095 * @see #TIMEOUT 1096 */ 1097 private void handleTimeout(int seq) { 1098 synchronized (KeyguardViewMediator.this) { 1099 if (DEBUG) Log.d(TAG, "handleTimeout"); 1100 if (seq == mWakelockSequence) { 1101 mWakeLock.release(); 1102 } 1103 } 1104 } 1105 1106 private void playSounds(boolean locked) { 1107 // User feedback for keyguard. 1108 1109 if (mSuppressNextLockSound) { 1110 mSuppressNextLockSound = false; 1111 return; 1112 } 1113 1114 final ContentResolver cr = mContext.getContentResolver(); 1115 if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) { 1116 final int whichSound = locked 1117 ? mLockSoundId 1118 : mUnlockSoundId; 1119 mLockSounds.stop(mLockSoundStreamId); 1120 // Init mAudioManager 1121 if (mAudioManager == null) { 1122 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 1123 if (mAudioManager == null) return; 1124 mMasterStreamType = mAudioManager.getMasterStreamType(); 1125 } 1126 // If the stream is muted, don't play the sound 1127 if (mAudioManager.isStreamMute(mMasterStreamType)) return; 1128 1129 mLockSoundStreamId = mLockSounds.play(whichSound, 1130 mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); 1131 } 1132 } 1133 1134 private void updateActivityLockScreenState() { 1135 try { 1136 ActivityManagerNative.getDefault().setLockScreenShown( 1137 mShowing && !mHidden); 1138 } catch (RemoteException e) { 1139 } 1140 } 1141 1142 /** 1143 * Handle message sent by {@link #showLocked}. 1144 * @see #SHOW 1145 */ 1146 private void handleShow() { 1147 synchronized (KeyguardViewMediator.this) { 1148 if (DEBUG) Log.d(TAG, "handleShow"); 1149 if (!mSystemReady) return; 1150 1151 mKeyguardViewManager.show(); 1152 mShowing = true; 1153 updateActivityLockScreenState(); 1154 adjustUserActivityLocked(); 1155 adjustStatusBarLocked(); 1156 try { 1157 ActivityManagerNative.getDefault().closeSystemDialogs("lock"); 1158 } catch (RemoteException e) { 1159 } 1160 1161 // Do this at the end to not slow down display of the keyguard. 1162 playSounds(true); 1163 1164 mShowKeyguardWakeLock.release(); 1165 } 1166 } 1167 1168 /** 1169 * Handle message sent by {@link #hideLocked()} 1170 * @see #HIDE 1171 */ 1172 private void handleHide() { 1173 synchronized (KeyguardViewMediator.this) { 1174 if (DEBUG) Log.d(TAG, "handleHide"); 1175 if (mWakeAndHandOff.isHeld()) { 1176 Log.w(TAG, "attempt to hide the keyguard while waking, ignored"); 1177 return; 1178 } 1179 1180 // only play "unlock" noises if not on a call (since the incall UI 1181 // disables the keyguard) 1182 if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { 1183 playSounds(false); 1184 } 1185 1186 mKeyguardViewManager.hide(); 1187 mShowing = false; 1188 updateActivityLockScreenState(); 1189 adjustUserActivityLocked(); 1190 adjustStatusBarLocked(); 1191 } 1192 } 1193 1194 private void adjustUserActivityLocked() { 1195 // disable user activity if we are shown and not hidden 1196 if (DEBUG) Log.d(TAG, "adjustUserActivityLocked mShowing: " + mShowing + " mHidden: " + mHidden); 1197 boolean enabled = !mShowing || mHidden; 1198 mRealPowerManager.enableUserActivity(enabled); 1199 if (!enabled && mScreenOn) { 1200 // reinstate our short screen timeout policy 1201 pokeWakelock(); 1202 } 1203 } 1204 1205 private void adjustStatusBarLocked() { 1206 if (mStatusBarManager == null) { 1207 mStatusBarManager = (StatusBarManager) 1208 mContext.getSystemService(Context.STATUS_BAR_SERVICE); 1209 } 1210 if (mStatusBarManager == null) { 1211 Log.w(TAG, "Could not get status bar manager"); 1212 } else { 1213 if (mShowLockIcon) { 1214 // Give feedback to user when secure keyguard is active and engaged 1215 if (mShowing && isSecure()) { 1216 if (!mShowingLockIcon) { 1217 String contentDescription = mContext.getString( 1218 com.android.internal.R.string.status_bar_device_locked); 1219 mStatusBarManager.setIcon("secure", 1220 com.android.internal.R.drawable.stat_sys_secure, 0, 1221 contentDescription); 1222 mShowingLockIcon = true; 1223 } 1224 } else { 1225 if (mShowingLockIcon) { 1226 mStatusBarManager.removeIcon("secure"); 1227 mShowingLockIcon = false; 1228 } 1229 } 1230 } 1231 1232 // Disable aspects of the system/status/navigation bars that must not be re-enabled by 1233 // windows that appear on top, ever 1234 int flags = StatusBarManager.DISABLE_NONE; 1235 if (mShowing) { 1236 // disable navigation status bar components (home, recents) if lock screen is up 1237 flags |= StatusBarManager.DISABLE_RECENT; 1238 if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) { 1239 // showing secure lockscreen; disable expanding. 1240 flags |= StatusBarManager.DISABLE_EXPAND; 1241 } 1242 if (isSecure()) { 1243 // showing secure lockscreen; disable ticker. 1244 flags |= StatusBarManager.DISABLE_NOTIFICATION_TICKER; 1245 } 1246 } 1247 1248 if (DEBUG) { 1249 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mHidden=" + mHidden 1250 + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags)); 1251 } 1252 1253 mStatusBarManager.disable(flags); 1254 } 1255 } 1256 1257 /** 1258 * Handle message sent by {@link #wakeWhenReadyLocked(int)} 1259 * @param keyCode The key that woke the device. 1260 * @see #WAKE_WHEN_READY 1261 */ 1262 private void handleWakeWhenReady(int keyCode) { 1263 synchronized (KeyguardViewMediator.this) { 1264 if (DBG_WAKE) Log.d(TAG, "handleWakeWhenReady(" + keyCode + ")"); 1265 1266 // this should result in a call to 'poke wakelock' which will set a timeout 1267 // on releasing the wakelock 1268 if (!mKeyguardViewManager.wakeWhenReadyTq(keyCode)) { 1269 // poke wakelock ourselves if keyguard is no longer active 1270 Log.w(TAG, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock, so poke it ourselves"); 1271 pokeWakelock(); 1272 } 1273 1274 /** 1275 * Now that the keyguard is ready and has poked the wake lock, we can 1276 * release the handoff wakelock 1277 */ 1278 mWakeAndHandOff.release(); 1279 1280 if (!mWakeLock.isHeld()) { 1281 Log.w(TAG, "mWakeLock not held in mKeyguardViewManager.wakeWhenReadyTq"); 1282 } 1283 } 1284 } 1285 1286 /** 1287 * Handle message sent by {@link #resetStateLocked()} 1288 * @see #RESET 1289 */ 1290 private void handleReset() { 1291 synchronized (KeyguardViewMediator.this) { 1292 if (DEBUG) Log.d(TAG, "handleReset"); 1293 mKeyguardViewManager.reset(); 1294 } 1295 } 1296 1297 /** 1298 * Handle message sent by {@link #verifyUnlock} 1299 * @see #RESET 1300 */ 1301 private void handleVerifyUnlock() { 1302 synchronized (KeyguardViewMediator.this) { 1303 if (DEBUG) Log.d(TAG, "handleVerifyUnlock"); 1304 mKeyguardViewManager.verifyUnlock(); 1305 mShowing = true; 1306 updateActivityLockScreenState(); 1307 } 1308 } 1309 1310 /** 1311 * Handle message sent by {@link #notifyScreenOffLocked()} 1312 * @see #NOTIFY_SCREEN_OFF 1313 */ 1314 private void handleNotifyScreenOff() { 1315 synchronized (KeyguardViewMediator.this) { 1316 if (DEBUG) Log.d(TAG, "handleNotifyScreenOff"); 1317 mKeyguardViewManager.onScreenTurnedOff(); 1318 } 1319 } 1320 1321 /** 1322 * Handle message sent by {@link #notifyScreenOnLocked()} 1323 * @see #NOTIFY_SCREEN_ON 1324 */ 1325 private void handleNotifyScreenOn(KeyguardViewManager.ShowListener showListener) { 1326 synchronized (KeyguardViewMediator.this) { 1327 if (DEBUG) Log.d(TAG, "handleNotifyScreenOn"); 1328 mKeyguardViewManager.onScreenTurnedOn(showListener); 1329 } 1330 } 1331 1332} 1333