KeyguardViewMediator.java revision 84dc08a208eea7a4ddf043cadbb28987cf90ae22
1/* 2 * Copyright (C) 2014 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.systemui.keyguard; 18 19import android.app.Activity; 20import android.app.ActivityManager; 21import android.app.ActivityManagerNative; 22import android.app.AlarmManager; 23import android.app.PendingIntent; 24import android.app.SearchManager; 25import android.app.StatusBarManager; 26import android.app.trust.TrustManager; 27import android.content.BroadcastReceiver; 28import android.content.ContentResolver; 29import android.content.Context; 30import android.content.Intent; 31import android.content.IntentFilter; 32import android.content.pm.UserInfo; 33import android.media.AudioManager; 34import android.media.SoundPool; 35import android.os.Bundle; 36import android.os.DeadObjectException; 37import android.os.Handler; 38import android.os.Looper; 39import android.os.Message; 40import android.os.PowerManager; 41import android.os.RemoteException; 42import android.os.SystemClock; 43import android.os.SystemProperties; 44import android.os.UserHandle; 45import android.os.UserManager; 46import android.provider.Settings; 47import android.telephony.SubscriptionManager; 48import android.telephony.TelephonyManager; 49import android.util.EventLog; 50import android.util.Log; 51import android.util.Slog; 52import android.view.IWindowManager; 53import android.view.ViewGroup; 54import android.view.WindowManagerGlobal; 55import android.view.WindowManagerPolicy; 56import android.view.animation.Animation; 57import android.view.animation.AnimationUtils; 58 59import com.android.internal.policy.IKeyguardDrawnCallback; 60import com.android.internal.policy.IKeyguardExitCallback; 61import com.android.internal.policy.IKeyguardStateCallback; 62import com.android.internal.telephony.IccCardConstants; 63import com.android.internal.widget.LockPatternUtils; 64import com.android.keyguard.KeyguardConstants; 65import com.android.keyguard.KeyguardDisplayManager; 66import com.android.keyguard.KeyguardSecurityView; 67import com.android.keyguard.KeyguardUpdateMonitor; 68import com.android.keyguard.KeyguardUpdateMonitorCallback; 69import com.android.keyguard.ViewMediatorCallback; 70import com.android.systemui.SystemUI; 71import com.android.systemui.statusbar.phone.FingerprintUnlockController; 72import com.android.systemui.statusbar.phone.PhoneStatusBar; 73import com.android.systemui.statusbar.phone.ScrimController; 74import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; 75import com.android.systemui.statusbar.phone.StatusBarWindowManager; 76 77import java.io.FileDescriptor; 78import java.io.PrintWriter; 79import java.util.ArrayList; 80import java.util.List; 81 82import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 83 84/** 85 * Mediates requests related to the keyguard. This includes queries about the 86 * state of the keyguard, power management events that effect whether the keyguard 87 * should be shown or reset, callbacks to the phone window manager to notify 88 * it of when the keyguard is showing, and events from the keyguard view itself 89 * stating that the keyguard was succesfully unlocked. 90 * 91 * Note that the keyguard view is shown when the screen is off (as appropriate) 92 * so that once the screen comes on, it will be ready immediately. 93 * 94 * Example queries about the keyguard: 95 * - is {movement, key} one that should wake the keygaurd? 96 * - is the keyguard showing? 97 * - are input events restricted due to the state of the keyguard? 98 * 99 * Callbacks to the phone window manager: 100 * - the keyguard is showing 101 * 102 * Example external events that translate to keyguard view changes: 103 * - screen turned off -> reset the keyguard, and show it so it will be ready 104 * next time the screen turns on 105 * - keyboard is slid open -> if the keyguard is not secure, hide it 106 * 107 * Events from the keyguard view: 108 * - user succesfully unlocked keyguard -> hide keyguard view, and no longer 109 * restrict input events. 110 * 111 * Note: in addition to normal power managment events that effect the state of 112 * whether the keyguard should be showing, external apps and services may request 113 * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}. When 114 * false, this will override all other conditions for turning on the keyguard. 115 * 116 * Threading and synchronization: 117 * This class is created by the initialization routine of the {@link android.view.WindowManagerPolicy}, 118 * and runs on its thread. The keyguard UI is created from that thread in the 119 * constructor of this class. The apis may be called from other threads, including the 120 * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s. 121 * Therefore, methods on this class are synchronized, and any action that is pointed 122 * directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI 123 * thread of the keyguard. 124 */ 125public class KeyguardViewMediator extends SystemUI { 126 private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000; 127 private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000; 128 129 private static final boolean DEBUG = KeyguardConstants.DEBUG; 130 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES; 131 private final static boolean DBG_WAKE = false; 132 133 private final static String TAG = "KeyguardViewMediator"; 134 135 private static final String DELAYED_KEYGUARD_ACTION = 136 "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"; 137 138 // used for handler messages 139 private static final int SHOW = 2; 140 private static final int HIDE = 3; 141 private static final int RESET = 4; 142 private static final int VERIFY_UNLOCK = 5; 143 private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 6; 144 private static final int NOTIFY_SCREEN_TURNING_ON = 7; 145 private static final int KEYGUARD_DONE = 9; 146 private static final int KEYGUARD_DONE_DRAWING = 10; 147 private static final int KEYGUARD_DONE_AUTHENTICATING = 11; 148 private static final int SET_OCCLUDED = 12; 149 private static final int KEYGUARD_TIMEOUT = 13; 150 private static final int DISMISS = 17; 151 private static final int START_KEYGUARD_EXIT_ANIM = 18; 152 private static final int ON_ACTIVITY_DRAWN = 19; 153 private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 20; 154 private static final int NOTIFY_STARTED_WAKING_UP = 21; 155 private static final int NOTIFY_SCREEN_TURNED_ON = 22; 156 private static final int NOTIFY_SCREEN_TURNED_OFF = 23; 157 158 /** 159 * The default amount of time we stay awake (used for all key input) 160 */ 161 public static final int AWAKE_INTERVAL_DEFAULT_MS = 10000; 162 163 /** 164 * How long to wait after the screen turns off due to timeout before 165 * turning on the keyguard (i.e, the user has this much time to turn 166 * the screen back on without having to face the keyguard). 167 */ 168 private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000; 169 170 /** 171 * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()} 172 * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)} 173 * that is reenabling the keyguard. 174 */ 175 private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000; 176 177 /** 178 * Secure setting whether analytics are collected on the keyguard. 179 */ 180 private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics"; 181 182 /** The stream type that the lock sounds are tied to. */ 183 private int mUiSoundsStreamType; 184 185 private AlarmManager mAlarmManager; 186 private AudioManager mAudioManager; 187 private StatusBarManager mStatusBarManager; 188 private boolean mSwitchingUser; 189 190 private boolean mSystemReady; 191 private boolean mBootCompleted; 192 private boolean mBootSendUserPresent; 193 194 /** High level access to the power manager for WakeLocks */ 195 private PowerManager mPM; 196 197 /** High level access to the window manager for dismissing keyguard animation */ 198 private IWindowManager mWM; 199 200 201 /** TrustManager for letting it know when we change visibility */ 202 private TrustManager mTrustManager; 203 204 /** SearchManager for determining whether or not search assistant is available */ 205 private SearchManager mSearchManager; 206 207 /** 208 * Used to keep the device awake while to ensure the keyguard finishes opening before 209 * we sleep. 210 */ 211 private PowerManager.WakeLock mShowKeyguardWakeLock; 212 213 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; 214 215 // these are protected by synchronized (this) 216 217 /** 218 * External apps (like the phone app) can tell us to disable the keygaurd. 219 */ 220 private boolean mExternallyEnabled = true; 221 222 /** 223 * Remember if an external call to {@link #setKeyguardEnabled} with value 224 * false caused us to hide the keyguard, so that we need to reshow it once 225 * the keygaurd is reenabled with another call with value true. 226 */ 227 private boolean mNeedToReshowWhenReenabled = false; 228 229 // cached value of whether we are showing (need to know this to quickly 230 // answer whether the input should be restricted) 231 private boolean mShowing; 232 233 /** Cached value of #isInputRestricted */ 234 private boolean mInputRestricted; 235 236 // true if the keyguard is hidden by another window 237 private boolean mOccluded = false; 238 239 /** 240 * Helps remember whether the screen has turned on since the last time 241 * it turned off due to timeout. see {@link #onScreenTurnedOff(int)} 242 */ 243 private int mDelayedShowingSequence; 244 245 /** 246 * If the user has disabled the keyguard, then requests to exit, this is 247 * how we'll ultimately let them know whether it was successful. We use this 248 * var being non-null as an indicator that there is an in progress request. 249 */ 250 private IKeyguardExitCallback mExitSecureCallback; 251 252 // the properties of the keyguard 253 254 private KeyguardUpdateMonitor mUpdateMonitor; 255 256 private boolean mDeviceInteractive; 257 private boolean mGoingToSleep; 258 259 // last known state of the cellular connection 260 private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE; 261 262 /** 263 * Whether a hide is pending an we are just waiting for #startKeyguardExitAnimation to be 264 * called. 265 * */ 266 private boolean mHiding; 267 268 /** 269 * we send this intent when the keyguard is dismissed. 270 */ 271 private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT) 272 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 273 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 274 275 /** 276 * {@link #setKeyguardEnabled} waits on this condition when it reenables 277 * the keyguard. 278 */ 279 private boolean mWaitingUntilKeyguardVisible = false; 280 private LockPatternUtils mLockPatternUtils; 281 private boolean mKeyguardDonePending = false; 282 private boolean mHideAnimationRun = false; 283 284 private SoundPool mLockSounds; 285 private int mLockSoundId; 286 private int mUnlockSoundId; 287 private int mTrustedSoundId; 288 private int mLockSoundStreamId; 289 290 /** 291 * The animation used for hiding keyguard. This is used to fetch the animation timings if 292 * WindowManager is not providing us with them. 293 */ 294 private Animation mHideAnimation; 295 296 /** 297 * The volume applied to the lock/unlock sounds. 298 */ 299 private float mLockSoundVolume; 300 301 /** 302 * For managing external displays 303 */ 304 private KeyguardDisplayManager mKeyguardDisplayManager; 305 306 private final ArrayList<IKeyguardStateCallback> mKeyguardStateCallbacks = new ArrayList<>(); 307 308 /** 309 * When starting going to sleep, we figured out that we need to reset Keyguard state and this 310 * should be committed when finished going to sleep. 311 */ 312 private boolean mPendingReset; 313 314 /** 315 * When starting going to sleep, we figured out that we need to lock Keyguard and this should be 316 * committed when finished going to sleep. 317 */ 318 private boolean mPendingLock; 319 320 private boolean mWakeAndUnlocking; 321 private IKeyguardDrawnCallback mDrawnCallback; 322 323 KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { 324 325 @Override 326 public void onUserSwitching(int userId) { 327 // Note that the mLockPatternUtils user has already been updated from setCurrentUser. 328 // We need to force a reset of the views, since lockNow (called by 329 // ActivityManagerService) will not reconstruct the keyguard if it is already showing. 330 synchronized (KeyguardViewMediator.this) { 331 mSwitchingUser = true; 332 resetKeyguardDonePendingLocked(); 333 resetStateLocked(); 334 adjustStatusBarLocked(); 335 } 336 } 337 338 @Override 339 public void onUserSwitchComplete(int userId) { 340 mSwitchingUser = false; 341 if (userId != UserHandle.USER_OWNER) { 342 UserInfo info = UserManager.get(mContext).getUserInfo(userId); 343 if (info != null && info.isGuest()) { 344 // If we just switched to a guest, try to dismiss keyguard. 345 dismiss(); 346 } 347 } 348 } 349 350 @Override 351 public void onUserInfoChanged(int userId) { 352 } 353 354 @Override 355 public void onPhoneStateChanged(int phoneState) { 356 synchronized (KeyguardViewMediator.this) { 357 if (TelephonyManager.CALL_STATE_IDLE == phoneState // call ending 358 && !mDeviceInteractive // screen off 359 && mExternallyEnabled) { // not disabled by any app 360 361 // note: this is a way to gracefully reenable the keyguard when the call 362 // ends and the screen is off without always reenabling the keyguard 363 // each time the screen turns off while in call (and having an occasional ugly 364 // flicker while turning back on the screen and disabling the keyguard again). 365 if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the " 366 + "keyguard is showing"); 367 doKeyguardLocked(null); 368 } 369 } 370 } 371 372 @Override 373 public void onClockVisibilityChanged() { 374 adjustStatusBarLocked(); 375 } 376 377 @Override 378 public void onDeviceProvisioned() { 379 sendUserPresentBroadcast(); 380 } 381 382 @Override 383 public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) { 384 385 if (DEBUG_SIM_STATES) { 386 Log.d(TAG, "onSimStateChanged(subId=" + subId + ", slotId=" + slotId 387 + ",state=" + simState + ")"); 388 } 389 390 int size = mKeyguardStateCallbacks.size(); 391 boolean simPinSecure = mUpdateMonitor.isSimPinSecure(); 392 for (int i = size - 1; i >= 0; i--) { 393 try { 394 mKeyguardStateCallbacks.get(i).onSimSecureStateChanged(simPinSecure); 395 } catch (RemoteException e) { 396 Slog.w(TAG, "Failed to call onSimSecureStateChanged", e); 397 if (e instanceof DeadObjectException) { 398 mKeyguardStateCallbacks.remove(i); 399 } 400 } 401 } 402 403 switch (simState) { 404 case NOT_READY: 405 case ABSENT: 406 // only force lock screen in case of missing sim if user hasn't 407 // gone through setup wizard 408 synchronized (this) { 409 if (shouldWaitForProvisioning()) { 410 if (!mShowing) { 411 if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing," 412 + " we need to show the keyguard since the " 413 + "device isn't provisioned yet."); 414 doKeyguardLocked(null); 415 } else { 416 resetStateLocked(); 417 } 418 } 419 } 420 break; 421 case PIN_REQUIRED: 422 case PUK_REQUIRED: 423 synchronized (this) { 424 if (!mShowing) { 425 if (DEBUG_SIM_STATES) Log.d(TAG, 426 "INTENT_VALUE_ICC_LOCKED and keygaurd isn't " 427 + "showing; need to show keyguard so user can enter sim pin"); 428 doKeyguardLocked(null); 429 } else { 430 resetStateLocked(); 431 } 432 } 433 break; 434 case PERM_DISABLED: 435 synchronized (this) { 436 if (!mShowing) { 437 if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and " 438 + "keygaurd isn't showing."); 439 doKeyguardLocked(null); 440 } else { 441 if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED, resetStateLocked to" 442 + "show permanently disabled message in lockscreen."); 443 resetStateLocked(); 444 } 445 } 446 break; 447 case READY: 448 synchronized (this) { 449 if (mShowing) { 450 resetStateLocked(); 451 } 452 } 453 break; 454 default: 455 if (DEBUG_SIM_STATES) Log.v(TAG, "Ignoring state: " + simState); 456 break; 457 } 458 } 459 }; 460 461 ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { 462 463 public void userActivity() { 464 KeyguardViewMediator.this.userActivity(); 465 } 466 467 public void keyguardDone(boolean strongAuth) { 468 if (!mKeyguardDonePending) { 469 KeyguardViewMediator.this.keyguardDone(true /* authenticated */); 470 } 471 if (strongAuth) { 472 mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt(); 473 } 474 } 475 476 public void keyguardDoneDrawing() { 477 mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING); 478 } 479 480 @Override 481 public void setNeedsInput(boolean needsInput) { 482 mStatusBarKeyguardViewManager.setNeedsInput(needsInput); 483 } 484 485 @Override 486 public void keyguardDonePending(boolean strongAuth) { 487 mKeyguardDonePending = true; 488 mHideAnimationRun = true; 489 mStatusBarKeyguardViewManager.startPreHideAnimation(null /* finishRunnable */); 490 mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT, 491 KEYGUARD_DONE_PENDING_TIMEOUT_MS); 492 if (strongAuth) { 493 mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt(); 494 } 495 } 496 497 @Override 498 public void keyguardGone() { 499 mKeyguardDisplayManager.hide(); 500 } 501 502 @Override 503 public void readyForKeyguardDone() { 504 if (mKeyguardDonePending) { 505 // Somebody has called keyguardDonePending before, which means that we are 506 // authenticated 507 KeyguardViewMediator.this.keyguardDone(true /* authenticated */); 508 } 509 } 510 511 @Override 512 public void resetKeyguard() { 513 resetStateLocked(); 514 } 515 516 @Override 517 public void playTrustedSound() { 518 KeyguardViewMediator.this.playTrustedSound(); 519 } 520 521 @Override 522 public boolean isInputRestricted() { 523 return KeyguardViewMediator.this.isInputRestricted(); 524 } 525 526 @Override 527 public boolean isScreenOn() { 528 return mDeviceInteractive; 529 } 530 531 @Override 532 public int getBouncerPromptReason() { 533 int currentUser = ActivityManager.getCurrentUser(); 534 if ((mUpdateMonitor.getUserTrustIsManaged(currentUser) 535 || mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)) 536 && !mUpdateMonitor.getStrongAuthTracker().hasUserAuthenticatedSinceBoot()) { 537 return KeyguardSecurityView.PROMPT_REASON_RESTART; 538 } else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser) 539 && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) { 540 return KeyguardSecurityView.PROMPT_REASON_TIMEOUT; 541 } 542 return KeyguardSecurityView.PROMPT_REASON_NONE; 543 } 544 }; 545 546 public void userActivity() { 547 mPM.userActivity(SystemClock.uptimeMillis(), false); 548 } 549 550 private void setupLocked() { 551 mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 552 mWM = WindowManagerGlobal.getWindowManagerService(); 553 mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE); 554 555 mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard"); 556 mShowKeyguardWakeLock.setReferenceCounted(false); 557 558 mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION)); 559 560 mKeyguardDisplayManager = new KeyguardDisplayManager(mContext); 561 562 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 563 564 mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); 565 566 mLockPatternUtils = new LockPatternUtils(mContext); 567 KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser()); 568 569 // Assume keyguard is showing (unless it's disabled) until we know for sure... 570 setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled( 571 KeyguardUpdateMonitor.getCurrentUser())); 572 updateInputRestrictedLocked(); 573 mTrustManager.reportKeyguardShowingChanged(); 574 575 mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext, 576 mViewMediatorCallback, mLockPatternUtils); 577 final ContentResolver cr = mContext.getContentResolver(); 578 579 mDeviceInteractive = mPM.isInteractive(); 580 581 mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0); 582 String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND); 583 if (soundPath != null) { 584 mLockSoundId = mLockSounds.load(soundPath, 1); 585 } 586 if (soundPath == null || mLockSoundId == 0) { 587 Log.w(TAG, "failed to load lock sound from " + soundPath); 588 } 589 soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND); 590 if (soundPath != null) { 591 mUnlockSoundId = mLockSounds.load(soundPath, 1); 592 } 593 if (soundPath == null || mUnlockSoundId == 0) { 594 Log.w(TAG, "failed to load unlock sound from " + soundPath); 595 } 596 soundPath = Settings.Global.getString(cr, Settings.Global.TRUSTED_SOUND); 597 if (soundPath != null) { 598 mTrustedSoundId = mLockSounds.load(soundPath, 1); 599 } 600 if (soundPath == null || mTrustedSoundId == 0) { 601 Log.w(TAG, "failed to load trusted sound from " + soundPath); 602 } 603 604 int lockSoundDefaultAttenuation = mContext.getResources().getInteger( 605 com.android.internal.R.integer.config_lockSoundVolumeDb); 606 mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20); 607 608 mHideAnimation = AnimationUtils.loadAnimation(mContext, 609 com.android.internal.R.anim.lock_screen_behind_enter); 610 } 611 612 @Override 613 public void start() { 614 synchronized (this) { 615 setupLocked(); 616 } 617 putComponent(KeyguardViewMediator.class, this); 618 } 619 620 /** 621 * Let us know that the system is ready after startup. 622 */ 623 public void onSystemReady() { 624 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 625 synchronized (this) { 626 if (DEBUG) Log.d(TAG, "onSystemReady"); 627 mSystemReady = true; 628 doKeyguardLocked(null); 629 mUpdateMonitor.registerCallback(mUpdateCallback); 630 } 631 // Most services aren't available until the system reaches the ready state, so we 632 // send it here when the device first boots. 633 maybeSendUserPresentBroadcast(); 634 } 635 636 /** 637 * Called to let us know the screen was turned off. 638 * @param why either {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_USER} or 639 * {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}. 640 */ 641 public void onStartedGoingToSleep(int why) { 642 if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + why + ")"); 643 synchronized (this) { 644 mDeviceInteractive = false; 645 mGoingToSleep = true; 646 647 // Lock immediately based on setting if secure (user has a pin/pattern/password). 648 // This also "locks" the device when not secure to provide easy access to the 649 // camera while preventing unwanted input. 650 int currentUser = KeyguardUpdateMonitor.getCurrentUser(); 651 final boolean lockImmediately = 652 mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser) 653 || !mLockPatternUtils.isSecure(currentUser); 654 655 if (mExitSecureCallback != null) { 656 if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled"); 657 try { 658 mExitSecureCallback.onKeyguardExitResult(false); 659 } catch (RemoteException e) { 660 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 661 } 662 mExitSecureCallback = null; 663 if (!mExternallyEnabled) { 664 hideLocked(); 665 } 666 } else if (mShowing) { 667 mPendingReset = true; 668 } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT 669 || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) { 670 doKeyguardLaterLocked(); 671 } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) { 672 mPendingLock = true; 673 } 674 675 if (mPendingLock) { 676 playSounds(true); 677 } 678 } 679 } 680 681 public void onFinishedGoingToSleep(int why) { 682 if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")"); 683 synchronized (this) { 684 mDeviceInteractive = false; 685 mGoingToSleep = false; 686 687 resetKeyguardDonePendingLocked(); 688 mHideAnimationRun = false; 689 690 notifyFinishedGoingToSleep(); 691 692 if (mPendingReset) { 693 resetStateLocked(); 694 mPendingReset = false; 695 } 696 if (mPendingLock) { 697 doKeyguardLocked(null); 698 mPendingLock = false; 699 } 700 } 701 KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why); 702 } 703 704 private void doKeyguardLaterLocked() { 705 // if the screen turned off because of timeout or the user hit the power button 706 // and we don't need to lock immediately, set an alarm 707 // to enable it a little bit later (i.e, give the user a chance 708 // to turn the screen back on within a certain window without 709 // having to unlock the screen) 710 final ContentResolver cr = mContext.getContentResolver(); 711 712 // From DisplaySettings 713 long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT, 714 KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT); 715 716 // From SecuritySettings 717 final long lockAfterTimeout = Settings.Secure.getInt(cr, 718 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 719 KEYGUARD_LOCK_AFTER_DELAY_DEFAULT); 720 721 // From DevicePolicyAdmin 722 final long policyTimeout = mLockPatternUtils.getDevicePolicyManager() 723 .getMaximumTimeToLock(null, KeyguardUpdateMonitor.getCurrentUser()); 724 725 long timeout; 726 if (policyTimeout > 0) { 727 // policy in effect. Make sure we don't go beyond policy limit. 728 displayTimeout = Math.max(displayTimeout, 0); // ignore negative values 729 timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout); 730 } else { 731 timeout = lockAfterTimeout; 732 } 733 734 if (timeout <= 0) { 735 // Lock now 736 doKeyguardLocked(null); 737 } else { 738 // Lock in the future 739 long when = SystemClock.elapsedRealtime() + timeout; 740 Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); 741 intent.putExtra("seq", mDelayedShowingSequence); 742 PendingIntent sender = PendingIntent.getBroadcast(mContext, 743 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); 744 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender); 745 if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " 746 + mDelayedShowingSequence); 747 } 748 } 749 750 private void cancelDoKeyguardLaterLocked() { 751 mDelayedShowingSequence++; 752 } 753 754 /** 755 * Let's us know when the device is waking up. 756 */ 757 public void onStartedWakingUp() { 758 759 // TODO: Rename all screen off/on references to interactive/sleeping 760 synchronized (this) { 761 mDeviceInteractive = true; 762 cancelDoKeyguardLaterLocked(); 763 if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence); 764 notifyStartedWakingUp(); 765 } 766 KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedWakingUp(); 767 maybeSendUserPresentBroadcast(); 768 } 769 770 public void onScreenTurningOn(IKeyguardDrawnCallback callback) { 771 notifyScreenOn(callback); 772 } 773 774 public void onScreenTurnedOn() { 775 notifyScreenTurnedOn(); 776 mUpdateMonitor.dispatchScreenTurnedOn(); 777 } 778 779 public void onScreenTurnedOff() { 780 notifyScreenTurnedOff(); 781 mUpdateMonitor.dispatchScreenTurnedOff(); 782 } 783 784 private void maybeSendUserPresentBroadcast() { 785 if (mSystemReady && mLockPatternUtils.isLockScreenDisabled( 786 KeyguardUpdateMonitor.getCurrentUser())) { 787 // Lock screen is disabled because the user has set the preference to "None". 788 // In this case, send out ACTION_USER_PRESENT here instead of in 789 // handleKeyguardDone() 790 sendUserPresentBroadcast(); 791 } 792 } 793 794 /** 795 * A dream started. We should lock after the usual screen-off lock timeout but only 796 * if there is a secure lock pattern. 797 */ 798 public void onDreamingStarted() { 799 synchronized (this) { 800 if (mDeviceInteractive 801 && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) { 802 doKeyguardLaterLocked(); 803 } 804 } 805 } 806 807 /** 808 * A dream stopped. 809 */ 810 public void onDreamingStopped() { 811 synchronized (this) { 812 if (mDeviceInteractive) { 813 cancelDoKeyguardLaterLocked(); 814 } 815 } 816 } 817 818 /** 819 * Same semantics as {@link android.view.WindowManagerPolicy#enableKeyguard}; provide 820 * a way for external stuff to override normal keyguard behavior. For instance 821 * the phone app disables the keyguard when it receives incoming calls. 822 */ 823 public void setKeyguardEnabled(boolean enabled) { 824 synchronized (this) { 825 if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")"); 826 827 mExternallyEnabled = enabled; 828 829 if (!enabled && mShowing) { 830 if (mExitSecureCallback != null) { 831 if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring"); 832 // we're in the process of handling a request to verify the user 833 // can get past the keyguard. ignore extraneous requests to disable / reenable 834 return; 835 } 836 837 // hiding keyguard that is showing, remember to reshow later 838 if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, " 839 + "disabling status bar expansion"); 840 mNeedToReshowWhenReenabled = true; 841 updateInputRestrictedLocked(); 842 hideLocked(); 843 } else if (enabled && mNeedToReshowWhenReenabled) { 844 // reenabled after previously hidden, reshow 845 if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling " 846 + "status bar expansion"); 847 mNeedToReshowWhenReenabled = false; 848 updateInputRestrictedLocked(); 849 850 if (mExitSecureCallback != null) { 851 if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting"); 852 try { 853 mExitSecureCallback.onKeyguardExitResult(false); 854 } catch (RemoteException e) { 855 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 856 } 857 mExitSecureCallback = null; 858 resetStateLocked(); 859 } else { 860 showLocked(null); 861 862 // block until we know the keygaurd is done drawing (and post a message 863 // to unblock us after a timeout so we don't risk blocking too long 864 // and causing an ANR). 865 mWaitingUntilKeyguardVisible = true; 866 mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS); 867 if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false"); 868 while (mWaitingUntilKeyguardVisible) { 869 try { 870 wait(); 871 } catch (InterruptedException e) { 872 Thread.currentThread().interrupt(); 873 } 874 } 875 if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible"); 876 } 877 } 878 } 879 } 880 881 /** 882 * @see android.app.KeyguardManager#exitKeyguardSecurely 883 */ 884 public void verifyUnlock(IKeyguardExitCallback callback) { 885 synchronized (this) { 886 if (DEBUG) Log.d(TAG, "verifyUnlock"); 887 if (shouldWaitForProvisioning()) { 888 // don't allow this api when the device isn't provisioned 889 if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned"); 890 try { 891 callback.onKeyguardExitResult(false); 892 } catch (RemoteException e) { 893 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 894 } 895 } else if (mExternallyEnabled) { 896 // this only applies when the user has externally disabled the 897 // keyguard. this is unexpected and means the user is not 898 // using the api properly. 899 Log.w(TAG, "verifyUnlock called when not externally disabled"); 900 try { 901 callback.onKeyguardExitResult(false); 902 } catch (RemoteException e) { 903 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 904 } 905 } else if (mExitSecureCallback != null) { 906 // already in progress with someone else 907 try { 908 callback.onKeyguardExitResult(false); 909 } catch (RemoteException e) { 910 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 911 } 912 } else { 913 mExitSecureCallback = callback; 914 verifyUnlockLocked(); 915 } 916 } 917 } 918 919 /** 920 * Is the keyguard currently showing and not being force hidden? 921 */ 922 public boolean isShowingAndNotOccluded() { 923 return mShowing && !mOccluded; 924 } 925 926 /** 927 * Notify us when the keyguard is occluded by another window 928 */ 929 public void setOccluded(boolean isOccluded) { 930 if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded); 931 mHandler.removeMessages(SET_OCCLUDED); 932 Message msg = mHandler.obtainMessage(SET_OCCLUDED, (isOccluded ? 1 : 0), 0); 933 mHandler.sendMessage(msg); 934 } 935 936 /** 937 * Handles SET_OCCLUDED message sent by setOccluded() 938 */ 939 private void handleSetOccluded(boolean isOccluded) { 940 synchronized (KeyguardViewMediator.this) { 941 if (mHiding && isOccluded) { 942 // We're in the process of going away but WindowManager wants to show a 943 // SHOW_WHEN_LOCKED activity instead. 944 startKeyguardExitAnimation(0, 0); 945 } 946 947 if (mOccluded != isOccluded) { 948 mOccluded = isOccluded; 949 mStatusBarKeyguardViewManager.setOccluded(isOccluded); 950 updateActivityLockScreenState(); 951 adjustStatusBarLocked(); 952 } 953 } 954 } 955 956 /** 957 * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout. 958 * This must be safe to call from any thread and with any window manager locks held. 959 */ 960 public void doKeyguardTimeout(Bundle options) { 961 mHandler.removeMessages(KEYGUARD_TIMEOUT); 962 Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options); 963 mHandler.sendMessage(msg); 964 } 965 966 /** 967 * Given the state of the keyguard, is the input restricted? 968 * Input is restricted when the keyguard is showing, or when the keyguard 969 * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet. 970 */ 971 public boolean isInputRestricted() { 972 return mShowing || mNeedToReshowWhenReenabled; 973 } 974 975 private void updateInputRestricted() { 976 synchronized (this) { 977 updateInputRestrictedLocked(); 978 } 979 } 980 private void updateInputRestrictedLocked() { 981 boolean inputRestricted = isInputRestricted(); 982 if (mInputRestricted != inputRestricted) { 983 mInputRestricted = inputRestricted; 984 int size = mKeyguardStateCallbacks.size(); 985 for (int i = size - 1; i >= 0; i--) { 986 try { 987 mKeyguardStateCallbacks.get(i).onInputRestrictedStateChanged(inputRestricted); 988 } catch (RemoteException e) { 989 Slog.w(TAG, "Failed to call onDeviceProvisioned", e); 990 if (e instanceof DeadObjectException) { 991 mKeyguardStateCallbacks.remove(i); 992 } 993 } 994 } 995 } 996 } 997 998 /** 999 * Enable the keyguard if the settings are appropriate. 1000 */ 1001 private void doKeyguardLocked(Bundle options) { 1002 // if another app is disabling us, don't show 1003 if (!mExternallyEnabled) { 1004 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); 1005 1006 // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes 1007 // for an occasional ugly flicker in this situation: 1008 // 1) receive a call with the screen on (no keyguard) or make a call 1009 // 2) screen times out 1010 // 3) user hits key to turn screen back on 1011 // instead, we reenable the keyguard when we know the screen is off and the call 1012 // ends (see the broadcast receiver below) 1013 // TODO: clean this up when we have better support at the window manager level 1014 // for apps that wish to be on top of the keyguard 1015 return; 1016 } 1017 1018 // if the keyguard is already showing, don't bother 1019 if (mStatusBarKeyguardViewManager.isShowing()) { 1020 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); 1021 resetStateLocked(); 1022 return; 1023 } 1024 1025 // if the setup wizard hasn't run yet, don't show 1026 final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false); 1027 final boolean absent = SubscriptionManager.isValidSubscriptionId( 1028 mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT)); 1029 final boolean disabled = SubscriptionManager.isValidSubscriptionId( 1030 mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED)); 1031 final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure() 1032 || ((absent || disabled) && requireSim); 1033 1034 if (!lockedOrMissing && shouldWaitForProvisioning()) { 1035 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned" 1036 + " and the sim is not locked or missing"); 1037 return; 1038 } 1039 1040 if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser()) 1041 && !lockedOrMissing) { 1042 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off"); 1043 return; 1044 } 1045 1046 if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) { 1047 if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted"); 1048 // Without this, settings is not enabled until the lock screen first appears 1049 setShowingLocked(false); 1050 hideLocked(); 1051 mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt(); 1052 return; 1053 } 1054 1055 if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen"); 1056 showLocked(options); 1057 } 1058 1059 private boolean shouldWaitForProvisioning() { 1060 return !mUpdateMonitor.isDeviceProvisioned() && !isSecure(); 1061 } 1062 1063 /** 1064 * Dismiss the keyguard through the security layers. 1065 */ 1066 public void handleDismiss() { 1067 if (mShowing && !mOccluded) { 1068 mStatusBarKeyguardViewManager.dismiss(); 1069 } 1070 } 1071 1072 public void dismiss() { 1073 mHandler.sendEmptyMessage(DISMISS); 1074 } 1075 1076 /** 1077 * Send message to keyguard telling it to reset its state. 1078 * @see #handleReset 1079 */ 1080 private void resetStateLocked() { 1081 if (DEBUG) Log.e(TAG, "resetStateLocked"); 1082 Message msg = mHandler.obtainMessage(RESET); 1083 mHandler.sendMessage(msg); 1084 } 1085 1086 /** 1087 * Send message to keyguard telling it to verify unlock 1088 * @see #handleVerifyUnlock() 1089 */ 1090 private void verifyUnlockLocked() { 1091 if (DEBUG) Log.d(TAG, "verifyUnlockLocked"); 1092 mHandler.sendEmptyMessage(VERIFY_UNLOCK); 1093 } 1094 1095 private void notifyFinishedGoingToSleep() { 1096 if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep"); 1097 mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP); 1098 } 1099 1100 private void notifyStartedWakingUp() { 1101 if (DEBUG) Log.d(TAG, "notifyStartedWakingUp"); 1102 mHandler.sendEmptyMessage(NOTIFY_STARTED_WAKING_UP); 1103 } 1104 1105 private void notifyScreenOn(IKeyguardDrawnCallback callback) { 1106 if (DEBUG) Log.d(TAG, "notifyScreenOn"); 1107 Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNING_ON, callback); 1108 mHandler.sendMessage(msg); 1109 } 1110 1111 private void notifyScreenTurnedOn() { 1112 if (DEBUG) Log.d(TAG, "notifyScreenTurnedOn"); 1113 Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_ON); 1114 mHandler.sendMessage(msg); 1115 } 1116 1117 private void notifyScreenTurnedOff() { 1118 if (DEBUG) Log.d(TAG, "notifyScreenTurnedOff"); 1119 Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_OFF); 1120 mHandler.sendMessage(msg); 1121 } 1122 1123 /** 1124 * Send message to keyguard telling it to show itself 1125 * @see #handleShow 1126 */ 1127 private void showLocked(Bundle options) { 1128 if (DEBUG) Log.d(TAG, "showLocked"); 1129 // ensure we stay awake until we are finished displaying the keyguard 1130 mShowKeyguardWakeLock.acquire(); 1131 Message msg = mHandler.obtainMessage(SHOW, options); 1132 mHandler.sendMessage(msg); 1133 } 1134 1135 /** 1136 * Send message to keyguard telling it to hide itself 1137 * @see #handleHide() 1138 */ 1139 private void hideLocked() { 1140 if (DEBUG) Log.d(TAG, "hideLocked"); 1141 Message msg = mHandler.obtainMessage(HIDE); 1142 mHandler.sendMessage(msg); 1143 } 1144 1145 public boolean isSecure() { 1146 return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()) 1147 || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure(); 1148 } 1149 1150 /** 1151 * Update the newUserId. Call while holding WindowManagerService lock. 1152 * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing. 1153 * 1154 * @param newUserId The id of the incoming user. 1155 */ 1156 public void setCurrentUser(int newUserId) { 1157 KeyguardUpdateMonitor.setCurrentUser(newUserId); 1158 } 1159 1160 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1161 @Override 1162 public void onReceive(Context context, Intent intent) { 1163 if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) { 1164 final int sequence = intent.getIntExtra("seq", 0); 1165 if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = " 1166 + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence); 1167 synchronized (KeyguardViewMediator.this) { 1168 if (mDelayedShowingSequence == sequence) { 1169 doKeyguardLocked(null); 1170 } 1171 } 1172 } 1173 } 1174 }; 1175 1176 public void keyguardDone(boolean authenticated) { 1177 if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated +")"); 1178 EventLog.writeEvent(70000, 2); 1179 Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0); 1180 mHandler.sendMessage(msg); 1181 } 1182 1183 /** 1184 * This handler will be associated with the policy thread, which will also 1185 * be the UI thread of the keyguard. Since the apis of the policy, and therefore 1186 * this class, can be called by other threads, any action that directly 1187 * interacts with the keyguard ui should be posted to this handler, rather 1188 * than called directly. 1189 */ 1190 private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) { 1191 @Override 1192 public void handleMessage(Message msg) { 1193 switch (msg.what) { 1194 case SHOW: 1195 handleShow((Bundle) msg.obj); 1196 break; 1197 case HIDE: 1198 handleHide(); 1199 break; 1200 case RESET: 1201 handleReset(); 1202 break; 1203 case VERIFY_UNLOCK: 1204 handleVerifyUnlock(); 1205 break; 1206 case NOTIFY_FINISHED_GOING_TO_SLEEP: 1207 handleNotifyFinishedGoingToSleep(); 1208 break; 1209 case NOTIFY_SCREEN_TURNING_ON: 1210 handleNotifyScreenTurningOn((IKeyguardDrawnCallback) msg.obj); 1211 break; 1212 case NOTIFY_SCREEN_TURNED_ON: 1213 handleNotifyScreenTurnedOn(); 1214 break; 1215 case NOTIFY_SCREEN_TURNED_OFF: 1216 handleNotifyScreenTurnedOff(); 1217 break; 1218 case NOTIFY_STARTED_WAKING_UP: 1219 handleNotifyStartedWakingUp(); 1220 break; 1221 case KEYGUARD_DONE: 1222 handleKeyguardDone(msg.arg1 != 0); 1223 break; 1224 case KEYGUARD_DONE_DRAWING: 1225 handleKeyguardDoneDrawing(); 1226 break; 1227 case SET_OCCLUDED: 1228 handleSetOccluded(msg.arg1 != 0); 1229 break; 1230 case KEYGUARD_TIMEOUT: 1231 synchronized (KeyguardViewMediator.this) { 1232 doKeyguardLocked((Bundle) msg.obj); 1233 } 1234 break; 1235 case DISMISS: 1236 handleDismiss(); 1237 break; 1238 case START_KEYGUARD_EXIT_ANIM: 1239 StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; 1240 handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); 1241 break; 1242 case KEYGUARD_DONE_PENDING_TIMEOUT: 1243 Log.w(TAG, "Timeout while waiting for activity drawn!"); 1244 // Fall through. 1245 case ON_ACTIVITY_DRAWN: 1246 handleOnActivityDrawn(); 1247 break; 1248 } 1249 } 1250 }; 1251 1252 /** 1253 * @see #keyguardDone 1254 * @see #KEYGUARD_DONE 1255 */ 1256 private void handleKeyguardDone(boolean authenticated) { 1257 if (DEBUG) Log.d(TAG, "handleKeyguardDone"); 1258 synchronized (this) { 1259 resetKeyguardDonePendingLocked(); 1260 } 1261 1262 if (authenticated) { 1263 mUpdateMonitor.clearFailedUnlockAttempts(); 1264 } 1265 mUpdateMonitor.clearFingerprintRecognized(); 1266 1267 if (mGoingToSleep) { 1268 Log.i(TAG, "Device is going to sleep, aborting keyguardDone"); 1269 return; 1270 } 1271 if (mExitSecureCallback != null) { 1272 try { 1273 mExitSecureCallback.onKeyguardExitResult(authenticated); 1274 } catch (RemoteException e) { 1275 Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e); 1276 } 1277 1278 mExitSecureCallback = null; 1279 1280 if (authenticated) { 1281 // after succesfully exiting securely, no need to reshow 1282 // the keyguard when they've released the lock 1283 mExternallyEnabled = true; 1284 mNeedToReshowWhenReenabled = false; 1285 updateInputRestricted(); 1286 } 1287 } 1288 1289 handleHide(); 1290 } 1291 1292 private void sendUserPresentBroadcast() { 1293 synchronized (this) { 1294 if (mBootCompleted) { 1295 final UserHandle currentUser = new UserHandle(KeyguardUpdateMonitor.getCurrentUser()); 1296 final UserManager um = (UserManager) mContext.getSystemService( 1297 Context.USER_SERVICE); 1298 List <UserInfo> userHandles = um.getProfiles(currentUser.getIdentifier()); 1299 for (UserInfo ui : userHandles) { 1300 mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, ui.getUserHandle()); 1301 } 1302 } else { 1303 mBootSendUserPresent = true; 1304 } 1305 } 1306 } 1307 1308 /** 1309 * @see #keyguardDone 1310 * @see #KEYGUARD_DONE_DRAWING 1311 */ 1312 private void handleKeyguardDoneDrawing() { 1313 synchronized(this) { 1314 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing"); 1315 if (mWaitingUntilKeyguardVisible) { 1316 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible"); 1317 mWaitingUntilKeyguardVisible = false; 1318 notifyAll(); 1319 1320 // there will usually be two of these sent, one as a timeout, and one 1321 // as a result of the callback, so remove any remaining messages from 1322 // the queue 1323 mHandler.removeMessages(KEYGUARD_DONE_DRAWING); 1324 } 1325 } 1326 } 1327 1328 private void playSounds(boolean locked) { 1329 playSound(locked ? mLockSoundId : mUnlockSoundId); 1330 } 1331 1332 private void playSound(int soundId) { 1333 if (soundId == 0) return; 1334 final ContentResolver cr = mContext.getContentResolver(); 1335 if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) { 1336 1337 mLockSounds.stop(mLockSoundStreamId); 1338 // Init mAudioManager 1339 if (mAudioManager == null) { 1340 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 1341 if (mAudioManager == null) return; 1342 mUiSoundsStreamType = mAudioManager.getUiSoundsStreamType(); 1343 } 1344 // If the stream is muted, don't play the sound 1345 if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return; 1346 1347 mLockSoundStreamId = mLockSounds.play(soundId, 1348 mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); 1349 } 1350 } 1351 1352 private void playTrustedSound() { 1353 playSound(mTrustedSoundId); 1354 } 1355 1356 private void updateActivityLockScreenState() { 1357 try { 1358 ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mOccluded); 1359 } catch (RemoteException e) { 1360 } 1361 } 1362 1363 /** 1364 * Handle message sent by {@link #showLocked}. 1365 * @see #SHOW 1366 */ 1367 private void handleShow(Bundle options) { 1368 synchronized (KeyguardViewMediator.this) { 1369 if (!mSystemReady) { 1370 if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready."); 1371 return; 1372 } else { 1373 if (DEBUG) Log.d(TAG, "handleShow"); 1374 } 1375 1376 setShowingLocked(true); 1377 mStatusBarKeyguardViewManager.show(options); 1378 mHiding = false; 1379 mWakeAndUnlocking = false; 1380 resetKeyguardDonePendingLocked(); 1381 mHideAnimationRun = false; 1382 updateActivityLockScreenState(); 1383 adjustStatusBarLocked(); 1384 userActivity(); 1385 1386 mShowKeyguardWakeLock.release(); 1387 } 1388 mKeyguardDisplayManager.show(); 1389 } 1390 1391 private final Runnable mKeyguardGoingAwayRunnable = new Runnable() { 1392 @Override 1393 public void run() { 1394 try { 1395 mStatusBarKeyguardViewManager.keyguardGoingAway(); 1396 1397 // Don't actually hide the Keyguard at the moment, wait for window 1398 // manager until it tells us it's safe to do so with 1399 // startKeyguardExitAnimation. 1400 ActivityManagerNative.getDefault().keyguardGoingAway( 1401 mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock() 1402 || mWakeAndUnlocking, 1403 mStatusBarKeyguardViewManager.isGoingToNotificationShade()); 1404 } catch (RemoteException e) { 1405 Log.e(TAG, "Error while calling WindowManager", e); 1406 } 1407 } 1408 }; 1409 1410 /** 1411 * Handle message sent by {@link #hideLocked()} 1412 * @see #HIDE 1413 */ 1414 private void handleHide() { 1415 synchronized (KeyguardViewMediator.this) { 1416 if (DEBUG) Log.d(TAG, "handleHide"); 1417 1418 mHiding = true; 1419 if (mShowing && !mOccluded) { 1420 if (!mHideAnimationRun) { 1421 mStatusBarKeyguardViewManager.startPreHideAnimation(mKeyguardGoingAwayRunnable); 1422 } else { 1423 mKeyguardGoingAwayRunnable.run(); 1424 } 1425 } else { 1426 1427 // Don't try to rely on WindowManager - if Keyguard wasn't showing, window 1428 // manager won't start the exit animation. 1429 handleStartKeyguardExitAnimation( 1430 SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), 1431 mHideAnimation.getDuration()); 1432 } 1433 } 1434 } 1435 1436 private void handleOnActivityDrawn() { 1437 if (DEBUG) Log.d(TAG, "handleOnActivityDrawn: mKeyguardDonePending=" + mKeyguardDonePending); 1438 if (mKeyguardDonePending) { 1439 mStatusBarKeyguardViewManager.onActivityDrawn(); 1440 } 1441 } 1442 1443 private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) { 1444 synchronized (KeyguardViewMediator.this) { 1445 1446 if (!mHiding) { 1447 return; 1448 } 1449 mHiding = false; 1450 1451 if (mWakeAndUnlocking && mDrawnCallback != null) { 1452 1453 // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report 1454 // the next draw from here so we don't have to wait for window manager to signal 1455 // this to our ViewRootImpl. 1456 mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw(); 1457 notifyDrawn(mDrawnCallback); 1458 } 1459 1460 // only play "unlock" noises if not on a call (since the incall UI 1461 // disables the keyguard) 1462 if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { 1463 playSounds(false); 1464 } 1465 1466 setShowingLocked(false); 1467 mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration); 1468 resetKeyguardDonePendingLocked(); 1469 mHideAnimationRun = false; 1470 updateActivityLockScreenState(); 1471 adjustStatusBarLocked(); 1472 sendUserPresentBroadcast(); 1473 } 1474 } 1475 1476 private void adjustStatusBarLocked() { 1477 if (mStatusBarManager == null) { 1478 mStatusBarManager = (StatusBarManager) 1479 mContext.getSystemService(Context.STATUS_BAR_SERVICE); 1480 } 1481 if (mStatusBarManager == null) { 1482 Log.w(TAG, "Could not get status bar manager"); 1483 } else { 1484 // Disable aspects of the system/status/navigation bars that must not be re-enabled by 1485 // windows that appear on top, ever 1486 int flags = StatusBarManager.DISABLE_NONE; 1487 if (mShowing) { 1488 // Permanently disable components not available when keyguard is enabled 1489 // (like recents). Temporary enable/disable (e.g. the "back" button) are 1490 // done in KeyguardHostView. 1491 flags |= StatusBarManager.DISABLE_RECENT; 1492 flags |= StatusBarManager.DISABLE_SEARCH; 1493 } 1494 if (isShowingAndNotOccluded()) { 1495 flags |= StatusBarManager.DISABLE_HOME; 1496 } 1497 1498 if (DEBUG) { 1499 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded 1500 + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags)); 1501 } 1502 1503 if (!(mContext instanceof Activity)) { 1504 mStatusBarManager.disable(flags); 1505 } 1506 } 1507 } 1508 1509 /** 1510 * Handle message sent by {@link #resetStateLocked} 1511 * @see #RESET 1512 */ 1513 private void handleReset() { 1514 synchronized (KeyguardViewMediator.this) { 1515 if (DEBUG) Log.d(TAG, "handleReset"); 1516 mStatusBarKeyguardViewManager.reset(); 1517 } 1518 } 1519 1520 /** 1521 * Handle message sent by {@link #verifyUnlock} 1522 * @see #VERIFY_UNLOCK 1523 */ 1524 private void handleVerifyUnlock() { 1525 synchronized (KeyguardViewMediator.this) { 1526 if (DEBUG) Log.d(TAG, "handleVerifyUnlock"); 1527 setShowingLocked(true); 1528 mStatusBarKeyguardViewManager.verifyUnlock(); 1529 updateActivityLockScreenState(); 1530 } 1531 } 1532 1533 /** 1534 * Handle message sent by {@link #notifyFinishedGoingToSleep()} 1535 * @see #NOTIFY_FINISHED_GOING_TO_SLEEP 1536 */ 1537 private void handleNotifyFinishedGoingToSleep() { 1538 synchronized (KeyguardViewMediator.this) { 1539 if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep"); 1540 mStatusBarKeyguardViewManager.onFinishedGoingToSleep(); 1541 } 1542 } 1543 1544 private void handleNotifyStartedWakingUp() { 1545 synchronized (KeyguardViewMediator.this) { 1546 if (DEBUG) Log.d(TAG, "handleNotifyWakingUp"); 1547 mStatusBarKeyguardViewManager.onStartedWakingUp(); 1548 } 1549 } 1550 1551 private void handleNotifyScreenTurningOn(IKeyguardDrawnCallback callback) { 1552 synchronized (KeyguardViewMediator.this) { 1553 if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn"); 1554 mStatusBarKeyguardViewManager.onScreenTurningOn(); 1555 if (callback != null) { 1556 if (mWakeAndUnlocking) { 1557 mDrawnCallback = callback; 1558 } else { 1559 notifyDrawn(callback); 1560 } 1561 } 1562 } 1563 } 1564 1565 private void handleNotifyScreenTurnedOn() { 1566 synchronized (this) { 1567 if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn"); 1568 mStatusBarKeyguardViewManager.onScreenTurnedOn(); 1569 } 1570 } 1571 1572 private void handleNotifyScreenTurnedOff() { 1573 synchronized (this) { 1574 if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff"); 1575 mStatusBarKeyguardViewManager.onScreenTurnedOff(); 1576 mWakeAndUnlocking = false; 1577 } 1578 } 1579 1580 private void notifyDrawn(final IKeyguardDrawnCallback callback) { 1581 try { 1582 callback.onDrawn(); 1583 } catch (RemoteException e) { 1584 Slog.w(TAG, "Exception calling onDrawn():", e); 1585 } 1586 } 1587 1588 private void resetKeyguardDonePendingLocked() { 1589 mKeyguardDonePending = false; 1590 mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT); 1591 } 1592 1593 public void onBootCompleted() { 1594 mUpdateMonitor.dispatchBootCompleted(); 1595 synchronized (this) { 1596 mBootCompleted = true; 1597 if (mBootSendUserPresent) { 1598 sendUserPresentBroadcast(); 1599 } 1600 } 1601 } 1602 1603 public void onWakeAndUnlocking() { 1604 mWakeAndUnlocking = true; 1605 keyguardDone(true /* authenticated */); 1606 } 1607 1608 public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar, 1609 ViewGroup container, StatusBarWindowManager statusBarWindowManager, 1610 ScrimController scrimController, 1611 FingerprintUnlockController fingerprintUnlockController) { 1612 mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container, 1613 statusBarWindowManager, scrimController, fingerprintUnlockController); 1614 return mStatusBarKeyguardViewManager; 1615 } 1616 1617 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 1618 Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM, 1619 new StartKeyguardExitAnimParams(startTime, fadeoutDuration)); 1620 mHandler.sendMessage(msg); 1621 } 1622 1623 public void onActivityDrawn() { 1624 mHandler.sendEmptyMessage(ON_ACTIVITY_DRAWN); 1625 } 1626 public ViewMediatorCallback getViewMediatorCallback() { 1627 return mViewMediatorCallback; 1628 } 1629 1630 @Override 1631 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1632 pw.print(" mSystemReady: "); pw.println(mSystemReady); 1633 pw.print(" mBootCompleted: "); pw.println(mBootCompleted); 1634 pw.print(" mBootSendUserPresent: "); pw.println(mBootSendUserPresent); 1635 pw.print(" mExternallyEnabled: "); pw.println(mExternallyEnabled); 1636 pw.print(" mNeedToReshowWhenReenabled: "); pw.println(mNeedToReshowWhenReenabled); 1637 pw.print(" mShowing: "); pw.println(mShowing); 1638 pw.print(" mInputRestricted: "); pw.println(mInputRestricted); 1639 pw.print(" mOccluded: "); pw.println(mOccluded); 1640 pw.print(" mDelayedShowingSequence: "); pw.println(mDelayedShowingSequence); 1641 pw.print(" mExitSecureCallback: "); pw.println(mExitSecureCallback); 1642 pw.print(" mDeviceInteractive: "); pw.println(mDeviceInteractive); 1643 pw.print(" mGoingToSleep: "); pw.println(mGoingToSleep); 1644 pw.print(" mHiding: "); pw.println(mHiding); 1645 pw.print(" mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible); 1646 pw.print(" mKeyguardDonePending: "); pw.println(mKeyguardDonePending); 1647 pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun); 1648 pw.print(" mPendingReset: "); pw.println(mPendingReset); 1649 pw.print(" mPendingLock: "); pw.println(mPendingLock); 1650 pw.print(" mWakeAndUnlocking: "); pw.println(mWakeAndUnlocking); 1651 pw.print(" mDrawnCallback: "); pw.println(mDrawnCallback); 1652 } 1653 1654 private static class StartKeyguardExitAnimParams { 1655 1656 long startTime; 1657 long fadeoutDuration; 1658 1659 private StartKeyguardExitAnimParams(long startTime, long fadeoutDuration) { 1660 this.startTime = startTime; 1661 this.fadeoutDuration = fadeoutDuration; 1662 } 1663 } 1664 1665 private void setShowingLocked(boolean showing) { 1666 if (showing != mShowing) { 1667 mShowing = showing; 1668 int size = mKeyguardStateCallbacks.size(); 1669 for (int i = size - 1; i >= 0; i--) { 1670 try { 1671 mKeyguardStateCallbacks.get(i).onShowingStateChanged(showing); 1672 } catch (RemoteException e) { 1673 Slog.w(TAG, "Failed to call onShowingStateChanged", e); 1674 if (e instanceof DeadObjectException) { 1675 mKeyguardStateCallbacks.remove(i); 1676 } 1677 } 1678 } 1679 updateInputRestrictedLocked(); 1680 mTrustManager.reportKeyguardShowingChanged(); 1681 } 1682 } 1683 1684 public void addStateMonitorCallback(IKeyguardStateCallback callback) { 1685 synchronized (this) { 1686 mKeyguardStateCallbacks.add(callback); 1687 try { 1688 callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure()); 1689 callback.onShowingStateChanged(mShowing); 1690 callback.onInputRestrictedStateChanged(mInputRestricted); 1691 } catch (RemoteException e) { 1692 Slog.w(TAG, "Failed to call onShowingStateChanged or onSimSecureStateChanged or onInputRestrictedStateChanged", e); 1693 } 1694 } 1695 } 1696} 1697