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