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