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