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