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