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