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