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