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