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