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