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