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