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