1 /* 2 * Copyright (C) 2008 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 17 package com.android.keyguard; 18 19 import android.app.ActivityManager; 20 import android.app.ActivityManagerNative; 21 import android.app.AlarmManager; 22 import android.app.IUserSwitchObserver; 23 import android.app.PendingIntent; 24 import android.app.admin.DevicePolicyManager; 25 import android.app.trust.TrustManager; 26 import android.content.BroadcastReceiver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentFilter; 30 import android.database.ContentObserver; 31 import android.graphics.Bitmap; 32 33 import static android.os.BatteryManager.BATTERY_STATUS_FULL; 34 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN; 35 import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN; 36 import static android.os.BatteryManager.EXTRA_STATUS; 37 import static android.os.BatteryManager.EXTRA_PLUGGED; 38 import static android.os.BatteryManager.EXTRA_LEVEL; 39 import static android.os.BatteryManager.EXTRA_HEALTH; 40 41 import android.media.AudioManager; 42 import android.os.BatteryManager; 43 import android.os.CancellationSignal; 44 import android.os.Handler; 45 import android.os.IRemoteCallback; 46 import android.os.Message; 47 import android.os.PowerManager; 48 import android.os.RemoteException; 49 import android.os.SystemClock; 50 import android.os.UserHandle; 51 import android.provider.Settings; 52 53 import com.android.internal.telephony.IccCardConstants; 54 import com.android.internal.telephony.IccCardConstants.State; 55 import com.android.internal.telephony.PhoneConstants; 56 import com.android.internal.telephony.TelephonyIntents; 57 58 import android.hardware.fingerprint.FingerprintManager; 59 import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback; 60 import android.hardware.fingerprint.FingerprintManager.AuthenticationResult; 61 import android.telephony.ServiceState; 62 import android.telephony.SubscriptionInfo; 63 import android.telephony.SubscriptionManager; 64 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; 65 import android.telephony.TelephonyManager; 66 import android.util.Log; 67 import android.util.SparseBooleanArray; 68 import android.util.SparseIntArray; 69 70 import com.google.android.collect.Lists; 71 72 import java.io.FileDescriptor; 73 import java.io.PrintWriter; 74 import java.lang.ref.WeakReference; 75 import java.util.ArrayList; 76 import java.util.HashMap; 77 import java.util.List; 78 import java.util.Map.Entry; 79 80 /** 81 * Watches for updates that may be interesting to the keyguard, and provides 82 * the up to date information as well as a registration for callbacks that care 83 * to be updated. 84 * 85 * Note: under time crunch, this has been extended to include some stuff that 86 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns 87 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()} 88 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'... 89 */ 90 public class KeyguardUpdateMonitor implements TrustManager.TrustListener { 91 92 private static final String TAG = "KeyguardUpdateMonitor"; 93 private static final boolean DEBUG = KeyguardConstants.DEBUG; 94 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES; 95 private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK; 96 private static final int LOW_BATTERY_THRESHOLD = 20; 97 private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000; 98 99 private static final String ACTION_FACE_UNLOCK_STARTED 100 = "com.android.facelock.FACE_UNLOCK_STARTED"; 101 private static final String ACTION_FACE_UNLOCK_STOPPED 102 = "com.android.facelock.FACE_UNLOCK_STOPPED"; 103 private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock"; 104 105 /** 106 * Mode in which we don't need to wake up the device when we get a fingerprint. 107 */ 108 private static final int FP_WAKE_NONE = 0; 109 110 /** 111 * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire 112 * a fingerprint while the screen is off and the device was sleeping. 113 */ 114 private static final int FP_WAKE_DIRECT_UNLOCK = 1; 115 116 /** 117 * Mode in which we wake up the device, but play the normal dismiss animation. Active when we 118 * acquire a fingerprint pulsing in doze mode. 119 * */ 120 private static final int FP_WAKE_WAKE_TO_BOUNCER = 2; 121 122 // Callback messages 123 private static final int MSG_TIME_UPDATE = 301; 124 private static final int MSG_BATTERY_UPDATE = 302; 125 private static final int MSG_SIM_STATE_CHANGE = 304; 126 private static final int MSG_RINGER_MODE_CHANGED = 305; 127 private static final int MSG_PHONE_STATE_CHANGED = 306; 128 private static final int MSG_DEVICE_PROVISIONED = 308; 129 private static final int MSG_DPM_STATE_CHANGED = 309; 130 private static final int MSG_USER_SWITCHING = 310; 131 private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 311; 132 private static final int MSG_KEYGUARD_RESET = 312; 133 private static final int MSG_BOOT_COMPLETED = 313; 134 private static final int MSG_USER_SWITCH_COMPLETE = 314; 135 private static final int MSG_USER_INFO_CHANGED = 317; 136 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318; 137 private static final int MSG_STARTED_WAKING_UP = 319; 138 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320; 139 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322; 140 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327; 141 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328; 142 private static final int MSG_AIRPLANE_MODE_CHANGED = 329; 143 private static final int MSG_SERVICE_STATE_CHANGE = 330; 144 145 private static KeyguardUpdateMonitor sInstance; 146 147 private final Context mContext; 148 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>(); 149 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>(); 150 151 private int mRingMode; 152 private int mPhoneState; 153 private boolean mKeyguardIsVisible; 154 private boolean mBouncer; 155 private boolean mBootCompleted; 156 private boolean mUserHasAuthenticatedSinceBoot; 157 158 // Device provisioning state 159 private boolean mDeviceProvisioned; 160 161 // Battery status 162 private BatteryStatus mBatteryStatus; 163 164 // Password attempts 165 private SparseIntArray mFailedAttempts = new SparseIntArray(); 166 167 private boolean mClockVisible; 168 169 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>> 170 mCallbacks = Lists.newArrayList(); 171 private ContentObserver mDeviceProvisionedObserver; 172 173 private boolean mSwitchingUser; 174 175 private boolean mDeviceInteractive; 176 private boolean mScreenOn; 177 private SubscriptionManager mSubscriptionManager; 178 private List<SubscriptionInfo> mSubscriptionInfo; 179 private boolean mFingerprintDetectionRunning; 180 private TrustManager mTrustManager; 181 private PowerManager mPowerManager; 182 183 private final Handler mHandler = new Handler() { 184 @Override 185 public void handleMessage(Message msg) { 186 switch (msg.what) { 187 case MSG_TIME_UPDATE: 188 handleTimeUpdate(); 189 break; 190 case MSG_BATTERY_UPDATE: 191 handleBatteryUpdate((BatteryStatus) msg.obj); 192 break; 193 case MSG_SIM_STATE_CHANGE: 194 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj); 195 break; 196 case MSG_RINGER_MODE_CHANGED: 197 handleRingerModeChange(msg.arg1); 198 break; 199 case MSG_PHONE_STATE_CHANGED: 200 handlePhoneStateChanged((String) msg.obj); 201 break; 202 case MSG_DEVICE_PROVISIONED: 203 handleDeviceProvisioned(); 204 break; 205 case MSG_DPM_STATE_CHANGED: 206 handleDevicePolicyManagerStateChanged(); 207 break; 208 case MSG_USER_SWITCHING: 209 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj); 210 break; 211 case MSG_USER_SWITCH_COMPLETE: 212 handleUserSwitchComplete(msg.arg1); 213 break; 214 case MSG_KEYGUARD_VISIBILITY_CHANGED: 215 handleKeyguardVisibilityChanged(msg.arg1); 216 break; 217 case MSG_KEYGUARD_RESET: 218 handleKeyguardReset(); 219 break; 220 case MSG_KEYGUARD_BOUNCER_CHANGED: 221 handleKeyguardBouncerChanged(msg.arg1); 222 break; 223 case MSG_BOOT_COMPLETED: 224 handleBootCompleted(); 225 break; 226 case MSG_USER_INFO_CHANGED: 227 handleUserInfoChanged(msg.arg1); 228 break; 229 case MSG_REPORT_EMERGENCY_CALL_ACTION: 230 handleReportEmergencyCallAction(); 231 break; 232 case MSG_FINISHED_GOING_TO_SLEEP: 233 handleFinishedGoingToSleep(msg.arg1); 234 break; 235 case MSG_STARTED_WAKING_UP: 236 handleStartedWakingUp(); 237 break; 238 case MSG_FACE_UNLOCK_STATE_CHANGED: 239 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2); 240 break; 241 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED: 242 handleSimSubscriptionInfoChanged(); 243 break; 244 case MSG_AIRPLANE_MODE_CHANGED: 245 handleAirplaneModeChanged(); 246 break; 247 case MSG_SERVICE_STATE_CHANGE: 248 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj); 249 break; 250 } 251 } 252 }; 253 254 private OnSubscriptionsChangedListener mSubscriptionListener = 255 new OnSubscriptionsChangedListener() { 256 @Override 257 public void onSubscriptionsChanged() { 258 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED); 259 } 260 }; 261 262 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray(); 263 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray(); 264 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray(); 265 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray(); 266 267 private static int sCurrentUser; 268 269 private int mFpWakeMode; 270 setCurrentUser(int currentUser)271 public synchronized static void setCurrentUser(int currentUser) { 272 sCurrentUser = currentUser; 273 } 274 getCurrentUser()275 public synchronized static int getCurrentUser() { 276 return sCurrentUser; 277 } 278 279 @Override onTrustChanged(boolean enabled, int userId, int flags)280 public void onTrustChanged(boolean enabled, int userId, int flags) { 281 mUserHasTrust.put(userId, enabled); 282 for (int i = 0; i < mCallbacks.size(); i++) { 283 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 284 if (cb != null) { 285 cb.onTrustChanged(userId); 286 if (enabled && flags != 0) { 287 cb.onTrustGrantedWithFlags(flags, userId); 288 } 289 } 290 } 291 } 292 handleSimSubscriptionInfoChanged()293 protected void handleSimSubscriptionInfoChanged() { 294 if (DEBUG_SIM_STATES) { 295 Log.v(TAG, "onSubscriptionInfoChanged()"); 296 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(); 297 if (sil != null) { 298 for (SubscriptionInfo subInfo : sil) { 299 Log.v(TAG, "SubInfo:" + subInfo); 300 } 301 } else { 302 Log.v(TAG, "onSubscriptionInfoChanged: list is null"); 303 } 304 } 305 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */); 306 307 // Hack level over 9000: Because the subscription id is not yet valid when we see the 308 // first update in handleSimStateChange, we need to force refresh all all SIM states 309 // so the subscription id for them is consistent. 310 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>(); 311 for (int i = 0; i < subscriptionInfos.size(); i++) { 312 SubscriptionInfo info = subscriptionInfos.get(i); 313 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex()); 314 if (changed) { 315 changedSubscriptions.add(info); 316 } 317 } 318 for (int i = 0; i < changedSubscriptions.size(); i++) { 319 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId()); 320 for (int j = 0; j < mCallbacks.size(); j++) { 321 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); 322 if (cb != null) { 323 cb.onSimStateChanged(data.subId, data.slotId, data.simState); 324 } 325 } 326 } 327 for (int j = 0; j < mCallbacks.size(); j++) { 328 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); 329 if (cb != null) { 330 cb.onRefreshCarrierInfo(); 331 } 332 } 333 } 334 handleAirplaneModeChanged()335 private void handleAirplaneModeChanged() { 336 for (int j = 0; j < mCallbacks.size(); j++) { 337 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); 338 if (cb != null) { 339 cb.onRefreshCarrierInfo(); 340 } 341 } 342 } 343 344 /** @return List of SubscriptionInfo records, maybe empty but never null */ getSubscriptionInfo(boolean forceReload)345 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) { 346 List<SubscriptionInfo> sil = mSubscriptionInfo; 347 if (sil == null || forceReload) { 348 sil = mSubscriptionManager.getActiveSubscriptionInfoList(); 349 } 350 if (sil == null) { 351 // getActiveSubscriptionInfoList was null callers expect an empty list. 352 mSubscriptionInfo = new ArrayList<SubscriptionInfo>(); 353 } else { 354 mSubscriptionInfo = sil; 355 } 356 return mSubscriptionInfo; 357 } 358 359 @Override onTrustManagedChanged(boolean managed, int userId)360 public void onTrustManagedChanged(boolean managed, int userId) { 361 mUserTrustIsManaged.put(userId, managed); 362 363 for (int i = 0; i < mCallbacks.size(); i++) { 364 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 365 if (cb != null) { 366 cb.onTrustManagedChanged(userId); 367 } 368 } 369 } 370 onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking)371 private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { 372 mUserFingerprintAuthenticated.put(userId, true); 373 for (int i = 0; i < mCallbacks.size(); i++) { 374 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 375 if (cb != null) { 376 cb.onFingerprintAuthenticated(userId, wakeAndUnlocking); 377 } 378 } 379 } 380 handleFingerprintAuthFailed()381 private void handleFingerprintAuthFailed() { 382 releaseFingerprintWakeLock(); 383 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized)); 384 } 385 handleFingerprintAcquired(int acquireInfo)386 private void handleFingerprintAcquired(int acquireInfo) { 387 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) { 388 return; 389 } 390 if (!mDeviceInteractive && !mScreenOn) { 391 releaseFingerprintWakeLock(); 392 mWakeLock = mPowerManager.newWakeLock( 393 PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME); 394 mWakeLock.acquire(); 395 mFpWakeMode = FP_WAKE_DIRECT_UNLOCK; 396 if (DEBUG_FP_WAKELOCK) { 397 Log.i(TAG, "fingerprint acquired, grabbing fp wakelock"); 398 } 399 mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable, 400 FINGERPRINT_WAKELOCK_TIMEOUT_MS); 401 } else if (!mDeviceInteractive) { 402 mFpWakeMode = FP_WAKE_WAKE_TO_BOUNCER; 403 } else { 404 mFpWakeMode = FP_WAKE_NONE; 405 } 406 } 407 408 private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() { 409 @Override 410 public void run() { 411 if (DEBUG_FP_WAKELOCK) { 412 Log.i(TAG, "fp wakelock: TIMEOUT!!"); 413 } 414 releaseFingerprintWakeLock(); 415 } 416 }; 417 releaseFingerprintWakeLock()418 private void releaseFingerprintWakeLock() { 419 if (mWakeLock != null) { 420 mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable); 421 if (DEBUG_FP_WAKELOCK) { 422 Log.i(TAG, "releasing fp wakelock"); 423 } 424 mWakeLock.release(); 425 mWakeLock = null; 426 } 427 } 428 handleFingerprintAuthenticated()429 private void handleFingerprintAuthenticated() { 430 if (mFpWakeMode == FP_WAKE_WAKE_TO_BOUNCER || mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) { 431 if (DEBUG_FP_WAKELOCK) { 432 Log.i(TAG, "fp wakelock: Authenticated, waking up..."); 433 } 434 mPowerManager.wakeUp(SystemClock.uptimeMillis()); 435 } 436 releaseFingerprintWakeLock(); 437 try { 438 final int userId; 439 try { 440 userId = ActivityManagerNative.getDefault().getCurrentUser().id; 441 } catch (RemoteException e) { 442 Log.e(TAG, "Failed to get current user id: ", e); 443 return; 444 } 445 if (isFingerprintDisabled(userId)) { 446 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId); 447 return; 448 } 449 onFingerprintAuthenticated(userId, mFpWakeMode == FP_WAKE_DIRECT_UNLOCK); 450 } finally { 451 setFingerprintRunningDetectionRunning(false); 452 } 453 } 454 handleFingerprintHelp(int msgId, String helpString)455 private void handleFingerprintHelp(int msgId, String helpString) { 456 for (int i = 0; i < mCallbacks.size(); i++) { 457 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 458 if (cb != null) { 459 cb.onFingerprintHelp(msgId, helpString); 460 } 461 } 462 } 463 handleFingerprintError(int msgId, String errString)464 private void handleFingerprintError(int msgId, String errString) { 465 setFingerprintRunningDetectionRunning(false); 466 for (int i = 0; i < mCallbacks.size(); i++) { 467 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 468 if (cb != null) { 469 cb.onFingerprintError(msgId, errString); 470 } 471 } 472 } 473 setFingerprintRunningDetectionRunning(boolean running)474 private void setFingerprintRunningDetectionRunning(boolean running) { 475 if (running != mFingerprintDetectionRunning) { 476 mFingerprintDetectionRunning = running; 477 notifyFingerprintRunningStateChanged(); 478 } 479 } 480 notifyFingerprintRunningStateChanged()481 private void notifyFingerprintRunningStateChanged() { 482 for (int i = 0; i < mCallbacks.size(); i++) { 483 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 484 if (cb != null) { 485 cb.onFingerprintRunningStateChanged(mFingerprintDetectionRunning); 486 } 487 } 488 } handleFaceUnlockStateChanged(boolean running, int userId)489 private void handleFaceUnlockStateChanged(boolean running, int userId) { 490 mUserFaceUnlockRunning.put(userId, running); 491 for (int i = 0; i < mCallbacks.size(); i++) { 492 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 493 if (cb != null) { 494 cb.onFaceUnlockStateChanged(running, userId); 495 } 496 } 497 } 498 isFaceUnlockRunning(int userId)499 public boolean isFaceUnlockRunning(int userId) { 500 return mUserFaceUnlockRunning.get(userId); 501 } 502 isFingerprintDetectionRunning()503 public boolean isFingerprintDetectionRunning() { 504 return mFingerprintDetectionRunning; 505 } 506 isTrustDisabled(int userId)507 private boolean isTrustDisabled(int userId) { 508 // Don't allow trust agent if device is secured with a SIM PIN. This is here 509 // mainly because there's no other way to prompt the user to enter their SIM PIN 510 // once they get past the keyguard screen. 511 final boolean disabledBySimPin = isSimPinSecure(); 512 return disabledBySimPin; 513 } 514 isFingerprintDisabled(int userId)515 private boolean isFingerprintDisabled(int userId) { 516 final DevicePolicyManager dpm = 517 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 518 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId) 519 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0; 520 } 521 getUserCanSkipBouncer(int userId)522 public boolean getUserCanSkipBouncer(int userId) { 523 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId) 524 && isUnlockingWithFingerprintAllowed()); 525 } 526 getUserHasTrust(int userId)527 public boolean getUserHasTrust(int userId) { 528 return !isTrustDisabled(userId) && mUserHasTrust.get(userId); 529 } 530 getUserTrustIsManaged(int userId)531 public boolean getUserTrustIsManaged(int userId) { 532 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId); 533 } 534 isUnlockingWithFingerprintAllowed()535 public boolean isUnlockingWithFingerprintAllowed() { 536 return mUserHasAuthenticatedSinceBoot; 537 } 538 539 static class DisplayClientState { 540 public int clientGeneration; 541 public boolean clearing; 542 public PendingIntent intent; 543 public int playbackState; 544 public long playbackEventTime; 545 } 546 547 private DisplayClientState mDisplayClientState = new DisplayClientState(); 548 549 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 550 551 public void onReceive(Context context, Intent intent) { 552 final String action = intent.getAction(); 553 if (DEBUG) Log.d(TAG, "received broadcast " + action); 554 555 if (Intent.ACTION_TIME_TICK.equals(action) 556 || Intent.ACTION_TIME_CHANGED.equals(action) 557 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { 558 mHandler.sendEmptyMessage(MSG_TIME_UPDATE); 559 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 560 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN); 561 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0); 562 final int level = intent.getIntExtra(EXTRA_LEVEL, 0); 563 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN); 564 final Message msg = mHandler.obtainMessage( 565 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health)); 566 mHandler.sendMessage(msg); 567 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) { 568 SimData args = SimData.fromIntent(intent); 569 if (DEBUG_SIM_STATES) { 570 Log.v(TAG, "action " + action 571 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE) 572 + " slotId: " + args.slotId + " subid: " + args.subId); 573 } 574 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState) 575 .sendToTarget(); 576 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) { 577 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED, 578 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0)); 579 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { 580 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 581 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state)); 582 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) { 583 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED); 584 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { 585 dispatchBootCompleted(); 586 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) { 587 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras()); 588 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, 589 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 590 if (DEBUG) { 591 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId=" 592 + subId); 593 } 594 mHandler.sendMessage( 595 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState)); 596 } 597 } 598 }; 599 600 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() { 601 602 public void onReceive(Context context, Intent intent) { 603 final String action = intent.getAction(); 604 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) { 605 mHandler.sendEmptyMessage(MSG_TIME_UPDATE); 606 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) { 607 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED, 608 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0)); 609 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) { 610 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1, 611 getSendingUserId())); 612 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) { 613 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0, 614 getSendingUserId())); 615 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED 616 .equals(action)) { 617 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED); 618 } 619 } 620 }; 621 622 private FingerprintManager.AuthenticationCallback mAuthenticationCallback 623 = new AuthenticationCallback() { 624 625 @Override 626 public void onAuthenticationFailed() { 627 handleFingerprintAuthFailed(); 628 }; 629 630 @Override 631 public void onAuthenticationSucceeded(AuthenticationResult result) { 632 handleFingerprintAuthenticated(); 633 } 634 635 @Override 636 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { 637 handleFingerprintHelp(helpMsgId, helpString.toString()); 638 } 639 640 @Override 641 public void onAuthenticationError(int errMsgId, CharSequence errString) { 642 handleFingerprintError(errMsgId, errString.toString()); 643 } 644 645 @Override 646 public void onAuthenticationAcquired(int acquireInfo) { 647 handleFingerprintAcquired(acquireInfo); 648 } 649 }; 650 private CancellationSignal mFingerprintCancelSignal; 651 private FingerprintManager mFpm; 652 private PowerManager.WakeLock mWakeLock; 653 654 /** 655 * When we receive a 656 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast, 657 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange}, 658 * we need a single object to pass to the handler. This class helps decode 659 * the intent and provide a {@link SimCard.State} result. 660 */ 661 private static class SimData { 662 public State simState; 663 public int slotId; 664 public int subId; 665 SimData(State state, int slot, int id)666 SimData(State state, int slot, int id) { 667 simState = state; 668 slotId = slot; 669 subId = id; 670 } 671 fromIntent(Intent intent)672 static SimData fromIntent(Intent intent) { 673 State state; 674 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) { 675 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED"); 676 } 677 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); 678 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0); 679 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, 680 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 681 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 682 final String absentReason = intent 683 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); 684 685 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals( 686 absentReason)) { 687 state = IccCardConstants.State.PERM_DISABLED; 688 } else { 689 state = IccCardConstants.State.ABSENT; 690 } 691 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { 692 state = IccCardConstants.State.READY; 693 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { 694 final String lockedReason = intent 695 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); 696 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { 697 state = IccCardConstants.State.PIN_REQUIRED; 698 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { 699 state = IccCardConstants.State.PUK_REQUIRED; 700 } else { 701 state = IccCardConstants.State.UNKNOWN; 702 } 703 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) { 704 state = IccCardConstants.State.NETWORK_LOCKED; 705 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra) 706 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) { 707 // This is required because telephony doesn't return to "READY" after 708 // these state transitions. See bug 7197471. 709 state = IccCardConstants.State.READY; 710 } else { 711 state = IccCardConstants.State.UNKNOWN; 712 } 713 return new SimData(state, slotId, subId); 714 } 715 toString()716 public String toString() { 717 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}"; 718 } 719 } 720 721 public static class BatteryStatus { 722 public final int status; 723 public final int level; 724 public final int plugged; 725 public final int health; BatteryStatus(int status, int level, int plugged, int health)726 public BatteryStatus(int status, int level, int plugged, int health) { 727 this.status = status; 728 this.level = level; 729 this.plugged = plugged; 730 this.health = health; 731 } 732 733 /** 734 * Determine whether the device is plugged in (USB, power, or wireless). 735 * @return true if the device is plugged in. 736 */ isPluggedIn()737 public boolean isPluggedIn() { 738 return plugged == BatteryManager.BATTERY_PLUGGED_AC 739 || plugged == BatteryManager.BATTERY_PLUGGED_USB 740 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS; 741 } 742 743 /** 744 * Whether or not the device is charged. Note that some devices never return 100% for 745 * battery level, so this allows either battery level or status to determine if the 746 * battery is charged. 747 * @return true if the device is charged 748 */ isCharged()749 public boolean isCharged() { 750 return status == BATTERY_STATUS_FULL || level >= 100; 751 } 752 753 /** 754 * Whether battery is low and needs to be charged. 755 * @return true if battery is low 756 */ isBatteryLow()757 public boolean isBatteryLow() { 758 return level < LOW_BATTERY_THRESHOLD; 759 } 760 761 } 762 getInstance(Context context)763 public static KeyguardUpdateMonitor getInstance(Context context) { 764 if (sInstance == null) { 765 sInstance = new KeyguardUpdateMonitor(context); 766 } 767 return sInstance; 768 } 769 handleStartedWakingUp()770 protected void handleStartedWakingUp() { 771 updateFingerprintListeningState(); 772 final int count = mCallbacks.size(); 773 for (int i = 0; i < count; i++) { 774 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 775 if (cb != null) { 776 cb.onStartedWakingUp(); 777 } 778 } 779 } 780 handleFinishedGoingToSleep(int arg1)781 protected void handleFinishedGoingToSleep(int arg1) { 782 clearFingerprintRecognized(); 783 final int count = mCallbacks.size(); 784 for (int i = 0; i < count; i++) { 785 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 786 if (cb != null) { 787 cb.onFinishedGoingToSleep(arg1); 788 } 789 } 790 updateFingerprintListeningState(); 791 } 792 793 /** 794 * IMPORTANT: Must be called from UI thread. 795 */ dispatchSetBackground(Bitmap bmp)796 public void dispatchSetBackground(Bitmap bmp) { 797 if (DEBUG) Log.d(TAG, "dispatchSetBackground"); 798 final int count = mCallbacks.size(); 799 for (int i = 0; i < count; i++) { 800 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 801 if (cb != null) { 802 cb.onSetBackground(bmp); 803 } 804 } 805 } 806 handleUserInfoChanged(int userId)807 private void handleUserInfoChanged(int userId) { 808 for (int i = 0; i < mCallbacks.size(); i++) { 809 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 810 if (cb != null) { 811 cb.onUserInfoChanged(userId); 812 } 813 } 814 } 815 KeyguardUpdateMonitor(Context context)816 private KeyguardUpdateMonitor(Context context) { 817 mContext = context; 818 mSubscriptionManager = SubscriptionManager.from(context); 819 mPowerManager = context.getSystemService(PowerManager.class); 820 mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); 821 // Since device can't be un-provisioned, we only need to register a content observer 822 // to update mDeviceProvisioned when we are... 823 if (!mDeviceProvisioned) { 824 watchForDeviceProvisioning(); 825 } 826 827 // Take a guess at initial SIM state, battery status and PLMN until we get an update 828 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0); 829 830 // Watch for interesting updates 831 final IntentFilter filter = new IntentFilter(); 832 filter.addAction(Intent.ACTION_TIME_TICK); 833 filter.addAction(Intent.ACTION_TIME_CHANGED); 834 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 835 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 836 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); 837 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 838 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 839 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 840 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 841 context.registerReceiver(mBroadcastReceiver, filter); 842 843 final IntentFilter bootCompleteFilter = new IntentFilter(); 844 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 845 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED); 846 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter); 847 848 final IntentFilter allUserFilter = new IntentFilter(); 849 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED); 850 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED); 851 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED); 852 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED); 853 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 854 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter, 855 null, null); 856 857 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener); 858 try { 859 ActivityManagerNative.getDefault().registerUserSwitchObserver( 860 new IUserSwitchObserver.Stub() { 861 @Override 862 public void onUserSwitching(int newUserId, IRemoteCallback reply) { 863 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING, 864 newUserId, 0, reply)); 865 } 866 @Override 867 public void onUserSwitchComplete(int newUserId) throws RemoteException { 868 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE, 869 newUserId, 0)); 870 } 871 @Override 872 public void onForegroundProfileSwitch(int newProfileId) { 873 // Ignore. 874 } 875 }); 876 } catch (RemoteException e) { 877 // TODO Auto-generated catch block 878 e.printStackTrace(); 879 } 880 881 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE); 882 mTrustManager.registerTrustListener(this); 883 884 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); 885 updateFingerprintListeningState(); 886 } 887 updateFingerprintListeningState()888 private void updateFingerprintListeningState() { 889 boolean shouldListenForFingerprint = shouldListenForFingerprint(); 890 if (mFingerprintDetectionRunning && !shouldListenForFingerprint) { 891 stopListeningForFingerprint(); 892 } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) { 893 startListeningForFingerprint(); 894 } 895 } 896 shouldListenForFingerprint()897 private boolean shouldListenForFingerprint() { 898 return mKeyguardIsVisible && !mSwitchingUser; 899 } 900 startListeningForFingerprint()901 private void startListeningForFingerprint() { 902 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()"); 903 int userId = ActivityManager.getCurrentUser(); 904 if (isUnlockWithFingerPrintPossible(userId)) { 905 mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot( 906 ActivityManager.getCurrentUser()); 907 if (mFingerprintCancelSignal != null) { 908 mFingerprintCancelSignal.cancel(); 909 } 910 mFingerprintCancelSignal = new CancellationSignal(); 911 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId); 912 setFingerprintRunningDetectionRunning(true); 913 } 914 } 915 isUnlockWithFingerPrintPossible(int userId)916 public boolean isUnlockWithFingerPrintPossible(int userId) { 917 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId) 918 && mFpm.getEnrolledFingerprints(userId).size() > 0; 919 } 920 stopListeningForFingerprint()921 private void stopListeningForFingerprint() { 922 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()"); 923 if (isFingerprintDetectionRunning()) { 924 mFingerprintCancelSignal.cancel(); 925 mFingerprintCancelSignal = null; 926 } 927 setFingerprintRunningDetectionRunning(false); 928 } 929 isDeviceProvisionedInSettingsDb()930 private boolean isDeviceProvisionedInSettingsDb() { 931 return Settings.Global.getInt(mContext.getContentResolver(), 932 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 933 } 934 watchForDeviceProvisioning()935 private void watchForDeviceProvisioning() { 936 mDeviceProvisionedObserver = new ContentObserver(mHandler) { 937 @Override 938 public void onChange(boolean selfChange) { 939 super.onChange(selfChange); 940 mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); 941 if (mDeviceProvisioned) { 942 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED); 943 } 944 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned); 945 } 946 }; 947 948 mContext.getContentResolver().registerContentObserver( 949 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 950 false, mDeviceProvisionedObserver); 951 952 // prevent a race condition between where we check the flag and where we register the 953 // observer by grabbing the value once again... 954 boolean provisioned = isDeviceProvisionedInSettingsDb(); 955 if (provisioned != mDeviceProvisioned) { 956 mDeviceProvisioned = provisioned; 957 if (mDeviceProvisioned) { 958 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED); 959 } 960 } 961 } 962 963 /** 964 * Handle {@link #MSG_DPM_STATE_CHANGED} 965 */ handleDevicePolicyManagerStateChanged()966 protected void handleDevicePolicyManagerStateChanged() { 967 for (int i = mCallbacks.size() - 1; i >= 0; i--) { 968 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 969 if (cb != null) { 970 cb.onDevicePolicyManagerStateChanged(); 971 } 972 } 973 } 974 975 /** 976 * Handle {@link #MSG_USER_SWITCHING} 977 */ handleUserSwitching(int userId, IRemoteCallback reply)978 protected void handleUserSwitching(int userId, IRemoteCallback reply) { 979 mSwitchingUser = true; 980 updateFingerprintListeningState(); 981 982 for (int i = 0; i < mCallbacks.size(); i++) { 983 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 984 if (cb != null) { 985 cb.onUserSwitching(userId); 986 } 987 } 988 try { 989 reply.sendResult(null); 990 } catch (RemoteException e) { 991 } 992 } 993 994 /** 995 * Handle {@link #MSG_USER_SWITCH_COMPLETE} 996 */ handleUserSwitchComplete(int userId)997 protected void handleUserSwitchComplete(int userId) { 998 mSwitchingUser = false; 999 updateFingerprintListeningState(); 1000 1001 for (int i = 0; i < mCallbacks.size(); i++) { 1002 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1003 if (cb != null) { 1004 cb.onUserSwitchComplete(userId); 1005 } 1006 } 1007 } 1008 1009 /** 1010 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If 1011 * keyguard crashes sometime after boot, then it will never receive this 1012 * broadcast and hence not handle the event. This method is ultimately called by 1013 * PhoneWindowManager in this case. 1014 */ dispatchBootCompleted()1015 public void dispatchBootCompleted() { 1016 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 1017 } 1018 1019 /** 1020 * Handle {@link #MSG_BOOT_COMPLETED} 1021 */ handleBootCompleted()1022 protected void handleBootCompleted() { 1023 if (mBootCompleted) return; 1024 mBootCompleted = true; 1025 for (int i = 0; i < mCallbacks.size(); i++) { 1026 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1027 if (cb != null) { 1028 cb.onBootCompleted(); 1029 } 1030 } 1031 } 1032 1033 /** 1034 * We need to store this state in the KeyguardUpdateMonitor since this class will not be 1035 * destroyed. 1036 */ hasBootCompleted()1037 public boolean hasBootCompleted() { 1038 return mBootCompleted; 1039 } 1040 1041 /** 1042 * Handle {@link #MSG_DEVICE_PROVISIONED} 1043 */ handleDeviceProvisioned()1044 protected void handleDeviceProvisioned() { 1045 for (int i = 0; i < mCallbacks.size(); i++) { 1046 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1047 if (cb != null) { 1048 cb.onDeviceProvisioned(); 1049 } 1050 } 1051 if (mDeviceProvisionedObserver != null) { 1052 // We don't need the observer anymore... 1053 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver); 1054 mDeviceProvisionedObserver = null; 1055 } 1056 } 1057 1058 /** 1059 * Handle {@link #MSG_PHONE_STATE_CHANGED} 1060 */ handlePhoneStateChanged(String newState)1061 protected void handlePhoneStateChanged(String newState) { 1062 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")"); 1063 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) { 1064 mPhoneState = TelephonyManager.CALL_STATE_IDLE; 1065 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) { 1066 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK; 1067 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) { 1068 mPhoneState = TelephonyManager.CALL_STATE_RINGING; 1069 } 1070 for (int i = 0; i < mCallbacks.size(); i++) { 1071 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1072 if (cb != null) { 1073 cb.onPhoneStateChanged(mPhoneState); 1074 } 1075 } 1076 } 1077 1078 /** 1079 * Handle {@link #MSG_RINGER_MODE_CHANGED} 1080 */ handleRingerModeChange(int mode)1081 protected void handleRingerModeChange(int mode) { 1082 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")"); 1083 mRingMode = mode; 1084 for (int i = 0; i < mCallbacks.size(); i++) { 1085 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1086 if (cb != null) { 1087 cb.onRingerModeChanged(mode); 1088 } 1089 } 1090 } 1091 1092 /** 1093 * Handle {@link #MSG_TIME_UPDATE} 1094 */ handleTimeUpdate()1095 private void handleTimeUpdate() { 1096 if (DEBUG) Log.d(TAG, "handleTimeUpdate"); 1097 for (int i = 0; i < mCallbacks.size(); i++) { 1098 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1099 if (cb != null) { 1100 cb.onTimeChanged(); 1101 } 1102 } 1103 } 1104 1105 /** 1106 * Handle {@link #MSG_BATTERY_UPDATE} 1107 */ handleBatteryUpdate(BatteryStatus status)1108 private void handleBatteryUpdate(BatteryStatus status) { 1109 if (DEBUG) Log.d(TAG, "handleBatteryUpdate"); 1110 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status); 1111 mBatteryStatus = status; 1112 if (batteryUpdateInteresting) { 1113 for (int i = 0; i < mCallbacks.size(); i++) { 1114 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1115 if (cb != null) { 1116 cb.onRefreshBatteryInfo(status); 1117 } 1118 } 1119 } 1120 } 1121 1122 /** 1123 * Handle {@link #MSG_SIM_STATE_CHANGE} 1124 */ handleSimStateChange(int subId, int slotId, State state)1125 private void handleSimStateChange(int subId, int slotId, State state) { 1126 1127 if (DEBUG_SIM_STATES) { 1128 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId=" 1129 + slotId + ", state=" + state +")"); 1130 } 1131 1132 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1133 Log.w(TAG, "invalid subId in handleSimStateChange()"); 1134 return; 1135 } 1136 1137 SimData data = mSimDatas.get(subId); 1138 final boolean changed; 1139 if (data == null) { 1140 data = new SimData(state, slotId, subId); 1141 mSimDatas.put(subId, data); 1142 changed = true; // no data yet; force update 1143 } else { 1144 changed = (data.simState != state || data.subId != subId || data.slotId != slotId); 1145 data.simState = state; 1146 data.subId = subId; 1147 data.slotId = slotId; 1148 } 1149 if (changed && state != State.UNKNOWN) { 1150 for (int i = 0; i < mCallbacks.size(); i++) { 1151 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1152 if (cb != null) { 1153 cb.onSimStateChanged(subId, slotId, state); 1154 } 1155 } 1156 } 1157 } 1158 1159 /** 1160 * Handle {@link #MSG_SERVICE_STATE_CHANGE} 1161 */ handleServiceStateChange(int subId, ServiceState serviceState)1162 private void handleServiceStateChange(int subId, ServiceState serviceState) { 1163 if (DEBUG) { 1164 Log.d(TAG, 1165 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState); 1166 } 1167 1168 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1169 Log.w(TAG, "invalid subId in handleServiceStateChange()"); 1170 return; 1171 } 1172 1173 mServiceStates.put(subId, serviceState); 1174 1175 for (int j = 0; j < mCallbacks.size(); j++) { 1176 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); 1177 if (cb != null) { 1178 cb.onRefreshCarrierInfo(); 1179 } 1180 } 1181 } 1182 1183 /** 1184 * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED} 1185 */ handleKeyguardVisibilityChanged(int showing)1186 private void handleKeyguardVisibilityChanged(int showing) { 1187 if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")"); 1188 boolean isShowing = (showing == 1); 1189 mKeyguardIsVisible = isShowing; 1190 for (int i = 0; i < mCallbacks.size(); i++) { 1191 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1192 if (cb != null) { 1193 cb.onKeyguardVisibilityChangedRaw(isShowing); 1194 } 1195 } 1196 updateFingerprintListeningState(); 1197 } 1198 1199 /** 1200 * Handle {@link #MSG_KEYGUARD_RESET} 1201 */ handleKeyguardReset()1202 private void handleKeyguardReset() { 1203 if (DEBUG) Log.d(TAG, "handleKeyguardReset"); 1204 if (!isUnlockingWithFingerprintAllowed()) { 1205 updateFingerprintListeningState(); 1206 } 1207 } 1208 1209 /** 1210 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED} 1211 * @see #sendKeyguardBouncerChanged(boolean) 1212 */ handleKeyguardBouncerChanged(int bouncer)1213 private void handleKeyguardBouncerChanged(int bouncer) { 1214 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")"); 1215 boolean isBouncer = (bouncer == 1); 1216 mBouncer = isBouncer; 1217 for (int i = 0; i < mCallbacks.size(); i++) { 1218 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1219 if (cb != null) { 1220 cb.onKeyguardBouncerChanged(isBouncer); 1221 } 1222 } 1223 } 1224 1225 /** 1226 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION} 1227 */ handleReportEmergencyCallAction()1228 private void handleReportEmergencyCallAction() { 1229 for (int i = 0; i < mCallbacks.size(); i++) { 1230 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 1231 if (cb != null) { 1232 cb.onEmergencyCallAction(); 1233 } 1234 } 1235 } 1236 isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current)1237 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) { 1238 final boolean nowPluggedIn = current.isPluggedIn(); 1239 final boolean wasPluggedIn = old.isPluggedIn(); 1240 final boolean stateChangedWhilePluggedIn = 1241 wasPluggedIn == true && nowPluggedIn == true 1242 && (old.status != current.status); 1243 1244 // change in plug state is always interesting 1245 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) { 1246 return true; 1247 } 1248 1249 // change in battery level while plugged in 1250 if (nowPluggedIn && old.level != current.level) { 1251 return true; 1252 } 1253 1254 // change where battery needs charging 1255 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) { 1256 return true; 1257 } 1258 return false; 1259 } 1260 1261 /** 1262 * Remove the given observer's callback. 1263 * 1264 * @param callback The callback to remove 1265 */ removeCallback(KeyguardUpdateMonitorCallback callback)1266 public void removeCallback(KeyguardUpdateMonitorCallback callback) { 1267 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback); 1268 for (int i = mCallbacks.size() - 1; i >= 0; i--) { 1269 if (mCallbacks.get(i).get() == callback) { 1270 mCallbacks.remove(i); 1271 } 1272 } 1273 } 1274 1275 /** 1276 * Register to receive notifications about general keyguard information 1277 * (see {@link InfoCallback}. 1278 * @param callback The callback to register 1279 */ registerCallback(KeyguardUpdateMonitorCallback callback)1280 public void registerCallback(KeyguardUpdateMonitorCallback callback) { 1281 if (DEBUG) Log.v(TAG, "*** register callback for " + callback); 1282 // Prevent adding duplicate callbacks 1283 for (int i = 0; i < mCallbacks.size(); i++) { 1284 if (mCallbacks.get(i).get() == callback) { 1285 if (DEBUG) Log.e(TAG, "Object tried to add another callback", 1286 new Exception("Called by")); 1287 return; 1288 } 1289 } 1290 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback)); 1291 removeCallback(null); // remove unused references 1292 sendUpdates(callback); 1293 } 1294 sendUpdates(KeyguardUpdateMonitorCallback callback)1295 private void sendUpdates(KeyguardUpdateMonitorCallback callback) { 1296 // Notify listener of the current state 1297 callback.onRefreshBatteryInfo(mBatteryStatus); 1298 callback.onTimeChanged(); 1299 callback.onRingerModeChanged(mRingMode); 1300 callback.onPhoneStateChanged(mPhoneState); 1301 callback.onRefreshCarrierInfo(); 1302 callback.onClockVisibilityChanged(); 1303 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) { 1304 final SimData state = data.getValue(); 1305 callback.onSimStateChanged(state.subId, state.slotId, state.simState); 1306 } 1307 } 1308 sendKeyguardVisibilityChanged(boolean showing)1309 public void sendKeyguardVisibilityChanged(boolean showing) { 1310 if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")"); 1311 Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED); 1312 message.arg1 = showing ? 1 : 0; 1313 message.sendToTarget(); 1314 } 1315 sendKeyguardReset()1316 public void sendKeyguardReset() { 1317 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget(); 1318 } 1319 1320 /** 1321 * @see #handleKeyguardBouncerChanged(int) 1322 */ sendKeyguardBouncerChanged(boolean showingBouncer)1323 public void sendKeyguardBouncerChanged(boolean showingBouncer) { 1324 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")"); 1325 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED); 1326 message.arg1 = showingBouncer ? 1 : 0; 1327 message.sendToTarget(); 1328 } 1329 1330 /** 1331 * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we 1332 * have the information earlier than waiting for the intent 1333 * broadcast from the telephony code. 1334 * 1335 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going 1336 * through mHandler, this *must* be called from the UI thread. 1337 */ reportSimUnlocked(int subId)1338 public void reportSimUnlocked(int subId) { 1339 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")"); 1340 int slotId = SubscriptionManager.getSlotId(subId); 1341 handleSimStateChange(subId, slotId, State.READY); 1342 } 1343 1344 /** 1345 * Report that the emergency call button has been pressed and the emergency dialer is 1346 * about to be displayed. 1347 * 1348 * @param bypassHandler runs immediately. 1349 * 1350 * NOTE: Must be called from UI thread if bypassHandler == true. 1351 */ reportEmergencyCallAction(boolean bypassHandler)1352 public void reportEmergencyCallAction(boolean bypassHandler) { 1353 if (!bypassHandler) { 1354 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget(); 1355 } else { 1356 handleReportEmergencyCallAction(); 1357 } 1358 } 1359 1360 /** 1361 * @return Whether the device is provisioned (whether they have gone through 1362 * the setup wizard) 1363 */ isDeviceProvisioned()1364 public boolean isDeviceProvisioned() { 1365 return mDeviceProvisioned; 1366 } 1367 clearFailedUnlockAttempts()1368 public void clearFailedUnlockAttempts() { 1369 mFailedAttempts.delete(sCurrentUser); 1370 } 1371 getFailedUnlockAttempts()1372 public int getFailedUnlockAttempts() { 1373 return mFailedAttempts.get(sCurrentUser, 0); 1374 } 1375 reportFailedUnlockAttempt()1376 public void reportFailedUnlockAttempt() { 1377 mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1); 1378 } 1379 clearFingerprintRecognized()1380 public void clearFingerprintRecognized() { 1381 mUserFingerprintAuthenticated.clear(); 1382 } 1383 isSimPinVoiceSecure()1384 public boolean isSimPinVoiceSecure() { 1385 // TODO: only count SIMs that handle voice 1386 return isSimPinSecure(); 1387 } 1388 isSimPinSecure()1389 public boolean isSimPinSecure() { 1390 // True if any SIM is pin secure 1391 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) { 1392 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true; 1393 } 1394 return false; 1395 } 1396 getSimState(int subId)1397 public State getSimState(int subId) { 1398 if (mSimDatas.containsKey(subId)) { 1399 return mSimDatas.get(subId).simState; 1400 } else { 1401 return State.UNKNOWN; 1402 } 1403 } 1404 1405 /** 1406 * @return true if and only if the state has changed for the specified {@code slotId} 1407 */ refreshSimState(int subId, int slotId)1408 private boolean refreshSimState(int subId, int slotId) { 1409 1410 // This is awful. It exists because there are two APIs for getting the SIM status 1411 // that don't return the complete set of values and have different types. In Keyguard we 1412 // need IccCardConstants, but TelephonyManager would only give us 1413 // TelephonyManager.SIM_STATE*, so we retrieve it manually. 1414 final TelephonyManager tele = TelephonyManager.from(mContext); 1415 int simState = tele.getSimState(slotId); 1416 State state; 1417 try { 1418 state = State.intToState(simState); 1419 } catch(IllegalArgumentException ex) { 1420 Log.w(TAG, "Unknown sim state: " + simState); 1421 state = State.UNKNOWN; 1422 } 1423 SimData data = mSimDatas.get(subId); 1424 final boolean changed; 1425 if (data == null) { 1426 data = new SimData(state, slotId, subId); 1427 mSimDatas.put(subId, data); 1428 changed = true; // no data yet; force update 1429 } else { 1430 changed = data.simState != state; 1431 data.simState = state; 1432 } 1433 return changed; 1434 } 1435 isSimPinSecure(IccCardConstants.State state)1436 public static boolean isSimPinSecure(IccCardConstants.State state) { 1437 final IccCardConstants.State simState = state; 1438 return (simState == IccCardConstants.State.PIN_REQUIRED 1439 || simState == IccCardConstants.State.PUK_REQUIRED 1440 || simState == IccCardConstants.State.PERM_DISABLED); 1441 } 1442 getCachedDisplayClientState()1443 public DisplayClientState getCachedDisplayClientState() { 1444 return mDisplayClientState; 1445 } 1446 1447 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*() 1448 // (KeyguardViewMediator, KeyguardHostView) dispatchStartedWakingUp()1449 public void dispatchStartedWakingUp() { 1450 synchronized (this) { 1451 mDeviceInteractive = true; 1452 } 1453 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP); 1454 } 1455 dispatchFinishedGoingToSleep(int why)1456 public void dispatchFinishedGoingToSleep(int why) { 1457 synchronized(this) { 1458 mDeviceInteractive = false; 1459 } 1460 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0)); 1461 } 1462 dispatchScreenTurnedOn()1463 public void dispatchScreenTurnedOn() { 1464 synchronized (this) { 1465 mScreenOn = true; 1466 } 1467 } 1468 dispatchScreenTurnedOff()1469 public void dispatchScreenTurnedOff() { 1470 synchronized(this) { 1471 mScreenOn = false; 1472 } 1473 } 1474 isDeviceInteractive()1475 public boolean isDeviceInteractive() { 1476 return mDeviceInteractive; 1477 } 1478 1479 /** 1480 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first. 1481 * @param state 1482 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found 1483 */ getNextSubIdForState(State state)1484 public int getNextSubIdForState(State state) { 1485 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */); 1486 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1487 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first 1488 for (int i = 0; i < list.size(); i++) { 1489 final SubscriptionInfo info = list.get(i); 1490 final int id = info.getSubscriptionId(); 1491 int slotId = SubscriptionManager.getSlotId(id); 1492 if (state == getSimState(id) && bestSlotId > slotId ) { 1493 resultId = id; 1494 bestSlotId = slotId; 1495 } 1496 } 1497 return resultId; 1498 } 1499 getSubscriptionInfoForSubId(int subId)1500 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) { 1501 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */); 1502 for (int i = 0; i < list.size(); i++) { 1503 SubscriptionInfo info = list.get(i); 1504 if (subId == info.getSubscriptionId()) return info; 1505 } 1506 return null; // not found 1507 } 1508 dump(FileDescriptor fd, PrintWriter pw, String[] args)1509 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1510 pw.println("KeyguardUpdateMonitor state:"); 1511 pw.println(" SIM States:"); 1512 for (SimData data : mSimDatas.values()) { 1513 pw.println(" " + data.toString()); 1514 } 1515 pw.println(" Subs:"); 1516 if (mSubscriptionInfo != null) { 1517 for (int i = 0; i < mSubscriptionInfo.size(); i++) { 1518 pw.println(" " + mSubscriptionInfo.get(i)); 1519 } 1520 } 1521 pw.println(" Service states:"); 1522 for (int subId : mServiceStates.keySet()) { 1523 pw.println(" " + subId + "=" + mServiceStates.get(subId)); 1524 } 1525 } 1526 } 1527