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 
17 package com.android.systemui.keyguard;
18 
19 import static android.app.StatusBarManager.SESSION_KEYGUARD;
20 import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
21 import static android.provider.Settings.System.LOCKSCREEN_SOUNDS_ENABLED;
22 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
23 import static android.view.RemoteAnimationTarget.MODE_OPENING;
24 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
25 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
26 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
27 
28 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN;
29 import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_OCCLUSION;
30 import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
31 import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_UNLOCK_ANIMATION;
32 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED;
33 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
34 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
35 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
36 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
37 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
38 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
39 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
40 import static com.android.systemui.DejankUtils.whitelistIpcs;
41 import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
42 import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
43 
44 import android.animation.Animator;
45 import android.animation.AnimatorListenerAdapter;
46 import android.animation.ValueAnimator;
47 import android.app.ActivityTaskManager;
48 import android.app.AlarmManager;
49 import android.app.BroadcastOptions;
50 import android.app.PendingIntent;
51 import android.app.StatusBarManager;
52 import android.app.WallpaperManager;
53 import android.app.WindowConfiguration;
54 import android.app.trust.TrustManager;
55 import android.content.BroadcastReceiver;
56 import android.content.ComponentName;
57 import android.content.ContentResolver;
58 import android.content.Context;
59 import android.content.Intent;
60 import android.content.IntentFilter;
61 import android.content.pm.PackageManager.NameNotFoundException;
62 import android.content.pm.UserInfo;
63 import android.graphics.Matrix;
64 import android.hardware.biometrics.BiometricSourceType;
65 import android.media.AudioAttributes;
66 import android.media.AudioManager;
67 import android.media.SoundPool;
68 import android.os.Binder;
69 import android.os.Bundle;
70 import android.os.DeadObjectException;
71 import android.os.Handler;
72 import android.os.IBinder;
73 import android.os.Looper;
74 import android.os.Message;
75 import android.os.PowerManager;
76 import android.os.RemoteException;
77 import android.os.ServiceManager;
78 import android.os.SystemProperties;
79 import android.os.Trace;
80 import android.os.UserHandle;
81 import android.os.UserManager;
82 import android.provider.DeviceConfig;
83 import android.provider.Settings;
84 import android.telephony.SubscriptionManager;
85 import android.telephony.TelephonyManager;
86 import android.util.Log;
87 import android.util.Slog;
88 import android.util.SparseBooleanArray;
89 import android.util.SparseIntArray;
90 import android.view.IRemoteAnimationFinishedCallback;
91 import android.view.IRemoteAnimationRunner;
92 import android.view.RemoteAnimationTarget;
93 import android.view.SurfaceControl.Transaction;
94 import android.view.SyncRtSurfaceTransactionApplier;
95 import android.view.View;
96 import android.view.ViewGroup;
97 import android.view.ViewRootImpl;
98 import android.view.WindowManager;
99 import android.view.WindowManagerPolicyConstants;
100 import android.view.animation.Animation;
101 import android.view.animation.AnimationUtils;
102 
103 import androidx.annotation.IntDef;
104 import androidx.annotation.NonNull;
105 import androidx.annotation.Nullable;
106 import androidx.annotation.VisibleForTesting;
107 
108 import com.android.app.animation.Interpolators;
109 import com.android.internal.jank.InteractionJankMonitor;
110 import com.android.internal.jank.InteractionJankMonitor.Configuration;
111 import com.android.internal.logging.UiEventLogger;
112 import com.android.internal.policy.IKeyguardDismissCallback;
113 import com.android.internal.policy.IKeyguardExitCallback;
114 import com.android.internal.policy.IKeyguardStateCallback;
115 import com.android.internal.policy.ScreenDecorationsUtils;
116 import com.android.internal.statusbar.IStatusBarService;
117 import com.android.internal.util.LatencyTracker;
118 import com.android.internal.widget.LockPatternUtils;
119 import com.android.keyguard.KeyguardConstants;
120 import com.android.keyguard.KeyguardDisplayManager;
121 import com.android.keyguard.KeyguardSecurityView;
122 import com.android.keyguard.KeyguardUpdateMonitor;
123 import com.android.keyguard.KeyguardUpdateMonitorCallback;
124 import com.android.keyguard.KeyguardViewController;
125 import com.android.keyguard.ViewMediatorCallback;
126 import com.android.keyguard.mediator.ScreenOnCoordinator;
127 import com.android.systemui.CoreStartable;
128 import com.android.systemui.DejankUtils;
129 import com.android.systemui.Dumpable;
130 import com.android.systemui.EventLogTags;
131 import com.android.systemui.R;
132 import com.android.systemui.animation.ActivityLaunchAnimator;
133 import com.android.systemui.animation.LaunchAnimator;
134 import com.android.systemui.broadcast.BroadcastDispatcher;
135 import com.android.systemui.classifier.FalsingCollector;
136 import com.android.systemui.dagger.qualifiers.Main;
137 import com.android.systemui.dagger.qualifiers.UiBackground;
138 import com.android.systemui.dreams.DreamOverlayStateController;
139 import com.android.systemui.dump.DumpManager;
140 import com.android.systemui.flags.FeatureFlags;
141 import com.android.systemui.flags.Flags;
142 import com.android.systemui.flags.SystemPropertiesHelper;
143 import com.android.systemui.keyguard.dagger.KeyguardModule;
144 import com.android.systemui.keyguard.shared.model.TransitionStep;
145 import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
146 import com.android.systemui.log.SessionTracker;
147 import com.android.systemui.navigationbar.NavigationModeController;
148 import com.android.systemui.plugins.statusbar.StatusBarStateController;
149 import com.android.systemui.settings.UserTracker;
150 import com.android.systemui.shade.ShadeController;
151 import com.android.systemui.shade.ShadeExpansionStateManager;
152 import com.android.systemui.shade.ShadeViewController;
153 import com.android.systemui.shared.system.QuickStepContract;
154 import com.android.systemui.statusbar.CommandQueue;
155 import com.android.systemui.statusbar.NotificationShadeDepthController;
156 import com.android.systemui.statusbar.NotificationShadeWindowController;
157 import com.android.systemui.statusbar.SysuiStatusBarStateController;
158 import com.android.systemui.statusbar.phone.BiometricUnlockController;
159 import com.android.systemui.statusbar.phone.CentralSurfaces;
160 import com.android.systemui.statusbar.phone.DozeParameters;
161 import com.android.systemui.statusbar.phone.KeyguardBypassController;
162 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
163 import com.android.systemui.statusbar.phone.ScrimController;
164 import com.android.systemui.statusbar.policy.KeyguardStateController;
165 import com.android.systemui.statusbar.policy.UserSwitcherController;
166 import com.android.systemui.util.DeviceConfigProxy;
167 import com.android.systemui.util.kotlin.JavaAdapter;
168 import com.android.systemui.util.settings.SecureSettings;
169 import com.android.systemui.util.settings.SystemSettings;
170 import com.android.systemui.util.time.SystemClock;
171 import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
172 import com.android.wm.shell.keyguard.KeyguardTransitions;
173 
174 import java.io.PrintWriter;
175 import java.lang.annotation.Retention;
176 import java.lang.annotation.RetentionPolicy;
177 import java.util.ArrayList;
178 import java.util.Arrays;
179 import java.util.Objects;
180 import java.util.concurrent.Executor;
181 import java.util.function.Consumer;
182 
183 import dagger.Lazy;
184 import kotlinx.coroutines.CoroutineDispatcher;
185 
186 /**
187  * Mediates requests related to the keyguard.  This includes queries about the
188  * state of the keyguard, power management events that effect whether the keyguard
189  * should be shown or reset, callbacks to the phone window manager to notify
190  * it of when the keyguard is showing, and events from the keyguard view itself
191  * stating that the keyguard was successfully unlocked.
192  *
193  * Note that the keyguard view is shown when the screen is off (as appropriate)
194  * so that once the screen comes on, it will be ready immediately.
195  *
196  * Example queries about the keyguard:
197  * - is {movement, key} one that should wake the keyguard?
198  * - is the keyguard showing?
199  * - are input events restricted due to the state of the keyguard?
200  *
201  * Callbacks to the phone window manager:
202  * - the keyguard is showing
203  *
204  * Example external events that translate to keyguard view changes:
205  * - screen turned off -> reset the keyguard, and show it, so it will be ready
206  *   next time the screen turns on
207  * - keyboard is slid open -> if the keyguard is not secure, hide it
208  *
209  * Events from the keyguard view:
210  * - user successfully unlocked keyguard -> hide keyguard view, and no longer
211  *   restrict input events.
212  *
213  * Note: in addition to normal power management events that effect the state of
214  * whether the keyguard should be showing, external apps and services may request
215  * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}.  When
216  * false, this will override all other conditions for turning on the keyguard.
217  *
218  * Threading and synchronization:
219  * This class is created by the initialization routine of the {@link WindowManagerPolicyConstants},
220  * and runs on its thread.  The keyguard UI is created from that thread in the
221  * constructor of this class.  The apis may be called from other threads, including the
222  * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
223  * Therefore, methods on this class are synchronized, and any action that is pointed
224  * directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI
225  * thread of the keyguard.
226  */
227 public class KeyguardViewMediator implements CoreStartable, Dumpable,
228         StatusBarStateController.StateListener {
229     private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
230     private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
231 
232     private static final boolean DEBUG = KeyguardConstants.DEBUG;
233     private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
234 
235     private final static String TAG = "KeyguardViewMediator";
236 
237     public static final String DELAYED_KEYGUARD_ACTION =
238         "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
239     private static final String DELAYED_LOCK_PROFILE_ACTION =
240             "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK";
241 
242     private static final String SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF";
243 
244     // used for handler messages
245     private static final int SHOW = 1;
246     private static final int HIDE = 2;
247     private static final int RESET = 3;
248     private static final int VERIFY_UNLOCK = 4;
249     private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 5;
250     private static final int KEYGUARD_DONE = 7;
251     private static final int KEYGUARD_DONE_DRAWING = 8;
252     private static final int SET_OCCLUDED = 9;
253     private static final int KEYGUARD_TIMEOUT = 10;
254     private static final int DISMISS = 11;
255     private static final int START_KEYGUARD_EXIT_ANIM = 12;
256     private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 13;
257     private static final int NOTIFY_STARTED_WAKING_UP = 14;
258     private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 17;
259     private static final int SYSTEM_READY = 18;
260     private static final int CANCEL_KEYGUARD_EXIT_ANIM = 19;
261 
262     /** Enum for reasons behind updating wakeAndUnlock state. */
263     @Retention(RetentionPolicy.SOURCE)
264     @IntDef(
265             value = {
266                     WakeAndUnlockUpdateReason.HIDE,
267                     WakeAndUnlockUpdateReason.SHOW,
268                     WakeAndUnlockUpdateReason.FULFILL,
269                     WakeAndUnlockUpdateReason.WAKE_AND_UNLOCK,
270             })
271     @interface WakeAndUnlockUpdateReason {
272         int HIDE = 0;
273         int SHOW = 1;
274         int FULFILL = 2;
275         int WAKE_AND_UNLOCK = 3;
276     }
277 
278     /**
279      * The default amount of time we stay awake (used for all key input)
280      */
281     public static final int AWAKE_INTERVAL_BOUNCER_MS = 10000;
282 
283     /**
284      * How long to wait after the screen turns off due to timeout before
285      * turning on the keyguard (i.e, the user has this much time to turn
286      * the screen back on without having to face the keyguard).
287      */
288     public static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
289 
290     /**
291      * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()}
292      * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)}
293      * that is re-enabling the keyguard.
294      */
295     private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
296 
297     private static final int UNOCCLUDE_ANIMATION_DURATION = 250;
298 
299     /**
300      * How far down to animate the unoccluding activity, in terms of percent of the activity's
301      * height.
302      */
303     private static final float UNOCCLUDE_TRANSLATE_DISTANCE_PERCENT = 0.1f;
304 
305     /**
306      * Boolean option for doKeyguardLocked/doKeyguardTimeout which, when set to true, forces the
307      * keyguard to show even if it is disabled for the current user.
308      */
309     public static final String OPTION_FORCE_SHOW = "force_show";
310     public static final String SYS_BOOT_REASON_PROP = "sys.boot.reason.last";
311     public static final String REBOOT_MAINLINE_UPDATE = "reboot,mainline_update";
312     private final DreamOverlayStateController mDreamOverlayStateController;
313     private final JavaAdapter mJavaAdapter;
314     private final WallpaperRepository mWallpaperRepository;
315 
316     /** The stream type that the lock sounds are tied to. */
317     private int mUiSoundsStreamType;
318 
319     private AlarmManager mAlarmManager;
320     private AudioManager mAudioManager;
321     private StatusBarManager mStatusBarManager;
322     private WallpaperManager mWallpaperManager;
323     private final IStatusBarService mStatusBarService;
324     private final IBinder mStatusBarDisableToken = new Binder();
325     private final UserTracker mUserTracker;
326     private final SysuiStatusBarStateController mStatusBarStateController;
327     private final Executor mUiBgExecutor;
328     private final ScreenOffAnimationController mScreenOffAnimationController;
329     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthController;
330     private final Lazy<ShadeController> mShadeController;
331 
332     private boolean mSystemReady;
333     private boolean mBootCompleted;
334     private boolean mBootSendUserPresent;
335     private boolean mShuttingDown;
336     private boolean mDozing;
337     private boolean mAnimatingScreenOff;
338     private final Context mContext;
339     private final FalsingCollector mFalsingCollector;
340 
341     /** High level access to the power manager for WakeLocks */
342     private final PowerManager mPM;
343 
344     /** TrustManager for letting it know when we change visibility */
345     private final TrustManager mTrustManager;
346 
347     /** UserSwitcherController for creating guest user on boot complete */
348     private final UserSwitcherController mUserSwitcherController;
349     private final SecureSettings mSecureSettings;
350     private final SystemSettings mSystemSettings;
351     private final SystemClock mSystemClock;
352     private SystemPropertiesHelper mSystemPropertiesHelper;
353 
354     /**
355      * Used to keep the device awake while to ensure the keyguard finishes opening before
356      * we sleep.
357      */
358     private PowerManager.WakeLock mShowKeyguardWakeLock;
359 
360     private final Lazy<KeyguardViewController> mKeyguardViewControllerLazy;
361 
362     // these are protected by synchronized (this)
363 
364     /**
365      * External apps (like the phone app) can tell us to disable the keyguard.
366      */
367     private boolean mExternallyEnabled = true;
368 
369     /**
370      * Remember if an external call to {@link #setKeyguardEnabled} with value
371      * false caused us to hide the keyguard, so that we need to reshow it once
372      * the keyguard is re-enabled with another call with value true.
373      */
374     private boolean mNeedToReshowWhenReenabled = false;
375 
376     // cached value of whether we are showing (need to know this to quickly
377     // answer whether the input should be restricted)
378     private boolean mShowing;
379 
380     // AOD is enabled and status bar is in AOD state.
381     private boolean mAodShowing;
382 
383     // Dream overlay is visible.
384     private boolean mDreamOverlayShowing;
385 
386     /** Cached value of #isInputRestricted */
387     private boolean mInputRestricted;
388 
389     // true if the keyguard is hidden by another window
390     private boolean mOccluded = false;
391 
392     /**
393      * Whether the {@link #mOccludeAnimationController} is currently playing the occlusion
394      * animation.
395      */
396     private boolean mOccludeAnimationPlaying = false;
397 
398     private boolean mWakeAndUnlocking = false;
399 
400     /**
401      * Helps remember whether the screen has turned on since the last time
402      * it turned off due to timeout. see {@link #onScreenTurnedOff(int)}
403      */
404     private int mDelayedShowingSequence;
405 
406     /**
407      * Similar to {@link #mDelayedProfileShowingSequence}, but it is for profile case.
408      */
409     private int mDelayedProfileShowingSequence;
410 
411     private final DismissCallbackRegistry mDismissCallbackRegistry;
412 
413     // the properties of the keyguard
414 
415     private final KeyguardUpdateMonitor mUpdateMonitor;
416     private final Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy;
417 
418     /**
419      * Last SIM state reported by the telephony system.
420      * Index is the slotId - in case of multiple SIM cards.
421      */
422     private final SparseIntArray mLastSimStates = new SparseIntArray();
423 
424     /**
425      * Indicates if a SIM card had the SIM PIN enabled during the initialization, before
426      * reaching the SIM_STATE_READY state. The flag is reset to false at SIM_STATE_READY.
427      * Index is the slotId - in case of multiple SIM cards.
428      */
429     private final SparseBooleanArray mSimWasLocked = new SparseBooleanArray();
430 
431     private boolean mDeviceInteractive;
432     private boolean mGoingToSleep;
433 
434     // last known state of the cellular connection
435     private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
436 
437     /**
438      * Whether a hide is pending and we are just waiting for #startKeyguardExitAnimation to be
439      * called.
440      * */
441     private boolean mHiding;
442 
443     /**
444      * we send this intent when the keyguard is dismissed.
445      */
446     private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT)
447             .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
448                     | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
449                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
450 
451     private static final Bundle USER_PRESENT_INTENT_OPTIONS =
452             BroadcastOptions.makeBasic()
453                     .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
454                     .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
455                     .toBundle();
456 
457     /**
458      * {@link #setKeyguardEnabled} waits on this condition when it re-enables
459      * the keyguard.
460      */
461     private boolean mWaitingUntilKeyguardVisible = false;
462     private final LockPatternUtils mLockPatternUtils;
463     private final BroadcastDispatcher mBroadcastDispatcher;
464     private boolean mKeyguardDonePending = false;
465     private boolean mUnlockingAndWakingFromDream = false;
466     private boolean mHideAnimationRun = false;
467     private boolean mHideAnimationRunning = false;
468 
469     private SoundPool mLockSounds;
470     private int mLockSoundId;
471     private int mUnlockSoundId;
472     private int mTrustedSoundId;
473     private int mLockSoundStreamId;
474     private final float mPowerButtonY;
475     private final float mWindowCornerRadius;
476 
477     /**
478      * The duration in milliseconds of the dream open animation.
479      */
480     private final int mDreamOpenAnimationDuration;
481 
482     /**
483      * Whether unlock and wake should be sequenced.
484      */
485     private final boolean mOrderUnlockAndWake;
486 
487     /**
488      * The animation used for hiding keyguard. This is used to fetch the animation timings if
489      * WindowManager is not providing us with them.
490      */
491     private Animation mHideAnimation;
492 
493     /**
494      * The volume applied to the lock/unlock sounds.
495      */
496     private float mLockSoundVolume;
497 
498     /**
499      * For managing external displays
500      */
501     private final KeyguardDisplayManager mKeyguardDisplayManager;
502 
503     private final ArrayList<IKeyguardStateCallback> mKeyguardStateCallbacks = new ArrayList<>();
504 
505     /**
506      * When starting going to sleep, we figured out that we need to reset Keyguard state and this
507      * should be committed when finished going to sleep.
508      */
509     private boolean mPendingReset;
510 
511     /**
512      * When starting going to sleep, we figured out that we need to lock Keyguard and this should be
513      * committed when finished going to sleep.
514      */
515     private boolean mPendingLock;
516 
517     /**
518      * When starting to go away, flag a need to show the PIN lock so the keyguard can be brought
519      * back.
520      */
521     private boolean mPendingPinLock = false;
522 
523     /**
524      * Whether a power button gesture (such as double tap for camera) has been detected. This is
525      * delivered directly from {@link KeyguardService}, immediately upon the gesture being detected.
526      * This is used in {@link #onStartedWakingUp} to decide whether to execute the pending lock, or
527      * ignore and reset it because we are actually launching an activity.
528      *
529      * This needs to be delivered directly to us, rather than waiting for
530      * {@link CommandQueue#onCameraLaunchGestureDetected}, because that call is asynchronous and is
531      * often delivered after the call to {@link #onStartedWakingUp}, which results in us locking the
532      * keyguard and then launching the activity behind it.
533      */
534     private boolean mPowerGestureIntercepted = false;
535 
536     /**
537      * Controller for showing individual "work challenge" lock screen windows inside managed profile
538      * tasks when the current user has been unlocked but the profile is still locked.
539      */
540     private WorkLockActivityController mWorkLockController;
541 
542     private boolean mLockLater;
543     private boolean mShowHomeOverLockscreen;
544     private boolean mInGestureNavigationMode;
545     private CharSequence mCustomMessage;
546 
547     /**
548      * Whether the RemoteAnimation on the app/launcher surface behind the keyguard is 'running'.
549      * Note that this does not necessarily mean the surface is currently in motion - we may be
550      * 'animating' it along with the user's finger during a swipe to unlock gesture, a gesture that
551      * can be paused or reversed.
552      */
553     private boolean mSurfaceBehindRemoteAnimationRunning;
554 
555     /**
556      * Whether we've asked to make the app/launcher surface behind the keyguard visible, via a call
557      * to {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}.
558      *
559      * Since that's an IPC, this doesn't necessarily mean the remote animation has started yet.
560      * {@link #mSurfaceBehindRemoteAnimationRunning} will be true if the call completed and the
561      * animation is now running.
562      */
563     private boolean mSurfaceBehindRemoteAnimationRequested = false;
564 
565     /**
566      * Callback to run to end the RemoteAnimation on the app/launcher surface behind the keyguard.
567      */
568     private IRemoteAnimationFinishedCallback mSurfaceBehindRemoteAnimationFinishedCallback;
569 
570     /**
571      * The animation runner to use for the next exit animation.
572      */
573     private IRemoteAnimationRunner mKeyguardExitAnimationRunner;
574 
575     private CentralSurfaces mCentralSurfaces;
576 
577     private IRemoteAnimationFinishedCallback mUnoccludeFromDreamFinishedCallback;
578 
579     private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
580             new DeviceConfig.OnPropertiesChangedListener() {
581             @Override
582             public void onPropertiesChanged(DeviceConfig.Properties properties) {
583                 if (properties.getKeyset().contains(NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN)) {
584                     mShowHomeOverLockscreen = properties.getBoolean(
585                             NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN, true /* defaultValue */);
586                 }
587             }
588     };
589 
590     private final DreamOverlayStateController.Callback mDreamOverlayStateCallback =
591             new DreamOverlayStateController.Callback() {
592                 @Override
593                 public void onStateChanged() {
594                     mDreamOverlayShowing = mDreamOverlayStateController.isOverlayActive();
595                 }
596             };
597 
598     KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
599 
600         @Override
601         public void onKeyguardVisibilityChanged(boolean visible) {
602             synchronized (KeyguardViewMediator.this) {
603                 if (!visible && mPendingPinLock) {
604                     Log.i(TAG, "PIN lock requested, starting keyguard");
605 
606                     // Bring the keyguard back in order to show the PIN lock
607                     mPendingPinLock = false;
608                     doKeyguardLocked(null);
609                 }
610             }
611         }
612 
613         @Override
614         public void onUserSwitching(int userId) {
615             if (DEBUG) Log.d(TAG, String.format("onUserSwitching %d", userId));
616             synchronized (KeyguardViewMediator.this) {
617                 resetKeyguardDonePendingLocked();
618                 dismiss(null /* callback */, null /* message */);
619                 adjustStatusBarLocked();
620             }
621         }
622 
623         @Override
624         public void onUserSwitchComplete(int userId) {
625             if (DEBUG) Log.d(TAG, String.format("onUserSwitchComplete %d", userId));
626             // We are calling dismiss again and with a delay as there are race conditions
627             // in some scenarios caused by async layout listeners
628             mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), 500);
629         }
630 
631         @Override
632         public void onDeviceProvisioned() {
633             sendUserPresentBroadcast();
634         }
635 
636         @Override
637         public void onSimStateChanged(int subId, int slotId, int simState) {
638 
639             if (DEBUG_SIM_STATES) {
640                 Log.d(TAG, "onSimStateChanged(subId=" + subId + ", slotId=" + slotId
641                         + ",state=" + simState + ")");
642             }
643 
644             int size = mKeyguardStateCallbacks.size();
645             boolean simPinSecure = mUpdateMonitor.isSimPinSecure();
646             for (int i = size - 1; i >= 0; i--) {
647                 try {
648                     mKeyguardStateCallbacks.get(i).onSimSecureStateChanged(simPinSecure);
649                 } catch (RemoteException e) {
650                     Slog.w(TAG, "Failed to call onSimSecureStateChanged", e);
651                     if (e instanceof DeadObjectException) {
652                         mKeyguardStateCallbacks.remove(i);
653                     }
654                 }
655             }
656 
657             boolean lastSimStateWasLocked;
658             synchronized (KeyguardViewMediator.this) {
659                 int lastState = mLastSimStates.get(slotId);
660                 lastSimStateWasLocked = (lastState == TelephonyManager.SIM_STATE_PIN_REQUIRED
661                         || lastState == TelephonyManager.SIM_STATE_PUK_REQUIRED);
662                 mLastSimStates.append(slotId, simState);
663             }
664 
665             switch (simState) {
666                 case TelephonyManager.SIM_STATE_NOT_READY:
667                 case TelephonyManager.SIM_STATE_ABSENT:
668                 case TelephonyManager.SIM_STATE_UNKNOWN:
669                     mPendingPinLock = false;
670                     // only force lock screen in case of missing sim if user hasn't
671                     // gone through setup wizard
672                     synchronized (KeyguardViewMediator.this) {
673                         if (shouldWaitForProvisioning()) {
674                             if (!mShowing) {
675                                 if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing,"
676                                         + " we need to show the keyguard since the "
677                                         + "device isn't provisioned yet.");
678                                 doKeyguardLocked(null);
679                             } else {
680                                 resetStateLocked();
681                             }
682                         }
683                         if (simState == TelephonyManager.SIM_STATE_ABSENT) {
684                             // MVNO SIMs can become transiently NOT_READY when switching networks,
685                             // so we should only lock when they are ABSENT.
686                             if (lastSimStateWasLocked) {
687                                 if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to ABSENT when the "
688                                         + "previous state was locked. Reset the state.");
689                                 resetStateLocked();
690                             }
691                             mSimWasLocked.append(slotId, false);
692                         }
693                     }
694                     break;
695                 case TelephonyManager.SIM_STATE_PIN_REQUIRED:
696                 case TelephonyManager.SIM_STATE_PUK_REQUIRED:
697                     synchronized (KeyguardViewMediator.this) {
698                         mSimWasLocked.append(slotId, true);
699                         mPendingPinLock = true;
700                         if (!mShowing) {
701                             if (DEBUG_SIM_STATES) Log.d(TAG,
702                                     "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
703                                     + "showing; need to show keyguard so user can enter sim pin");
704                             doKeyguardLocked(null);
705                         } else {
706                             resetStateLocked();
707                         }
708                     }
709                     break;
710                 case TelephonyManager.SIM_STATE_PERM_DISABLED:
711                     synchronized (KeyguardViewMediator.this) {
712                         if (!mShowing) {
713                             if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and "
714                                   + "keygaurd isn't showing.");
715                             doKeyguardLocked(null);
716                         } else {
717                             if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
718                                   + "show permanently disabled message in lockscreen.");
719                             resetStateLocked();
720                         }
721                     }
722                     break;
723                 case TelephonyManager.SIM_STATE_READY:
724                     synchronized (KeyguardViewMediator.this) {
725                         if (DEBUG_SIM_STATES) Log.d(TAG, "READY, reset state? " + mShowing);
726                         if (mShowing && mSimWasLocked.get(slotId, false)) {
727                             if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to READY when the "
728                                     + "previously was locked. Reset the state.");
729                             mSimWasLocked.append(slotId, false);
730                             resetStateLocked();
731                         }
732                     }
733                     break;
734                 default:
735                     if (DEBUG_SIM_STATES) Log.v(TAG, "Unspecific state: " + simState);
736                     break;
737             }
738         }
739 
740         @Override
741         public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
742             final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
743             if (mLockPatternUtils.isSecure(currentUser)) {
744                 mLockPatternUtils.getDevicePolicyManager().reportFailedBiometricAttempt(
745                         currentUser);
746             }
747         }
748 
749         @Override
750         public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
751                 boolean isStrongBiometric) {
752             if (mLockPatternUtils.isSecure(userId)) {
753                 mLockPatternUtils.getDevicePolicyManager().reportSuccessfulBiometricAttempt(
754                         userId);
755             }
756         }
757 
758         @Override
759         public void onTrustChanged(int userId) {
760             if (userId == KeyguardUpdateMonitor.getCurrentUser()) {
761                 synchronized (KeyguardViewMediator.this) {
762                     notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(userId));
763                 }
764             }
765         }
766 
767         @Override
768         public void onStrongAuthStateChanged(int userId) {
769             if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
770                 doKeyguardLocked(null);
771             }
772         }
773     };
774 
775     ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
776 
777         @Override
778         public void userActivity() {
779             KeyguardViewMediator.this.userActivity();
780         }
781 
782         @Override
783         public void keyguardDone(boolean primaryAuth, int targetUserId) {
784             if (targetUserId != KeyguardUpdateMonitor.getCurrentUser()) {
785                 return;
786             }
787             if (DEBUG) Log.d(TAG, "keyguardDone");
788             tryKeyguardDone();
789         }
790 
791         @Override
792         public void keyguardDoneDrawing() {
793             Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDoneDrawing");
794             mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING);
795             Trace.endSection();
796         }
797 
798         @Override
799         public void setNeedsInput(boolean needsInput) {
800             mKeyguardViewControllerLazy.get().setNeedsInput(needsInput);
801         }
802 
803         @Override
804         public void keyguardDonePending(boolean primaryAuth, int targetUserId) {
805             Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending");
806             if (DEBUG) Log.d(TAG, "keyguardDonePending");
807             if (targetUserId != KeyguardUpdateMonitor.getCurrentUser()) {
808                 Trace.endSection();
809                 return;
810             }
811 
812             mKeyguardDonePending = true;
813             mHideAnimationRun = true;
814             mHideAnimationRunning = true;
815             mKeyguardViewControllerLazy.get()
816                     .startPreHideAnimation(mHideAnimationFinishedRunnable);
817             mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
818                     KEYGUARD_DONE_PENDING_TIMEOUT_MS);
819             Trace.endSection();
820         }
821 
822         @Override
823         public void keyguardGone() {
824             Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardGone");
825             if (DEBUG) Log.d(TAG, "keyguardGone");
826             mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false);
827             mKeyguardDisplayManager.hide();
828             mUpdateMonitor.startBiometricWatchdog();
829 
830             // It's possible that the device was unlocked (via BOUNCER or Fingerprint) while
831             // dreaming. It's time to wake up.
832             if (mUnlockingAndWakingFromDream) {
833                 Log.d(TAG, "waking from dream after unlock");
834                 setUnlockAndWakeFromDream(false, WakeAndUnlockUpdateReason.FULFILL);
835 
836                 if (mKeyguardStateController.isShowing()) {
837                     Log.d(TAG, "keyguard showing after keyguardGone, dismiss");
838                     mKeyguardViewControllerLazy.get()
839                             .notifyKeyguardAuthenticated(!mWakeAndUnlocking);
840                 } else {
841                     Log.d(TAG, "keyguard gone, waking up from dream");
842                     mPM.wakeUp(mSystemClock.uptimeMillis(),
843                             mWakeAndUnlocking ? PowerManager.WAKE_REASON_BIOMETRIC
844                             : PowerManager.WAKE_REASON_GESTURE,
845                             "com.android.systemui:UNLOCK_DREAMING");
846                 }
847             }
848             Trace.endSection();
849         }
850 
851         @Override
852         public void readyForKeyguardDone() {
853             Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#readyForKeyguardDone");
854             if (mKeyguardDonePending) {
855                 mKeyguardDonePending = false;
856                 tryKeyguardDone();
857             }
858             Trace.endSection();
859         }
860 
861         @Override
862         public void resetKeyguard() {
863             resetStateLocked();
864         }
865 
866         @Override
867         public void onCancelClicked() {
868             mKeyguardViewControllerLazy.get().onCancelClicked();
869         }
870 
871         @Override
872         public void onBouncerSwipeDown() {
873             mKeyguardViewControllerLazy.get().reset(/* hideBouncerWhenShowing= */ true);
874         }
875 
876         @Override
877         public void playTrustedSound() {
878             KeyguardViewMediator.this.playTrustedSound();
879         }
880 
881         @Override
882         public boolean isScreenOn() {
883             return mDeviceInteractive;
884         }
885 
886         @Override
887         public int getBouncerPromptReason() {
888             int currentUser = KeyguardUpdateMonitor.getCurrentUser();
889             boolean trustAgentsEnabled = mUpdateMonitor.isTrustUsuallyManaged(currentUser);
890             boolean biometricsEnrolled =
891                     mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
892             boolean any = trustAgentsEnabled || biometricsEnrolled;
893             KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
894                     mUpdateMonitor.getStrongAuthTracker();
895             int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
896             boolean allowedNonStrongAfterIdleTimeout =
897                     strongAuthTracker.isNonStrongBiometricAllowedAfterIdleTimeout(currentUser);
898 
899             if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
900                 String reasonForReboot = mSystemPropertiesHelper.get(SYS_BOOT_REASON_PROP);
901                 if (Objects.equals(reasonForReboot, REBOOT_MAINLINE_UPDATE)) {
902                     return KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE;
903                 } else {
904                     return  KeyguardSecurityView.PROMPT_REASON_RESTART;
905                 }
906             } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
907                 return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
908             } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0) {
909                 return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
910             } else if ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
911                 return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
912             } else if (trustAgentsEnabled
913                     && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
914                 return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
915             } else if (trustAgentsEnabled
916                     && (strongAuth & SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED) != 0) {
917                 return KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
918             } else if (any && ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0
919                     || mUpdateMonitor.isFingerprintLockedOut())) {
920                 return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
921             } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE) != 0) {
922                 return KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
923             } else if (any && (strongAuth
924                     & STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT) != 0) {
925                 return KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT;
926             } else if (any && !allowedNonStrongAfterIdleTimeout) {
927                 return KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT;
928             }
929             return KeyguardSecurityView.PROMPT_REASON_NONE;
930         }
931 
932         @Override
933         public CharSequence consumeCustomMessage() {
934             final CharSequence message = mCustomMessage;
935             mCustomMessage = null;
936             return message;
937         }
938 
939         @Override
940         public void setCustomMessage(CharSequence customMessage) {
941             mCustomMessage = customMessage;
942         }
943     };
944 
945     /**
946      * Animation launch controller for activities that occlude the keyguard.
947      */
948     @VisibleForTesting
949     final ActivityLaunchAnimator.Controller mOccludeAnimationController =
950             new ActivityLaunchAnimator.Controller() {
951                 @Override
952                 public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
953                     mOccludeAnimationPlaying = true;
954                     mScrimControllerLazy.get().setOccludeAnimationPlaying(true);
955                 }
956 
957                 @Override
958                 public void onLaunchAnimationCancelled(@Nullable Boolean newKeyguardOccludedState) {
959                     Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: "
960                             + mOccluded);
961                     mOccludeAnimationPlaying = false;
962 
963                     // Ensure keyguard state is set correctly if we're cancelled.
964                     mCentralSurfaces.updateIsKeyguard();
965                     mScrimControllerLazy.get().setOccludeAnimationPlaying(false);
966                 }
967 
968                 @Override
969                 public void onLaunchAnimationEnd(boolean launchIsFullScreen) {
970                     if (launchIsFullScreen) {
971                         mShadeController.get().instantCollapseShade();
972                     }
973 
974                     mOccludeAnimationPlaying = false;
975 
976                     // Hide the keyguard now that we're done launching the occluding activity over
977                     // it.
978                     mCentralSurfaces.updateIsKeyguard();
979                     mScrimControllerLazy.get().setOccludeAnimationPlaying(false);
980 
981                     mInteractionJankMonitor.end(CUJ_LOCKSCREEN_OCCLUSION);
982                 }
983 
984                 @NonNull
985                 @Override
986                 public ViewGroup getLaunchContainer() {
987                     return ((ViewGroup) mKeyguardViewControllerLazy.get()
988                             .getViewRootImpl().getView());
989                 }
990 
991                 @Override
992                 public void setLaunchContainer(@NonNull ViewGroup launchContainer) {
993                     // No-op, launch container is always the shade.
994                     Log.wtf(TAG, "Someone tried to change the launch container for the "
995                             + "ActivityLaunchAnimator, which should never happen.");
996                 }
997 
998                 @NonNull
999                 @Override
1000                 public LaunchAnimator.State createAnimatorState() {
1001                     final int fullWidth = getLaunchContainer().getWidth();
1002                     final int fullHeight = getLaunchContainer().getHeight();
1003 
1004                     if (mUpdateMonitor.isSecureCameraLaunchedOverKeyguard()) {
1005                         final float initialHeight = fullHeight / 3f;
1006                         final float initialWidth = fullWidth / 3f;
1007 
1008                         // Start the animation near the power button, at one-third size, since the
1009                         // camera was launched from the power button.
1010                         return new LaunchAnimator.State(
1011                                 (int) (mPowerButtonY - initialHeight / 2f) /* top */,
1012                                 (int) (mPowerButtonY + initialHeight / 2f) /* bottom */,
1013                                 (int) (fullWidth - initialWidth) /* left */,
1014                                 fullWidth /* right */,
1015                                 mWindowCornerRadius, mWindowCornerRadius);
1016                     } else {
1017                         final float initialHeight = fullHeight / 2f;
1018                         final float initialWidth = fullWidth / 2f;
1019 
1020                         // Start the animation in the center of the screen, scaled down to half
1021                         // size.
1022                         return new LaunchAnimator.State(
1023                                 (int) (fullHeight - initialHeight) / 2,
1024                                 (int) (initialHeight + (fullHeight - initialHeight) / 2),
1025                                 (int) (fullWidth - initialWidth) / 2,
1026                                 (int) (initialWidth + (fullWidth - initialWidth) / 2),
1027                                 mWindowCornerRadius, mWindowCornerRadius);
1028                     }
1029                 }
1030             };
1031 
1032     private final IRemoteAnimationRunner.Stub mExitAnimationRunner =
1033             new IRemoteAnimationRunner.Stub() {
1034         @Override // Binder interface
1035         public void onAnimationStart(@WindowManager.TransitionOldType int transit,
1036                 RemoteAnimationTarget[] apps,
1037                 RemoteAnimationTarget[] wallpapers,
1038                 RemoteAnimationTarget[] nonApps,
1039                 IRemoteAnimationFinishedCallback finishedCallback) {
1040             Trace.beginSection("mExitAnimationRunner.onAnimationStart#startKeyguardExitAnimation");
1041             startKeyguardExitAnimation(transit, apps, wallpapers, nonApps, finishedCallback);
1042             if (mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
1043                 mWmLockscreenVisibilityManager.get().onKeyguardGoingAwayRemoteAnimationStart(
1044                         transit, apps, wallpapers, nonApps, finishedCallback);
1045             }
1046             Trace.endSection();
1047         }
1048 
1049         @Override // Binder interface
1050         public void onAnimationCancelled() {
1051             cancelKeyguardExitAnimation();
1052             if (mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
1053                 mWmLockscreenVisibilityManager.get().onKeyguardGoingAwayRemoteAnimationCancelled();
1054             }
1055         }
1056     };
1057 
1058     private final IRemoteAnimationRunner mOccludeAnimationRunner =
1059             new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
1060 
1061     private final IRemoteAnimationRunner mOccludeByDreamAnimationRunner =
1062             new IRemoteAnimationRunner.Stub() {
1063                 @Nullable private ValueAnimator mOccludeByDreamAnimator;
1064 
1065                 @Override
1066                 public void onAnimationCancelled() {
1067                     mContext.getMainExecutor().execute(() -> {
1068                         if (mOccludeByDreamAnimator != null) {
1069                             mOccludeByDreamAnimator.cancel();
1070                         }
1071                     });
1072 
1073                     Log.d(TAG, "OccludeByDreamAnimator#onAnimationCancelled. Set occluded = true");
1074                     setOccluded(true /* isOccluded */, false /* animate */);
1075                 }
1076 
1077                 @Override
1078                 public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
1079                         RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
1080                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
1081                     if (!handleOnAnimationStart(
1082                                 transit, apps, wallpapers, nonApps, finishedCallback)) {
1083                         // Usually we rely on animation completion to synchronize occluded status,
1084                         // but there was no animation to play, so just update it now.
1085                         setOccluded(true /* isOccluded */, false /* animate */);
1086                         finishedCallback.onAnimationFinished();
1087                     }
1088                 }
1089 
1090                 private boolean handleOnAnimationStart(int transit, RemoteAnimationTarget[] apps,
1091                         RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
1092                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
1093                     if (apps == null || apps.length == 0 || apps[0] == null) {
1094                         Log.d(TAG, "No apps provided to the OccludeByDream runner; "
1095                                 + "skipping occluding animation.");
1096                         return false;
1097                     }
1098 
1099                     final RemoteAnimationTarget primary = apps[0];
1100                     final boolean isDream = (apps[0].taskInfo != null
1101                             && apps[0].taskInfo.topActivityType
1102                             == WindowConfiguration.ACTIVITY_TYPE_DREAM);
1103                     if (!isDream) {
1104                         Log.w(TAG, "The occluding app isn't Dream; "
1105                                 + "finishing up. Please check that the config is correct.");
1106                         return false;
1107                     }
1108 
1109                     final SyncRtSurfaceTransactionApplier applier =
1110                             new SyncRtSurfaceTransactionApplier(
1111                                     mKeyguardViewControllerLazy.get().getViewRootImpl().getView());
1112 
1113                     mContext.getMainExecutor().execute(() -> {
1114                         if (mOccludeByDreamAnimator != null) {
1115                             mOccludeByDreamAnimator.cancel();
1116                         }
1117 
1118                         mOccludeByDreamAnimator = ValueAnimator.ofFloat(0f, 1f);
1119                         mOccludeByDreamAnimator.setDuration(mDreamOpenAnimationDuration);
1120                         //mOccludeByDreamAnimator.setInterpolator(Interpolators.LINEAR);
1121                         mOccludeByDreamAnimator.addUpdateListener(
1122                                 animation -> {
1123                                     SyncRtSurfaceTransactionApplier.SurfaceParams.Builder
1124                                             paramsBuilder =
1125                                             new SyncRtSurfaceTransactionApplier.SurfaceParams
1126                                                     .Builder(primary.leash)
1127                                                     .withAlpha(animation.getAnimatedFraction());
1128                                     applier.scheduleApply(paramsBuilder.build());
1129                                 });
1130                         mOccludeByDreamAnimator.addListener(new AnimatorListenerAdapter() {
1131                             private boolean mIsCancelled = false;
1132                             @Override
1133                             public void onAnimationCancel(Animator animation) {
1134                                 mIsCancelled = true;
1135                             }
1136 
1137                             @Override
1138                             public void onAnimationEnd(Animator animation) {
1139                                 try {
1140                                     if (!mIsCancelled) {
1141                                         // We're already on the main thread, don't queue this call
1142                                         handleSetOccluded(true /* isOccluded */,
1143                                                 false /* animate */);
1144                                     }
1145                                     finishedCallback.onAnimationFinished();
1146                                     mOccludeByDreamAnimator = null;
1147                                 } catch (RemoteException e) {
1148                                     e.printStackTrace();
1149                                 }
1150                             }
1151                         });
1152 
1153                         mOccludeByDreamAnimator.start();
1154                     });
1155                     return true;
1156                 }
1157             };
1158 
1159     /**
1160      * Animation controller for activities that unocclude the keyguard. This does not use the
1161      * ActivityLaunchAnimator since we're just translating down, rather than emerging from a view
1162      * or the power button.
1163      */
1164     private final IRemoteAnimationRunner mUnoccludeAnimationRunner =
1165             new IRemoteAnimationRunner.Stub() {
1166 
1167                 @Nullable private ValueAnimator mUnoccludeAnimator;
1168                 private final Matrix mUnoccludeMatrix = new Matrix();
1169 
1170                 @Override
1171                 public void onAnimationCancelled() {
1172                     mContext.getMainExecutor().execute(() -> {
1173                         if (mUnoccludeAnimator != null) {
1174                             mUnoccludeAnimator.cancel();
1175                         }
1176                     });
1177 
1178                     Log.d(TAG, "Unocclude animation cancelled.");
1179                     mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_OCCLUSION);
1180                 }
1181 
1182                 @Override
1183                 public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
1184                         RemoteAnimationTarget[] wallpapers,
1185                         RemoteAnimationTarget[] nonApps,
1186                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
1187                     Log.d(TAG, "UnoccludeAnimator#onAnimationStart. Set occluded = false.");
1188                     mInteractionJankMonitor.begin(
1189                             createInteractionJankMonitorConf(CUJ_LOCKSCREEN_OCCLUSION)
1190                                     .setTag("UNOCCLUDE"));
1191                     setOccluded(false /* isOccluded */, true /* animate */);
1192 
1193                     if (apps == null || apps.length == 0 || apps[0] == null) {
1194                         Log.d(TAG, "No apps provided to unocclude runner; "
1195                                 + "skipping animation and unoccluding.");
1196                         finishedCallback.onAnimationFinished();
1197                         return;
1198                     }
1199 
1200                     mRemoteAnimationTarget = apps[0];
1201                     final boolean isDream = (apps[0].taskInfo != null
1202                             && apps[0].taskInfo.topActivityType
1203                             == WindowConfiguration.ACTIVITY_TYPE_DREAM);
1204 
1205 
1206                     final View localView = mKeyguardViewControllerLazy.get()
1207                             .getViewRootImpl().getView();
1208                     final SyncRtSurfaceTransactionApplier applier =
1209                             new SyncRtSurfaceTransactionApplier(localView);
1210 
1211                     mContext.getMainExecutor().execute(() -> {
1212                         if (mUnoccludeAnimator != null) {
1213                             mUnoccludeAnimator.cancel();
1214                         }
1215 
1216                         if (isDream) {
1217                             initAlphaForAnimationTargets(wallpapers);
1218                             getRemoteSurfaceAlphaApplier().accept(0.0f);
1219                             mDreamingToLockscreenTransitionViewModel.get()
1220                                     .startTransition();
1221                             mUnoccludeFromDreamFinishedCallback = finishedCallback;
1222                             return;
1223                         }
1224 
1225                         mUnoccludeAnimator = ValueAnimator.ofFloat(1f, 0f);
1226                         mUnoccludeAnimator.setDuration(UNOCCLUDE_ANIMATION_DURATION);
1227                         mUnoccludeAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE);
1228                         mUnoccludeAnimator.addUpdateListener(
1229                                 animation -> {
1230                                     final float animatedValue =
1231                                             (float) animation.getAnimatedValue();
1232 
1233                                     final float surfaceHeight =
1234                                             mRemoteAnimationTarget.screenSpaceBounds.height();
1235 
1236                                     // Fade for all types of activities.
1237                                     SyncRtSurfaceTransactionApplier.SurfaceParams.Builder
1238                                             paramsBuilder =
1239                                             new SyncRtSurfaceTransactionApplier.SurfaceParams
1240                                                     .Builder(mRemoteAnimationTarget.leash)
1241                                                     .withAlpha(animatedValue);
1242 
1243                                     mUnoccludeMatrix.setTranslate(
1244                                             0f,
1245                                             (1f - animatedValue)
1246                                                     * surfaceHeight
1247                                                     * UNOCCLUDE_TRANSLATE_DISTANCE_PERCENT);
1248 
1249                                     paramsBuilder.withMatrix(mUnoccludeMatrix).withCornerRadius(
1250                                             mWindowCornerRadius);
1251 
1252                                     applier.scheduleApply(paramsBuilder.build());
1253                                 });
1254                         mUnoccludeAnimator.addListener(new AnimatorListenerAdapter() {
1255                             @Override
1256                             public void onAnimationEnd(Animator animation) {
1257                                 try {
1258                                     finishedCallback.onAnimationFinished();
1259                                     mUnoccludeAnimator = null;
1260 
1261                                     mInteractionJankMonitor.end(CUJ_LOCKSCREEN_OCCLUSION);
1262                                 } catch (RemoteException e) {
1263                                     e.printStackTrace();
1264                                 }
1265                             }
1266                         });
1267 
1268                         mUnoccludeAnimator.start();
1269                     });
1270                 }
1271             };
1272 
initAlphaForAnimationTargets( @ndroid.annotation.NonNull RemoteAnimationTarget[] targets )1273     private static void initAlphaForAnimationTargets(
1274             @android.annotation.NonNull RemoteAnimationTarget[] targets
1275     ) {
1276         for (RemoteAnimationTarget target : targets) {
1277             if (target.mode != MODE_OPENING) continue;
1278 
1279             try (Transaction t = new Transaction()) {
1280                 t.setAlpha(target.leash, 1.f);
1281                 t.apply();
1282             }
1283         }
1284     }
1285 
getRemoteSurfaceAlphaApplier()1286     private Consumer<Float> getRemoteSurfaceAlphaApplier() {
1287         return (Float alpha) -> {
1288             if (mRemoteAnimationTarget == null) return;
1289             final View localView = mKeyguardViewControllerLazy.get().getViewRootImpl().getView();
1290             final SyncRtSurfaceTransactionApplier applier =
1291                     new SyncRtSurfaceTransactionApplier(localView);
1292             SyncRtSurfaceTransactionApplier.SurfaceParams
1293                     params =
1294                     new SyncRtSurfaceTransactionApplier.SurfaceParams
1295                             .Builder(mRemoteAnimationTarget.leash)
1296                             .withAlpha(alpha).build();
1297             applier.scheduleApply(params);
1298         };
1299     }
1300 
getFinishedCallbackConsumer()1301     private Consumer<TransitionStep> getFinishedCallbackConsumer() {
1302         return (TransitionStep step) -> {
1303             if (mUnoccludeFromDreamFinishedCallback == null) return;
1304             try {
1305                 mUnoccludeFromDreamFinishedCallback.onAnimationFinished();
1306                 mUnoccludeFromDreamFinishedCallback = null;
1307             } catch (RemoteException e) {
1308                 Log.e(TAG, "Wasn't able to callback", e);
1309             }
1310             mInteractionJankMonitor.end(CUJ_LOCKSCREEN_OCCLUSION);
1311         };
1312     }
1313 
1314     private DeviceConfigProxy mDeviceConfig;
1315     private DozeParameters mDozeParameters;
1316 
1317     private final KeyguardStateController mKeyguardStateController;
1318     private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
1319             new KeyguardStateController.Callback() {
1320         @Override
1321         public void onPrimaryBouncerShowingChanged() {
1322             synchronized (KeyguardViewMediator.this) {
1323                 if (mKeyguardStateController.isPrimaryBouncerShowing()
1324                         && !mKeyguardStateController.isKeyguardGoingAway()) {
1325                     mPendingPinLock = false;
1326                 }
1327                 adjustStatusBarLocked(mKeyguardStateController.isPrimaryBouncerShowing(), false);
1328             }
1329         }
1330     };
1331 
1332     private final Lazy<KeyguardUnlockAnimationController> mKeyguardUnlockAnimationControllerLazy;
1333     private final InteractionJankMonitor mInteractionJankMonitor;
1334     private boolean mWallpaperSupportsAmbientMode;
1335     private ScreenOnCoordinator mScreenOnCoordinator;
1336     private final KeyguardTransitions mKeyguardTransitions;
1337 
1338     private Lazy<ActivityLaunchAnimator> mActivityLaunchAnimator;
1339     private Lazy<ScrimController> mScrimControllerLazy;
1340 
1341     private FeatureFlags mFeatureFlags;
1342     private final UiEventLogger mUiEventLogger;
1343     private final SessionTracker mSessionTracker;
1344     private final CoroutineDispatcher mMainDispatcher;
1345     private final Lazy<DreamingToLockscreenTransitionViewModel>
1346             mDreamingToLockscreenTransitionViewModel;
1347     private RemoteAnimationTarget mRemoteAnimationTarget;
1348 
1349     private Lazy<WindowManagerLockscreenVisibilityManager> mWmLockscreenVisibilityManager;
1350 
1351     /**
1352      * Injected constructor. See {@link KeyguardModule}.
1353      */
1354     public KeyguardViewMediator(
1355             Context context,
1356             UiEventLogger uiEventLogger,
1357             SessionTracker sessionTracker,
1358             UserTracker userTracker,
1359             FalsingCollector falsingCollector,
1360             LockPatternUtils lockPatternUtils,
1361             BroadcastDispatcher broadcastDispatcher,
1362             Lazy<KeyguardViewController> statusBarKeyguardViewManagerLazy,
1363             DismissCallbackRegistry dismissCallbackRegistry,
1364             KeyguardUpdateMonitor keyguardUpdateMonitor, DumpManager dumpManager,
1365             @UiBackground Executor uiBgExecutor, PowerManager powerManager,
1366             TrustManager trustManager,
1367             UserSwitcherController userSwitcherController,
1368             DeviceConfigProxy deviceConfig,
1369             NavigationModeController navigationModeController,
1370             KeyguardDisplayManager keyguardDisplayManager,
1371             DozeParameters dozeParameters,
1372             SysuiStatusBarStateController statusBarStateController,
1373             KeyguardStateController keyguardStateController,
1374             Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy,
1375             ScreenOffAnimationController screenOffAnimationController,
1376             Lazy<NotificationShadeDepthController> notificationShadeDepthController,
1377             ScreenOnCoordinator screenOnCoordinator,
1378             KeyguardTransitions keyguardTransitions,
1379             InteractionJankMonitor interactionJankMonitor,
1380             DreamOverlayStateController dreamOverlayStateController,
1381             JavaAdapter javaAdapter,
1382             WallpaperRepository wallpaperRepository,
1383             Lazy<ShadeController> shadeControllerLazy,
1384             Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
1385             Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
1386             Lazy<ScrimController> scrimControllerLazy,
1387             FeatureFlags featureFlags,
1388             SecureSettings secureSettings,
1389             SystemSettings systemSettings,
1390             SystemClock systemClock,
1391             @Main CoroutineDispatcher mainDispatcher,
1392             Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel,
1393             SystemPropertiesHelper systemPropertiesHelper,
1394             Lazy<WindowManagerLockscreenVisibilityManager> wmLockscreenVisibilityManager) {
1395         mContext = context;
1396         mUserTracker = userTracker;
1397         mFalsingCollector = falsingCollector;
1398         mLockPatternUtils = lockPatternUtils;
1399         mBroadcastDispatcher = broadcastDispatcher;
1400         mKeyguardViewControllerLazy = statusBarKeyguardViewManagerLazy;
1401         mDismissCallbackRegistry = dismissCallbackRegistry;
1402         mNotificationShadeDepthController = notificationShadeDepthController;
1403         mUiBgExecutor = uiBgExecutor;
1404         mUpdateMonitor = keyguardUpdateMonitor;
1405         mPM = powerManager;
1406         mTrustManager = trustManager;
1407         mUserSwitcherController = userSwitcherController;
1408         mSecureSettings = secureSettings;
1409         mSystemSettings = systemSettings;
1410         mSystemClock = systemClock;
1411         mSystemPropertiesHelper = systemPropertiesHelper;
1412         mStatusBarService = IStatusBarService.Stub.asInterface(
1413                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
1414         mKeyguardDisplayManager = keyguardDisplayManager;
1415         mShadeController = shadeControllerLazy;
1416         dumpManager.registerDumpable(getClass().getName(), this);
1417         mDeviceConfig = deviceConfig;
1418         mScreenOnCoordinator = screenOnCoordinator;
1419         mKeyguardTransitions = keyguardTransitions;
1420         mNotificationShadeWindowControllerLazy = notificationShadeWindowControllerLazy;
1421         mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
1422                 DeviceConfig.NAMESPACE_SYSTEMUI,
1423                 NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN,
1424                 /* defaultValue = */ true);
1425         mDeviceConfig.addOnPropertiesChangedListener(
1426                 DeviceConfig.NAMESPACE_SYSTEMUI,
1427                 mHandler::post,
1428                 mOnPropertiesChangedListener);
1429         mInGestureNavigationMode =
1430                 QuickStepContract.isGesturalMode(navigationModeController.addListener(mode -> {
1431                     mInGestureNavigationMode = QuickStepContract.isGesturalMode(mode);
1432                 }));
1433         mDozeParameters = dozeParameters;
1434 
1435         mStatusBarStateController = statusBarStateController;
1436         statusBarStateController.addCallback(this);
1437 
1438         mKeyguardStateController = keyguardStateController;
1439         keyguardStateController.addCallback(mKeyguardStateControllerCallback);
1440         mKeyguardUnlockAnimationControllerLazy = keyguardUnlockAnimationControllerLazy;
1441         mScreenOffAnimationController = screenOffAnimationController;
1442         mInteractionJankMonitor = interactionJankMonitor;
1443         mDreamOverlayStateController = dreamOverlayStateController;
1444         mJavaAdapter = javaAdapter;
1445         mWallpaperRepository = wallpaperRepository;
1446 
1447         mActivityLaunchAnimator = activityLaunchAnimator;
1448         mScrimControllerLazy = scrimControllerLazy;
1449 
1450         mPowerButtonY = context.getResources().getDimensionPixelSize(
1451                 R.dimen.physical_power_button_center_screen_location_y);
1452         mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
1453 
1454         mDreamOpenAnimationDuration = (int) DREAMING_ANIMATION_DURATION_MS;
1455 
1456         mFeatureFlags = featureFlags;
1457         mUiEventLogger = uiEventLogger;
1458         mSessionTracker = sessionTracker;
1459 
1460         mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
1461         mWmLockscreenVisibilityManager = wmLockscreenVisibilityManager;
1462         mMainDispatcher = mainDispatcher;
1463 
1464         mOrderUnlockAndWake = context.getResources().getBoolean(
1465                 com.android.internal.R.bool.config_orderUnlockAndWake);
1466     }
1467 
1468     public void userActivity() {
1469         mPM.userActivity(mSystemClock.uptimeMillis(), false);
1470     }
1471 
1472     private void setupLocked() {
1473         mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
1474         mShowKeyguardWakeLock.setReferenceCounted(false);
1475 
1476         IntentFilter filter = new IntentFilter();
1477         filter.addAction(Intent.ACTION_SHUTDOWN);
1478         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
1479 
1480         final IntentFilter delayedActionFilter = new IntentFilter();
1481         delayedActionFilter.addAction(DELAYED_KEYGUARD_ACTION);
1482         delayedActionFilter.addAction(DELAYED_LOCK_PROFILE_ACTION);
1483         delayedActionFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1484         mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
1485                 SYSTEMUI_PERMISSION, null /* scheduler */,
1486                 Context.RECEIVER_EXPORTED_UNAUDITED);
1487 
1488         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
1489 
1490         KeyguardUpdateMonitor.setCurrentUser(mUserTracker.getUserId());
1491 
1492         // Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard
1493         // is disabled.
1494         if (isKeyguardServiceEnabled()) {
1495             setShowingLocked(!shouldWaitForProvisioning()
1496                     && !mLockPatternUtils.isLockScreenDisabled(
1497                             KeyguardUpdateMonitor.getCurrentUser()), true /* forceCallbacks */);
1498         } else {
1499             // The system's keyguard is disabled or missing.
1500             setShowingLocked(false /* showing */, true /* forceCallbacks */);
1501         }
1502 
1503         boolean isLLwpEnabled = getWallpaperManager().isLockscreenLiveWallpaperEnabled();
1504         mKeyguardTransitions.register(
1505                 KeyguardService.wrap(this, getExitAnimationRunner(), isLLwpEnabled),
1506                 KeyguardService.wrap(this, getOccludeAnimationRunner(), isLLwpEnabled),
1507                 KeyguardService.wrap(this, getOccludeByDreamAnimationRunner(), isLLwpEnabled),
1508                 KeyguardService.wrap(this, getUnoccludeAnimationRunner(), isLLwpEnabled));
1509 
1510         final ContentResolver cr = mContext.getContentResolver();
1511 
1512         mDeviceInteractive = mPM.isInteractive();
1513 
1514         mLockSounds = new SoundPool.Builder()
1515                 .setMaxStreams(1)
1516                 .setAudioAttributes(
1517                         new AudioAttributes.Builder()
1518                                 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
1519                                 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
1520                                 .build())
1521                 .build();
1522         String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
1523         if (soundPath != null) {
1524             mLockSoundId = mLockSounds.load(soundPath, 1);
1525         }
1526         if (soundPath == null || mLockSoundId == 0) {
1527             Log.w(TAG, "failed to load lock sound from " + soundPath);
1528         }
1529         soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
1530         if (soundPath != null) {
1531             mUnlockSoundId = mLockSounds.load(soundPath, 1);
1532         }
1533         if (soundPath == null || mUnlockSoundId == 0) {
1534             Log.w(TAG, "failed to load unlock sound from " + soundPath);
1535         }
1536         soundPath = Settings.Global.getString(cr, Settings.Global.TRUSTED_SOUND);
1537         if (soundPath != null) {
1538             mTrustedSoundId = mLockSounds.load(soundPath, 1);
1539         }
1540         if (soundPath == null || mTrustedSoundId == 0) {
1541             Log.w(TAG, "failed to load trusted sound from " + soundPath);
1542         }
1543 
1544         int lockSoundDefaultAttenuation = mContext.getResources().getInteger(
1545                 com.android.internal.R.integer.config_lockSoundVolumeDb);
1546         mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20);
1547 
1548         mHideAnimation = AnimationUtils.loadAnimation(mContext,
1549                 com.android.internal.R.anim.lock_screen_behind_enter);
1550 
1551         mWorkLockController = new WorkLockActivityController(mContext, mUserTracker);
1552 
1553         mJavaAdapter.alwaysCollectFlow(
1554                 mWallpaperRepository.getWallpaperSupportsAmbientMode(),
1555                 this::setWallpaperSupportsAmbientMode);
1556     }
1557 
1558     // TODO(b/273443374) remove, temporary util to get a feature flag
1559     private WallpaperManager getWallpaperManager() {
1560         if (mWallpaperManager == null) {
1561             mWallpaperManager = mContext.getSystemService(WallpaperManager.class);
1562         }
1563         return mWallpaperManager;
1564     }
1565 
1566     @Override
1567     public void start() {
1568         synchronized (this) {
1569             setupLocked();
1570         }
1571     }
1572 
1573     /**
1574      * Let us know that the system is ready after startup.
1575      */
1576     public void onSystemReady() {
1577         mHandler.obtainMessage(SYSTEM_READY).sendToTarget();
1578     }
1579 
1580     private void handleSystemReady() {
1581         synchronized (this) {
1582             if (DEBUG) Log.d(TAG, "onSystemReady");
1583             mSystemReady = true;
1584             doKeyguardLocked(null);
1585             mUpdateMonitor.registerCallback(mUpdateCallback);
1586             adjustStatusBarLocked();
1587             mDreamOverlayStateController.addCallback(mDreamOverlayStateCallback);
1588 
1589             ViewRootImpl viewRootImpl = mKeyguardViewControllerLazy.get().getViewRootImpl();
1590             if (viewRootImpl != null) {
1591                 collectFlow(viewRootImpl.getView(),
1592                         mDreamingToLockscreenTransitionViewModel.get().getDreamOverlayAlpha(),
1593                         getRemoteSurfaceAlphaApplier(), mMainDispatcher);
1594                 collectFlow(viewRootImpl.getView(),
1595                         mDreamingToLockscreenTransitionViewModel.get().getTransitionEnded(),
1596                         getFinishedCallbackConsumer(), mMainDispatcher);
1597             }
1598         }
1599         // Most services aren't available until the system reaches the ready state, so we
1600         // send it here when the device first boots.
1601         maybeSendUserPresentBroadcast();
1602     }
1603 
1604     /**
1605      * Called to let us know the screen was turned off.
1606      * @param offReason either {@link WindowManagerPolicyConstants#OFF_BECAUSE_OF_USER} or
1607      * {@link WindowManagerPolicyConstants#OFF_BECAUSE_OF_TIMEOUT}.
1608      */
1609     public void onStartedGoingToSleep(@WindowManagerPolicyConstants.OffReason int offReason) {
1610         if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + offReason + ")");
1611         synchronized (this) {
1612             mDeviceInteractive = false;
1613             mPowerGestureIntercepted = false;
1614             mGoingToSleep = true;
1615 
1616             // Lock immediately based on setting if secure (user has a pin/pattern/password).
1617             // This also "locks" the device when not secure to provide easy access to the
1618             // camera while preventing unwanted input.
1619             int currentUser = KeyguardUpdateMonitor.getCurrentUser();
1620             final boolean lockImmediately =
1621                     mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
1622                             || !mLockPatternUtils.isSecure(currentUser);
1623             long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
1624             mLockLater = false;
1625             if (mShowing && !mKeyguardStateController.isKeyguardGoingAway()) {
1626                 // If we are going to sleep but the keyguard is showing (and will continue to be
1627                 // showing, not in the process of going away) then reset its state. Otherwise, let
1628                 // this fall through and explicitly re-lock the keyguard.
1629                 mPendingReset = true;
1630             } else if (
1631                     (offReason == WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT
1632                             && timeout > 0)
1633                             || (offReason == WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER
1634                             && !lockImmediately)) {
1635                 doKeyguardLaterLocked(timeout);
1636                 mLockLater = true;
1637             } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
1638                 setPendingLock(true);
1639             }
1640 
1641             if (mPendingLock) {
1642                 playSounds(true);
1643             }
1644         }
1645 
1646         mUpdateMonitor.dispatchStartedGoingToSleep(offReason);
1647 
1648         // Reset keyguard going away state, so we can start listening for fingerprint. We
1649         // explicitly DO NOT want to call
1650         // mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false)
1651         // here, since that will mess with the device lock state.
1652         mUpdateMonitor.dispatchKeyguardGoingAway(false);
1653 
1654         notifyStartedGoingToSleep();
1655     }
1656 
1657     /**
1658      * Called to let us know the screen finished turning off.
1659      * @param offReason either {@link WindowManagerPolicyConstants#OFF_BECAUSE_OF_USER} or
1660      * {@link WindowManagerPolicyConstants#OFF_BECAUSE_OF_TIMEOUT}.
1661      */
1662     public void onFinishedGoingToSleep(
1663             @WindowManagerPolicyConstants.OffReason int offReason, boolean cameraGestureTriggered) {
1664         if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + offReason + ")");
1665         synchronized (this) {
1666             mDeviceInteractive = false;
1667             mGoingToSleep = false;
1668             mWakeAndUnlocking = false;
1669             mAnimatingScreenOff = mDozeParameters.shouldAnimateDozingChange();
1670 
1671             resetKeyguardDonePendingLocked();
1672             mHideAnimationRun = false;
1673 
1674             notifyFinishedGoingToSleep();
1675 
1676             if (cameraGestureTriggered) {
1677                 // Just to make sure, make sure the device is awake.
1678                 mContext.getSystemService(PowerManager.class).wakeUp(mSystemClock.uptimeMillis(),
1679                         PowerManager.WAKE_REASON_CAMERA_LAUNCH,
1680                         "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
1681                 setPendingLock(false);
1682                 mPendingReset = false;
1683                 mPowerGestureIntercepted = true;
1684                 if (DEBUG) {
1685                     Log.d(TAG, "cameraGestureTriggered=" + cameraGestureTriggered
1686                             + ",mPowerGestureIntercepted=" + mPowerGestureIntercepted);
1687                 }
1688             }
1689 
1690             if (mPendingReset) {
1691                 resetStateLocked();
1692                 mPendingReset = false;
1693             }
1694 
1695             maybeHandlePendingLock();
1696 
1697             // We do not have timeout and power button instant lock setting for profile lock.
1698             // So we use the personal setting if there is any. But if there is no device
1699             // we need to make sure we lock it immediately when the screen is off.
1700             if (!mLockLater && !cameraGestureTriggered) {
1701                 doKeyguardForChildProfilesLocked();
1702             }
1703 
1704         }
1705         mUpdateMonitor.dispatchFinishedGoingToSleep(offReason);
1706     }
1707 
1708     /**
1709      * Locks the keyguard if {@link #mPendingLock} is true, and there are no reasons to further
1710      * delay the pending lock.
1711      *
1712      * If you do delay handling the pending lock, you must ensure that this method is ALWAYS called
1713      * again when the condition causing the delay changes. Otherwise, the device may remain unlocked
1714      * indefinitely.
1715      */
1716     public void maybeHandlePendingLock() {
1717         if (mPendingLock) {
1718 
1719             // The screen off animation is playing or is about to be, so if we lock now, the
1720             // foreground app will vanish and the keyguard will jump-cut in. Delay it, until either:
1721             //   - The screen off animation ends. We will call maybeHandlePendingLock from
1722             //     the end action in UnlockedScreenOffAnimationController#animateInKeyguard.
1723             //   - The screen off animation is cancelled by the device waking back up. We will call
1724             //     maybeHandlePendingLock from KeyguardViewMediator#onStartedWakingUp.
1725             if (mScreenOffAnimationController.shouldDelayKeyguardShow()) {
1726                 if (DEBUG) {
1727                     Log.d(TAG, "#maybeHandlePendingLock: not handling because the screen off "
1728                             + "animation's shouldDelayKeyguardShow() returned true. This should be "
1729                             + "handled soon by #onStartedWakingUp, or by the end actions of the "
1730                             + "screen off animation.");
1731                 }
1732 
1733                 return;
1734             }
1735 
1736             // The device was re-locked while in the process of unlocking. If we lock now, callbacks
1737             // in the unlock sequence might end up re-unlocking the device. Delay the lock until the
1738             // keyguard is done going away. We'll call maybeHandlePendingLock again in
1739             // StatusBar#finishKeyguardFadingAway, which is always responsible for setting
1740             // isKeyguardGoingAway to false.
1741             if (mKeyguardStateController.isKeyguardGoingAway()) {
1742                 if (DEBUG) {
1743                     Log.d(TAG, "#maybeHandlePendingLock: not handling because the keyguard is "
1744                             + "going away. This should be handled shortly by "
1745                             + "StatusBar#finishKeyguardFadingAway.");
1746                 }
1747 
1748                 return;
1749             }
1750 
1751             if (DEBUG) {
1752                 Log.d(TAG, "#maybeHandlePendingLock: handling pending lock; locking keyguard.");
1753             }
1754 
1755             doKeyguardLocked(null);
1756             setPendingLock(false);
1757         }
1758     }
1759 
1760     private boolean isKeyguardServiceEnabled() {
1761         try {
1762             return mContext.getPackageManager().getServiceInfo(
1763                     new ComponentName(mContext, KeyguardService.class), 0).isEnabled();
1764         } catch (NameNotFoundException e) {
1765             return true;
1766         }
1767     }
1768 
1769     private long getLockTimeout(int userId) {
1770         // if the screen turned off because of timeout or the user hit the power button,
1771         // and we don't need to lock immediately, set an alarm
1772         // to enable it a bit later (i.e, give the user a chance
1773         // to turn the screen back on within a certain window without
1774         // having to unlock the screen)
1775 
1776         // From SecuritySettings
1777         final long lockAfterTimeout = mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
1778                 KEYGUARD_LOCK_AFTER_DELAY_DEFAULT,
1779                 userId);
1780 
1781         // From DevicePolicyAdmin
1782         final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
1783                 .getMaximumTimeToLock(null, userId);
1784 
1785         long timeout;
1786 
1787         if (policyTimeout <= 0) {
1788             timeout = lockAfterTimeout;
1789         } else {
1790             // From DisplaySettings
1791             long displayTimeout = mSystemSettings.getIntForUser(SCREEN_OFF_TIMEOUT,
1792                     KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT,
1793                     userId);
1794 
1795             // policy in effect. Make sure we don't go beyond policy limit.
1796             displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
1797             timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
1798             timeout = Math.max(timeout, 0);
1799         }
1800         return timeout;
1801     }
1802 
1803     private void doKeyguardLaterLocked() {
1804         long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
1805         if (timeout == 0) {
1806             doKeyguardLocked(null);
1807         } else {
1808             doKeyguardLaterLocked(timeout);
1809         }
1810     }
1811 
1812     private void doKeyguardLaterLocked(long timeout) {
1813         // Lock in the future
1814         long when = mSystemClock.elapsedRealtime() + timeout;
1815         Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
1816         intent.setPackage(mContext.getPackageName());
1817         intent.putExtra("seq", mDelayedShowingSequence);
1818         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1819         PendingIntent sender = PendingIntent.getBroadcast(mContext,
1820                 0, intent, PendingIntent.FLAG_CANCEL_CURRENT |  PendingIntent.FLAG_IMMUTABLE);
1821         mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
1822         if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
1823                          + mDelayedShowingSequence);
1824         doKeyguardLaterForChildProfilesLocked();
1825     }
1826 
1827     private void doKeyguardLaterForChildProfilesLocked() {
1828         for (UserInfo profile : mUserTracker.getUserProfiles()) {
1829             if (!profile.isEnabled()) continue;
1830             final int profileId = profile.id;
1831             if (mLockPatternUtils.isSeparateProfileChallengeEnabled(profileId)) {
1832                 long userTimeout = getLockTimeout(profileId);
1833                 if (userTimeout == 0) {
1834                     doKeyguardForChildProfilesLocked();
1835                 } else {
1836                     long userWhen = mSystemClock.elapsedRealtime() + userTimeout;
1837                     Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION);
1838                     lockIntent.setPackage(mContext.getPackageName());
1839                     lockIntent.putExtra("seq", mDelayedProfileShowingSequence);
1840                     lockIntent.putExtra(Intent.EXTRA_USER_ID, profileId);
1841                     lockIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1842                     PendingIntent lockSender = PendingIntent.getBroadcast(
1843                             mContext, 0, lockIntent,
1844                             PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
1845                     mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1846                             userWhen, lockSender);
1847                 }
1848             }
1849         }
1850     }
1851 
1852     private void doKeyguardForChildProfilesLocked() {
1853         for (UserInfo profile : mUserTracker.getUserProfiles()) {
1854             if (!profile.isEnabled()) continue;
1855             final int profileId = profile.id;
1856             if (mLockPatternUtils.isSeparateProfileChallengeEnabled(profileId)) {
1857                 lockProfile(profileId);
1858             }
1859         }
1860     }
1861 
1862     private void cancelDoKeyguardLaterLocked() {
1863         mDelayedShowingSequence++;
1864     }
1865 
1866     private void cancelDoKeyguardForChildProfilesLocked() {
1867         mDelayedProfileShowingSequence++;
1868     }
1869 
1870     /**
1871      * It will let us know when the device is waking up.
1872      */
1873     public void onStartedWakingUp(@PowerManager.WakeReason int pmWakeReason,
1874             boolean cameraGestureTriggered) {
1875         Trace.beginSection("KeyguardViewMediator#onStartedWakingUp");
1876 
1877         // TODO: Rename all screen off/on references to interactive/sleeping
1878         synchronized (this) {
1879             mDeviceInteractive = true;
1880             if (mPendingLock && !cameraGestureTriggered && !mWakeAndUnlocking) {
1881                 doKeyguardLocked(null);
1882             }
1883             mAnimatingScreenOff = false;
1884             cancelDoKeyguardLaterLocked();
1885             cancelDoKeyguardForChildProfilesLocked();
1886             if (cameraGestureTriggered) {
1887                 mPowerGestureIntercepted = true;
1888             }
1889             if (DEBUG) {
1890                 Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence
1891                         + ", mPowerGestureIntercepted = " + mPowerGestureIntercepted);
1892             }
1893             notifyStartedWakingUp();
1894         }
1895         mUiEventLogger.logWithInstanceIdAndPosition(
1896                 BiometricUnlockController.BiometricUiEvent.STARTED_WAKING_UP,
1897                 0,
1898                 null,
1899                 mSessionTracker.getSessionId(SESSION_KEYGUARD),
1900                 pmWakeReason
1901         );
1902         mUpdateMonitor.dispatchStartedWakingUp(pmWakeReason);
1903         maybeSendUserPresentBroadcast();
1904         Trace.endSection();
1905     }
1906 
1907     public void onScreenTurnedOff() {
1908         mUpdateMonitor.dispatchScreenTurnedOff();
1909     }
1910 
1911     private void maybeSendUserPresentBroadcast() {
1912         if (mSystemReady && mLockPatternUtils.isLockScreenDisabled(
1913                 KeyguardUpdateMonitor.getCurrentUser())) {
1914             // Lock screen is disabled because the user has set the preference to "None".
1915             // In this case, send out ACTION_USER_PRESENT here instead of in
1916             // handleKeyguardDone()
1917             sendUserPresentBroadcast();
1918         } else if (mSystemReady && shouldWaitForProvisioning()) {
1919             // Skipping the lockscreen because we're not yet provisioned, but we still need to
1920             // notify the StrongAuthTracker that it's now safe to run trust agents, in case the
1921             // user sets a credential later.
1922             mLockPatternUtils.userPresent(KeyguardUpdateMonitor.getCurrentUser());
1923         }
1924     }
1925 
1926     /**
1927      * A dream started. We should lock after the usual screen-off lock timeout regardless if
1928      * there is a secure lock pattern or not
1929      */
1930     public void onDreamingStarted() {
1931         mUpdateMonitor.dispatchDreamingStarted();
1932         synchronized (this) {
1933             final boolean alwaysShowKeyguard =
1934                 mFeatureFlags.isEnabled(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING);
1935             if (mDeviceInteractive
1936                 && (alwaysShowKeyguard ||
1937                 mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()))) {
1938                 doKeyguardLaterLocked();
1939             }
1940         }
1941     }
1942 
1943     /**
1944      * A dream stopped.
1945      */
1946     public void onDreamingStopped() {
1947         mUpdateMonitor.dispatchDreamingStopped();
1948         synchronized (this) {
1949             if (mDeviceInteractive) {
1950                 cancelDoKeyguardLaterLocked();
1951             }
1952         }
1953     }
1954 
1955     /**
1956      * Same semantics as {@link WindowManagerPolicyConstants#enableKeyguard}; provide
1957      * a way for external stuff to override normal keyguard behavior.  For instance
1958      * the phone app disables the keyguard when it receives incoming calls.
1959      */
1960     public void setKeyguardEnabled(boolean enabled) {
1961         synchronized (this) {
1962             if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")");
1963 
1964             mExternallyEnabled = enabled;
1965 
1966             if (!enabled && mShowing) {
1967                 if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
1968                     Log.d(TAG, "keyguardEnabled(false) overridden by user lockdown");
1969                     return;
1970                 }
1971                 // hiding keyguard that is showing, remember to reshow later
1972                 if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
1973                         + "disabling status bar expansion");
1974                 mNeedToReshowWhenReenabled = true;
1975                 updateInputRestrictedLocked();
1976                 hideLocked();
1977             } else if (enabled && mNeedToReshowWhenReenabled) {
1978                 // re-enabled after previously hidden, reshow
1979                 if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling "
1980                         + "status bar expansion");
1981                 mNeedToReshowWhenReenabled = false;
1982                 updateInputRestrictedLocked();
1983 
1984                 showLocked(null);
1985 
1986                 // block until we know the keyguard is done drawing (and post a message
1987                 // to unblock us after a timeout, so we don't risk blocking too long
1988                 // and causing an ANR).
1989                 mWaitingUntilKeyguardVisible = true;
1990                 mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING,
1991                         KEYGUARD_DONE_DRAWING_TIMEOUT_MS);
1992                 if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false");
1993                 while (mWaitingUntilKeyguardVisible) {
1994                     try {
1995                         wait();
1996                     } catch (InterruptedException e) {
1997                         Thread.currentThread().interrupt();
1998                     }
1999                 }
2000                 if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible");
2001             }
2002         }
2003     }
2004 
2005     /**
2006      * @see android.app.KeyguardManager#exitKeyguardSecurely
2007      */
2008     public void verifyUnlock(IKeyguardExitCallback callback) {
2009         Trace.beginSection("KeyguardViewMediator#verifyUnlock");
2010         synchronized (this) {
2011             if (DEBUG) Log.d(TAG, "verifyUnlock");
2012             if (shouldWaitForProvisioning()) {
2013                 // don't allow this api when the device isn't provisioned
2014                 if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned");
2015                 try {
2016                     callback.onKeyguardExitResult(false);
2017                 } catch (RemoteException e) {
2018                     Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
2019                 }
2020             } else if (mExternallyEnabled) {
2021                 // this only applies when the user has externally disabled the
2022                 // keyguard.  this is unexpected and means the user is not
2023                 // using the api properly.
2024                 Log.w(TAG, "verifyUnlock called when not externally disabled");
2025                 try {
2026                     callback.onKeyguardExitResult(false);
2027                 } catch (RemoteException e) {
2028                     Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
2029                 }
2030             } else if (!isSecure()) {
2031 
2032                 // Keyguard is not secure, no need to do anything, and we don't need to reshow
2033                 // the Keyguard after the client releases the Keyguard lock.
2034                 mExternallyEnabled = true;
2035                 mNeedToReshowWhenReenabled = false;
2036                 updateInputRestricted();
2037                 try {
2038                     callback.onKeyguardExitResult(true);
2039                 } catch (RemoteException e) {
2040                     Slog.w(TAG, "Failed to call onKeyguardExitResult(true)", e);
2041                 }
2042             } else {
2043 
2044                 // Since we prevent apps from hiding the Keyguard if we are secure, this should be
2045                 // a no-op as well.
2046                 try {
2047                     callback.onKeyguardExitResult(false);
2048                 } catch (RemoteException e) {
2049                     Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
2050                 }
2051             }
2052         }
2053         Trace.endSection();
2054     }
2055 
2056     /**
2057      * Is the keyguard currently showing and not being force hidden?
2058      */
2059     public boolean isShowingAndNotOccluded() {
2060         return mShowing && !mOccluded;
2061     }
2062 
2063     public boolean isOccludeAnimationPlaying() {
2064         return mOccludeAnimationPlaying;
2065     }
2066 
2067     /**
2068      * Notify us when the keyguard is occluded by another window
2069      */
2070     public void setOccluded(boolean isOccluded, boolean animate) {
2071         Log.d(TAG, "setOccluded(" + isOccluded + ")");
2072 
2073         Trace.beginSection("KeyguardViewMediator#setOccluded");
2074         if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
2075         mHandler.removeMessages(SET_OCCLUDED);
2076         Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
2077         mHandler.sendMessage(msg);
2078         Trace.endSection();
2079     }
2080 
2081     public IRemoteAnimationRunner getExitAnimationRunner() {
2082         return validatingRemoteAnimationRunner(mExitAnimationRunner);
2083     }
2084 
2085     public IRemoteAnimationRunner getOccludeAnimationRunner() {
2086         return validatingRemoteAnimationRunner(mOccludeAnimationRunner);
2087     }
2088 
2089     public IRemoteAnimationRunner getOccludeByDreamAnimationRunner() {
2090         return validatingRemoteAnimationRunner(mOccludeByDreamAnimationRunner);
2091     }
2092 
2093     public IRemoteAnimationRunner getUnoccludeAnimationRunner() {
2094         return validatingRemoteAnimationRunner(mUnoccludeAnimationRunner);
2095     }
2096 
2097     public boolean isHiding() {
2098         return mHiding;
2099     }
2100 
2101     public boolean isAnimatingScreenOff() {
2102         return mAnimatingScreenOff;
2103     }
2104 
2105     /**
2106      * Handles SET_OCCLUDED message sent by setOccluded()
2107      */
2108     private void handleSetOccluded(boolean isOccluded, boolean animate) {
2109         Trace.beginSection("KeyguardViewMediator#handleSetOccluded");
2110         Log.d(TAG, "handleSetOccluded(" + isOccluded + ")");
2111         EventLogTags.writeSysuiKeyguard(isOccluded ? 1 : 0, animate ? 1 : 0);
2112 
2113         mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
2114 
2115         synchronized (KeyguardViewMediator.this) {
2116             if (mHiding && isOccluded) {
2117                 // We're in the process of going away but WindowManager wants to show a
2118                 // SHOW_WHEN_LOCKED activity instead.
2119                 // TODO(bc-unlock): Migrate to remote animation.
2120                 startKeyguardExitAnimation(0, 0);
2121             }
2122 
2123             mPowerGestureIntercepted =
2124                     isOccluded && mUpdateMonitor.isSecureCameraLaunchedOverKeyguard();
2125 
2126             if (mOccluded != isOccluded) {
2127                 mOccluded = isOccluded;
2128                 mKeyguardViewControllerLazy.get().setOccluded(isOccluded, animate
2129                         && mDeviceInteractive);
2130                 adjustStatusBarLocked();
2131             }
2132 
2133             if (DEBUG) {
2134                 Log.d(TAG, "isOccluded=" + isOccluded + ",mPowerGestureIntercepted="
2135                         + mPowerGestureIntercepted);
2136             }
2137         }
2138         Trace.endSection();
2139     }
2140 
2141     /**
2142      * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout.
2143      * This must be safe to call from any thread and with any window manager locks held.
2144      */
2145     public void doKeyguardTimeout(Bundle options) {
2146         mHandler.removeMessages(KEYGUARD_TIMEOUT);
2147         Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
2148         // Treat these messages with priority - A call to timeout means the device should lock
2149         // as soon as possible and not wait for other messages on the thread to process first.
2150         mHandler.sendMessageAtFrontOfQueue(msg);
2151     }
2152 
2153     /**
2154      * Given the state of the keyguard, is the input restricted?
2155      * Input is restricted when the keyguard is showing, or when the keyguard
2156      * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
2157      */
2158     public boolean isInputRestricted() {
2159         return mShowing || mNeedToReshowWhenReenabled;
2160     }
2161 
2162     private void updateInputRestricted() {
2163         synchronized (this) {
2164             updateInputRestrictedLocked();
2165         }
2166     }
2167 
2168     private void updateInputRestrictedLocked() {
2169         boolean inputRestricted = isInputRestricted();
2170         if (mInputRestricted != inputRestricted) {
2171             mInputRestricted = inputRestricted;
2172             int size = mKeyguardStateCallbacks.size();
2173             for (int i = size - 1; i >= 0; i--) {
2174                 final IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
2175                 try {
2176                     callback.onInputRestrictedStateChanged(inputRestricted);
2177                 } catch (RemoteException e) {
2178                     Slog.w(TAG, "Failed to call onDeviceProvisioned", e);
2179                     if (e instanceof DeadObjectException) {
2180                         mKeyguardStateCallbacks.remove(callback);
2181                     }
2182                 }
2183             }
2184         }
2185     }
2186 
2187     /**
2188      * Enable the keyguard if the settings are appropriate.
2189      */
2190     private void doKeyguardLocked(Bundle options) {
2191         // if another app is disabling us, don't show
2192         if (!mExternallyEnabled
2193                 && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
2194             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
2195 
2196             mNeedToReshowWhenReenabled = true;
2197             return;
2198         }
2199 
2200         // If the keyguard is already showing, see if we don't need to bother re-showing it. Check
2201         // flags in both files to account for the hiding animation which results in a delay and
2202         // discrepancy between flags. If we're in the middle of hiding, do not short circuit so that
2203         // we explicitly re-set state.
2204         if (mShowing && mKeyguardStateController.isShowing()) {
2205             if (mPM.isInteractive() && !mHiding) {
2206                 if (mKeyguardStateController.isKeyguardGoingAway()) {
2207                     Log.e(TAG, "doKeyguard: we're still showing, but going away. Re-show the "
2208                             + "keyguard rather than short-circuiting and resetting.");
2209                 } else {
2210                     // It's already showing, and we're not trying to show it while the screen is
2211                     // off. We can simply reset all of the views, but don't hide the bouncer in case
2212                     // the user is currently interacting with it.
2213                     if (DEBUG) Log.d(TAG,
2214                             "doKeyguard: not showing (instead, resetting) because it is "
2215                                     + "already showing, we're interactive, we were not "
2216                                     + "previously hiding. It should be safe to short-circuit "
2217                                     + "here.");
2218                     resetStateLocked(/* hideBouncer= */ false);
2219                     return;
2220                 }
2221             } else {
2222                 // We are trying to show the keyguard while the screen is off or while we were in
2223                 // the middle of hiding - this results from race conditions involving locking while
2224                 // unlocking. Don't short-circuit here and ensure the keyguard is fully re-shown.
2225                 Log.e(TAG,
2226                         "doKeyguard: already showing, but re-showing because we're interactive or "
2227                                 + "were in the middle of hiding.");
2228             }
2229         }
2230 
2231         // if the setup wizard hasn't run yet, don't show
2232         final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
2233         final boolean absent = SubscriptionManager.isValidSubscriptionId(
2234                 mUpdateMonitor.getNextSubIdForState(TelephonyManager.SIM_STATE_ABSENT));
2235         final boolean disabled = SubscriptionManager.isValidSubscriptionId(
2236                 mUpdateMonitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PERM_DISABLED));
2237         final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
2238                 || ((absent || disabled) && requireSim);
2239 
2240         if (!lockedOrMissing && shouldWaitForProvisioning()) {
2241             if (DEBUG) {
2242                 Log.d(TAG, "doKeyguard: not showing because device isn't provisioned and the sim is"
2243                         + " not locked or missing");
2244             }
2245             return;
2246         }
2247 
2248         boolean forceShow = options != null && options.getBoolean(OPTION_FORCE_SHOW, false);
2249         if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
2250                 && !lockedOrMissing && !forceShow) {
2251             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
2252             return;
2253         }
2254 
2255         if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
2256         showLocked(options);
2257     }
2258 
2259     private void lockProfile(int userId) {
2260         mTrustManager.setDeviceLockedForUser(userId, true);
2261     }
2262 
2263     private boolean shouldWaitForProvisioning() {
2264         return !mUpdateMonitor.isDeviceProvisioned() && !isSecure();
2265     }
2266 
2267     /**
2268      * Dismiss the keyguard through the security layers.
2269      * @param callback Callback to be informed about the result
2270      * @param message Message that should be displayed on the bouncer.
2271      */
2272     private void handleDismiss(IKeyguardDismissCallback callback, CharSequence message) {
2273         if (mShowing) {
2274             if (callback != null) {
2275                 mDismissCallbackRegistry.addCallback(callback);
2276             }
2277             mCustomMessage = message;
2278             mKeyguardViewControllerLazy.get().dismissAndCollapse();
2279         } else if (callback != null) {
2280             new DismissCallbackWrapper(callback).notifyDismissError();
2281         }
2282     }
2283 
2284     public void dismiss(IKeyguardDismissCallback callback, CharSequence message) {
2285         mHandler.obtainMessage(DISMISS, new DismissMessage(callback, message)).sendToTarget();
2286     }
2287 
2288     /**
2289      * Send message to keyguard telling it to reset its state.
2290      * @see #handleReset
2291      */
2292     private void resetStateLocked() {
2293         resetStateLocked(/* hideBouncer= */ true);
2294     }
2295 
2296     private void resetStateLocked(boolean hideBouncer) {
2297         if (DEBUG) Log.e(TAG, "resetStateLocked");
2298         Message msg = mHandler.obtainMessage(RESET, hideBouncer ? 1 : 0, 0);
2299         mHandler.sendMessage(msg);
2300     }
2301 
2302     /**
2303      * Send message to keyguard telling it to verify unlock
2304      * @see #handleVerifyUnlock()
2305      */
2306     private void verifyUnlockLocked() {
2307         if (DEBUG) Log.d(TAG, "verifyUnlockLocked");
2308         mHandler.sendEmptyMessage(VERIFY_UNLOCK);
2309     }
2310 
2311     private void notifyStartedGoingToSleep() {
2312         if (DEBUG) Log.d(TAG, "notifyStartedGoingToSleep");
2313         mHandler.sendEmptyMessage(NOTIFY_STARTED_GOING_TO_SLEEP);
2314     }
2315 
2316     private void notifyFinishedGoingToSleep() {
2317         if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep");
2318         mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP);
2319     }
2320 
2321     private void notifyStartedWakingUp() {
2322         if (DEBUG) Log.d(TAG, "notifyStartedWakingUp");
2323         mHandler.sendEmptyMessage(NOTIFY_STARTED_WAKING_UP);
2324     }
2325 
2326     /**
2327      * Send message to keyguard telling it to show itself
2328      * @see #handleShow
2329      */
2330     private void showLocked(Bundle options) {
2331         Trace.beginSection("KeyguardViewMediator#showLocked acquiring mShowKeyguardWakeLock");
2332         if (DEBUG) Log.d(TAG, "showLocked");
2333         // ensure we stay awake until we are finished displaying the keyguard
2334         mShowKeyguardWakeLock.acquire();
2335         Message msg = mHandler.obtainMessage(SHOW, options);
2336         // Treat these messages with priority - This call can originate from #doKeyguardTimeout,
2337         // meaning the device should lock as soon as possible and not wait for other messages on
2338         // the thread to process first.
2339         mHandler.sendMessageAtFrontOfQueue(msg);
2340         Trace.endSection();
2341     }
2342 
2343     /**
2344      * Send message to keyguard telling it to hide itself
2345      * @see #handleHide()
2346      */
2347     private void hideLocked() {
2348         Trace.beginSection("KeyguardViewMediator#hideLocked");
2349         if (DEBUG) Log.d(TAG, "hideLocked");
2350         Message msg = mHandler.obtainMessage(HIDE);
2351         mHandler.sendMessage(msg);
2352         Trace.endSection();
2353     }
2354 
2355     /**
2356      * Hide the keyguard and let {@code runner} handle the animation.
2357      *
2358      * This method should typically be called after {@link ViewMediatorCallback#keyguardDonePending}
2359      * was called, when we are ready to hide the keyguard. It will do nothing if we were not
2360      * expecting the keyguard to go away when called.
2361      */
2362     public void hideWithAnimation(IRemoteAnimationRunner runner) {
2363         if (!mKeyguardDonePending) {
2364             return;
2365         }
2366 
2367         mKeyguardExitAnimationRunner = runner;
2368         mViewMediatorCallback.readyForKeyguardDone();
2369     }
2370 
2371     /**
2372      * Disable notification shade background blurs until the keyguard is dismissed.
2373      * (Used during app launch animations)
2374      */
2375     public void setBlursDisabledForAppLaunch(boolean disabled) {
2376         mNotificationShadeDepthController.get().setBlursDisabledForAppLaunch(disabled);
2377     }
2378 
2379     public boolean isSecure() {
2380         return isSecure(KeyguardUpdateMonitor.getCurrentUser());
2381     }
2382 
2383     public boolean isSecure(int userId) {
2384         return mLockPatternUtils.isSecure(userId)
2385                 || mUpdateMonitor.isSimPinSecure();
2386     }
2387 
2388     /**
2389      * Whether any of the SIMs on the device are secured with a PIN. If so, the keyguard should not
2390      * be dismissable until the PIN is entered, even if the device itself has no lock set.
2391      */
2392     public boolean isAnySimPinSecure() {
2393         for (int i = 0; i < mLastSimStates.size(); i++) {
2394             final int key = mLastSimStates.keyAt(i);
2395             if (KeyguardUpdateMonitor.isSimPinSecure(mLastSimStates.get(key))) {
2396                 return true;
2397             }
2398         }
2399 
2400         return false;
2401     }
2402 
2403     public void setSwitchingUser(boolean switching) {
2404         mUpdateMonitor.setSwitchingUser(switching);
2405     }
2406 
2407     /**
2408      * Update the newUserId. Call while holding WindowManagerService lock.
2409      * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing.
2410      *
2411      * @param newUserId The id of the incoming user.
2412      */
2413     public void setCurrentUser(int newUserId) {
2414         KeyguardUpdateMonitor.setCurrentUser(newUserId);
2415         synchronized (this) {
2416             notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(newUserId));
2417         }
2418     }
2419 
2420     /**
2421      * This broadcast receiver should be registered with the SystemUI permission.
2422      */
2423     private final BroadcastReceiver mDelayedLockBroadcastReceiver = new BroadcastReceiver() {
2424         @Override
2425         public void onReceive(Context context, Intent intent) {
2426             if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) {
2427                 final int sequence = intent.getIntExtra("seq", 0);
2428                 if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
2429                         + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
2430                 synchronized (KeyguardViewMediator.this) {
2431                     if (mDelayedShowingSequence == sequence) {
2432                         doKeyguardLocked(null);
2433                     }
2434                 }
2435             } else if (DELAYED_LOCK_PROFILE_ACTION.equals(intent.getAction())) {
2436                 final int sequence = intent.getIntExtra("seq", 0);
2437                 int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, 0);
2438                 if (userId != 0) {
2439                     synchronized (KeyguardViewMediator.this) {
2440                         if (mDelayedProfileShowingSequence == sequence) {
2441                             lockProfile(userId);
2442                         }
2443                     }
2444                 }
2445             }
2446         }
2447     };
2448 
2449     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2450         @Override
2451         public void onReceive(Context context, Intent intent) {
2452             if (Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
2453                 synchronized (KeyguardViewMediator.this){
2454                     mShuttingDown = true;
2455                 }
2456             }
2457         }
2458     };
2459 
2460     /**
2461      * This handler will be associated with the policy thread, which will also
2462      * be the UI thread of the keyguard.  Since the apis of the policy, and therefore
2463      * this class, can be called by other threads, any action that directly
2464      * interacts with the keyguard ui should be posted to this handler, rather
2465      * than called directly.
2466      */
2467     private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
2468         @Override
2469         public void handleMessage(Message msg) {
2470             String message = "";
2471             switch (msg.what) {
2472                 case SHOW:
2473                     message = "SHOW";
2474                     handleShow((Bundle) msg.obj);
2475                     break;
2476                 case HIDE:
2477                     message = "HIDE";
2478                     handleHide();
2479                     break;
2480                 case RESET:
2481                     message = "RESET";
2482                     handleReset(msg.arg1 != 0);
2483                     break;
2484                 case VERIFY_UNLOCK:
2485                     message = "VERIFY_UNLOCK";
2486                     Trace.beginSection("KeyguardViewMediator#handleMessage VERIFY_UNLOCK");
2487                     handleVerifyUnlock();
2488                     Trace.endSection();
2489                     break;
2490                 case NOTIFY_STARTED_GOING_TO_SLEEP:
2491                     message = "NOTIFY_STARTED_GOING_TO_SLEEP";
2492                     handleNotifyStartedGoingToSleep();
2493                     break;
2494                 case NOTIFY_FINISHED_GOING_TO_SLEEP:
2495                     message = "NOTIFY_FINISHED_GOING_TO_SLEEP";
2496                     handleNotifyFinishedGoingToSleep();
2497                     break;
2498                 case NOTIFY_STARTED_WAKING_UP:
2499                     message = "NOTIFY_STARTED_WAKING_UP";
2500                     Trace.beginSection(
2501                             "KeyguardViewMediator#handleMessage NOTIFY_STARTED_WAKING_UP");
2502                     handleNotifyStartedWakingUp();
2503                     Trace.endSection();
2504                     break;
2505                 case KEYGUARD_DONE:
2506                     message = "KEYGUARD_DONE";
2507                     Trace.beginSection("KeyguardViewMediator#handleMessage KEYGUARD_DONE");
2508                     handleKeyguardDone();
2509                     Trace.endSection();
2510                     break;
2511                 case KEYGUARD_DONE_DRAWING:
2512                     message = "KEYGUARD_DONE_DRAWING";
2513                     Trace.beginSection("KeyguardViewMediator#handleMessage KEYGUARD_DONE_DRAWING");
2514                     handleKeyguardDoneDrawing();
2515                     Trace.endSection();
2516                     break;
2517                 case SET_OCCLUDED:
2518                     message = "SET_OCCLUDED";
2519                     Trace.beginSection("KeyguardViewMediator#handleMessage SET_OCCLUDED");
2520                     handleSetOccluded(msg.arg1 != 0, msg.arg2 != 0);
2521                     Trace.endSection();
2522                     break;
2523                 case KEYGUARD_TIMEOUT:
2524                     message = "KEYGUARD_TIMEOUT";
2525                     synchronized (KeyguardViewMediator.this) {
2526                         doKeyguardLocked((Bundle) msg.obj);
2527                     }
2528                     break;
2529                 case DISMISS:
2530                     message = "DISMISS";
2531                     final DismissMessage dismissMsg = (DismissMessage) msg.obj;
2532                     handleDismiss(dismissMsg.getCallback(), dismissMsg.getMessage());
2533                     break;
2534                 case START_KEYGUARD_EXIT_ANIM:
2535                     message = "START_KEYGUARD_EXIT_ANIM";
2536                     Trace.beginSection(
2537                             "KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM");
2538                     synchronized (KeyguardViewMediator.this) {
2539                         mHiding = true;
2540                     }
2541                     StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
2542                     mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(
2543                             () -> {
2544                                 handleStartKeyguardExitAnimation(params.startTime,
2545                                         params.fadeoutDuration,
2546                                         params.mApps, params.mWallpapers, params.mNonApps,
2547                                         params.mFinishedCallback);
2548                                 mFalsingCollector.onSuccessfulUnlock();
2549                             });
2550                     Trace.endSection();
2551                     break;
2552                 case CANCEL_KEYGUARD_EXIT_ANIM:
2553                     message = "CANCEL_KEYGUARD_EXIT_ANIM";
2554                     Trace.beginSection(
2555                             "KeyguardViewMediator#handleMessage CANCEL_KEYGUARD_EXIT_ANIM");
2556                     handleCancelKeyguardExitAnimation();
2557                     Trace.endSection();
2558                     break;
2559                 case KEYGUARD_DONE_PENDING_TIMEOUT:
2560                     message = "KEYGUARD_DONE_PENDING_TIMEOUT";
2561                     Trace.beginSection("KeyguardViewMediator#handleMessage"
2562                             + " KEYGUARD_DONE_PENDING_TIMEOUT");
2563                     Log.w(TAG, "Timeout while waiting for activity drawn!");
2564                     Trace.endSection();
2565                     break;
2566                 case SYSTEM_READY:
2567                     message = "SYSTEM_READY";
2568                     handleSystemReady();
2569                     break;
2570             }
2571             Log.d(TAG, "KeyguardViewMediator queue processing message: " + message);
2572         }
2573     };
2574 
2575     private void tryKeyguardDone() {
2576         if (DEBUG) {
2577             Log.d(TAG, "tryKeyguardDone: pending - " + mKeyguardDonePending + ", animRan - "
2578                     + mHideAnimationRun + " animRunning - " + mHideAnimationRunning);
2579         }
2580         if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
2581             handleKeyguardDone();
2582         } else if (mSurfaceBehindRemoteAnimationRunning) {
2583             // We're already running the keyguard exit animation, likely due to an in-progress swipe
2584             // to unlock.
2585             exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* showKeyguard */);
2586         } else if (!mHideAnimationRun) {
2587             if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
2588             mHideAnimationRun = true;
2589             mHideAnimationRunning = true;
2590             mKeyguardViewControllerLazy.get()
2591                     .startPreHideAnimation(mHideAnimationFinishedRunnable);
2592         }
2593     }
2594 
2595     /**
2596      * @see #keyguardDone
2597      * @see #KEYGUARD_DONE
2598      */
2599     private void handleKeyguardDone() {
2600         Trace.beginSection("KeyguardViewMediator#handleKeyguardDone");
2601         final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
2602         mUiBgExecutor.execute(() -> {
2603             if (mLockPatternUtils.isSecure(currentUser)) {
2604                 mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
2605             }
2606         });
2607         if (DEBUG) Log.d(TAG, "handleKeyguardDone");
2608         synchronized (this) {
2609             resetKeyguardDonePendingLocked();
2610         }
2611 
2612         if (mGoingToSleep) {
2613             mUpdateMonitor.clearBiometricRecognizedWhenKeyguardDone(currentUser);
2614             Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
2615             return;
2616         }
2617         setPendingLock(false); // user may have authenticated during the screen off animation
2618 
2619         handleHide();
2620         mUpdateMonitor.clearBiometricRecognizedWhenKeyguardDone(currentUser);
2621         Trace.endSection();
2622     }
2623 
2624     private void sendUserPresentBroadcast() {
2625         synchronized (this) {
2626             if (mBootCompleted) {
2627                 int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
2628                 final UserHandle currentUser = new UserHandle(currentUserId);
2629                 final UserManager um = (UserManager) mContext.getSystemService(
2630                         Context.USER_SERVICE);
2631                 mUiBgExecutor.execute(() -> {
2632                     for (int profileId : um.getProfileIdsWithDisabled(currentUser.getIdentifier())) {
2633                         mContext.sendBroadcastAsUser(USER_PRESENT_INTENT,
2634                                 UserHandle.of(profileId),
2635                                 null,
2636                                 USER_PRESENT_INTENT_OPTIONS);
2637                     }
2638                     mLockPatternUtils.userPresent(currentUserId);
2639                 });
2640             } else {
2641                 mBootSendUserPresent = true;
2642             }
2643         }
2644     }
2645 
2646     /**
2647      * @see #keyguardDone
2648      * @see #KEYGUARD_DONE_DRAWING
2649      */
2650     private void handleKeyguardDoneDrawing() {
2651         Trace.beginSection("KeyguardViewMediator#handleKeyguardDoneDrawing");
2652         synchronized(this) {
2653             if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing");
2654             if (mWaitingUntilKeyguardVisible) {
2655                 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible");
2656                 mWaitingUntilKeyguardVisible = false;
2657                 notifyAll();
2658 
2659                 // there will usually be two of these sent, one as a timeout, and one
2660                 // as a result of the callback, so remove any remaining messages from
2661                 // the queue
2662                 mHandler.removeMessages(KEYGUARD_DONE_DRAWING);
2663             }
2664         }
2665         Trace.endSection();
2666     }
2667 
2668     private void playSounds(boolean locked) {
2669         playSound(locked ? mLockSoundId : mUnlockSoundId);
2670     }
2671 
2672     private void playSound(int soundId) {
2673         if (soundId == 0) return;
2674         int lockscreenSoundsEnabled = mSystemSettings.getIntForUser(LOCKSCREEN_SOUNDS_ENABLED, 1,
2675                 KeyguardUpdateMonitor.getCurrentUser());
2676         if (lockscreenSoundsEnabled == 1) {
2677 
2678             mLockSounds.stop(mLockSoundStreamId);
2679             // Init mAudioManager
2680             if (mAudioManager == null) {
2681                 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
2682                 if (mAudioManager == null) return;
2683                 mUiSoundsStreamType = mAudioManager.getUiSoundsStreamType();
2684             }
2685 
2686             mUiBgExecutor.execute(() -> {
2687                 // If the stream is muted, don't play the sound
2688                 if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return;
2689 
2690                 int id = mLockSounds.play(soundId,
2691                         mLockSoundVolume, mLockSoundVolume, 1/*priority*/, 0/*loop*/, 1.0f/*rate*/);
2692                 synchronized (this) {
2693                     mLockSoundStreamId = id;
2694                 }
2695             });
2696 
2697         }
2698     }
2699 
2700     private void playTrustedSound() {
2701         playSound(mTrustedSoundId);
2702     }
2703 
2704     private void updateActivityLockScreenState(boolean showing, boolean aodShowing) {
2705         mUiBgExecutor.execute(() -> {
2706             if (DEBUG) {
2707                 Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")");
2708             }
2709 
2710             if (mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
2711                 // Handled in WmLockscreenVisibilityManager if flag is enabled.
2712                 return;
2713             }
2714 
2715             try {
2716                 ActivityTaskManager.getService().setLockScreenShown(showing, aodShowing);
2717             } catch (RemoteException e) {
2718             }
2719         });
2720     }
2721 
2722     /**
2723      * Handle message sent by {@link #showLocked}.
2724      * @see #SHOW
2725      */
2726     private void handleShow(Bundle options) {
2727         Trace.beginSection("KeyguardViewMediator#handleShow");
2728         final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
2729         if (mLockPatternUtils.isSecure(currentUser)) {
2730             mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser);
2731         }
2732         synchronized (KeyguardViewMediator.this) {
2733             if (!mSystemReady) {
2734                 if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
2735                 return;
2736             } else {
2737                 if (DEBUG) Log.d(TAG, "handleShow");
2738             }
2739 
2740             mKeyguardExitAnimationRunner = null;
2741             mWakeAndUnlocking = false;
2742             setUnlockAndWakeFromDream(false, WakeAndUnlockUpdateReason.SHOW);
2743             setPendingLock(false);
2744 
2745             final boolean hidingOrGoingAway =
2746                     mHiding || mKeyguardStateController.isKeyguardGoingAway();
2747             if (hidingOrGoingAway) {
2748                 Log.d(TAG, "Forcing setShowingLocked because one of these is true:"
2749                         + "mHiding=" + mHiding
2750                         + ", keyguardGoingAway=" + mKeyguardStateController.isKeyguardGoingAway()
2751                         + ", which means we're showing in the middle of hiding.");
2752             }
2753 
2754             // Force if we we're showing in the middle of unlocking, to ensure we end up in the
2755             // correct state.
2756             setShowingLocked(true, hidingOrGoingAway /* force */);
2757             mHiding = false;
2758 
2759             if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
2760                 // Handled directly in StatusBarKeyguardViewManager if enabled.
2761                 mKeyguardViewControllerLazy.get().show(options);
2762             }
2763 
2764             resetKeyguardDonePendingLocked();
2765             mHideAnimationRun = false;
2766             adjustStatusBarLocked();
2767             userActivity();
2768             mUpdateMonitor.setKeyguardGoingAway(false);
2769             mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false);
2770             mShowKeyguardWakeLock.release();
2771         }
2772         mKeyguardDisplayManager.show();
2773 
2774         scheduleNonStrongBiometricIdleTimeout();
2775 
2776         Trace.endSection();
2777     }
2778 
2779     /**
2780      * Schedule 4-hour idle timeout for non-strong biometrics when the device is locked
2781      */
2782     private void scheduleNonStrongBiometricIdleTimeout() {
2783         final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
2784         // If unlocking with non-strong (i.e. weak or convenience) biometrics is possible, schedule
2785         // 4hr idle timeout after which non-strong biometrics can't be used to unlock device until
2786         // unlocking with strong biometric or primary auth (i.e. PIN/pattern/password)
2787         if (mUpdateMonitor.isUnlockingWithNonStrongBiometricsPossible(currentUser)) {
2788             if (DEBUG) {
2789                 Log.d(TAG, "scheduleNonStrongBiometricIdleTimeout: schedule an alarm for "
2790                         + "currentUser=" + currentUser);
2791             }
2792             mLockPatternUtils.scheduleNonStrongBiometricIdleTimeout(currentUser);
2793         }
2794     }
2795 
2796     private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
2797         @Override
2798         public void run() {
2799             Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
2800             if (DEBUG) Log.d(TAG, "keyguardGoingAway");
2801             mKeyguardViewControllerLazy.get().keyguardGoingAway();
2802 
2803             int flags = 0;
2804             if (mKeyguardViewControllerLazy.get().shouldDisableWindowAnimationsForUnlock()
2805                     || mWakeAndUnlocking && !mWallpaperSupportsAmbientMode) {
2806                 flags |= KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
2807             }
2808             if (mKeyguardViewControllerLazy.get().isGoingToNotificationShade()
2809                     || mWakeAndUnlocking && mWallpaperSupportsAmbientMode) {
2810                 // When the wallpaper supports ambient mode, the scrim isn't fully opaque during
2811                 // wake and unlock, and we should fade in the app on top of the wallpaper
2812                 flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
2813             }
2814             if (mKeyguardViewControllerLazy.get().isUnlockWithWallpaper()) {
2815                 flags |= KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
2816             }
2817             if (mKeyguardViewControllerLazy.get().shouldSubtleWindowAnimationsForUnlock()) {
2818                 flags |= WindowManagerPolicyConstants
2819                         .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
2820             }
2821 
2822             // If we are unlocking to the launcher, clear the snapshot so that any changes as part
2823             // of the in-window animations are reflected. This is needed even if we're not actually
2824             // playing in-window animations for this particular unlock since a previous unlock might
2825             // have changed the Launcher state.
2826             if (mWakeAndUnlocking
2827                     && KeyguardUnlockAnimationController.Companion.isNexusLauncherUnderneath()) {
2828                 flags |= KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
2829             }
2830 
2831             mUpdateMonitor.setKeyguardGoingAway(true);
2832             mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(true);
2833 
2834             // Handled in WmLockscreenVisibilityManager if flag is enabled.
2835             if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
2836                 // Don't actually hide the Keyguard at the moment, wait for window manager until it
2837                 // tells us it's safe to do so with startKeyguardExitAnimation.
2838                 // Posting to mUiOffloadThread to ensure that calls to ActivityTaskManager will be
2839                 // in order.
2840                 final int keyguardFlag = flags;
2841                 mUiBgExecutor.execute(() -> {
2842                     try {
2843                         ActivityTaskManager.getService().keyguardGoingAway(keyguardFlag);
2844                     } catch (RemoteException e) {
2845                         Log.e(TAG, "Error while calling WindowManager", e);
2846                     }
2847                 });
2848             }
2849 
2850             Trace.endSection();
2851         }
2852     };
2853 
2854     private final Runnable mHideAnimationFinishedRunnable = () -> {
2855         Log.e(TAG, "mHideAnimationFinishedRunnable#run");
2856         mHideAnimationRunning = false;
2857         tryKeyguardDone();
2858     };
2859 
2860     private void setUnlockAndWakeFromDream(boolean updatedValue,
2861             @WakeAndUnlockUpdateReason int reason) {
2862         if (!mOrderUnlockAndWake) {
2863             return;
2864         }
2865 
2866         if (updatedValue == mUnlockingAndWakingFromDream) {
2867             return;
2868         }
2869 
2870         final String reasonDescription;
2871 
2872         switch(reason) {
2873             case WakeAndUnlockUpdateReason.FULFILL:
2874                 reasonDescription = "fulfilling existing request";
2875                 break;
2876             case WakeAndUnlockUpdateReason.HIDE:
2877                 reasonDescription = "hiding keyguard";
2878                 break;
2879             case WakeAndUnlockUpdateReason.SHOW:
2880                 reasonDescription = "showing keyguard";
2881                 break;
2882             case WakeAndUnlockUpdateReason.WAKE_AND_UNLOCK:
2883                 reasonDescription = "waking to unlock";
2884                 break;
2885             default:
2886                 throw new IllegalStateException("Unexpected value: " + reason);
2887         }
2888 
2889         final boolean unsetUnfulfilled = !updatedValue
2890                 && reason != WakeAndUnlockUpdateReason.FULFILL;
2891 
2892         mUnlockingAndWakingFromDream = updatedValue;
2893 
2894         final String description;
2895 
2896         if (unsetUnfulfilled) {
2897             description = "Interrupting request to wake and unlock";
2898         } else if (mUnlockingAndWakingFromDream) {
2899             description = "Initiating request to wake and unlock";
2900         } else {
2901             description = "Fulfilling request to wake and unlock";
2902         }
2903 
2904         Log.d(TAG, String.format(
2905                 "Updating waking and unlocking request to %b. description:[%s]. reason:[%s]",
2906                 mUnlockingAndWakingFromDream,  description, reasonDescription));
2907     }
2908 
2909     /**
2910      * Handle message sent by {@link #hideLocked()}
2911      * @see #HIDE
2912      */
2913     private void handleHide() {
2914         Trace.beginSection("KeyguardViewMediator#handleHide");
2915 
2916         // It's possible that the device was unlocked (via BOUNCER) while dozing. It's time to
2917         // wake up.
2918         if (mAodShowing) {
2919             mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
2920                     "com.android.systemui:BOUNCER_DOZING");
2921         }
2922 
2923         synchronized (KeyguardViewMediator.this) {
2924             if (DEBUG) Log.d(TAG, "handleHide");
2925 
2926             mHiding = true;
2927 
2928             // If waking and unlocking, waking from dream has been set properly.
2929             if (!mWakeAndUnlocking) {
2930                 setUnlockAndWakeFromDream(mStatusBarStateController.isDreaming()
2931                         && mPM.isInteractive(), WakeAndUnlockUpdateReason.HIDE);
2932             }
2933 
2934             if ((mShowing && !mOccluded) || mUnlockingAndWakingFromDream) {
2935                 if (mUnlockingAndWakingFromDream) {
2936                     Log.d(TAG, "hiding keyguard before waking from dream");
2937                 }
2938                 mKeyguardGoingAwayRunnable.run();
2939             } else {
2940                 // TODO(bc-unlock): Fill parameters
2941                 mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(() -> {
2942                     handleStartKeyguardExitAnimation(
2943                             mSystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
2944                             mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */,
2945                             null /* nonApps */, null /* finishedCallback */);
2946                 });
2947             }
2948 
2949             // It's possible that the device was unlocked (via BOUNCER or Fingerprint) while
2950             // dreaming. It's time to wake up.
2951             if ((mDreamOverlayShowing || mUpdateMonitor.isDreaming()) && !mOrderUnlockAndWake) {
2952                 mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
2953                         "com.android.systemui:UNLOCK_DREAMING");
2954             }
2955         }
2956         Trace.endSection();
2957     }
2958 
2959     private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration,
2960             RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
2961             RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
2962         Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
2963         Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
2964                 + " fadeoutDuration=" + fadeoutDuration);
2965         synchronized (KeyguardViewMediator.this) {
2966             // Tell ActivityManager that we canceled the keyguard animation if
2967             // handleStartKeyguardExitAnimation was called, but we're not hiding the keyguard,
2968             // unless we're animating the surface behind the keyguard and will be hiding the
2969             // keyguard shortly.
2970             if (!mHiding
2971                     && !mSurfaceBehindRemoteAnimationRequested
2972                     && !mKeyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture()) {
2973                 // If the flag is enabled, remote animation state is handled in
2974                 // WmLockscreenVisibilityManager.
2975                 if (finishedCallback != null
2976                         && !mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
2977                     // There will not execute animation, send a finish callback to ensure the remote
2978                     // animation won't hang there.
2979                     try {
2980                         finishedCallback.onAnimationFinished();
2981                     } catch (RemoteException e) {
2982                         Slog.w(TAG, "Failed to call onAnimationFinished", e);
2983                     }
2984                 }
2985                 setShowingLocked(mShowing, true /* force */);
2986                 return;
2987             }
2988             mHiding = false;
2989             IRemoteAnimationRunner runner = mKeyguardExitAnimationRunner;
2990             mKeyguardExitAnimationRunner = null;
2991 
2992             LatencyTracker.getInstance(mContext)
2993                     .onActionEnd(LatencyTracker.ACTION_LOCKSCREEN_UNLOCK);
2994 
2995             if (runner != null
2996                     && finishedCallback != null) {
2997                 // Wrap finishedCallback to clean up the keyguard state once the animation is done.
2998                 IRemoteAnimationFinishedCallback callback =
2999                         new IRemoteAnimationFinishedCallback() {
3000                             @Override
3001                             public void onAnimationFinished() throws RemoteException {
3002                                 if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3003                                     try {
3004                                         finishedCallback.onAnimationFinished();
3005                                     } catch (RemoteException e) {
3006                                         Slog.w(TAG, "Failed to call onAnimationFinished", e);
3007                                     }
3008                                 }
3009                                 onKeyguardExitFinished();
3010                                 mKeyguardViewControllerLazy.get().hide(0 /* startTime */,
3011                                         0 /* fadeoutDuration */);
3012                                 mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
3013                             }
3014 
3015                             @Override
3016                             public IBinder asBinder() {
3017                                 return finishedCallback.asBinder();
3018                             }
3019                         };
3020                 try {
3021                     mInteractionJankMonitor.begin(
3022                             createInteractionJankMonitorConf(
3023                                     CUJ_LOCKSCREEN_UNLOCK_ANIMATION, "RunRemoteAnimation"));
3024                     runner.onAnimationStart(WindowManager.TRANSIT_KEYGUARD_GOING_AWAY, apps,
3025                             wallpapers, nonApps, callback);
3026                 } catch (RemoteException e) {
3027                     Slog.w(TAG, "Failed to call onAnimationStart", e);
3028                 }
3029 
3030             // When remaining on the shade, there's no need to do a fancy remote animation,
3031             // it will dismiss the panel in that case.
3032             } else if (!mStatusBarStateController.leaveOpenOnKeyguardHide()
3033                     && apps != null && apps.length > 0) {
3034                 if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3035                     // Handled in WmLockscreenVisibilityManager. Other logic in this class will
3036                     // short circuit when this is null.
3037                     mSurfaceBehindRemoteAnimationFinishedCallback = finishedCallback;
3038                 }
3039                 mSurfaceBehindRemoteAnimationRunning = true;
3040 
3041                 mInteractionJankMonitor.begin(
3042                         createInteractionJankMonitorConf(
3043                                 CUJ_LOCKSCREEN_UNLOCK_ANIMATION, "DismissPanel"));
3044 
3045                 // Pass the surface and metadata to the unlock animation controller.
3046                 RemoteAnimationTarget[] openingWallpapers = Arrays.stream(wallpapers).filter(
3047                         w -> w.mode == RemoteAnimationTarget.MODE_OPENING).toArray(
3048                         RemoteAnimationTarget[]::new);
3049                 mKeyguardUnlockAnimationControllerLazy.get()
3050                         .notifyStartSurfaceBehindRemoteAnimation(
3051                                 apps, openingWallpapers, startTime,
3052                                 mSurfaceBehindRemoteAnimationRequested);
3053             } else {
3054                 mInteractionJankMonitor.begin(
3055                         createInteractionJankMonitorConf(
3056                                 CUJ_LOCKSCREEN_UNLOCK_ANIMATION, "RemoteAnimationDisabled"));
3057 
3058                 if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3059                     // Handled directly in StatusBarKeyguardViewManager if enabled.
3060                     mKeyguardViewControllerLazy.get().hide(startTime, fadeoutDuration);
3061                 }
3062 
3063                 // TODO(bc-animation): When remote animation is enabled for keyguard exit animation,
3064                 // apps, wallpapers and finishedCallback are set to non-null. nonApps is not yet
3065                 // supported, so it's always null.
3066                 mContext.getMainExecutor().execute(() -> {
3067                     if (finishedCallback == null) {
3068                         mKeyguardUnlockAnimationControllerLazy.get()
3069                                 .notifyFinishedKeyguardExitAnimation(false /* showKeyguard */);
3070                         mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
3071                         return;
3072                     }
3073                     if (apps == null || apps.length == 0) {
3074                         Slog.e(TAG, "Keyguard exit without a corresponding app to show.");
3075 
3076                         try {
3077                             if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3078                                 finishedCallback.onAnimationFinished();
3079                             }
3080                         } catch (RemoteException e) {
3081                             Slog.e(TAG, "RemoteException");
3082                         } finally {
3083                             mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
3084                         }
3085 
3086                         return;
3087                     }
3088 
3089                     // TODO(bc-unlock): Sample animation, just to apply alpha animation on the app.
3090                     final SyncRtSurfaceTransactionApplier applier =
3091                             new SyncRtSurfaceTransactionApplier(
3092                                     mKeyguardViewControllerLazy.get().getViewRootImpl().getView());
3093                     final RemoteAnimationTarget primary = apps[0];
3094                     ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
3095                     anim.setDuration(400 /* duration */);
3096                     anim.setInterpolator(Interpolators.LINEAR);
3097                     anim.addUpdateListener((ValueAnimator animation) -> {
3098                         SyncRtSurfaceTransactionApplier.SurfaceParams params =
3099                                 new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
3100                                         primary.leash)
3101                                         .withAlpha(animation.getAnimatedFraction())
3102                                         .build();
3103                         applier.scheduleApply(params);
3104                     });
3105                     anim.addListener(new AnimatorListenerAdapter() {
3106                         @Override
3107                         public void onAnimationEnd(Animator animation) {
3108                             try {
3109                                 if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3110                                     finishedCallback.onAnimationFinished();
3111                                 }
3112                             } catch (RemoteException e) {
3113                                 Slog.e(TAG, "RemoteException");
3114                             } finally {
3115                                 mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
3116                             }
3117                         }
3118 
3119                         @Override
3120                         public void onAnimationCancel(Animator animation) {
3121                             try {
3122                                 if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3123                                     finishedCallback.onAnimationFinished();
3124                                 }
3125                             } catch (RemoteException e) {
3126                                 Slog.e(TAG, "RemoteException");
3127                             } finally {
3128                                 mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
3129                             }
3130                         }
3131                     });
3132                     anim.start();
3133                 });
3134 
3135                 onKeyguardExitFinished();
3136             }
3137         }
3138 
3139         Trace.endSection();
3140     }
3141 
3142     private void onKeyguardExitFinished() {
3143         if (DEBUG) Log.d(TAG, "onKeyguardExitFinished()");
3144         // only play "unlock" noises if not on a call (since the incall UI
3145         // disables the keyguard)
3146         if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
3147             playSounds(false);
3148         }
3149 
3150         setShowingLocked(false);
3151         mWakeAndUnlocking = false;
3152         mDismissCallbackRegistry.notifyDismissSucceeded();
3153         resetKeyguardDonePendingLocked();
3154         mHideAnimationRun = false;
3155         adjustStatusBarLocked();
3156         sendUserPresentBroadcast();
3157     }
3158 
3159     private Configuration.Builder createInteractionJankMonitorConf(int cuj) {
3160         return createInteractionJankMonitorConf(cuj, null /* tag */);
3161     }
3162 
3163     private Configuration.Builder createInteractionJankMonitorConf(int cuj, @Nullable String tag) {
3164         final Configuration.Builder builder = Configuration.Builder.withView(
3165                 cuj, mKeyguardViewControllerLazy.get().getViewRootImpl().getView());
3166 
3167         return tag != null ? builder.setTag(tag) : builder;
3168     }
3169 
3170     /**
3171      * Whether we're currently animating between the keyguard and the app/launcher surface behind
3172      * it, or will be shortly (which happens if we started a fling to dismiss the keyguard).
3173      */
3174     public boolean isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe() {
3175         return mSurfaceBehindRemoteAnimationRunning
3176                 || mKeyguardStateController.isFlingingToDismissKeyguard();
3177     }
3178 
3179     /**
3180      * Called if the keyguard exit animation has been cancelled.
3181      *
3182      * This can happen due to the system cancelling the RemoteAnimation (due to a timeout, a new
3183      * app transition before finishing the current RemoteAnimation, or the keyguard being re-shown).
3184      */
3185     private void handleCancelKeyguardExitAnimation() {
3186         if (mPendingLock) {
3187             Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
3188                     + "There's a pending lock, so we were cancelled because the device was locked "
3189                     + "again during the unlock sequence. We should end up locked.");
3190 
3191             // A lock is pending, meaning the keyguard exit animation was cancelled because we're
3192             // re-locking. We should just end the surface-behind animation without exiting the
3193             // keyguard. The pending lock will be handled by onFinishedGoingToSleep().
3194             finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
3195             maybeHandlePendingLock();
3196         } else {
3197             Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
3198                     + "No pending lock, we should end up unlocked with the app/launcher visible.");
3199 
3200             // No lock is pending, so the animation was cancelled during the unlock sequence, but
3201             // we should end up unlocked. Show the surface and exit the keyguard.
3202             showSurfaceBehindKeyguard();
3203             exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* showKeyguard */);
3204         }
3205     }
3206 
3207     /**
3208      * Called when we're done running the keyguard exit animation, we should now end up unlocked.
3209      *
3210      * This will call {@link #handleCancelKeyguardExitAnimation()} to let WM know that we're done
3211      * with the RemoteAnimation, actually hide the keyguard, and clean up state related to the
3212      * keyguard exit animation.
3213      *
3214      * @param showKeyguard {@code true} if the animation was cancelled and keyguard should remain
3215      *                        visible
3216      */
3217     public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean showKeyguard) {
3218         Log.d(TAG, "exitKeyguardAndFinishSurfaceBehindRemoteAnimation");
3219         if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
3220             Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished showKeyguard=" + showKeyguard
3221                     + " surfaceAnimationRunning=" + mSurfaceBehindRemoteAnimationRunning
3222                     + " surfaceAnimationRequested=" + mSurfaceBehindRemoteAnimationRequested);
3223             return;
3224         }
3225 
3226         // Block the panel from expanding, in case we were doing a swipe to dismiss gesture.
3227         mKeyguardViewControllerLazy.get().blockPanelExpansionFromCurrentTouch();
3228         final boolean wasShowing = mShowing;
3229         InteractionJankMonitor.getInstance().end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
3230 
3231         // Post layout changes to the next frame, so we don't hang at the end of the animation.
3232         DejankUtils.postAfterTraversal(() -> {
3233             if (!mPM.isInteractive() && !mPendingLock) {
3234                 Log.e(TAG, "exitKeyguardAndFinishSurfaceBehindRemoteAnimation#postAfterTraversal:"
3235                         + "mPM.isInteractive()=" + mPM.isInteractive()
3236                         + "mPendingLock=" + mPendingLock + "."
3237                         + "One of these being false means we re-locked the device during unlock. "
3238                         + "Do not proceed to finish keyguard exit and unlock.");
3239                 doKeyguardLocked(null);
3240                 finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
3241                 // Ensure WM is notified that we made a decision to show
3242                 setShowingLocked(true /* showing */, true /* force */);
3243 
3244                 return;
3245             }
3246 
3247             onKeyguardExitFinished();
3248 
3249             if (mKeyguardStateController.isDismissingFromSwipe() || wasShowing) {
3250                 Log.d(TAG, "onKeyguardExitRemoteAnimationFinished"
3251                         + "#hideKeyguardViewAfterRemoteAnimation");
3252                 mKeyguardUnlockAnimationControllerLazy.get().hideKeyguardViewAfterRemoteAnimation();
3253             } else {
3254                 Log.d(TAG, "skip hideKeyguardViewAfterRemoteAnimation"
3255                         + " dismissFromSwipe=" + mKeyguardStateController.isDismissingFromSwipe()
3256                         + " wasShowing=" + wasShowing);
3257             }
3258 
3259             finishSurfaceBehindRemoteAnimation(showKeyguard);
3260 
3261             // Dispatch the callback on animation finishes.
3262             mUpdateMonitor.dispatchKeyguardDismissAnimationFinished();
3263         });
3264 
3265     }
3266 
3267     /**
3268      * Tells the ActivityTaskManager that the keyguard is planning to go away, so that it makes the
3269      * surface behind the keyguard visible and calls {@link #handleStartKeyguardExitAnimation} with
3270      * the parameters needed to animate the surface.
3271      */
3272     public void showSurfaceBehindKeyguard() {
3273         mSurfaceBehindRemoteAnimationRequested = true;
3274 
3275         try {
3276             int flags = KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS
3277                     | KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
3278 
3279             // If we are unlocking to the launcher, clear the snapshot so that any changes as part
3280             // of the in-window animations are reflected. This is needed even if we're not actually
3281             // playing in-window animations for this particular unlock since a previous unlock might
3282             // have changed the Launcher state.
3283             if (KeyguardUnlockAnimationController.Companion.isNexusLauncherUnderneath()) {
3284                 flags |= KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
3285             }
3286 
3287             if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
3288                 // Handled in WmLockscreenVisibilityManager.
3289                 ActivityTaskManager.getService().keyguardGoingAway(flags);
3290             }
3291             mKeyguardStateController.notifyKeyguardGoingAway(true);
3292         } catch (RemoteException e) {
3293             mSurfaceBehindRemoteAnimationRequested = false;
3294             e.printStackTrace();
3295         }
3296     }
3297 
3298     /** Hides the surface behind the keyguard by re-showing the keyguard/activity lock screen. */
3299     public void hideSurfaceBehindKeyguard() {
3300         mSurfaceBehindRemoteAnimationRequested = false;
3301         mKeyguardStateController.notifyKeyguardGoingAway(false);
3302         if (mShowing) {
3303             setShowingLocked(true, true);
3304         }
3305     }
3306 
3307     /**
3308      * Whether we have requested to show the surface behind the keyguard, even if it's not yet
3309      * visible due to IPC delay.
3310      */
3311     public boolean requestedShowSurfaceBehindKeyguard() {
3312         return mSurfaceBehindRemoteAnimationRequested;
3313     }
3314 
3315     public boolean isAnimatingBetweenKeyguardAndSurfaceBehind() {
3316         return mSurfaceBehindRemoteAnimationRunning;
3317     }
3318 
3319     /**
3320      * If it's running, finishes the RemoteAnimation on the surface behind the keyguard and resets
3321      * related state.
3322      *
3323      * This does not set keyguard state to either locked or unlocked, it simply ends the remote
3324      * animation on the surface behind the keyguard. This can be called by
3325      */
3326     void finishSurfaceBehindRemoteAnimation(boolean showKeyguard) {
3327         mKeyguardUnlockAnimationControllerLazy.get()
3328                 .notifyFinishedKeyguardExitAnimation(showKeyguard);
3329 
3330         mSurfaceBehindRemoteAnimationRequested = false;
3331         mSurfaceBehindRemoteAnimationRunning = false;
3332         mKeyguardStateController.notifyKeyguardGoingAway(false);
3333 
3334         if (mSurfaceBehindRemoteAnimationFinishedCallback != null) {
3335             try {
3336                 mSurfaceBehindRemoteAnimationFinishedCallback.onAnimationFinished();
3337             } catch (Throwable t) {
3338                 // The surface may no longer be available. Just capture the exception
3339                 Log.w(TAG, "Surface behind remote animation callback failed, and it's probably ok: "
3340                         + t.getMessage());
3341             } finally {
3342                 mSurfaceBehindRemoteAnimationFinishedCallback = null;
3343             }
3344         }
3345     }
3346 
3347     private void adjustStatusBarLocked() {
3348         adjustStatusBarLocked(false /* forceHideHomeRecentsButtons */,
3349                 false /* forceClearFlags */);
3350     }
3351 
3352     private void adjustStatusBarLocked(boolean forceHideHomeRecentsButtons,
3353             boolean forceClearFlags) {
3354         if (mStatusBarManager == null) {
3355             mStatusBarManager = (StatusBarManager)
3356                     mContext.getSystemService(Context.STATUS_BAR_SERVICE);
3357         }
3358 
3359         if (mStatusBarManager == null) {
3360             Log.w(TAG, "Could not get status bar manager");
3361         } else {
3362             // Disable aspects of the system/status/navigation bars that must not be re-enabled by
3363             // windows that appear on top, ever
3364             int flags = StatusBarManager.DISABLE_NONE;
3365 
3366             // TODO (b/155663717) After restart, status bar will not properly hide home button
3367             //  unless disable is called to show un-hide it once first
3368             if (forceClearFlags) {
3369                 try {
3370                     mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
3371                             mContext.getPackageName(), mUserTracker.getUserId());
3372                 } catch (RemoteException e) {
3373                     Log.d(TAG, "Failed to force clear flags", e);
3374                 }
3375             }
3376 
3377             if (forceHideHomeRecentsButtons || isShowingAndNotOccluded()) {
3378                 if (!mShowHomeOverLockscreen || !mInGestureNavigationMode) {
3379                     flags |= StatusBarManager.DISABLE_HOME;
3380                 }
3381                 flags |= StatusBarManager.DISABLE_RECENT;
3382             }
3383 
3384             if (mPowerGestureIntercepted && mOccluded && isSecure()
3385                     && mUpdateMonitor.isFaceEnrolled()) {
3386                 flags |= StatusBarManager.DISABLE_RECENT;
3387             }
3388 
3389             if (DEBUG) {
3390                 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded
3391                         + " isSecure=" + isSecure() + " force=" + forceHideHomeRecentsButtons
3392                         + " mPowerGestureIntercepted=" + mPowerGestureIntercepted
3393                         +  " --> flags=0x" + Integer.toHexString(flags));
3394             }
3395 
3396             try {
3397                 mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
3398                         mContext.getPackageName(), mUserTracker.getUserId());
3399             } catch (RemoteException e) {
3400                 Log.d(TAG, "Failed to set disable flags: " + flags, e);
3401             }
3402         }
3403     }
3404 
3405     /**
3406      * Handle message sent by {@link #resetStateLocked}
3407      * @see #RESET
3408      */
3409     private void handleReset(boolean hideBouncer) {
3410         synchronized (KeyguardViewMediator.this) {
3411             if (DEBUG) Log.d(TAG, "handleReset");
3412             mKeyguardViewControllerLazy.get().reset(hideBouncer);
3413         }
3414 
3415         scheduleNonStrongBiometricIdleTimeout();
3416     }
3417 
3418     /**
3419      * Handle message sent by {@link #verifyUnlock}
3420      * @see #VERIFY_UNLOCK
3421      */
3422     private void handleVerifyUnlock() {
3423         Trace.beginSection("KeyguardViewMediator#handleVerifyUnlock");
3424         synchronized (KeyguardViewMediator.this) {
3425             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
3426             setShowingLocked(true);
3427             mKeyguardViewControllerLazy.get().dismissAndCollapse();
3428         }
3429         Trace.endSection();
3430     }
3431 
3432     private void handleNotifyStartedGoingToSleep() {
3433         synchronized (KeyguardViewMediator.this) {
3434             if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep");
3435             mKeyguardViewControllerLazy.get().onStartedGoingToSleep();
3436         }
3437     }
3438 
3439     /**
3440      * Handle message sent by {@link #notifyFinishedGoingToSleep()}
3441      * @see #NOTIFY_FINISHED_GOING_TO_SLEEP
3442      */
3443     private void handleNotifyFinishedGoingToSleep() {
3444         synchronized (KeyguardViewMediator.this) {
3445             if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
3446             mKeyguardViewControllerLazy.get().onFinishedGoingToSleep();
3447         }
3448     }
3449 
3450     private void handleNotifyStartedWakingUp() {
3451         Trace.beginSection("KeyguardViewMediator#handleMotifyStartedWakingUp");
3452         synchronized (KeyguardViewMediator.this) {
3453             if (DEBUG) Log.d(TAG, "handleNotifyWakingUp");
3454             mKeyguardViewControllerLazy.get().onStartedWakingUp();
3455         }
3456         Trace.endSection();
3457     }
3458 
3459     private void resetKeyguardDonePendingLocked() {
3460         mKeyguardDonePending = false;
3461         mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT);
3462     }
3463 
3464     @Override
3465     public void onBootCompleted() {
3466         synchronized (this) {
3467             if (mContext.getResources().getBoolean(
3468                     com.android.internal.R.bool.config_guestUserAutoCreated)) {
3469                 // TODO(b/191067027): Move post-boot guest creation to system_server
3470                 mUserSwitcherController.schedulePostBootGuestCreation();
3471             }
3472             mBootCompleted = true;
3473             adjustStatusBarLocked(false, true);
3474             if (mBootSendUserPresent) {
3475                 sendUserPresentBroadcast();
3476             }
3477         }
3478     }
3479 
3480     /**
3481      * Informs the keyguard view mediator that the device is waking and unlocking.
3482      * @param fromDream Whether waking and unlocking is happening over an interactive dream.
3483      */
3484     public void onWakeAndUnlocking(boolean fromDream) {
3485         Trace.beginSection("KeyguardViewMediator#onWakeAndUnlocking");
3486         mWakeAndUnlocking = true;
3487         setUnlockAndWakeFromDream(fromDream, WakeAndUnlockUpdateReason.WAKE_AND_UNLOCK);
3488 
3489         mKeyguardViewControllerLazy.get().notifyKeyguardAuthenticated(/* primaryAuth */ false);
3490         userActivity();
3491         Trace.endSection();
3492     }
3493 
3494     /**
3495      * Registers the CentralSurfaces to which the Keyguard View is mounted.
3496      *
3497      * @param centralSurfaces
3498      * @param panelView
3499      * @param biometricUnlockController
3500      * @param notificationContainer
3501      * @param bypassController
3502      * @return the View Controller for the Keyguard View this class is mediating.
3503      */
3504     public KeyguardViewController registerCentralSurfaces(CentralSurfaces centralSurfaces,
3505             ShadeViewController panelView,
3506             @Nullable ShadeExpansionStateManager shadeExpansionStateManager,
3507             BiometricUnlockController biometricUnlockController,
3508             View notificationContainer, KeyguardBypassController bypassController) {
3509         mCentralSurfaces = centralSurfaces;
3510         mKeyguardViewControllerLazy.get().registerCentralSurfaces(
3511                 centralSurfaces,
3512                 panelView,
3513                 shadeExpansionStateManager,
3514                 biometricUnlockController,
3515                 notificationContainer,
3516                 bypassController);
3517         return mKeyguardViewControllerLazy.get();
3518     }
3519 
3520     /**
3521      * Notifies to System UI that the activity behind has now been drawn, and it's safe to remove
3522      * the wallpaper and keyguard flag, and WindowManager has started running keyguard exit
3523      * animation.
3524      *
3525      * @param startTime the start time of the animation in uptime milliseconds. Deprecated.
3526      * @param fadeoutDuration the duration of the exit animation, in milliseconds Deprecated.
3527      * @deprecated Will be migrate to remote animation soon.
3528      */
3529     @Deprecated
3530     public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
3531         startKeyguardExitAnimation(0, startTime, fadeoutDuration, null, null, null, null);
3532     }
3533 
3534     /**
3535      * Notifies to System UI that the activity behind has now been drawn, and it's safe to remove
3536      * the wallpaper and keyguard flag, and System UI should start running keyguard exit animation.
3537      *
3538      * @param apps The list of apps to animate.
3539      * @param wallpapers The list of wallpapers to animate.
3540      * @param nonApps The list of non-app windows such as Bubbles to animate.
3541      * @param finishedCallback The callback to invoke when the animation is finished.
3542      */
3543     public void startKeyguardExitAnimation(@WindowManager.TransitionOldType int transit,
3544             RemoteAnimationTarget[] apps,
3545             RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
3546             IRemoteAnimationFinishedCallback finishedCallback) {
3547         startKeyguardExitAnimation(transit, 0, 0, apps, wallpapers, nonApps, finishedCallback);
3548     }
3549 
3550     /**
3551      * Notifies to System UI that the activity behind has now been drawn, and it's safe to remove
3552      * the wallpaper and keyguard flag, and start running keyguard exit animation.
3553      *
3554      * @param startTime the start time of the animation in uptime milliseconds. Deprecated.
3555      * @param fadeoutDuration the duration of the exit animation, in milliseconds Deprecated.
3556      * @param apps The list of apps to animate.
3557      * @param wallpapers The list of wallpapers to animate.
3558      * @param nonApps The list of non-app windows such as Bubbles to animate.
3559      * @param finishedCallback The callback to invoke when the animation is finished.
3560      */
3561     private void startKeyguardExitAnimation(@WindowManager.TransitionOldType int transit,
3562             long startTime, long fadeoutDuration,
3563             RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
3564             RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
3565         Trace.beginSection("KeyguardViewMediator#startKeyguardExitAnimation");
3566         mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
3567         Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM,
3568                 new StartKeyguardExitAnimParams(transit, startTime, fadeoutDuration, apps,
3569                         wallpapers, nonApps, finishedCallback));
3570         mHandler.sendMessage(msg);
3571         Trace.endSection();
3572     }
3573 
3574     /**
3575      * Cancel the keyguard exit animation, usually because we were swiping to unlock but WM starts
3576      * a new remote animation before finishing the keyguard exit animation.
3577      */
3578     public void cancelKeyguardExitAnimation() {
3579         Trace.beginSection("KeyguardViewMediator#cancelKeyguardExitAnimation");
3580         Message msg = mHandler.obtainMessage(CANCEL_KEYGUARD_EXIT_ANIM);
3581         mHandler.sendMessage(msg);
3582         Trace.endSection();
3583     }
3584 
3585     public void onShortPowerPressedGoHome() {
3586         // do nothing
3587     }
3588 
3589     public void dismissKeyguardToLaunch(Intent intentToLaunch) {
3590         // do nothing
3591     }
3592 
3593     public void onSystemKeyPressed(int keycode) {
3594         // do nothing
3595     }
3596 
3597     public ViewMediatorCallback getViewMediatorCallback() {
3598         return mViewMediatorCallback;
3599     }
3600 
3601     @Override
3602     public void dump(PrintWriter pw, String[] args) {
3603         pw.print("  mSystemReady: "); pw.println(mSystemReady);
3604         pw.print("  mBootCompleted: "); pw.println(mBootCompleted);
3605         pw.print("  mBootSendUserPresent: "); pw.println(mBootSendUserPresent);
3606         pw.print("  mExternallyEnabled: "); pw.println(mExternallyEnabled);
3607         pw.print("  mShuttingDown: "); pw.println(mShuttingDown);
3608         pw.print("  mNeedToReshowWhenReenabled: "); pw.println(mNeedToReshowWhenReenabled);
3609         pw.print("  mShowing: "); pw.println(mShowing);
3610         pw.print("  mInputRestricted: "); pw.println(mInputRestricted);
3611         pw.print("  mOccluded: "); pw.println(mOccluded);
3612         pw.print("  mDelayedShowingSequence: "); pw.println(mDelayedShowingSequence);
3613         pw.print("  mDeviceInteractive: "); pw.println(mDeviceInteractive);
3614         pw.print("  mGoingToSleep: "); pw.println(mGoingToSleep);
3615         pw.print("  mHiding: "); pw.println(mHiding);
3616         pw.print("  mDozing: "); pw.println(mDozing);
3617         pw.print("  mAodShowing: "); pw.println(mAodShowing);
3618         pw.print("  mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible);
3619         pw.print("  mKeyguardDonePending: "); pw.println(mKeyguardDonePending);
3620         pw.print("  mHideAnimationRun: "); pw.println(mHideAnimationRun);
3621         pw.print("  mPendingReset: "); pw.println(mPendingReset);
3622         pw.print("  mPendingLock: "); pw.println(mPendingLock);
3623         pw.print("  wakeAndUnlocking: "); pw.println(mWakeAndUnlocking);
3624         pw.print("  mPendingPinLock: "); pw.println(mPendingPinLock);
3625         pw.print("  mPowerGestureIntercepted: "); pw.println(mPowerGestureIntercepted);
3626     }
3627 
3628     /**
3629      * @param dozing true when AOD - or ambient mode - is showing.
3630      */
3631     public void setDozing(boolean dozing) {
3632         if (dozing == mDozing) {
3633             return;
3634         }
3635         mDozing = dozing;
3636         if (!dozing) {
3637             mAnimatingScreenOff = false;
3638         }
3639 
3640         // Don't hide the keyguard due to a doze change if there's a lock pending, because we're
3641         // just going to show it again.
3642         // If the device is not capable of controlling the screen off animation, SysUI needs to
3643         // update lock screen state in ATMS here, otherwise ATMS tries to resume activities when
3644         // enabling doze state.
3645         if (mShowing || !mPendingLock || !mDozeParameters.canControlUnlockedScreenOff()) {
3646             setShowingLocked(mShowing);
3647         }
3648     }
3649 
3650     @Override
3651     public void onDozeAmountChanged(float linear, float interpolated) {
3652         // If we were animating the screen off, and we've completed the doze animation (doze amount
3653         // is 1f), then show the activity lock screen.
3654         if (mAnimatingScreenOff && mDozing && linear == 1f) {
3655             mAnimatingScreenOff = false;
3656             setShowingLocked(mShowing, true);
3657         }
3658     }
3659 
3660     /**
3661      * Set if the wallpaper supports ambient mode. This is used to trigger the right animation.
3662      * In case it does support it, we have to fade in the incoming app, otherwise we'll reveal it
3663      * with the light reveal scrim.
3664      */
3665     private void setWallpaperSupportsAmbientMode(boolean supportsAmbientMode) {
3666         mWallpaperSupportsAmbientMode = supportsAmbientMode;
3667     }
3668 
3669     private static class StartKeyguardExitAnimParams {
3670 
3671         @WindowManager.TransitionOldType int mTransit;
3672         long startTime;
3673         long fadeoutDuration;
3674         RemoteAnimationTarget[] mApps;
3675         RemoteAnimationTarget[] mWallpapers;
3676         RemoteAnimationTarget[] mNonApps;
3677         IRemoteAnimationFinishedCallback mFinishedCallback;
3678 
3679         private StartKeyguardExitAnimParams(@WindowManager.TransitionOldType int transit,
3680                 long startTime, long fadeoutDuration,
3681                 RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
3682                 RemoteAnimationTarget[] nonApps,
3683                 IRemoteAnimationFinishedCallback finishedCallback) {
3684             this.mTransit = transit;
3685             this.startTime = startTime;
3686             this.fadeoutDuration = fadeoutDuration;
3687             this.mApps = apps;
3688             this.mWallpapers = wallpapers;
3689             this.mNonApps = nonApps;
3690             this.mFinishedCallback = finishedCallback;
3691         }
3692     }
3693 
3694     void setShowingLocked(boolean showing) {
3695         setShowingLocked(showing, false /* forceCallbacks */);
3696     }
3697 
3698     private void setShowingLocked(boolean showing, boolean forceCallbacks) {
3699         final boolean aodShowing = mDozing && !mWakeAndUnlocking;
3700         final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks;
3701         final boolean updateActivityLockScreenState = showing != mShowing
3702                 || aodShowing != mAodShowing || forceCallbacks;
3703         mShowing = showing;
3704         mAodShowing = aodShowing;
3705         if (notifyDefaultDisplayCallbacks) {
3706             notifyDefaultDisplayCallbacks(showing);
3707         }
3708         if (updateActivityLockScreenState) {
3709             updateActivityLockScreenState(showing, aodShowing);
3710         }
3711 
3712     }
3713 
3714     private void notifyDefaultDisplayCallbacks(boolean showing) {
3715         // TODO(b/140053364)
3716         whitelistIpcs(() -> {
3717             int size = mKeyguardStateCallbacks.size();
3718             for (int i = size - 1; i >= 0; i--) {
3719                 IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
3720                 try {
3721                     callback.onShowingStateChanged(showing, KeyguardUpdateMonitor.getCurrentUser());
3722                 } catch (RemoteException e) {
3723                     Slog.w(TAG, "Failed to call onShowingStateChanged", e);
3724                     if (e instanceof DeadObjectException) {
3725                         mKeyguardStateCallbacks.remove(callback);
3726                     }
3727                 }
3728             }
3729         });
3730         updateInputRestrictedLocked();
3731         mUiBgExecutor.execute(() -> {
3732             mTrustManager.reportKeyguardShowingChanged();
3733         });
3734     }
3735 
3736     private void notifyTrustedChangedLocked(boolean trusted) {
3737         int size = mKeyguardStateCallbacks.size();
3738         for (int i = size - 1; i >= 0; i--) {
3739             try {
3740                 mKeyguardStateCallbacks.get(i).onTrustedChanged(trusted);
3741             } catch (RemoteException e) {
3742                 Slog.w(TAG, "Failed to call notifyTrustedChangedLocked", e);
3743                 if (e instanceof DeadObjectException) {
3744                     mKeyguardStateCallbacks.remove(i);
3745                 }
3746             }
3747         }
3748     }
3749 
3750     public void setPendingLock(boolean hasPendingLock) {
3751         mPendingLock = hasPendingLock;
3752         Trace.traceCounter(Trace.TRACE_TAG_APP, "pendingLock", mPendingLock ? 1 : 0);
3753     }
3754 
3755     private boolean isViewRootReady() {
3756         return mKeyguardViewControllerLazy.get().getViewRootImpl() != null;
3757     }
3758 
3759     public void addStateMonitorCallback(IKeyguardStateCallback callback) {
3760         synchronized (this) {
3761             mKeyguardStateCallbacks.add(callback);
3762             try {
3763                 callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
3764                 callback.onShowingStateChanged(mShowing, KeyguardUpdateMonitor.getCurrentUser());
3765                 callback.onInputRestrictedStateChanged(mInputRestricted);
3766                 callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust(
3767                         KeyguardUpdateMonitor.getCurrentUser()));
3768             } catch (RemoteException e) {
3769                 Slog.w(TAG, "Failed to call to IKeyguardStateCallback", e);
3770             }
3771         }
3772     }
3773 
3774     private static class DismissMessage {
3775         private final CharSequence mMessage;
3776         private final IKeyguardDismissCallback mCallback;
3777 
3778         DismissMessage(IKeyguardDismissCallback callback, CharSequence message) {
3779             mCallback = callback;
3780             mMessage = message;
3781         }
3782 
3783         public IKeyguardDismissCallback getCallback() {
3784             return mCallback;
3785         }
3786 
3787         public CharSequence getMessage() {
3788             return mMessage;
3789         }
3790     }
3791 
3792     /**
3793      * Notify whether keyguard has created a remote animation runner for next app launch.
3794      */
3795     public void launchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {
3796         mKeyguardTransitions.setLaunchingActivityOverLockscreen(isLaunchingActivityOverLockscreen);
3797     }
3798 
3799     /**
3800      * Implementation of RemoteAnimationRunner that creates a new
3801      * {@link ActivityLaunchAnimator.Runner} whenever onAnimationStart is called, delegating the
3802      * remote animation methods to that runner.
3803      */
3804     private class ActivityLaunchRemoteAnimationRunner extends IRemoteAnimationRunner.Stub {
3805 
3806         private final ActivityLaunchAnimator.Controller mActivityLaunchController;
3807         @Nullable private ActivityLaunchAnimator.Runner mRunner;
3808 
3809         ActivityLaunchRemoteAnimationRunner(ActivityLaunchAnimator.Controller controller) {
3810             mActivityLaunchController = controller;
3811         }
3812 
3813         @Override
3814         public void onAnimationCancelled() throws RemoteException {
3815             if (mRunner != null) {
3816                 mRunner.onAnimationCancelled();
3817             }
3818         }
3819 
3820         @Override
3821         public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
3822                 RemoteAnimationTarget[] wallpapers,
3823                 RemoteAnimationTarget[] nonApps,
3824                 IRemoteAnimationFinishedCallback finishedCallback)
3825                 throws RemoteException {
3826             mRunner = mActivityLaunchAnimator.get().createRunner(mActivityLaunchController);
3827             mRunner.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
3828         }
3829     }
3830 
3831     /**
3832      * Subclass of {@link ActivityLaunchRemoteAnimationRunner} that calls {@link #setOccluded} when
3833      * onAnimationStart is called.
3834      */
3835     private class OccludeActivityLaunchRemoteAnimationRunner
3836             extends ActivityLaunchRemoteAnimationRunner {
3837 
3838         OccludeActivityLaunchRemoteAnimationRunner(
3839                 ActivityLaunchAnimator.Controller controller) {
3840             super(controller);
3841         }
3842 
3843         @Override
3844         public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
3845                 RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
3846                 IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
3847             super.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
3848 
3849             mInteractionJankMonitor.begin(
3850                     createInteractionJankMonitorConf(CUJ_LOCKSCREEN_OCCLUSION)
3851                             .setTag("OCCLUDE"));
3852 
3853             // This is the first signal we have from WM that we're going to be occluded. Set our
3854             // internal state to reflect that immediately, vs. waiting for the launch animator to
3855             // begin. Otherwise, calls to setShowingLocked, etc. will not know that we're about to
3856             // be occluded and might re-show the keyguard.
3857             Log.d(TAG, "OccludeAnimator#onAnimationStart. Set occluded = true.");
3858             setOccluded(true /* isOccluded */, false /* animate */);
3859         }
3860 
3861         @Override
3862         public void onAnimationCancelled() throws RemoteException {
3863             super.onAnimationCancelled();
3864             Log.d(TAG, "Occlude animation cancelled by WM.");
3865             mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_OCCLUSION);
3866         }
3867     }
3868 
3869     private IRemoteAnimationRunner validatingRemoteAnimationRunner(IRemoteAnimationRunner wrapped) {
3870         return new IRemoteAnimationRunner.Stub() {
3871             @Override
3872             public void onAnimationCancelled() throws RemoteException {
3873                 wrapped.onAnimationCancelled();
3874             }
3875 
3876             @Override
3877             public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
3878                                          RemoteAnimationTarget[] wallpapers,
3879                                          RemoteAnimationTarget[] nonApps,
3880                                          IRemoteAnimationFinishedCallback finishedCallback)
3881                     throws RemoteException {
3882                 if (!isViewRootReady()) {
3883                     Log.w(TAG, "Skipping remote animation - view root not ready");
3884                     return;
3885                 }
3886 
3887                 wrapped.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
3888             }
3889         };
3890     }
3891 }
3892