KeyguardViewMediator.java revision b9d6079120747205e2ae18162aa730fad3b58d9c
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 mShowing = false; 910 hideLocked(); 911 return; 912 } 913 914 if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen"); 915 showLocked(options); 916 } 917 918 /** 919 * Dismiss the keyguard through the security layers. 920 */ 921 public void handleDismiss() { 922 if (mShowing && !mOccluded) { 923 mStatusBarKeyguardViewManager.dismiss(); 924 } 925 } 926 927 public void dismiss() { 928 mHandler.sendEmptyMessage(DISMISS); 929 } 930 931 /** 932 * Send message to keyguard telling it to reset its state. 933 * @see #handleReset 934 */ 935 private void resetStateLocked() { 936 if (DEBUG) Log.e(TAG, "resetStateLocked"); 937 Message msg = mHandler.obtainMessage(RESET); 938 mHandler.sendMessage(msg); 939 } 940 941 /** 942 * Send message to keyguard telling it to verify unlock 943 * @see #handleVerifyUnlock() 944 */ 945 private void verifyUnlockLocked() { 946 if (DEBUG) Log.d(TAG, "verifyUnlockLocked"); 947 mHandler.sendEmptyMessage(VERIFY_UNLOCK); 948 } 949 950 951 /** 952 * Send a message to keyguard telling it the screen just turned on. 953 * @see #onScreenTurnedOff(int) 954 * @see #handleNotifyScreenOff 955 */ 956 private void notifyScreenOffLocked() { 957 if (DEBUG) Log.d(TAG, "notifyScreenOffLocked"); 958 mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF); 959 } 960 961 /** 962 * Send a message to keyguard telling it the screen just turned on. 963 * @see #onScreenTurnedOn 964 * @see #handleNotifyScreenOn 965 */ 966 private void notifyScreenOnLocked(IKeyguardShowCallback result) { 967 if (DEBUG) Log.d(TAG, "notifyScreenOnLocked"); 968 Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, result); 969 mHandler.sendMessage(msg); 970 } 971 972 /** 973 * Send message to keyguard telling it to show itself 974 * @see #handleShow 975 */ 976 private void showLocked(Bundle options) { 977 if (DEBUG) Log.d(TAG, "showLocked"); 978 // ensure we stay awake until we are finished displaying the keyguard 979 mShowKeyguardWakeLock.acquire(); 980 Message msg = mHandler.obtainMessage(SHOW, options); 981 mHandler.sendMessage(msg); 982 } 983 984 /** 985 * Send message to keyguard telling it to hide itself 986 * @see #handleHide() 987 */ 988 private void hideLocked() { 989 if (DEBUG) Log.d(TAG, "hideLocked"); 990 Message msg = mHandler.obtainMessage(HIDE); 991 mHandler.sendMessage(msg); 992 } 993 994 public boolean isSecure() { 995 return mLockPatternUtils.isSecure() 996 || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure(); 997 } 998 999 /** 1000 * Update the newUserId. Call while holding WindowManagerService lock. 1001 * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing. 1002 * 1003 * @param newUserId The id of the incoming user. 1004 */ 1005 public void setCurrentUser(int newUserId) { 1006 mLockPatternUtils.setCurrentUser(newUserId); 1007 } 1008 1009 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1010 @Override 1011 public void onReceive(Context context, Intent intent) { 1012 if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) { 1013 final int sequence = intent.getIntExtra("seq", 0); 1014 if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = " 1015 + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence); 1016 synchronized (KeyguardViewMediator.this) { 1017 if (mDelayedShowingSequence == sequence) { 1018 // Don't play lockscreen SFX if the screen went off due to timeout. 1019 mSuppressNextLockSound = true; 1020 doKeyguardLocked(null); 1021 } 1022 } 1023 } 1024 } 1025 }; 1026 1027 public void keyguardDone(boolean authenticated, boolean wakeup) { 1028 if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")"); 1029 EventLog.writeEvent(70000, 2); 1030 synchronized (this) { 1031 mKeyguardDonePending = false; 1032 } 1033 Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0, wakeup ? 1 : 0); 1034 mHandler.sendMessage(msg); 1035 } 1036 1037 /** 1038 * This handler will be associated with the policy thread, which will also 1039 * be the UI thread of the keyguard. Since the apis of the policy, and therefore 1040 * this class, can be called by other threads, any action that directly 1041 * interacts with the keyguard ui should be posted to this handler, rather 1042 * than called directly. 1043 */ 1044 private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) { 1045 @Override 1046 public void handleMessage(Message msg) { 1047 switch (msg.what) { 1048 case SHOW: 1049 handleShow((Bundle) msg.obj); 1050 break; 1051 case HIDE: 1052 handleHide(); 1053 break; 1054 case RESET: 1055 handleReset(); 1056 break; 1057 case VERIFY_UNLOCK: 1058 handleVerifyUnlock(); 1059 break; 1060 case NOTIFY_SCREEN_OFF: 1061 handleNotifyScreenOff(); 1062 break; 1063 case NOTIFY_SCREEN_ON: 1064 handleNotifyScreenOn((IKeyguardShowCallback) msg.obj); 1065 break; 1066 case KEYGUARD_DONE: 1067 handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0); 1068 break; 1069 case KEYGUARD_DONE_DRAWING: 1070 handleKeyguardDoneDrawing(); 1071 break; 1072 case KEYGUARD_DONE_AUTHENTICATING: 1073 keyguardDone(true, true); 1074 break; 1075 case SET_OCCLUDED: 1076 handleSetOccluded(msg.arg1 != 0); 1077 break; 1078 case KEYGUARD_TIMEOUT: 1079 synchronized (KeyguardViewMediator.this) { 1080 doKeyguardLocked((Bundle) msg.obj); 1081 } 1082 break; 1083 case DISMISS: 1084 handleDismiss(); 1085 break; 1086 case START_KEYGUARD_EXIT_ANIM: 1087 StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; 1088 handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); 1089 break; 1090 } 1091 } 1092 }; 1093 1094 /** 1095 * @see #keyguardDone 1096 * @see #KEYGUARD_DONE 1097 */ 1098 private void handleKeyguardDone(boolean authenticated, boolean wakeup) { 1099 if (DEBUG) Log.d(TAG, "handleKeyguardDone"); 1100 1101 if (authenticated) { 1102 mUpdateMonitor.clearFailedUnlockAttempts(); 1103 } 1104 1105 if (mExitSecureCallback != null) { 1106 try { 1107 mExitSecureCallback.onKeyguardExitResult(authenticated); 1108 } catch (RemoteException e) { 1109 Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e); 1110 } 1111 1112 mExitSecureCallback = null; 1113 1114 if (authenticated) { 1115 // after succesfully exiting securely, no need to reshow 1116 // the keyguard when they've released the lock 1117 mExternallyEnabled = true; 1118 mNeedToReshowWhenReenabled = false; 1119 } 1120 } 1121 1122 handleHide(); 1123 sendUserPresentBroadcast(); 1124 } 1125 1126 private void sendUserPresentBroadcast() { 1127 final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser()); 1128 mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser); 1129 } 1130 1131 /** 1132 * @see #keyguardDone 1133 * @see #KEYGUARD_DONE_DRAWING 1134 */ 1135 private void handleKeyguardDoneDrawing() { 1136 synchronized(this) { 1137 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing"); 1138 if (mWaitingUntilKeyguardVisible) { 1139 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible"); 1140 mWaitingUntilKeyguardVisible = false; 1141 notifyAll(); 1142 1143 // there will usually be two of these sent, one as a timeout, and one 1144 // as a result of the callback, so remove any remaining messages from 1145 // the queue 1146 mHandler.removeMessages(KEYGUARD_DONE_DRAWING); 1147 } 1148 } 1149 } 1150 1151 private void playSounds(boolean locked) { 1152 // User feedback for keyguard. 1153 1154 if (mSuppressNextLockSound) { 1155 mSuppressNextLockSound = false; 1156 return; 1157 } 1158 1159 final ContentResolver cr = mContext.getContentResolver(); 1160 if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) { 1161 final int whichSound = locked 1162 ? mLockSoundId 1163 : mUnlockSoundId; 1164 mLockSounds.stop(mLockSoundStreamId); 1165 // Init mAudioManager 1166 if (mAudioManager == null) { 1167 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 1168 if (mAudioManager == null) return; 1169 mMasterStreamType = mAudioManager.getMasterStreamType(); 1170 } 1171 // If the stream is muted, don't play the sound 1172 if (mAudioManager.isStreamMute(mMasterStreamType)) return; 1173 1174 mLockSoundStreamId = mLockSounds.play(whichSound, 1175 mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); 1176 } 1177 } 1178 1179 private void updateActivityLockScreenState() { 1180 try { 1181 ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mOccluded); 1182 } catch (RemoteException e) { 1183 } 1184 } 1185 1186 /** 1187 * Handle message sent by {@link #showLocked}. 1188 * @see #SHOW 1189 */ 1190 private void handleShow(Bundle options) { 1191 synchronized (KeyguardViewMediator.this) { 1192 if (!mSystemReady) { 1193 if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready."); 1194 return; 1195 } else { 1196 if (DEBUG) Log.d(TAG, "handleShow"); 1197 } 1198 1199 mStatusBarKeyguardViewManager.show(options); 1200 mShowing = true; 1201 mKeyguardDonePending = false; 1202 updateActivityLockScreenState(); 1203 adjustStatusBarLocked(); 1204 userActivity(); 1205 1206 // Do this at the end to not slow down display of the keyguard. 1207 playSounds(true); 1208 1209 mShowKeyguardWakeLock.release(); 1210 } 1211 mKeyguardDisplayManager.show(); 1212 } 1213 1214 /** 1215 * Handle message sent by {@link #hideLocked()} 1216 * @see #HIDE 1217 */ 1218 private void handleHide() { 1219 synchronized (KeyguardViewMediator.this) { 1220 if (DEBUG) Log.d(TAG, "handleHide"); 1221 try { 1222 1223 if (mShowing) { 1224 1225 // Don't actually hide the Keyguard at the moment, wait for window manager until 1226 // it tells us it's safe to do so with startKeyguardExitAnimation. 1227 mWM.keyguardGoingAway(); 1228 } else { 1229 1230 // Don't try to rely on WindowManager - if Keyguard wasn't showing, window 1231 // manager won't start the exit animation. 1232 handleStartKeyguardExitAnimation(0, 0); 1233 } 1234 } catch (RemoteException e) { 1235 Log.e(TAG, "Error while calling WindowManager", e); 1236 } 1237 } 1238 } 1239 1240 private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) { 1241 synchronized (KeyguardViewMediator.this) { 1242 1243 // only play "unlock" noises if not on a call (since the incall UI 1244 // disables the keyguard) 1245 if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { 1246 playSounds(false); 1247 } 1248 1249 mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration); 1250 mShowing = false; 1251 mKeyguardDonePending = false; 1252 updateActivityLockScreenState(); 1253 adjustStatusBarLocked(); 1254 } 1255 } 1256 1257 private void adjustStatusBarLocked() { 1258 if (mStatusBarManager == null) { 1259 mStatusBarManager = (StatusBarManager) 1260 mContext.getSystemService(Context.STATUS_BAR_SERVICE); 1261 } 1262 if (mStatusBarManager == null) { 1263 Log.w(TAG, "Could not get status bar manager"); 1264 } else { 1265 // Disable aspects of the system/status/navigation bars that must not be re-enabled by 1266 // windows that appear on top, ever 1267 int flags = StatusBarManager.DISABLE_NONE; 1268 if (mShowing) { 1269 // Permanently disable components not available when keyguard is enabled 1270 // (like recents). Temporary enable/disable (e.g. the "back" button) are 1271 // done in KeyguardHostView. 1272 flags |= StatusBarManager.DISABLE_RECENT; 1273 if (!isAssistantAvailable()) { 1274 flags |= StatusBarManager.DISABLE_SEARCH; 1275 } 1276 } 1277 if (isShowingAndNotOccluded()) { 1278 flags |= StatusBarManager.DISABLE_HOME; 1279 } 1280 1281 if (DEBUG) { 1282 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded 1283 + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags)); 1284 } 1285 1286 if (!(mContext instanceof Activity)) { 1287 mStatusBarManager.disable(flags); 1288 } 1289 } 1290 } 1291 1292 /** 1293 * Handle message sent by {@link #resetStateLocked} 1294 * @see #RESET 1295 */ 1296 private void handleReset() { 1297 synchronized (KeyguardViewMediator.this) { 1298 if (DEBUG) Log.d(TAG, "handleReset"); 1299 mStatusBarKeyguardViewManager.reset(); 1300 } 1301 } 1302 1303 /** 1304 * Handle message sent by {@link #verifyUnlock} 1305 * @see #VERIFY_UNLOCK 1306 */ 1307 private void handleVerifyUnlock() { 1308 synchronized (KeyguardViewMediator.this) { 1309 if (DEBUG) Log.d(TAG, "handleVerifyUnlock"); 1310 mStatusBarKeyguardViewManager.verifyUnlock(); 1311 mShowing = true; 1312 updateActivityLockScreenState(); 1313 } 1314 } 1315 1316 /** 1317 * Handle message sent by {@link #notifyScreenOffLocked()} 1318 * @see #NOTIFY_SCREEN_OFF 1319 */ 1320 private void handleNotifyScreenOff() { 1321 synchronized (KeyguardViewMediator.this) { 1322 if (DEBUG) Log.d(TAG, "handleNotifyScreenOff"); 1323 mStatusBarKeyguardViewManager.onScreenTurnedOff(); 1324 } 1325 } 1326 1327 /** 1328 * Handle message sent by {@link #notifyScreenOnLocked} 1329 * @see #NOTIFY_SCREEN_ON 1330 */ 1331 private void handleNotifyScreenOn(IKeyguardShowCallback callback) { 1332 synchronized (KeyguardViewMediator.this) { 1333 if (DEBUG) Log.d(TAG, "handleNotifyScreenOn"); 1334 mStatusBarKeyguardViewManager.onScreenTurnedOn(callback); 1335 } 1336 } 1337 1338 public boolean isDismissable() { 1339 return mKeyguardDonePending || !isSecure(); 1340 } 1341 1342 private boolean isAssistantAvailable() { 1343 return mSearchManager != null 1344 && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null; 1345 } 1346 1347 public void onBootCompleted() { 1348 mUpdateMonitor.dispatchBootCompleted(); 1349 } 1350 1351 public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar, 1352 ViewGroup container, StatusBarWindowManager statusBarWindowManager, 1353 ScrimController scrimController) { 1354 mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container, 1355 statusBarWindowManager, scrimController); 1356 return mStatusBarKeyguardViewManager; 1357 } 1358 1359 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 1360 Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM, 1361 new StartKeyguardExitAnimParams(startTime, fadeoutDuration)); 1362 mHandler.sendMessage(msg); 1363 } 1364 1365 public ViewMediatorCallback getViewMediatorCallback() { 1366 return mViewMediatorCallback; 1367 } 1368 1369 private static class StartKeyguardExitAnimParams { 1370 1371 long startTime; 1372 long fadeoutDuration; 1373 1374 private StartKeyguardExitAnimParams(long startTime, long fadeoutDuration) { 1375 this.startTime = startTime; 1376 this.fadeoutDuration = fadeoutDuration; 1377 } 1378 } 1379} 1380