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