KeyguardViewMediator.java revision c13723f22e476b4558061942c001ee62eaca79e4
1/*
2 * Copyright (C) 2014 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.systemui.keyguard;
18
19import android.app.Activity;
20import android.app.ActivityManager;
21import android.app.ActivityManagerNative;
22import android.app.AlarmManager;
23import android.app.PendingIntent;
24import android.app.SearchManager;
25import android.app.StatusBarManager;
26import android.app.trust.TrustManager;
27import android.auditing.SecurityLog;
28import android.content.BroadcastReceiver;
29import android.content.ContentResolver;
30import android.content.Context;
31import android.content.Intent;
32import android.content.IntentFilter;
33import android.content.pm.UserInfo;
34import android.media.AudioManager;
35import android.media.SoundPool;
36import android.os.Bundle;
37import android.os.DeadObjectException;
38import android.os.Handler;
39import android.os.Looper;
40import android.os.Message;
41import android.os.PowerManager;
42import android.os.RemoteException;
43import android.os.SystemClock;
44import android.os.SystemProperties;
45import android.os.UserHandle;
46import android.os.UserManager;
47import android.os.storage.StorageManager;
48import android.provider.Settings;
49import android.telephony.SubscriptionManager;
50import android.telephony.TelephonyManager;
51import android.util.EventLog;
52import android.util.Log;
53import android.util.Slog;
54import android.view.IWindowManager;
55import android.view.ViewGroup;
56import android.view.WindowManagerGlobal;
57import android.view.WindowManagerPolicy;
58import android.view.animation.Animation;
59import android.view.animation.AnimationUtils;
60
61import com.android.internal.policy.IKeyguardDrawnCallback;
62import com.android.internal.policy.IKeyguardExitCallback;
63import com.android.internal.policy.IKeyguardStateCallback;
64import com.android.internal.telephony.IccCardConstants;
65import com.android.internal.widget.LockPatternUtils;
66import com.android.keyguard.KeyguardConstants;
67import com.android.keyguard.KeyguardDisplayManager;
68import com.android.keyguard.KeyguardSecurityView;
69import com.android.keyguard.KeyguardUpdateMonitor;
70import com.android.keyguard.KeyguardUpdateMonitorCallback;
71import com.android.keyguard.ViewMediatorCallback;
72import com.android.systemui.SystemUI;
73import com.android.systemui.SystemUIFactory;
74import com.android.systemui.classifier.FalsingManager;
75import com.android.systemui.statusbar.phone.FingerprintUnlockController;
76import com.android.systemui.statusbar.phone.PhoneStatusBar;
77import com.android.systemui.statusbar.phone.ScrimController;
78import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
79import com.android.systemui.statusbar.phone.StatusBarWindowManager;
80
81import java.io.FileDescriptor;
82import java.io.PrintWriter;
83import java.util.ArrayList;
84import java.util.List;
85
86import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
87import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
88import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL;
89import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
90import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
91
92/**
93 * Mediates requests related to the keyguard.  This includes queries about the
94 * state of the keyguard, power management events that effect whether the keyguard
95 * should be shown or reset, callbacks to the phone window manager to notify
96 * it of when the keyguard is showing, and events from the keyguard view itself
97 * stating that the keyguard was succesfully unlocked.
98 *
99 * Note that the keyguard view is shown when the screen is off (as appropriate)
100 * so that once the screen comes on, it will be ready immediately.
101 *
102 * Example queries about the keyguard:
103 * - is {movement, key} one that should wake the keygaurd?
104 * - is the keyguard showing?
105 * - are input events restricted due to the state of the keyguard?
106 *
107 * Callbacks to the phone window manager:
108 * - the keyguard is showing
109 *
110 * Example external events that translate to keyguard view changes:
111 * - screen turned off -> reset the keyguard, and show it so it will be ready
112 *   next time the screen turns on
113 * - keyboard is slid open -> if the keyguard is not secure, hide it
114 *
115 * Events from the keyguard view:
116 * - user succesfully unlocked keyguard -> hide keyguard view, and no longer
117 *   restrict input events.
118 *
119 * Note: in addition to normal power managment events that effect the state of
120 * whether the keyguard should be showing, external apps and services may request
121 * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}.  When
122 * false, this will override all other conditions for turning on the keyguard.
123 *
124 * Threading and synchronization:
125 * This class is created by the initialization routine of the {@link android.view.WindowManagerPolicy},
126 * and runs on its thread.  The keyguard UI is created from that thread in the
127 * constructor of this class.  The apis may be called from other threads, including the
128 * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
129 * Therefore, methods on this class are synchronized, and any action that is pointed
130 * directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI
131 * thread of the keyguard.
132 */
133public class KeyguardViewMediator extends SystemUI {
134    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
135    private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
136
137    private static final boolean DEBUG = KeyguardConstants.DEBUG;
138    private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
139    private final static boolean DBG_WAKE = false;
140
141    private final static String TAG = "KeyguardViewMediator";
142
143    private static final String DELAYED_KEYGUARD_ACTION =
144        "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
145    private static final String DELAYED_LOCK_PROFILE_ACTION =
146            "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK";
147
148    // used for handler messages
149    private static final int SHOW = 2;
150    private static final int HIDE = 3;
151    private static final int RESET = 4;
152    private static final int VERIFY_UNLOCK = 5;
153    private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 6;
154    private static final int NOTIFY_SCREEN_TURNING_ON = 7;
155    private static final int KEYGUARD_DONE = 9;
156    private static final int KEYGUARD_DONE_DRAWING = 10;
157    private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
158    private static final int SET_OCCLUDED = 12;
159    private static final int KEYGUARD_TIMEOUT = 13;
160    private static final int DISMISS = 17;
161    private static final int START_KEYGUARD_EXIT_ANIM = 18;
162    private static final int ON_ACTIVITY_DRAWN = 19;
163    private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 20;
164    private static final int NOTIFY_STARTED_WAKING_UP = 21;
165    private static final int NOTIFY_SCREEN_TURNED_ON = 22;
166    private static final int NOTIFY_SCREEN_TURNED_OFF = 23;
167    private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 24;
168
169    /**
170     * The default amount of time we stay awake (used for all key input)
171     */
172    public static final int AWAKE_INTERVAL_DEFAULT_MS = 10000;
173
174    /**
175     * How long to wait after the screen turns off due to timeout before
176     * turning on the keyguard (i.e, the user has this much time to turn
177     * the screen back on without having to face the keyguard).
178     */
179    private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
180
181    /**
182     * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()}
183     * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)}
184     * that is reenabling the keyguard.
185     */
186    private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
187
188    /**
189     * Secure setting whether analytics are collected on the keyguard.
190     */
191    private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
192
193    /** The stream type that the lock sounds are tied to. */
194    private int mUiSoundsStreamType;
195
196    private AlarmManager mAlarmManager;
197    private AudioManager mAudioManager;
198    private StatusBarManager mStatusBarManager;
199    private boolean mSwitchingUser;
200
201    private boolean mSystemReady;
202    private boolean mBootCompleted;
203    private boolean mBootSendUserPresent;
204
205    /** High level access to the power manager for WakeLocks */
206    private PowerManager mPM;
207
208    /** High level access to the window manager for dismissing keyguard animation */
209    private IWindowManager mWM;
210
211
212    /** TrustManager for letting it know when we change visibility */
213    private TrustManager mTrustManager;
214
215    /** SearchManager for determining whether or not search assistant is available */
216    private SearchManager mSearchManager;
217
218    /**
219     * Used to keep the device awake while to ensure the keyguard finishes opening before
220     * we sleep.
221     */
222    private PowerManager.WakeLock mShowKeyguardWakeLock;
223
224    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
225
226    // these are protected by synchronized (this)
227
228    /**
229     * External apps (like the phone app) can tell us to disable the keygaurd.
230     */
231    private boolean mExternallyEnabled = true;
232
233    /**
234     * Remember if an external call to {@link #setKeyguardEnabled} with value
235     * false caused us to hide the keyguard, so that we need to reshow it once
236     * the keygaurd is reenabled with another call with value true.
237     */
238    private boolean mNeedToReshowWhenReenabled = false;
239
240    // cached value of whether we are showing (need to know this to quickly
241    // answer whether the input should be restricted)
242    private boolean mShowing;
243
244    /** Cached value of #isInputRestricted */
245    private boolean mInputRestricted;
246
247    // true if the keyguard is hidden by another window
248    private boolean mOccluded = false;
249
250    /**
251     * Helps remember whether the screen has turned on since the last time
252     * it turned off due to timeout. see {@link #onScreenTurnedOff(int)}
253     */
254    private int mDelayedShowingSequence;
255
256    /**
257     * If the user has disabled the keyguard, then requests to exit, this is
258     * how we'll ultimately let them know whether it was successful.  We use this
259     * var being non-null as an indicator that there is an in progress request.
260     */
261    private IKeyguardExitCallback mExitSecureCallback;
262
263    // the properties of the keyguard
264
265    private KeyguardUpdateMonitor mUpdateMonitor;
266
267    private boolean mDeviceInteractive;
268    private boolean mGoingToSleep;
269
270    // last known state of the cellular connection
271    private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
272
273    /**
274     * Whether a hide is pending an we are just waiting for #startKeyguardExitAnimation to be
275     * called.
276     * */
277    private boolean mHiding;
278
279    /**
280     * we send this intent when the keyguard is dismissed.
281     */
282    private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT)
283            .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
284                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
285
286    /**
287     * {@link #setKeyguardEnabled} waits on this condition when it reenables
288     * the keyguard.
289     */
290    private boolean mWaitingUntilKeyguardVisible = false;
291    private LockPatternUtils mLockPatternUtils;
292    private boolean mKeyguardDonePending = false;
293    private boolean mHideAnimationRun = false;
294
295    private SoundPool mLockSounds;
296    private int mLockSoundId;
297    private int mUnlockSoundId;
298    private int mTrustedSoundId;
299    private int mLockSoundStreamId;
300
301    /**
302     * The animation used for hiding keyguard. This is used to fetch the animation timings if
303     * WindowManager is not providing us with them.
304     */
305    private Animation mHideAnimation;
306
307    /**
308     * The volume applied to the lock/unlock sounds.
309     */
310    private float mLockSoundVolume;
311
312    /**
313     * For managing external displays
314     */
315    private KeyguardDisplayManager mKeyguardDisplayManager;
316
317    private final ArrayList<IKeyguardStateCallback> mKeyguardStateCallbacks = new ArrayList<>();
318
319    /**
320     * When starting going to sleep, we figured out that we need to reset Keyguard state and this
321     * should be committed when finished going to sleep.
322     */
323    private boolean mPendingReset;
324
325    /**
326     * When starting going to sleep, we figured out that we need to lock Keyguard and this should be
327     * committed when finished going to sleep.
328     */
329    private boolean mPendingLock;
330
331    private boolean mWakeAndUnlocking;
332    private IKeyguardDrawnCallback mDrawnCallback;
333
334    private boolean mIsPerUserLock;
335
336    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
337
338        @Override
339        public void onUserSwitching(int userId) {
340            // Note that the mLockPatternUtils user has already been updated from setCurrentUser.
341            // We need to force a reset of the views, since lockNow (called by
342            // ActivityManagerService) will not reconstruct the keyguard if it is already showing.
343            synchronized (KeyguardViewMediator.this) {
344                mSwitchingUser = true;
345                resetKeyguardDonePendingLocked();
346                resetStateLocked();
347                adjustStatusBarLocked();
348            }
349        }
350
351        @Override
352        public void onUserSwitchComplete(int userId) {
353            mSwitchingUser = false;
354            if (userId != UserHandle.USER_SYSTEM) {
355                UserInfo info = UserManager.get(mContext).getUserInfo(userId);
356                if (info != null && info.isGuest()) {
357                    // If we just switched to a guest, try to dismiss keyguard.
358                    dismiss();
359                }
360            }
361        }
362
363        @Override
364        public void onUserInfoChanged(int userId) {
365        }
366
367        @Override
368        public void onPhoneStateChanged(int phoneState) {
369            synchronized (KeyguardViewMediator.this) {
370                if (TelephonyManager.CALL_STATE_IDLE == phoneState  // call ending
371                        && !mDeviceInteractive                           // screen off
372                        && mExternallyEnabled) {                // not disabled by any app
373
374                    // note: this is a way to gracefully reenable the keyguard when the call
375                    // ends and the screen is off without always reenabling the keyguard
376                    // each time the screen turns off while in call (and having an occasional ugly
377                    // flicker while turning back on the screen and disabling the keyguard again).
378                    if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
379                            + "keyguard is showing");
380                    doKeyguardLocked(null);
381                }
382            }
383        }
384
385        @Override
386        public void onClockVisibilityChanged() {
387            adjustStatusBarLocked();
388        }
389
390        @Override
391        public void onDeviceProvisioned() {
392            sendUserPresentBroadcast();
393            synchronized (KeyguardViewMediator.this) {
394                // If system user is provisioned, we might want to lock now to avoid showing launcher
395                if (UserManager.isSplitSystemUser()
396                        && KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM) {
397                    doKeyguardLocked(null);
398                }
399            }
400        }
401
402        @Override
403        public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) {
404
405            if (DEBUG_SIM_STATES) {
406                Log.d(TAG, "onSimStateChanged(subId=" + subId + ", slotId=" + slotId
407                        + ",state=" + simState + ")");
408            }
409
410            int size = mKeyguardStateCallbacks.size();
411            boolean simPinSecure = mUpdateMonitor.isSimPinSecure();
412            for (int i = size - 1; i >= 0; i--) {
413                try {
414                    mKeyguardStateCallbacks.get(i).onSimSecureStateChanged(simPinSecure);
415                } catch (RemoteException e) {
416                    Slog.w(TAG, "Failed to call onSimSecureStateChanged", e);
417                    if (e instanceof DeadObjectException) {
418                        mKeyguardStateCallbacks.remove(i);
419                    }
420                }
421            }
422
423            switch (simState) {
424                case NOT_READY:
425                case ABSENT:
426                    // only force lock screen in case of missing sim if user hasn't
427                    // gone through setup wizard
428                    synchronized (this) {
429                        if (shouldWaitForProvisioning()) {
430                            if (!mShowing) {
431                                if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing,"
432                                        + " we need to show the keyguard since the "
433                                        + "device isn't provisioned yet.");
434                                doKeyguardLocked(null);
435                            } else {
436                                resetStateLocked();
437                            }
438                        }
439                    }
440                    break;
441                case PIN_REQUIRED:
442                case PUK_REQUIRED:
443                    synchronized (this) {
444                        if (!mShowing) {
445                            if (DEBUG_SIM_STATES) Log.d(TAG,
446                                    "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
447                                    + "showing; need to show keyguard so user can enter sim pin");
448                            doKeyguardLocked(null);
449                        } else {
450                            resetStateLocked();
451                        }
452                    }
453                    break;
454                case PERM_DISABLED:
455                    synchronized (this) {
456                        if (!mShowing) {
457                            if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and "
458                                  + "keygaurd isn't showing.");
459                            doKeyguardLocked(null);
460                        } else {
461                            if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
462                                  + "show permanently disabled message in lockscreen.");
463                            resetStateLocked();
464                        }
465                    }
466                    break;
467                case READY:
468                    synchronized (this) {
469                        if (mShowing) {
470                            resetStateLocked();
471                        }
472                    }
473                    break;
474                default:
475                    if (DEBUG_SIM_STATES) Log.v(TAG, "Ignoring state: " + simState);
476                    break;
477            }
478        }
479    };
480
481    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
482
483        @Override
484        public void userActivity() {
485            KeyguardViewMediator.this.userActivity();
486        }
487
488        @Override
489        public void keyguardDone(boolean strongAuth) {
490            if (!mKeyguardDonePending) {
491                KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
492            }
493            if (strongAuth) {
494                mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
495            }
496        }
497
498        @Override
499        public void keyguardDoneDrawing() {
500            mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING);
501        }
502
503        @Override
504        public void setNeedsInput(boolean needsInput) {
505            mStatusBarKeyguardViewManager.setNeedsInput(needsInput);
506        }
507
508        @Override
509        public void keyguardDonePending(boolean strongAuth) {
510            mKeyguardDonePending = true;
511            mHideAnimationRun = true;
512            mStatusBarKeyguardViewManager.startPreHideAnimation(null /* finishRunnable */);
513            mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
514                    KEYGUARD_DONE_PENDING_TIMEOUT_MS);
515            if (strongAuth) {
516                mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
517            }
518        }
519
520        @Override
521        public void keyguardGone() {
522            mKeyguardDisplayManager.hide();
523        }
524
525        @Override
526        public void readyForKeyguardDone() {
527            if (mKeyguardDonePending) {
528                // Somebody has called keyguardDonePending before, which means that we are
529                // authenticated
530                KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
531            }
532        }
533
534        @Override
535        public void resetKeyguard() {
536            resetStateLocked();
537        }
538
539        @Override
540        public void playTrustedSound() {
541            KeyguardViewMediator.this.playTrustedSound();
542        }
543
544        @Override
545        public boolean isInputRestricted() {
546            return KeyguardViewMediator.this.isInputRestricted();
547        }
548
549        @Override
550        public boolean isScreenOn() {
551            return mDeviceInteractive;
552        }
553
554        @Override
555        public int getBouncerPromptReason() {
556            int currentUser = ActivityManager.getCurrentUser();
557            boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser);
558            boolean fingerprint = mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser);
559            boolean any = trust || fingerprint;
560            KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
561                    mUpdateMonitor.getStrongAuthTracker();
562            int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
563
564            if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
565                return KeyguardSecurityView.PROMPT_REASON_RESTART;
566            } else if (fingerprint && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
567                return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
568            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
569                return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
570            } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
571                return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
572            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
573                return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
574            } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL) != 0) {
575                return KeyguardSecurityView.PROMPT_REASON_WRONG_CREDENTIAL;
576            }
577
578
579            return KeyguardSecurityView.PROMPT_REASON_NONE;
580        }
581    };
582
583    public void userActivity() {
584        mPM.userActivity(SystemClock.uptimeMillis(), false);
585    }
586
587    private void setupLocked() {
588        mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
589        mWM = WindowManagerGlobal.getWindowManagerService();
590        mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
591
592        mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
593        mShowKeyguardWakeLock.setReferenceCounted(false);
594
595        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
596        mContext.registerReceiver(
597                mBroadcastReceiver, new IntentFilter(DELAYED_LOCK_PROFILE_ACTION));
598
599        mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
600
601        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
602
603        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
604
605        mLockPatternUtils = new LockPatternUtils(mContext);
606        KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
607
608        // Assume keyguard is showing (unless it's disabled) until we know for sure...
609        setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled(
610                KeyguardUpdateMonitor.getCurrentUser()));
611        updateInputRestrictedLocked();
612        mTrustManager.reportKeyguardShowingChanged();
613
614        mStatusBarKeyguardViewManager =
615                SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(mContext,
616                        mViewMediatorCallback, mLockPatternUtils);
617        final ContentResolver cr = mContext.getContentResolver();
618
619        mDeviceInteractive = mPM.isInteractive();
620
621        mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
622        String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
623        if (soundPath != null) {
624            mLockSoundId = mLockSounds.load(soundPath, 1);
625        }
626        if (soundPath == null || mLockSoundId == 0) {
627            Log.w(TAG, "failed to load lock sound from " + soundPath);
628        }
629        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
630        if (soundPath != null) {
631            mUnlockSoundId = mLockSounds.load(soundPath, 1);
632        }
633        if (soundPath == null || mUnlockSoundId == 0) {
634            Log.w(TAG, "failed to load unlock sound from " + soundPath);
635        }
636        soundPath = Settings.Global.getString(cr, Settings.Global.TRUSTED_SOUND);
637        if (soundPath != null) {
638            mTrustedSoundId = mLockSounds.load(soundPath, 1);
639        }
640        if (soundPath == null || mTrustedSoundId == 0) {
641            Log.w(TAG, "failed to load trusted sound from " + soundPath);
642        }
643
644        int lockSoundDefaultAttenuation = mContext.getResources().getInteger(
645                com.android.internal.R.integer.config_lockSoundVolumeDb);
646        mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20);
647
648        mHideAnimation = AnimationUtils.loadAnimation(mContext,
649                com.android.internal.R.anim.lock_screen_behind_enter);
650    }
651
652    @Override
653    public void start() {
654        synchronized (this) {
655            setupLocked();
656        }
657        putComponent(KeyguardViewMediator.class, this);
658    }
659
660    /**
661     * Let us know that the system is ready after startup.
662     */
663    public void onSystemReady() {
664        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
665        synchronized (this) {
666            if (DEBUG) Log.d(TAG, "onSystemReady");
667            mSystemReady = true;
668            doKeyguardLocked(null);
669            mUpdateMonitor.registerCallback(mUpdateCallback);
670        }
671        mIsPerUserLock = StorageManager.isFileBasedEncryptionEnabled();
672        // Most services aren't available until the system reaches the ready state, so we
673        // send it here when the device first boots.
674        maybeSendUserPresentBroadcast();
675    }
676
677    /**
678     * Called to let us know the screen was turned off.
679     * @param why either {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_USER} or
680     *   {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}.
681     */
682    public void onStartedGoingToSleep(int why) {
683        if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + why + ")");
684        synchronized (this) {
685            mDeviceInteractive = false;
686            mGoingToSleep = true;
687
688            // Lock immediately based on setting if secure (user has a pin/pattern/password).
689            // This also "locks" the device when not secure to provide easy access to the
690            // camera while preventing unwanted input.
691            int currentUser = KeyguardUpdateMonitor.getCurrentUser();
692            final boolean lockImmediately =
693                    mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
694                            || !mLockPatternUtils.isSecure(currentUser);
695            long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
696
697            if (mExitSecureCallback != null) {
698                if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
699                try {
700                    mExitSecureCallback.onKeyguardExitResult(false);
701                } catch (RemoteException e) {
702                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
703                }
704                mExitSecureCallback = null;
705                if (!mExternallyEnabled) {
706                    hideLocked();
707                }
708            } else if (mShowing) {
709                mPendingReset = true;
710            } else if ((why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT && timeout > 0)
711                    || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
712                doKeyguardLaterLocked(timeout);
713            } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
714                mPendingLock = true;
715            }
716
717            if (mPendingLock) {
718                playSounds(true);
719            }
720        }
721        KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedGoingToSleep(why);
722        notifyStartedGoingToSleep();
723    }
724
725    public void onFinishedGoingToSleep(int why) {
726        if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")");
727        synchronized (this) {
728            mDeviceInteractive = false;
729            mGoingToSleep = false;
730
731            resetKeyguardDonePendingLocked();
732            mHideAnimationRun = false;
733
734            notifyFinishedGoingToSleep();
735
736            if (mPendingReset) {
737                resetStateLocked();
738                mPendingReset = false;
739            }
740            if (mPendingLock) {
741                doKeyguardLocked(null);
742                mPendingLock = false;
743            }
744        }
745        doKeyguardLaterLockedForChildProfiles();
746        KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
747    }
748
749    private long getLockTimeout(int userId) {
750        // if the screen turned off because of timeout or the user hit the power button
751        // and we don't need to lock immediately, set an alarm
752        // to enable it a little bit later (i.e, give the user a chance
753        // to turn the screen back on within a certain window without
754        // having to unlock the screen)
755        final ContentResolver cr = mContext.getContentResolver();
756
757        // From SecuritySettings
758        final long lockAfterTimeout = Settings.Secure.getInt(cr,
759                Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
760                KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
761
762        // From DevicePolicyAdmin
763        final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
764                .getMaximumTimeToLock(null, userId);
765
766        long timeout;
767
768        if ((mLockPatternUtils.isSeparateProfileChallengeEnabled(userId))
769                || policyTimeout <= 0) {
770            timeout = lockAfterTimeout;
771        } else {
772            // From DisplaySettings
773            long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
774                    KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
775
776            // policy in effect. Make sure we don't go beyond policy limit.
777            displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
778            timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
779        }
780        return timeout;
781    }
782
783    private void doKeyguardLaterLocked() {
784        long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
785        if (timeout == 0) {
786            doKeyguardLocked(null);
787        } else {
788            doKeyguardLaterLocked(timeout);
789        }
790    }
791
792    private void doKeyguardLaterLocked(long timeout) {
793        // Lock in the future
794        long when = SystemClock.elapsedRealtime() + timeout;
795        Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
796        intent.putExtra("seq", mDelayedShowingSequence);
797        PendingIntent sender = PendingIntent.getBroadcast(mContext,
798                0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
799        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
800        if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
801                         + mDelayedShowingSequence);
802        doKeyguardLaterLockedForChildProfiles();
803    }
804
805    private void doKeyguardLaterLockedForChildProfiles() {
806        UserManager um = UserManager.get(mContext);
807        List<UserInfo> profiles = um.getEnabledProfiles(UserHandle.myUserId());
808        if (profiles.size() > 1) {
809            for (UserInfo info : profiles) {
810                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(info.id)) {
811                    long userTimeout = getLockTimeout(info.id);
812                    long userWhen = SystemClock.elapsedRealtime() + userTimeout;
813                    Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION);
814                    lockIntent.putExtra(Intent.EXTRA_USER_ID, info.id);
815                    PendingIntent lockSender = PendingIntent.getBroadcast(
816                            mContext, 0, lockIntent, PendingIntent.FLAG_CANCEL_CURRENT);
817                    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, userWhen, lockSender);
818                }
819            }
820        }
821    }
822
823    private void cancelDoKeyguardLaterLocked() {
824        mDelayedShowingSequence++;
825    }
826
827    /**
828     * Let's us know when the device is waking up.
829     */
830    public void onStartedWakingUp() {
831
832        // TODO: Rename all screen off/on references to interactive/sleeping
833        synchronized (this) {
834            mDeviceInteractive = true;
835            cancelDoKeyguardLaterLocked();
836            if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence);
837            notifyStartedWakingUp();
838        }
839        KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedWakingUp();
840        maybeSendUserPresentBroadcast();
841    }
842
843    public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
844        notifyScreenOn(callback);
845    }
846
847    public void onScreenTurnedOn() {
848        notifyScreenTurnedOn();
849        mUpdateMonitor.dispatchScreenTurnedOn();
850    }
851
852    public void onScreenTurnedOff() {
853        notifyScreenTurnedOff();
854        mUpdateMonitor.dispatchScreenTurnedOff();
855    }
856
857    private void maybeSendUserPresentBroadcast() {
858        if (mSystemReady && mLockPatternUtils.isLockScreenDisabled(
859                KeyguardUpdateMonitor.getCurrentUser())) {
860            // Lock screen is disabled because the user has set the preference to "None".
861            // In this case, send out ACTION_USER_PRESENT here instead of in
862            // handleKeyguardDone()
863            sendUserPresentBroadcast();
864        }
865    }
866
867    /**
868     * A dream started.  We should lock after the usual screen-off lock timeout but only
869     * if there is a secure lock pattern.
870     */
871    public void onDreamingStarted() {
872        synchronized (this) {
873            if (mDeviceInteractive
874                    && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
875                doKeyguardLaterLocked();
876            }
877        }
878    }
879
880    /**
881     * A dream stopped.
882     */
883    public void onDreamingStopped() {
884        synchronized (this) {
885            if (mDeviceInteractive) {
886                cancelDoKeyguardLaterLocked();
887            }
888        }
889    }
890
891    /**
892     * Same semantics as {@link android.view.WindowManagerPolicy#enableKeyguard}; provide
893     * a way for external stuff to override normal keyguard behavior.  For instance
894     * the phone app disables the keyguard when it receives incoming calls.
895     */
896    public void setKeyguardEnabled(boolean enabled) {
897        synchronized (this) {
898            if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")");
899
900            mExternallyEnabled = enabled;
901
902            if (!enabled && mShowing) {
903                if (mExitSecureCallback != null) {
904                    if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
905                    // we're in the process of handling a request to verify the user
906                    // can get past the keyguard. ignore extraneous requests to disable / reenable
907                    return;
908                }
909
910                // hiding keyguard that is showing, remember to reshow later
911                if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
912                        + "disabling status bar expansion");
913                mNeedToReshowWhenReenabled = true;
914                updateInputRestrictedLocked();
915                hideLocked();
916            } else if (enabled && mNeedToReshowWhenReenabled) {
917                // reenabled after previously hidden, reshow
918                if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling "
919                        + "status bar expansion");
920                mNeedToReshowWhenReenabled = false;
921                updateInputRestrictedLocked();
922
923                if (mExitSecureCallback != null) {
924                    if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting");
925                    try {
926                        mExitSecureCallback.onKeyguardExitResult(false);
927                    } catch (RemoteException e) {
928                        Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
929                    }
930                    mExitSecureCallback = null;
931                    resetStateLocked();
932                } else {
933                    showLocked(null);
934
935                    // block until we know the keygaurd is done drawing (and post a message
936                    // to unblock us after a timeout so we don't risk blocking too long
937                    // and causing an ANR).
938                    mWaitingUntilKeyguardVisible = true;
939                    mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS);
940                    if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false");
941                    while (mWaitingUntilKeyguardVisible) {
942                        try {
943                            wait();
944                        } catch (InterruptedException e) {
945                            Thread.currentThread().interrupt();
946                        }
947                    }
948                    if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible");
949                }
950            }
951        }
952    }
953
954    /**
955     * @see android.app.KeyguardManager#exitKeyguardSecurely
956     */
957    public void verifyUnlock(IKeyguardExitCallback callback) {
958        synchronized (this) {
959            if (DEBUG) Log.d(TAG, "verifyUnlock");
960            if (shouldWaitForProvisioning()) {
961                // don't allow this api when the device isn't provisioned
962                if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned");
963                try {
964                    callback.onKeyguardExitResult(false);
965                } catch (RemoteException e) {
966                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
967                }
968            } else if (mExternallyEnabled) {
969                // this only applies when the user has externally disabled the
970                // keyguard.  this is unexpected and means the user is not
971                // using the api properly.
972                Log.w(TAG, "verifyUnlock called when not externally disabled");
973                try {
974                    callback.onKeyguardExitResult(false);
975                } catch (RemoteException e) {
976                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
977                }
978            } else if (mExitSecureCallback != null) {
979                // already in progress with someone else
980                try {
981                    callback.onKeyguardExitResult(false);
982                } catch (RemoteException e) {
983                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
984                }
985            } else if (!isSecure()) {
986
987                // Keyguard is not secure, no need to do anything, and we don't need to reshow
988                // the Keyguard after the client releases the Keyguard lock.
989                mExternallyEnabled = true;
990                mNeedToReshowWhenReenabled = false;
991                updateInputRestricted();
992                try {
993                    callback.onKeyguardExitResult(true);
994                } catch (RemoteException e) {
995                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
996                }
997            } else {
998
999                // Since we prevent apps from hiding the Keyguard if we are secure, this should be
1000                // a no-op as well.
1001                try {
1002                    callback.onKeyguardExitResult(false);
1003                } catch (RemoteException e) {
1004                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
1005                }
1006            }
1007        }
1008    }
1009
1010    /**
1011     * Is the keyguard currently showing and not being force hidden?
1012     */
1013    public boolean isShowingAndNotOccluded() {
1014        return mShowing && !mOccluded;
1015    }
1016
1017    /**
1018     * Notify us when the keyguard is occluded by another window
1019     */
1020    public void setOccluded(boolean isOccluded) {
1021        if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
1022        mHandler.removeMessages(SET_OCCLUDED);
1023        Message msg = mHandler.obtainMessage(SET_OCCLUDED, (isOccluded ? 1 : 0), 0);
1024        mHandler.sendMessage(msg);
1025    }
1026
1027    /**
1028     * Handles SET_OCCLUDED message sent by setOccluded()
1029     */
1030    private void handleSetOccluded(boolean isOccluded) {
1031        synchronized (KeyguardViewMediator.this) {
1032            if (mHiding && isOccluded) {
1033                // We're in the process of going away but WindowManager wants to show a
1034                // SHOW_WHEN_LOCKED activity instead.
1035                startKeyguardExitAnimation(0, 0);
1036            }
1037
1038            if (mOccluded != isOccluded) {
1039                mOccluded = isOccluded;
1040                mStatusBarKeyguardViewManager.setOccluded(isOccluded);
1041                updateActivityLockScreenState();
1042                adjustStatusBarLocked();
1043            }
1044        }
1045    }
1046
1047    /**
1048     * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout.
1049     * This must be safe to call from any thread and with any window manager locks held.
1050     */
1051    public void doKeyguardTimeout(Bundle options) {
1052        mHandler.removeMessages(KEYGUARD_TIMEOUT);
1053        Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
1054        mHandler.sendMessage(msg);
1055    }
1056
1057    /**
1058     * Given the state of the keyguard, is the input restricted?
1059     * Input is restricted when the keyguard is showing, or when the keyguard
1060     * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
1061     */
1062    public boolean isInputRestricted() {
1063        return mShowing || mNeedToReshowWhenReenabled;
1064    }
1065
1066    private void updateInputRestricted() {
1067        synchronized (this) {
1068            updateInputRestrictedLocked();
1069        }
1070    }
1071    private void updateInputRestrictedLocked() {
1072        boolean inputRestricted = isInputRestricted();
1073        if (mInputRestricted != inputRestricted) {
1074            mInputRestricted = inputRestricted;
1075            int size = mKeyguardStateCallbacks.size();
1076            for (int i = size - 1; i >= 0; i--) {
1077                try {
1078                    mKeyguardStateCallbacks.get(i).onInputRestrictedStateChanged(inputRestricted);
1079                } catch (RemoteException e) {
1080                    Slog.w(TAG, "Failed to call onDeviceProvisioned", e);
1081                    if (e instanceof DeadObjectException) {
1082                        mKeyguardStateCallbacks.remove(i);
1083                    }
1084                }
1085            }
1086        }
1087    }
1088
1089    /**
1090     * Enable the keyguard if the settings are appropriate.
1091     */
1092    private void doKeyguardLocked(Bundle options) {
1093        // if another app is disabling us, don't show
1094        if (!mExternallyEnabled) {
1095            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
1096
1097            // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
1098            // for an occasional ugly flicker in this situation:
1099            // 1) receive a call with the screen on (no keyguard) or make a call
1100            // 2) screen times out
1101            // 3) user hits key to turn screen back on
1102            // instead, we reenable the keyguard when we know the screen is off and the call
1103            // ends (see the broadcast receiver below)
1104            // TODO: clean this up when we have better support at the window manager level
1105            // for apps that wish to be on top of the keyguard
1106            return;
1107        }
1108
1109        // if the keyguard is already showing, don't bother
1110        if (mStatusBarKeyguardViewManager.isShowing()) {
1111            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
1112            resetStateLocked();
1113            return;
1114        }
1115
1116        // In split system user mode, we never unlock system user.
1117        if (!UserManager.isSplitSystemUser()
1118                || KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM
1119                || !mUpdateMonitor.isDeviceProvisioned()) {
1120
1121            // if the setup wizard hasn't run yet, don't show
1122            final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
1123            final boolean absent = SubscriptionManager.isValidSubscriptionId(
1124                    mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT));
1125            final boolean disabled = SubscriptionManager.isValidSubscriptionId(
1126                    mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
1127            final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
1128                    || ((absent || disabled) && requireSim);
1129
1130            if (!lockedOrMissing && shouldWaitForProvisioning()) {
1131                if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
1132                        + " and the sim is not locked or missing");
1133                return;
1134            }
1135
1136            if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
1137                    && !lockedOrMissing) {
1138                if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
1139                return;
1140            }
1141
1142            if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
1143                if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
1144                // Without this, settings is not enabled until the lock screen first appears
1145                setShowingLocked(false);
1146                hideLocked();
1147                mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
1148                return;
1149            }
1150        }
1151
1152        if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
1153        showLocked(options);
1154    }
1155
1156    private void lockProfile(int userId) {
1157        mTrustManager.setDeviceLockedForUser(userId, true);
1158    }
1159
1160    private boolean shouldWaitForProvisioning() {
1161        return !mUpdateMonitor.isDeviceProvisioned() && !isSecure();
1162    }
1163
1164    /**
1165     * Dismiss the keyguard through the security layers.
1166     */
1167    public void handleDismiss() {
1168        if (mShowing && !mOccluded) {
1169            mStatusBarKeyguardViewManager.dismiss();
1170        }
1171    }
1172
1173    public void dismiss() {
1174        mHandler.sendEmptyMessage(DISMISS);
1175    }
1176
1177    /**
1178     * Send message to keyguard telling it to reset its state.
1179     * @see #handleReset
1180     */
1181    private void resetStateLocked() {
1182        if (DEBUG) Log.e(TAG, "resetStateLocked");
1183        Message msg = mHandler.obtainMessage(RESET);
1184        mHandler.sendMessage(msg);
1185    }
1186
1187    /**
1188     * Send message to keyguard telling it to verify unlock
1189     * @see #handleVerifyUnlock()
1190     */
1191    private void verifyUnlockLocked() {
1192        if (DEBUG) Log.d(TAG, "verifyUnlockLocked");
1193        mHandler.sendEmptyMessage(VERIFY_UNLOCK);
1194    }
1195
1196    private void notifyStartedGoingToSleep() {
1197        if (DEBUG) Log.d(TAG, "notifyStartedGoingToSleep");
1198        mHandler.sendEmptyMessage(NOTIFY_STARTED_GOING_TO_SLEEP);
1199    }
1200
1201    private void notifyFinishedGoingToSleep() {
1202        if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep");
1203        mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP);
1204    }
1205
1206    private void notifyStartedWakingUp() {
1207        if (DEBUG) Log.d(TAG, "notifyStartedWakingUp");
1208        mHandler.sendEmptyMessage(NOTIFY_STARTED_WAKING_UP);
1209    }
1210
1211    private void notifyScreenOn(IKeyguardDrawnCallback callback) {
1212        if (DEBUG) Log.d(TAG, "notifyScreenOn");
1213        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNING_ON, callback);
1214        mHandler.sendMessage(msg);
1215    }
1216
1217    private void notifyScreenTurnedOn() {
1218        if (DEBUG) Log.d(TAG, "notifyScreenTurnedOn");
1219        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_ON);
1220        mHandler.sendMessage(msg);
1221    }
1222
1223    private void notifyScreenTurnedOff() {
1224        if (DEBUG) Log.d(TAG, "notifyScreenTurnedOff");
1225        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_OFF);
1226        mHandler.sendMessage(msg);
1227    }
1228
1229    /**
1230     * Send message to keyguard telling it to show itself
1231     * @see #handleShow
1232     */
1233    private void showLocked(Bundle options) {
1234        if (DEBUG) Log.d(TAG, "showLocked");
1235        // ensure we stay awake until we are finished displaying the keyguard
1236        mShowKeyguardWakeLock.acquire();
1237        Message msg = mHandler.obtainMessage(SHOW, options);
1238        mHandler.sendMessage(msg);
1239    }
1240
1241    /**
1242     * Send message to keyguard telling it to hide itself
1243     * @see #handleHide()
1244     */
1245    private void hideLocked() {
1246        if (DEBUG) Log.d(TAG, "hideLocked");
1247        Message msg = mHandler.obtainMessage(HIDE);
1248        mHandler.sendMessage(msg);
1249    }
1250
1251    public boolean isSecure() {
1252        return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())
1253            || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
1254    }
1255
1256    /**
1257     * Update the newUserId. Call while holding WindowManagerService lock.
1258     * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing.
1259     *
1260     * @param newUserId The id of the incoming user.
1261     */
1262    public void setCurrentUser(int newUserId) {
1263        KeyguardUpdateMonitor.setCurrentUser(newUserId);
1264    }
1265
1266    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1267        @Override
1268        public void onReceive(Context context, Intent intent) {
1269            if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) {
1270                final int sequence = intent.getIntExtra("seq", 0);
1271                if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
1272                        + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
1273                synchronized (KeyguardViewMediator.this) {
1274                    if (mDelayedShowingSequence == sequence) {
1275                        doKeyguardLocked(null);
1276                    }
1277                }
1278            } else if (DELAYED_LOCK_PROFILE_ACTION.equals(intent.getAction())) {
1279                int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, 0);
1280                if (userId != 0) {
1281                    synchronized (KeyguardViewMediator.this) {
1282                        lockProfile(userId);
1283                    }
1284                }
1285            }
1286        }
1287    };
1288
1289    public void keyguardDone(boolean authenticated) {
1290        if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated +")");
1291        EventLog.writeEvent(70000, 2);
1292        Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0);
1293        mHandler.sendMessage(msg);
1294    }
1295
1296    /**
1297     * This handler will be associated with the policy thread, which will also
1298     * be the UI thread of the keyguard.  Since the apis of the policy, and therefore
1299     * this class, can be called by other threads, any action that directly
1300     * interacts with the keyguard ui should be posted to this handler, rather
1301     * than called directly.
1302     */
1303    private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
1304        @Override
1305        public void handleMessage(Message msg) {
1306            switch (msg.what) {
1307                case SHOW:
1308                    handleShow((Bundle) msg.obj);
1309                    break;
1310                case HIDE:
1311                    handleHide();
1312                    break;
1313                case RESET:
1314                    handleReset();
1315                    break;
1316                case VERIFY_UNLOCK:
1317                    handleVerifyUnlock();
1318                    break;
1319                case NOTIFY_STARTED_GOING_TO_SLEEP:
1320                    handleNotifyStartedGoingToSleep();
1321                    break;
1322                case NOTIFY_FINISHED_GOING_TO_SLEEP:
1323                    handleNotifyFinishedGoingToSleep();
1324                    break;
1325                case NOTIFY_SCREEN_TURNING_ON:
1326                    handleNotifyScreenTurningOn((IKeyguardDrawnCallback) msg.obj);
1327                    break;
1328                case NOTIFY_SCREEN_TURNED_ON:
1329                    handleNotifyScreenTurnedOn();
1330                    break;
1331                case NOTIFY_SCREEN_TURNED_OFF:
1332                    handleNotifyScreenTurnedOff();
1333                    break;
1334                case NOTIFY_STARTED_WAKING_UP:
1335                    handleNotifyStartedWakingUp();
1336                    break;
1337                case KEYGUARD_DONE:
1338                    handleKeyguardDone(msg.arg1 != 0);
1339                    break;
1340                case KEYGUARD_DONE_DRAWING:
1341                    handleKeyguardDoneDrawing();
1342                    break;
1343                case SET_OCCLUDED:
1344                    handleSetOccluded(msg.arg1 != 0);
1345                    break;
1346                case KEYGUARD_TIMEOUT:
1347                    synchronized (KeyguardViewMediator.this) {
1348                        doKeyguardLocked((Bundle) msg.obj);
1349                    }
1350                    break;
1351                case DISMISS:
1352                    handleDismiss();
1353                    break;
1354                case START_KEYGUARD_EXIT_ANIM:
1355                    StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
1356                    handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration);
1357                    FalsingManager.getInstance(mContext).onSucccessfulUnlock();
1358                    break;
1359                case KEYGUARD_DONE_PENDING_TIMEOUT:
1360                    Log.w(TAG, "Timeout while waiting for activity drawn!");
1361                    // Fall through.
1362                case ON_ACTIVITY_DRAWN:
1363                    handleOnActivityDrawn();
1364                    break;
1365            }
1366        }
1367    };
1368
1369    /**
1370     * @see #keyguardDone
1371     * @see #KEYGUARD_DONE
1372     */
1373    private void handleKeyguardDone(boolean authenticated) {
1374        if (SecurityLog.isLoggingEnabled()
1375                && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
1376            SecurityLog.writeEvent(SecurityLog.TAG_DEVICE_UNLOCK_ATTEMPT,
1377                    (authenticated ? 1 : 0), "Unknown");
1378        }
1379        if (DEBUG) Log.d(TAG, "handleKeyguardDone");
1380        synchronized (this) {
1381            resetKeyguardDonePendingLocked();
1382        }
1383
1384        if (authenticated) {
1385            mUpdateMonitor.clearFailedUnlockAttempts();
1386        }
1387        mUpdateMonitor.clearFingerprintRecognized();
1388
1389        if (mGoingToSleep) {
1390            Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
1391            return;
1392        }
1393        if (mExitSecureCallback != null) {
1394            try {
1395                mExitSecureCallback.onKeyguardExitResult(authenticated);
1396            } catch (RemoteException e) {
1397                Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e);
1398            }
1399
1400            mExitSecureCallback = null;
1401
1402            if (authenticated) {
1403                // after succesfully exiting securely, no need to reshow
1404                // the keyguard when they've released the lock
1405                mExternallyEnabled = true;
1406                mNeedToReshowWhenReenabled = false;
1407                updateInputRestricted();
1408            }
1409        }
1410
1411        handleHide();
1412    }
1413
1414    private void sendUserPresentBroadcast() {
1415        synchronized (this) {
1416            if (mBootCompleted) {
1417                final UserHandle currentUser = new UserHandle(KeyguardUpdateMonitor.getCurrentUser());
1418                final UserManager um = (UserManager) mContext.getSystemService(
1419                        Context.USER_SERVICE);
1420                List <UserInfo> userHandles = um.getProfiles(currentUser.getIdentifier());
1421                for (UserInfo ui : userHandles) {
1422                    mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, ui.getUserHandle());
1423                }
1424            } else {
1425                mBootSendUserPresent = true;
1426            }
1427        }
1428    }
1429
1430    /**
1431     * @see #keyguardDone
1432     * @see #KEYGUARD_DONE_DRAWING
1433     */
1434    private void handleKeyguardDoneDrawing() {
1435        synchronized(this) {
1436            if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing");
1437            if (mWaitingUntilKeyguardVisible) {
1438                if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible");
1439                mWaitingUntilKeyguardVisible = false;
1440                notifyAll();
1441
1442                // there will usually be two of these sent, one as a timeout, and one
1443                // as a result of the callback, so remove any remaining messages from
1444                // the queue
1445                mHandler.removeMessages(KEYGUARD_DONE_DRAWING);
1446            }
1447        }
1448    }
1449
1450    private void playSounds(boolean locked) {
1451        playSound(locked ? mLockSoundId : mUnlockSoundId);
1452    }
1453
1454    private void playSound(int soundId) {
1455        if (soundId == 0) return;
1456        final ContentResolver cr = mContext.getContentResolver();
1457        if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
1458
1459            mLockSounds.stop(mLockSoundStreamId);
1460            // Init mAudioManager
1461            if (mAudioManager == null) {
1462                mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
1463                if (mAudioManager == null) return;
1464                mUiSoundsStreamType = mAudioManager.getUiSoundsStreamType();
1465            }
1466            // If the stream is muted, don't play the sound
1467            if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return;
1468
1469            mLockSoundStreamId = mLockSounds.play(soundId,
1470                    mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
1471        }
1472    }
1473
1474    private void playTrustedSound() {
1475        playSound(mTrustedSoundId);
1476    }
1477
1478    private void updateActivityLockScreenState() {
1479        try {
1480            ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mOccluded);
1481        } catch (RemoteException e) {
1482        }
1483    }
1484
1485    /**
1486     * Handle message sent by {@link #showLocked}.
1487     * @see #SHOW
1488     */
1489    private void handleShow(Bundle options) {
1490        if (SecurityLog.isLoggingEnabled()
1491                && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
1492            SecurityLog.writeEvent(SecurityLog.TAG_DEVICE_LOCKED, "");
1493        }
1494        synchronized (KeyguardViewMediator.this) {
1495            if (!mSystemReady) {
1496                if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
1497                return;
1498            } else {
1499                if (DEBUG) Log.d(TAG, "handleShow");
1500            }
1501
1502            setShowingLocked(true);
1503            mStatusBarKeyguardViewManager.show(options);
1504            mHiding = false;
1505            mWakeAndUnlocking = false;
1506            resetKeyguardDonePendingLocked();
1507            mHideAnimationRun = false;
1508            updateActivityLockScreenState();
1509            adjustStatusBarLocked();
1510            userActivity();
1511
1512            mShowKeyguardWakeLock.release();
1513        }
1514        mKeyguardDisplayManager.show();
1515    }
1516
1517    private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
1518        @Override
1519        public void run() {
1520            try {
1521                mStatusBarKeyguardViewManager.keyguardGoingAway();
1522
1523                // Don't actually hide the Keyguard at the moment, wait for window
1524                // manager until it tells us it's safe to do so with
1525                // startKeyguardExitAnimation.
1526                ActivityManagerNative.getDefault().keyguardGoingAway(
1527                        mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
1528                                || mWakeAndUnlocking,
1529                        mStatusBarKeyguardViewManager.isGoingToNotificationShade());
1530            } catch (RemoteException e) {
1531                Log.e(TAG, "Error while calling WindowManager", e);
1532            }
1533        }
1534    };
1535
1536    /**
1537     * Handle message sent by {@link #hideLocked()}
1538     * @see #HIDE
1539     */
1540    private void handleHide() {
1541        synchronized (KeyguardViewMediator.this) {
1542            if (DEBUG) Log.d(TAG, "handleHide");
1543
1544            if (UserManager.isSplitSystemUser()
1545                    && KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM) {
1546                // In split system user mode, we never unlock system user. The end user has to
1547                // switch to another user.
1548                // TODO: We should stop it early by disabling the swipe up flow. Right now swipe up
1549                // still completes and makes the screen blank.
1550                if (DEBUG) Log.d(TAG, "Split system user, quit unlocking.");
1551                return;
1552            }
1553            mHiding = true;
1554            if (mShowing && !mOccluded) {
1555                if (!mHideAnimationRun) {
1556                    mStatusBarKeyguardViewManager.startPreHideAnimation(mKeyguardGoingAwayRunnable);
1557                } else {
1558                    mKeyguardGoingAwayRunnable.run();
1559                }
1560            } else {
1561
1562                // Don't try to rely on WindowManager - if Keyguard wasn't showing, window
1563                // manager won't start the exit animation.
1564                handleStartKeyguardExitAnimation(
1565                        SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
1566                        mHideAnimation.getDuration());
1567            }
1568        }
1569    }
1570
1571    private void handleOnActivityDrawn() {
1572        if (DEBUG) Log.d(TAG, "handleOnActivityDrawn: mKeyguardDonePending=" + mKeyguardDonePending);
1573        if (mKeyguardDonePending) {
1574            mStatusBarKeyguardViewManager.onActivityDrawn();
1575        }
1576    }
1577
1578    private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
1579        synchronized (KeyguardViewMediator.this) {
1580
1581            if (!mHiding) {
1582                return;
1583            }
1584            mHiding = false;
1585
1586            if (mWakeAndUnlocking && mDrawnCallback != null) {
1587
1588                // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
1589                // the next draw from here so we don't have to wait for window manager to signal
1590                // this to our ViewRootImpl.
1591                mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
1592                notifyDrawn(mDrawnCallback);
1593            }
1594
1595            // only play "unlock" noises if not on a call (since the incall UI
1596            // disables the keyguard)
1597            if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
1598                playSounds(false);
1599            }
1600
1601            setShowingLocked(false);
1602            mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
1603            resetKeyguardDonePendingLocked();
1604            mHideAnimationRun = false;
1605            updateActivityLockScreenState();
1606            adjustStatusBarLocked();
1607            sendUserPresentBroadcast();
1608        }
1609    }
1610
1611    private void adjustStatusBarLocked() {
1612        if (mStatusBarManager == null) {
1613            mStatusBarManager = (StatusBarManager)
1614                    mContext.getSystemService(Context.STATUS_BAR_SERVICE);
1615        }
1616        if (mStatusBarManager == null) {
1617            Log.w(TAG, "Could not get status bar manager");
1618        } else {
1619            // Disable aspects of the system/status/navigation bars that must not be re-enabled by
1620            // windows that appear on top, ever
1621            int flags = StatusBarManager.DISABLE_NONE;
1622            if (mShowing) {
1623                // Permanently disable components not available when keyguard is enabled
1624                // (like recents). Temporary enable/disable (e.g. the "back" button) are
1625                // done in KeyguardHostView.
1626                flags |= StatusBarManager.DISABLE_RECENT;
1627                flags |= StatusBarManager.DISABLE_SEARCH;
1628            }
1629            if (isShowingAndNotOccluded()) {
1630                flags |= StatusBarManager.DISABLE_HOME;
1631            }
1632
1633            if (DEBUG) {
1634                Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded
1635                        + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags));
1636            }
1637
1638            if (!(mContext instanceof Activity)) {
1639                mStatusBarManager.disable(flags);
1640            }
1641        }
1642    }
1643
1644    /**
1645     * Handle message sent by {@link #resetStateLocked}
1646     * @see #RESET
1647     */
1648    private void handleReset() {
1649        synchronized (KeyguardViewMediator.this) {
1650            if (DEBUG) Log.d(TAG, "handleReset");
1651            mStatusBarKeyguardViewManager.reset();
1652        }
1653    }
1654
1655    /**
1656     * Handle message sent by {@link #verifyUnlock}
1657     * @see #VERIFY_UNLOCK
1658     */
1659    private void handleVerifyUnlock() {
1660        synchronized (KeyguardViewMediator.this) {
1661            if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
1662            setShowingLocked(true);
1663            mStatusBarKeyguardViewManager.verifyUnlock();
1664            updateActivityLockScreenState();
1665        }
1666    }
1667
1668    private void handleNotifyStartedGoingToSleep() {
1669        synchronized (KeyguardViewMediator.this) {
1670            if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep");
1671            mStatusBarKeyguardViewManager.onStartedGoingToSleep();
1672        }
1673    }
1674
1675    /**
1676     * Handle message sent by {@link #notifyFinishedGoingToSleep()}
1677     * @see #NOTIFY_FINISHED_GOING_TO_SLEEP
1678     */
1679    private void handleNotifyFinishedGoingToSleep() {
1680        synchronized (KeyguardViewMediator.this) {
1681            if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
1682            mStatusBarKeyguardViewManager.onFinishedGoingToSleep();
1683        }
1684    }
1685
1686    private void handleNotifyStartedWakingUp() {
1687        synchronized (KeyguardViewMediator.this) {
1688            if (DEBUG) Log.d(TAG, "handleNotifyWakingUp");
1689            mStatusBarKeyguardViewManager.onStartedWakingUp();
1690        }
1691    }
1692
1693    private void handleNotifyScreenTurningOn(IKeyguardDrawnCallback callback) {
1694        synchronized (KeyguardViewMediator.this) {
1695            if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
1696            mStatusBarKeyguardViewManager.onScreenTurningOn();
1697            if (callback != null) {
1698                if (mWakeAndUnlocking) {
1699                    mDrawnCallback = callback;
1700                } else {
1701                    notifyDrawn(callback);
1702                }
1703            }
1704        }
1705    }
1706
1707    private void handleNotifyScreenTurnedOn() {
1708        synchronized (this) {
1709            if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn");
1710            mStatusBarKeyguardViewManager.onScreenTurnedOn();
1711        }
1712    }
1713
1714    private void handleNotifyScreenTurnedOff() {
1715        synchronized (this) {
1716            if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
1717            mStatusBarKeyguardViewManager.onScreenTurnedOff();
1718            mWakeAndUnlocking = false;
1719        }
1720    }
1721
1722    private void notifyDrawn(final IKeyguardDrawnCallback callback) {
1723        try {
1724            callback.onDrawn();
1725        } catch (RemoteException e) {
1726            Slog.w(TAG, "Exception calling onDrawn():", e);
1727        }
1728    }
1729
1730    private void resetKeyguardDonePendingLocked() {
1731        mKeyguardDonePending = false;
1732        mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT);
1733    }
1734
1735    @Override
1736    public void onBootCompleted() {
1737        mUpdateMonitor.dispatchBootCompleted();
1738        synchronized (this) {
1739            mBootCompleted = true;
1740            if (mBootSendUserPresent) {
1741                sendUserPresentBroadcast();
1742            }
1743        }
1744    }
1745
1746    public void onWakeAndUnlocking() {
1747        mWakeAndUnlocking = true;
1748        keyguardDone(true /* authenticated */);
1749    }
1750
1751    public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
1752            ViewGroup container, StatusBarWindowManager statusBarWindowManager,
1753            ScrimController scrimController,
1754            FingerprintUnlockController fingerprintUnlockController) {
1755        mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container,
1756                statusBarWindowManager, scrimController, fingerprintUnlockController);
1757        return mStatusBarKeyguardViewManager;
1758    }
1759
1760    public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
1761        Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM,
1762                new StartKeyguardExitAnimParams(startTime, fadeoutDuration));
1763        mHandler.sendMessage(msg);
1764    }
1765
1766    public void onActivityDrawn() {
1767        mHandler.sendEmptyMessage(ON_ACTIVITY_DRAWN);
1768    }
1769
1770    public ViewMediatorCallback getViewMediatorCallback() {
1771        return mViewMediatorCallback;
1772    }
1773
1774    public LockPatternUtils getLockPatternUtils() {
1775        return mLockPatternUtils;
1776    }
1777
1778    @Override
1779    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1780        pw.print("  mSystemReady: "); pw.println(mSystemReady);
1781        pw.print("  mBootCompleted: "); pw.println(mBootCompleted);
1782        pw.print("  mBootSendUserPresent: "); pw.println(mBootSendUserPresent);
1783        pw.print("  mExternallyEnabled: "); pw.println(mExternallyEnabled);
1784        pw.print("  mNeedToReshowWhenReenabled: "); pw.println(mNeedToReshowWhenReenabled);
1785        pw.print("  mShowing: "); pw.println(mShowing);
1786        pw.print("  mInputRestricted: "); pw.println(mInputRestricted);
1787        pw.print("  mOccluded: "); pw.println(mOccluded);
1788        pw.print("  mDelayedShowingSequence: "); pw.println(mDelayedShowingSequence);
1789        pw.print("  mExitSecureCallback: "); pw.println(mExitSecureCallback);
1790        pw.print("  mDeviceInteractive: "); pw.println(mDeviceInteractive);
1791        pw.print("  mGoingToSleep: "); pw.println(mGoingToSleep);
1792        pw.print("  mHiding: "); pw.println(mHiding);
1793        pw.print("  mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible);
1794        pw.print("  mKeyguardDonePending: "); pw.println(mKeyguardDonePending);
1795        pw.print("  mHideAnimationRun: "); pw.println(mHideAnimationRun);
1796        pw.print("  mPendingReset: "); pw.println(mPendingReset);
1797        pw.print("  mPendingLock: "); pw.println(mPendingLock);
1798        pw.print("  mWakeAndUnlocking: "); pw.println(mWakeAndUnlocking);
1799        pw.print("  mDrawnCallback: "); pw.println(mDrawnCallback);
1800    }
1801
1802    private static class StartKeyguardExitAnimParams {
1803
1804        long startTime;
1805        long fadeoutDuration;
1806
1807        private StartKeyguardExitAnimParams(long startTime, long fadeoutDuration) {
1808            this.startTime = startTime;
1809            this.fadeoutDuration = fadeoutDuration;
1810        }
1811    }
1812
1813    private void setShowingLocked(boolean showing) {
1814        if (showing != mShowing) {
1815            mShowing = showing;
1816            int size = mKeyguardStateCallbacks.size();
1817            for (int i = size - 1; i >= 0; i--) {
1818                try {
1819                    mKeyguardStateCallbacks.get(i).onShowingStateChanged(showing);
1820                } catch (RemoteException e) {
1821                    Slog.w(TAG, "Failed to call onShowingStateChanged", e);
1822                    if (e instanceof DeadObjectException) {
1823                        mKeyguardStateCallbacks.remove(i);
1824                    }
1825                }
1826            }
1827            updateInputRestrictedLocked();
1828            mTrustManager.reportKeyguardShowingChanged();
1829        }
1830    }
1831
1832    public void addStateMonitorCallback(IKeyguardStateCallback callback) {
1833        synchronized (this) {
1834            mKeyguardStateCallbacks.add(callback);
1835            try {
1836                callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
1837                callback.onShowingStateChanged(mShowing);
1838                callback.onInputRestrictedStateChanged(mInputRestricted);
1839            } catch (RemoteException e) {
1840                Slog.w(TAG, "Failed to call onShowingStateChanged or onSimSecureStateChanged or onInputRestrictedStateChanged", e);
1841            }
1842        }
1843    }
1844}
1845