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