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.ActivityManagerNative; 20 import android.app.AlarmManager; 21 import android.app.IUserSwitchObserver; 22 import android.app.PendingIntent; 23 import android.app.admin.DevicePolicyManager; 24 import android.app.trust.TrustManager; 25 import android.content.BroadcastReceiver; 26 import android.content.ContentResolver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentFilter; 30 import android.content.pm.UserInfo; 31 import android.database.ContentObserver; 32 import android.graphics.Bitmap; 33 34 import static android.os.BatteryManager.BATTERY_STATUS_FULL; 35 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN; 36 import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN; 37 import static android.os.BatteryManager.EXTRA_STATUS; 38 import static android.os.BatteryManager.EXTRA_PLUGGED; 39 import static android.os.BatteryManager.EXTRA_LEVEL; 40 import static android.os.BatteryManager.EXTRA_HEALTH; 41 42 import android.media.AudioManager; 43 import android.media.IRemoteControlDisplay; 44 import android.os.BatteryManager; 45 import android.os.Bundle; 46 import android.os.Handler; 47 import android.os.IRemoteCallback; 48 import android.os.Message; 49 import android.os.RemoteException; 50 import android.os.UserHandle; 51 import android.provider.Settings; 52 53 import com.android.internal.telephony.IccCardConstants; 54 import com.android.internal.telephony.TelephonyIntents; 55 56 import android.service.fingerprint.FingerprintManager; 57 import android.service.fingerprint.FingerprintManagerReceiver; 58 import android.service.fingerprint.FingerprintUtils; 59 import android.telephony.TelephonyManager; 60 import android.util.Log; 61 import android.util.SparseBooleanArray; 62 63 import com.google.android.collect.Lists; 64 65 import java.lang.ref.WeakReference; 66 import java.util.ArrayList; 67 68 /** 69 * Watches for updates that may be interesting to the keyguard, and provides 70 * the up to date information as well as a registration for callbacks that care 71 * to be updated. 72 * 73 * Note: under time crunch, this has been extended to include some stuff that 74 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns 75 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()} 76 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'... 77 */ 78 public class KeyguardUpdateMonitor implements TrustManager.TrustListener { 79 80 private static final String TAG = "KeyguardUpdateMonitor"; 81 private static final boolean DEBUG = KeyguardConstants.DEBUG; 82 private static final boolean DEBUG_SIM_STATES = DEBUG || false; 83 private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3; 84 private static final int LOW_BATTERY_THRESHOLD = 20; 85 86 private static final String ACTION_FACE_UNLOCK_STARTED 87 = "com.android.facelock.FACE_UNLOCK_STARTED"; 88 private static final String ACTION_FACE_UNLOCK_STOPPED 89 = "com.android.facelock.FACE_UNLOCK_STOPPED"; 90 91 // Callback messages 92 private static final int MSG_TIME_UPDATE = 301; 93 private static final int MSG_BATTERY_UPDATE = 302; 94 private static final int MSG_CARRIER_INFO_UPDATE = 303; 95 private static final int MSG_SIM_STATE_CHANGE = 304; 96 private static final int MSG_RINGER_MODE_CHANGED = 305; 97 private static final int MSG_PHONE_STATE_CHANGED = 306; 98 private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307; 99 private static final int MSG_DEVICE_PROVISIONED = 308; 100 private static final int MSG_DPM_STATE_CHANGED = 309; 101 private static final int MSG_USER_SWITCHING = 310; 102 private static final int MSG_USER_REMOVED = 311; 103 private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312; 104 private static final int MSG_BOOT_COMPLETED = 313; 105 private static final int MSG_USER_SWITCH_COMPLETE = 314; 106 private static final int MSG_SET_CURRENT_CLIENT_ID = 315; 107 private static final int MSG_SET_PLAYBACK_STATE = 316; 108 private static final int MSG_USER_INFO_CHANGED = 317; 109 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318; 110 private static final int MSG_SCREEN_TURNED_ON = 319; 111 private static final int MSG_SCREEN_TURNED_OFF = 320; 112 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322; 113 private static final int MSG_FINGERPRINT_PROCESSED = 323; 114 private static final int MSG_FINGERPRINT_ACQUIRED = 324; 115 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 325; 116 117 private static KeyguardUpdateMonitor sInstance; 118 119 private final Context mContext; 120 121 // Telephony state 122 private IccCardConstants.State mSimState = IccCardConstants.State.READY; 123 private CharSequence mTelephonyPlmn; 124 private CharSequence mTelephonySpn; 125 private int mRingMode; 126 private int mPhoneState; 127 private boolean mKeyguardIsVisible; 128 private boolean mBouncer; 129 private boolean mBootCompleted; 130 131 // Device provisioning state 132 private boolean mDeviceProvisioned; 133 134 // Battery status 135 private BatteryStatus mBatteryStatus; 136 137 // Password attempts 138 private int mFailedAttempts = 0; 139 private int mFailedBiometricUnlockAttempts = 0; 140 141 private boolean mAlternateUnlockEnabled; 142 143 private boolean mClockVisible; 144 145 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>> 146 mCallbacks = Lists.newArrayList(); 147 private ContentObserver mDeviceProvisionedObserver; 148 149 private boolean mSwitchingUser; 150 151 private boolean mScreenOn; 152 153 private final Handler mHandler = new Handler() { 154 @Override 155 public void handleMessage(Message msg) { 156 switch (msg.what) { 157 case MSG_TIME_UPDATE: 158 handleTimeUpdate(); 159 break; 160 case MSG_BATTERY_UPDATE: 161 handleBatteryUpdate((BatteryStatus) msg.obj); 162 break; 163 case MSG_CARRIER_INFO_UPDATE: 164 handleCarrierInfoUpdate(); 165 break; 166 case MSG_SIM_STATE_CHANGE: 167 handleSimStateChange((SimArgs) msg.obj); 168 break; 169 case MSG_RINGER_MODE_CHANGED: 170 handleRingerModeChange(msg.arg1); 171 break; 172 case MSG_PHONE_STATE_CHANGED: 173 handlePhoneStateChanged((String) msg.obj); 174 break; 175 case MSG_CLOCK_VISIBILITY_CHANGED: 176 handleClockVisibilityChanged(); 177 break; 178 case MSG_DEVICE_PROVISIONED: 179 handleDeviceProvisioned(); 180 break; 181 case MSG_DPM_STATE_CHANGED: 182 handleDevicePolicyManagerStateChanged(); 183 break; 184 case MSG_USER_SWITCHING: 185 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj); 186 break; 187 case MSG_USER_SWITCH_COMPLETE: 188 handleUserSwitchComplete(msg.arg1); 189 break; 190 case MSG_USER_REMOVED: 191 handleUserRemoved(msg.arg1); 192 break; 193 case MSG_KEYGUARD_VISIBILITY_CHANGED: 194 handleKeyguardVisibilityChanged(msg.arg1); 195 break; 196 case MSG_KEYGUARD_BOUNCER_CHANGED: 197 handleKeyguardBouncerChanged(msg.arg1); 198 break; 199 case MSG_BOOT_COMPLETED: 200 handleBootCompleted(); 201 break; 202 case MSG_USER_INFO_CHANGED: 203 handleUserInfoChanged(msg.arg1); 204 break; 205 case MSG_REPORT_EMERGENCY_CALL_ACTION: 206 handleReportEmergencyCallAction(); 207 break; 208 case MSG_SCREEN_TURNED_OFF: 209 handleScreenTurnedOff(msg.arg1); 210 break; 211 case MSG_SCREEN_TURNED_ON: 212 handleScreenTurnedOn(); 213 break; 214 case MSG_FINGERPRINT_ACQUIRED: 215 handleFingerprintAcquired(msg.arg1); 216 break; 217 case MSG_FINGERPRINT_PROCESSED: 218 handleFingerprintProcessed(msg.arg1); 219 break; 220 case MSG_FACE_UNLOCK_STATE_CHANGED: 221 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2); 222 break; 223 } 224 } 225 }; 226 227 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray(); 228 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray(); 229 private SparseBooleanArray mUserFingerprintRecognized = new SparseBooleanArray(); 230 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray(); 231 232 @Override onTrustChanged(boolean enabled, int userId, boolean initiatedByUser)233 public void onTrustChanged(boolean enabled, int userId, boolean initiatedByUser) { 234 mUserHasTrust.put(userId, enabled); 235 236 for (int i = 0; i < mCallbacks.size(); i++) { 237 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 238 if (cb != null) { 239 cb.onTrustChanged(userId); 240 if (enabled && initiatedByUser) { 241 cb.onTrustInitiatedByUser(userId); 242 } 243 } 244 } 245 } 246 247 @Override onTrustManagedChanged(boolean managed, int userId)248 public void onTrustManagedChanged(boolean managed, int userId) { 249 mUserTrustIsManaged.put(userId, managed); 250 251 for (int i = 0; i < mCallbacks.size(); i++) { 252 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 253 if (cb != null) { 254 cb.onTrustManagedChanged(userId); 255 } 256 } 257 } 258 onFingerprintRecognized(int userId)259 private void onFingerprintRecognized(int userId) { 260 mUserFingerprintRecognized.put(userId, true); 261 for (int i = 0; i < mCallbacks.size(); i++) { 262 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 263 if (cb != null) { 264 cb.onFingerprintRecognized(userId); 265 } 266 } 267 } 268 handleFingerprintProcessed(int fingerprintId)269 private void handleFingerprintProcessed(int fingerprintId) { 270 if (fingerprintId == 0) return; // not a valid fingerprint 271 272 final int userId; 273 try { 274 userId = ActivityManagerNative.getDefault().getCurrentUser().id; 275 } catch (RemoteException e) { 276 Log.e(TAG, "Failed to get current user id: ", e); 277 return; 278 } 279 if (isFingerprintDisabled(userId)) { 280 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId); 281 return; 282 } 283 final ContentResolver res = mContext.getContentResolver(); 284 final int ids[] = FingerprintUtils.getFingerprintIdsForUser(res, userId); 285 for (int i = 0; i < ids.length; i++) { 286 if (ids[i] == fingerprintId) { 287 onFingerprintRecognized(userId); 288 } 289 } 290 } 291 handleFingerprintAcquired(int info)292 private void handleFingerprintAcquired(int info) { 293 for (int i = 0; i < mCallbacks.size(); i++) { 294 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 295 if (cb != null) { 296 cb.onFingerprintAcquired(info); 297 } 298 } 299 } 300 handleFaceUnlockStateChanged(boolean running, int userId)301 private void handleFaceUnlockStateChanged(boolean running, int userId) { 302 mUserFaceUnlockRunning.put(userId, running); 303 for (int i = 0; i < mCallbacks.size(); i++) { 304 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 305 if (cb != null) { 306 cb.onFaceUnlockStateChanged(running, userId); 307 } 308 } 309 } 310 isFaceUnlockRunning(int userId)311 public boolean isFaceUnlockRunning(int userId) { 312 return mUserFaceUnlockRunning.get(userId); 313 } 314 isTrustDisabled(int userId)315 private boolean isTrustDisabled(int userId) { 316 final DevicePolicyManager dpm = 317 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 318 if (dpm != null) { 319 // TODO once UI is finalized 320 final boolean disabledByGlobalActions = false; 321 final boolean disabledBySettings = false; 322 323 // Don't allow trust agent if device is secured with a SIM PIN. This is here 324 // mainly because there's no other way to prompt the user to enter their SIM PIN 325 // once they get past the keyguard screen. 326 final boolean disabledBySimPin = isSimPinSecure(); 327 328 final boolean disabledByDpm = (dpm.getKeyguardDisabledFeatures(null, userId) 329 & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0; 330 return disabledByDpm || disabledByGlobalActions || disabledBySettings 331 || disabledBySimPin; 332 } 333 return false; 334 } 335 isFingerprintDisabled(int userId)336 private boolean isFingerprintDisabled(int userId) { 337 final DevicePolicyManager dpm = 338 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 339 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId) 340 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0; 341 } 342 getUserHasTrust(int userId)343 public boolean getUserHasTrust(int userId) { 344 return !isTrustDisabled(userId) && mUserHasTrust.get(userId) 345 || mUserFingerprintRecognized.get(userId); 346 } 347 getUserTrustIsManaged(int userId)348 public boolean getUserTrustIsManaged(int userId) { 349 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId); 350 } 351 352 static class DisplayClientState { 353 public int clientGeneration; 354 public boolean clearing; 355 public PendingIntent intent; 356 public int playbackState; 357 public long playbackEventTime; 358 } 359 360 private DisplayClientState mDisplayClientState = new DisplayClientState(); 361 362 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 363 364 public void onReceive(Context context, Intent intent) { 365 final String action = intent.getAction(); 366 if (DEBUG) Log.d(TAG, "received broadcast " + action); 367 368 if (Intent.ACTION_TIME_TICK.equals(action) 369 || Intent.ACTION_TIME_CHANGED.equals(action) 370 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { 371 mHandler.sendEmptyMessage(MSG_TIME_UPDATE); 372 } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { 373 mTelephonyPlmn = getTelephonyPlmnFrom(intent); 374 mTelephonySpn = getTelephonySpnFrom(intent); 375 mHandler.sendEmptyMessage(MSG_CARRIER_INFO_UPDATE); 376 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 377 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN); 378 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0); 379 final int level = intent.getIntExtra(EXTRA_LEVEL, 0); 380 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN); 381 final Message msg = mHandler.obtainMessage( 382 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health)); 383 mHandler.sendMessage(msg); 384 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) { 385 if (DEBUG_SIM_STATES) { 386 Log.v(TAG, "action " + action + " state" + 387 intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)); 388 } 389 mHandler.sendMessage(mHandler.obtainMessage( 390 MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent))); 391 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) { 392 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED, 393 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0)); 394 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { 395 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 396 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state)); 397 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 398 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED, 399 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0)); 400 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { 401 dispatchBootCompleted(); 402 } 403 } 404 }; 405 406 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() { 407 408 public void onReceive(Context context, Intent intent) { 409 final String action = intent.getAction(); 410 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) { 411 mHandler.sendEmptyMessage(MSG_TIME_UPDATE); 412 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) { 413 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED, 414 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0)); 415 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) { 416 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1, 417 getSendingUserId())); 418 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) { 419 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0, 420 getSendingUserId())); 421 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED 422 .equals(action)) { 423 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED); 424 } 425 } 426 }; 427 private FingerprintManagerReceiver mFingerprintManagerReceiver = 428 new FingerprintManagerReceiver() { 429 @Override 430 public void onProcessed(int fingerprintId) { 431 mHandler.obtainMessage(MSG_FINGERPRINT_PROCESSED, fingerprintId, 0).sendToTarget(); 432 }; 433 434 @Override 435 public void onAcquired(int info) { 436 mHandler.obtainMessage(MSG_FINGERPRINT_ACQUIRED, info, 0).sendToTarget(); 437 } 438 439 @Override 440 public void onError(int error) { 441 if (DEBUG) Log.w(TAG, "FingerprintManager reported error: " + error); 442 } 443 }; 444 445 /** 446 * When we receive a 447 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast, 448 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange}, 449 * we need a single object to pass to the handler. This class helps decode 450 * the intent and provide a {@link SimCard.State} result. 451 */ 452 private static class SimArgs { 453 public final IccCardConstants.State simState; 454 SimArgs(IccCardConstants.State state)455 SimArgs(IccCardConstants.State state) { 456 simState = state; 457 } 458 fromIntent(Intent intent)459 static SimArgs fromIntent(Intent intent) { 460 IccCardConstants.State state; 461 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) { 462 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED"); 463 } 464 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); 465 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 466 final String absentReason = intent 467 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); 468 469 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals( 470 absentReason)) { 471 state = IccCardConstants.State.PERM_DISABLED; 472 } else { 473 state = IccCardConstants.State.ABSENT; 474 } 475 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { 476 state = IccCardConstants.State.READY; 477 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { 478 final String lockedReason = intent 479 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); 480 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { 481 state = IccCardConstants.State.PIN_REQUIRED; 482 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { 483 state = IccCardConstants.State.PUK_REQUIRED; 484 } else { 485 state = IccCardConstants.State.UNKNOWN; 486 } 487 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) { 488 state = IccCardConstants.State.NETWORK_LOCKED; 489 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra) 490 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) { 491 // This is required because telephony doesn't return to "READY" after 492 // these state transitions. See bug 7197471. 493 state = IccCardConstants.State.READY; 494 } else { 495 state = IccCardConstants.State.UNKNOWN; 496 } 497 return new SimArgs(state); 498 } 499 toString()500 public String toString() { 501 return simState.toString(); 502 } 503 } 504 505 public static class BatteryStatus { 506 public final int status; 507 public final int level; 508 public final int plugged; 509 public final int health; BatteryStatus(int status, int level, int plugged, int health)510 public BatteryStatus(int status, int level, int plugged, int health) { 511 this.status = status; 512 this.level = level; 513 this.plugged = plugged; 514 this.health = health; 515 } 516 517 /** 518 * Determine whether the device is plugged in (USB, power, or wireless). 519 * @return true if the device is plugged in. 520 */ isPluggedIn()521 boolean isPluggedIn() { 522 return plugged == BatteryManager.BATTERY_PLUGGED_AC 523 || plugged == BatteryManager.BATTERY_PLUGGED_USB 524 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS; 525 } 526 527 /** 528 * Whether or not the device is charged. Note that some devices never return 100% for 529 * battery level, so this allows either battery level or status to determine if the 530 * battery is charged. 531 * @return true if the device is charged 532 */ isCharged()533 public boolean isCharged() { 534 return status == BATTERY_STATUS_FULL || level >= 100; 535 } 536 537 /** 538 * Whether battery is low and needs to be charged. 539 * @return true if battery is low 540 */ isBatteryLow()541 public boolean isBatteryLow() { 542 return level < LOW_BATTERY_THRESHOLD; 543 } 544 545 } 546 getInstance(Context context)547 public static KeyguardUpdateMonitor getInstance(Context context) { 548 if (sInstance == null) { 549 sInstance = new KeyguardUpdateMonitor(context); 550 } 551 return sInstance; 552 } 553 handleScreenTurnedOn()554 protected void handleScreenTurnedOn() { 555 final int count = mCallbacks.size(); 556 for (int i = 0; i < count; i++) { 557 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 558 if (cb != null) { 559 cb.onScreenTurnedOn(); 560 } 561 } 562 } 563 handleScreenTurnedOff(int arg1)564 protected void handleScreenTurnedOff(int arg1) { 565 clearFingerprintRecognized(); 566 final int count = mCallbacks.size(); 567 for (int i = 0; i < count; i++) { 568 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 569 if (cb != null) { 570 cb.onScreenTurnedOff(arg1); 571 } 572 } 573 } 574 575 /** 576 * IMPORTANT: Must be called from UI thread. 577 */ dispatchSetBackground(Bitmap bmp)578 public void dispatchSetBackground(Bitmap bmp) { 579 if (DEBUG) Log.d(TAG, "dispatchSetBackground"); 580 final int count = mCallbacks.size(); 581 for (int i = 0; i < count; i++) { 582 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 583 if (cb != null) { 584 cb.onSetBackground(bmp); 585 } 586 } 587 } 588 handleUserInfoChanged(int userId)589 private void handleUserInfoChanged(int userId) { 590 for (int i = 0; i < mCallbacks.size(); i++) { 591 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 592 if (cb != null) { 593 cb.onUserInfoChanged(userId); 594 } 595 } 596 } 597 KeyguardUpdateMonitor(Context context)598 private KeyguardUpdateMonitor(Context context) { 599 mContext = context; 600 mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); 601 // Since device can't be un-provisioned, we only need to register a content observer 602 // to update mDeviceProvisioned when we are... 603 if (!mDeviceProvisioned) { 604 watchForDeviceProvisioning(); 605 } 606 607 // Take a guess at initial SIM state, battery status and PLMN until we get an update 608 mSimState = IccCardConstants.State.NOT_READY; 609 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0); 610 mTelephonyPlmn = getDefaultPlmn(); 611 612 // Watch for interesting updates 613 final IntentFilter filter = new IntentFilter(); 614 filter.addAction(Intent.ACTION_TIME_TICK); 615 filter.addAction(Intent.ACTION_TIME_CHANGED); 616 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 617 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 618 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 619 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 620 filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION); 621 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 622 filter.addAction(Intent.ACTION_USER_REMOVED); 623 context.registerReceiver(mBroadcastReceiver, filter); 624 625 final IntentFilter bootCompleteFilter = new IntentFilter(); 626 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 627 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED); 628 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter); 629 630 final IntentFilter allUserFilter = new IntentFilter(); 631 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED); 632 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED); 633 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED); 634 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED); 635 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 636 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter, 637 null, null); 638 639 try { 640 ActivityManagerNative.getDefault().registerUserSwitchObserver( 641 new IUserSwitchObserver.Stub() { 642 @Override 643 public void onUserSwitching(int newUserId, IRemoteCallback reply) { 644 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING, 645 newUserId, 0, reply)); 646 mSwitchingUser = true; 647 } 648 @Override 649 public void onUserSwitchComplete(int newUserId) throws RemoteException { 650 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE, 651 newUserId, 0)); 652 mSwitchingUser = false; 653 } 654 }); 655 } catch (RemoteException e) { 656 // TODO Auto-generated catch block 657 e.printStackTrace(); 658 } 659 660 TrustManager trustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE); 661 trustManager.registerTrustListener(this); 662 663 FingerprintManager fpm; 664 fpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); 665 fpm.startListening(mFingerprintManagerReceiver); 666 } 667 isDeviceProvisionedInSettingsDb()668 private boolean isDeviceProvisionedInSettingsDb() { 669 return Settings.Global.getInt(mContext.getContentResolver(), 670 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 671 } 672 watchForDeviceProvisioning()673 private void watchForDeviceProvisioning() { 674 mDeviceProvisionedObserver = new ContentObserver(mHandler) { 675 @Override 676 public void onChange(boolean selfChange) { 677 super.onChange(selfChange); 678 mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); 679 if (mDeviceProvisioned) { 680 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED); 681 } 682 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned); 683 } 684 }; 685 686 mContext.getContentResolver().registerContentObserver( 687 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 688 false, mDeviceProvisionedObserver); 689 690 // prevent a race condition between where we check the flag and where we register the 691 // observer by grabbing the value once again... 692 boolean provisioned = isDeviceProvisionedInSettingsDb(); 693 if (provisioned != mDeviceProvisioned) { 694 mDeviceProvisioned = provisioned; 695 if (mDeviceProvisioned) { 696 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED); 697 } 698 } 699 } 700 701 /** 702 * Handle {@link #MSG_DPM_STATE_CHANGED} 703 */ handleDevicePolicyManagerStateChanged()704 protected void handleDevicePolicyManagerStateChanged() { 705 for (int i = mCallbacks.size() - 1; i >= 0; i--) { 706 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 707 if (cb != null) { 708 cb.onDevicePolicyManagerStateChanged(); 709 } 710 } 711 } 712 713 /** 714 * Handle {@link #MSG_USER_SWITCHING} 715 */ handleUserSwitching(int userId, IRemoteCallback reply)716 protected void handleUserSwitching(int userId, IRemoteCallback reply) { 717 for (int i = 0; i < mCallbacks.size(); i++) { 718 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 719 if (cb != null) { 720 cb.onUserSwitching(userId); 721 } 722 } 723 try { 724 reply.sendResult(null); 725 } catch (RemoteException e) { 726 } 727 } 728 729 /** 730 * Handle {@link #MSG_USER_SWITCH_COMPLETE} 731 */ handleUserSwitchComplete(int userId)732 protected void handleUserSwitchComplete(int userId) { 733 for (int i = 0; i < mCallbacks.size(); i++) { 734 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 735 if (cb != null) { 736 cb.onUserSwitchComplete(userId); 737 } 738 } 739 } 740 741 /** 742 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If 743 * keyguard crashes sometime after boot, then it will never receive this 744 * broadcast and hence not handle the event. This method is ultimately called by 745 * PhoneWindowManager in this case. 746 */ dispatchBootCompleted()747 public void dispatchBootCompleted() { 748 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 749 } 750 751 /** 752 * Handle {@link #MSG_BOOT_COMPLETED} 753 */ handleBootCompleted()754 protected void handleBootCompleted() { 755 if (mBootCompleted) return; 756 mBootCompleted = true; 757 for (int i = 0; i < mCallbacks.size(); i++) { 758 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 759 if (cb != null) { 760 cb.onBootCompleted(); 761 } 762 } 763 } 764 765 /** 766 * We need to store this state in the KeyguardUpdateMonitor since this class will not be 767 * destroyed. 768 */ hasBootCompleted()769 public boolean hasBootCompleted() { 770 return mBootCompleted; 771 } 772 773 /** 774 * Handle {@link #MSG_USER_REMOVED} 775 */ handleUserRemoved(int userId)776 protected void handleUserRemoved(int userId) { 777 for (int i = 0; i < mCallbacks.size(); i++) { 778 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 779 if (cb != null) { 780 cb.onUserRemoved(userId); 781 } 782 } 783 } 784 785 /** 786 * Handle {@link #MSG_DEVICE_PROVISIONED} 787 */ handleDeviceProvisioned()788 protected void handleDeviceProvisioned() { 789 for (int i = 0; i < mCallbacks.size(); i++) { 790 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 791 if (cb != null) { 792 cb.onDeviceProvisioned(); 793 } 794 } 795 if (mDeviceProvisionedObserver != null) { 796 // We don't need the observer anymore... 797 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver); 798 mDeviceProvisionedObserver = null; 799 } 800 } 801 802 /** 803 * Handle {@link #MSG_PHONE_STATE_CHANGED} 804 */ handlePhoneStateChanged(String newState)805 protected void handlePhoneStateChanged(String newState) { 806 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")"); 807 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) { 808 mPhoneState = TelephonyManager.CALL_STATE_IDLE; 809 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) { 810 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK; 811 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) { 812 mPhoneState = TelephonyManager.CALL_STATE_RINGING; 813 } 814 for (int i = 0; i < mCallbacks.size(); i++) { 815 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 816 if (cb != null) { 817 cb.onPhoneStateChanged(mPhoneState); 818 } 819 } 820 } 821 822 /** 823 * Handle {@link #MSG_RINGER_MODE_CHANGED} 824 */ handleRingerModeChange(int mode)825 protected void handleRingerModeChange(int mode) { 826 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")"); 827 mRingMode = mode; 828 for (int i = 0; i < mCallbacks.size(); i++) { 829 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 830 if (cb != null) { 831 cb.onRingerModeChanged(mode); 832 } 833 } 834 } 835 836 /** 837 * Handle {@link #MSG_TIME_UPDATE} 838 */ handleTimeUpdate()839 private void handleTimeUpdate() { 840 if (DEBUG) Log.d(TAG, "handleTimeUpdate"); 841 for (int i = 0; i < mCallbacks.size(); i++) { 842 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 843 if (cb != null) { 844 cb.onTimeChanged(); 845 } 846 } 847 } 848 849 /** 850 * Handle {@link #MSG_BATTERY_UPDATE} 851 */ handleBatteryUpdate(BatteryStatus status)852 private void handleBatteryUpdate(BatteryStatus status) { 853 if (DEBUG) Log.d(TAG, "handleBatteryUpdate"); 854 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status); 855 mBatteryStatus = status; 856 if (batteryUpdateInteresting) { 857 for (int i = 0; i < mCallbacks.size(); i++) { 858 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 859 if (cb != null) { 860 cb.onRefreshBatteryInfo(status); 861 } 862 } 863 } 864 } 865 866 /** 867 * Handle {@link #MSG_CARRIER_INFO_UPDATE} 868 */ handleCarrierInfoUpdate()869 private void handleCarrierInfoUpdate() { 870 if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn 871 + ", spn = " + mTelephonySpn); 872 873 for (int i = 0; i < mCallbacks.size(); i++) { 874 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 875 if (cb != null) { 876 cb.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn); 877 } 878 } 879 } 880 881 /** 882 * Handle {@link #MSG_SIM_STATE_CHANGE} 883 */ handleSimStateChange(SimArgs simArgs)884 private void handleSimStateChange(SimArgs simArgs) { 885 final IccCardConstants.State state = simArgs.simState; 886 887 if (DEBUG) { 888 Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " " 889 + "state resolved to " + state.toString()); 890 } 891 892 if (state != IccCardConstants.State.UNKNOWN && state != mSimState) { 893 mSimState = state; 894 for (int i = 0; i < mCallbacks.size(); i++) { 895 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 896 if (cb != null) { 897 cb.onSimStateChanged(state); 898 } 899 } 900 } 901 } 902 903 /** 904 * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED} 905 */ handleClockVisibilityChanged()906 private void handleClockVisibilityChanged() { 907 if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()"); 908 for (int i = 0; i < mCallbacks.size(); i++) { 909 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 910 if (cb != null) { 911 cb.onClockVisibilityChanged(); 912 } 913 } 914 } 915 916 /** 917 * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED} 918 */ handleKeyguardVisibilityChanged(int showing)919 private void handleKeyguardVisibilityChanged(int showing) { 920 if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")"); 921 boolean isShowing = (showing == 1); 922 mKeyguardIsVisible = isShowing; 923 for (int i = 0; i < mCallbacks.size(); i++) { 924 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 925 if (cb != null) { 926 cb.onKeyguardVisibilityChangedRaw(isShowing); 927 } 928 } 929 } 930 931 /** 932 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED} 933 * @see #sendKeyguardBouncerChanged(boolean) 934 */ handleKeyguardBouncerChanged(int bouncer)935 private void handleKeyguardBouncerChanged(int bouncer) { 936 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")"); 937 boolean isBouncer = (bouncer == 1); 938 mBouncer = isBouncer; 939 for (int i = 0; i < mCallbacks.size(); i++) { 940 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 941 if (cb != null) { 942 cb.onKeyguardBouncerChanged(isBouncer); 943 } 944 } 945 } 946 947 /** 948 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION} 949 */ handleReportEmergencyCallAction()950 private void handleReportEmergencyCallAction() { 951 for (int i = 0; i < mCallbacks.size(); i++) { 952 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); 953 if (cb != null) { 954 cb.onEmergencyCallAction(); 955 } 956 } 957 } 958 isKeyguardVisible()959 public boolean isKeyguardVisible() { 960 return mKeyguardIsVisible; 961 } 962 963 /** 964 * @return if the keyguard is currently in bouncer mode. 965 */ isKeyguardBouncer()966 public boolean isKeyguardBouncer() { 967 return mBouncer; 968 } 969 isSwitchingUser()970 public boolean isSwitchingUser() { 971 return mSwitchingUser; 972 } 973 isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current)974 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) { 975 final boolean nowPluggedIn = current.isPluggedIn(); 976 final boolean wasPluggedIn = old.isPluggedIn(); 977 final boolean stateChangedWhilePluggedIn = 978 wasPluggedIn == true && nowPluggedIn == true 979 && (old.status != current.status); 980 981 // change in plug state is always interesting 982 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) { 983 return true; 984 } 985 986 // change in battery level while plugged in 987 if (nowPluggedIn && old.level != current.level) { 988 return true; 989 } 990 991 // change where battery needs charging 992 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) { 993 return true; 994 } 995 return false; 996 } 997 998 /** 999 * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION} 1000 * @return The string to use for the plmn, or null if it should not be shown. 1001 */ getTelephonyPlmnFrom(Intent intent)1002 private CharSequence getTelephonyPlmnFrom(Intent intent) { 1003 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) { 1004 final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN); 1005 return (plmn != null) ? plmn : getDefaultPlmn(); 1006 } 1007 return null; 1008 } 1009 1010 /** 1011 * @return The default plmn (no service) 1012 */ getDefaultPlmn()1013 private CharSequence getDefaultPlmn() { 1014 return mContext.getResources().getText(R.string.keyguard_carrier_default); 1015 } 1016 1017 /** 1018 * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION} 1019 * @return The string to use for the plmn, or null if it should not be shown. 1020 */ getTelephonySpnFrom(Intent intent)1021 private CharSequence getTelephonySpnFrom(Intent intent) { 1022 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) { 1023 final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN); 1024 if (spn != null) { 1025 return spn; 1026 } 1027 } 1028 return null; 1029 } 1030 1031 /** 1032 * Remove the given observer's callback. 1033 * 1034 * @param callback The callback to remove 1035 */ removeCallback(KeyguardUpdateMonitorCallback callback)1036 public void removeCallback(KeyguardUpdateMonitorCallback callback) { 1037 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback); 1038 for (int i = mCallbacks.size() - 1; i >= 0; i--) { 1039 if (mCallbacks.get(i).get() == callback) { 1040 mCallbacks.remove(i); 1041 } 1042 } 1043 } 1044 1045 /** 1046 * Register to receive notifications about general keyguard information 1047 * (see {@link InfoCallback}. 1048 * @param callback The callback to register 1049 */ registerCallback(KeyguardUpdateMonitorCallback callback)1050 public void registerCallback(KeyguardUpdateMonitorCallback callback) { 1051 if (DEBUG) Log.v(TAG, "*** register callback for " + callback); 1052 // Prevent adding duplicate callbacks 1053 for (int i = 0; i < mCallbacks.size(); i++) { 1054 if (mCallbacks.get(i).get() == callback) { 1055 if (DEBUG) Log.e(TAG, "Object tried to add another callback", 1056 new Exception("Called by")); 1057 return; 1058 } 1059 } 1060 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback)); 1061 removeCallback(null); // remove unused references 1062 sendUpdates(callback); 1063 } 1064 sendUpdates(KeyguardUpdateMonitorCallback callback)1065 private void sendUpdates(KeyguardUpdateMonitorCallback callback) { 1066 // Notify listener of the current state 1067 callback.onRefreshBatteryInfo(mBatteryStatus); 1068 callback.onTimeChanged(); 1069 callback.onRingerModeChanged(mRingMode); 1070 callback.onPhoneStateChanged(mPhoneState); 1071 callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn); 1072 callback.onClockVisibilityChanged(); 1073 callback.onSimStateChanged(mSimState); 1074 } 1075 sendKeyguardVisibilityChanged(boolean showing)1076 public void sendKeyguardVisibilityChanged(boolean showing) { 1077 if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")"); 1078 Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED); 1079 message.arg1 = showing ? 1 : 0; 1080 message.sendToTarget(); 1081 } 1082 1083 /** 1084 * @see #handleKeyguardBouncerChanged(int) 1085 */ sendKeyguardBouncerChanged(boolean showingBouncer)1086 public void sendKeyguardBouncerChanged(boolean showingBouncer) { 1087 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")"); 1088 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED); 1089 message.arg1 = showingBouncer ? 1 : 0; 1090 message.sendToTarget(); 1091 } 1092 reportClockVisible(boolean visible)1093 public void reportClockVisible(boolean visible) { 1094 mClockVisible = visible; 1095 mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget(); 1096 } 1097 getSimState()1098 public IccCardConstants.State getSimState() { 1099 return mSimState; 1100 } 1101 1102 /** 1103 * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we 1104 * have the information earlier than waiting for the intent 1105 * broadcast from the telephony code. 1106 * 1107 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going 1108 * through mHandler, this *must* be called from the UI thread. 1109 */ reportSimUnlocked()1110 public void reportSimUnlocked() { 1111 handleSimStateChange(new SimArgs(IccCardConstants.State.READY)); 1112 } 1113 1114 /** 1115 * Report that the emergency call button has been pressed and the emergency dialer is 1116 * about to be displayed. 1117 * 1118 * @param bypassHandler runs immediately. 1119 * 1120 * NOTE: Must be called from UI thread if bypassHandler == true. 1121 */ reportEmergencyCallAction(boolean bypassHandler)1122 public void reportEmergencyCallAction(boolean bypassHandler) { 1123 if (!bypassHandler) { 1124 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget(); 1125 } else { 1126 handleReportEmergencyCallAction(); 1127 } 1128 } 1129 getTelephonyPlmn()1130 public CharSequence getTelephonyPlmn() { 1131 return mTelephonyPlmn; 1132 } 1133 getTelephonySpn()1134 public CharSequence getTelephonySpn() { 1135 return mTelephonySpn; 1136 } 1137 1138 /** 1139 * @return Whether the device is provisioned (whether they have gone through 1140 * the setup wizard) 1141 */ isDeviceProvisioned()1142 public boolean isDeviceProvisioned() { 1143 return mDeviceProvisioned; 1144 } 1145 getFailedUnlockAttempts()1146 public int getFailedUnlockAttempts() { 1147 return mFailedAttempts; 1148 } 1149 clearFailedUnlockAttempts()1150 public void clearFailedUnlockAttempts() { 1151 mFailedAttempts = 0; 1152 mFailedBiometricUnlockAttempts = 0; 1153 } 1154 clearFingerprintRecognized()1155 public void clearFingerprintRecognized() { 1156 mUserFingerprintRecognized.clear(); 1157 } 1158 reportFailedUnlockAttempt()1159 public void reportFailedUnlockAttempt() { 1160 mFailedAttempts++; 1161 } 1162 isClockVisible()1163 public boolean isClockVisible() { 1164 return mClockVisible; 1165 } 1166 getPhoneState()1167 public int getPhoneState() { 1168 return mPhoneState; 1169 } 1170 reportFailedBiometricUnlockAttempt()1171 public void reportFailedBiometricUnlockAttempt() { 1172 mFailedBiometricUnlockAttempts++; 1173 } 1174 getMaxBiometricUnlockAttemptsReached()1175 public boolean getMaxBiometricUnlockAttemptsReached() { 1176 return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP; 1177 } 1178 isAlternateUnlockEnabled()1179 public boolean isAlternateUnlockEnabled() { 1180 return mAlternateUnlockEnabled; 1181 } 1182 setAlternateUnlockEnabled(boolean enabled)1183 public void setAlternateUnlockEnabled(boolean enabled) { 1184 mAlternateUnlockEnabled = enabled; 1185 } 1186 isSimLocked()1187 public boolean isSimLocked() { 1188 return isSimLocked(mSimState); 1189 } 1190 isSimLocked(IccCardConstants.State state)1191 public static boolean isSimLocked(IccCardConstants.State state) { 1192 return state == IccCardConstants.State.PIN_REQUIRED 1193 || state == IccCardConstants.State.PUK_REQUIRED 1194 || state == IccCardConstants.State.PERM_DISABLED; 1195 } 1196 isSimPinSecure()1197 public boolean isSimPinSecure() { 1198 return isSimPinSecure(mSimState); 1199 } 1200 isSimPinSecure(IccCardConstants.State state)1201 public static boolean isSimPinSecure(IccCardConstants.State state) { 1202 final IccCardConstants.State simState = state; 1203 return (simState == IccCardConstants.State.PIN_REQUIRED 1204 || simState == IccCardConstants.State.PUK_REQUIRED 1205 || simState == IccCardConstants.State.PERM_DISABLED); 1206 } 1207 getCachedDisplayClientState()1208 public DisplayClientState getCachedDisplayClientState() { 1209 return mDisplayClientState; 1210 } 1211 1212 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*() 1213 // (KeyguardViewMediator, KeyguardHostView) dispatchScreenTurnedOn()1214 public void dispatchScreenTurnedOn() { 1215 synchronized (this) { 1216 mScreenOn = true; 1217 } 1218 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON); 1219 } 1220 dispatchScreenTurndOff(int why)1221 public void dispatchScreenTurndOff(int why) { 1222 synchronized(this) { 1223 mScreenOn = false; 1224 } 1225 mHandler.sendMessage(mHandler.obtainMessage(MSG_SCREEN_TURNED_OFF, why, 0)); 1226 } 1227 isScreenOn()1228 public boolean isScreenOn() { 1229 return mScreenOn; 1230 } 1231 } 1232