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