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