1 /*
2  * Copyright (C) 2010 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.statusbar.phone;
18 
19 import static android.app.StatusBarManager.DISABLE_HOME;
20 import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
21 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
22 import static android.app.StatusBarManager.WindowVisibleState;
23 import static android.app.StatusBarManager.windowStateToString;
24 
25 import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
26 import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
27 import static androidx.lifecycle.Lifecycle.State.RESUMED;
28 
29 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
30 import static com.android.systemui.Flags.keyboardShortcutHelperRewrite;
31 import static com.android.systemui.Flags.lightRevealMigration;
32 import static com.android.systemui.Flags.newAodTransition;
33 import static com.android.systemui.Flags.truncatedStatusBarIconsFix;
34 import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
35 import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
36 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
37 import static com.android.systemui.statusbar.StatusBarState.SHADE;
38 
39 import android.annotation.Nullable;
40 import android.app.ActivityOptions;
41 import android.app.IWallpaperManager;
42 import android.app.KeyguardManager;
43 import android.app.Notification;
44 import android.app.NotificationManager;
45 import android.app.PendingIntent;
46 import android.app.StatusBarManager;
47 import android.app.TaskInfo;
48 import android.app.UiModeManager;
49 import android.app.WallpaperManager;
50 import android.app.admin.DevicePolicyManager;
51 import android.content.BroadcastReceiver;
52 import android.content.Context;
53 import android.content.Intent;
54 import android.content.IntentFilter;
55 import android.content.res.Configuration;
56 import android.graphics.Point;
57 import android.hardware.devicestate.DeviceStateManager;
58 import android.hardware.fingerprint.FingerprintManager;
59 import android.metrics.LogMaker;
60 import android.net.Uri;
61 import android.os.Binder;
62 import android.os.Bundle;
63 import android.os.Handler;
64 import android.os.PowerManager;
65 import android.os.RemoteException;
66 import android.os.ServiceManager;
67 import android.os.SystemClock;
68 import android.os.SystemProperties;
69 import android.os.Trace;
70 import android.os.UserHandle;
71 import android.provider.Settings;
72 import android.service.dreams.IDreamManager;
73 import android.service.notification.StatusBarNotification;
74 import android.util.ArraySet;
75 import android.util.DisplayMetrics;
76 import android.util.EventLog;
77 import android.util.IndentingPrintWriter;
78 import android.util.Log;
79 import android.view.Display;
80 import android.view.IRemoteAnimationRunner;
81 import android.view.IWindowManager;
82 import android.view.MotionEvent;
83 import android.view.ThreadedRenderer;
84 import android.view.View;
85 import android.view.WindowInsets;
86 import android.view.WindowManager;
87 import android.view.WindowManagerGlobal;
88 import android.view.accessibility.AccessibilityManager;
89 import android.widget.DateTimeView;
90 
91 import androidx.annotation.NonNull;
92 import androidx.lifecycle.Lifecycle;
93 import androidx.lifecycle.LifecycleRegistry;
94 
95 import com.android.internal.annotations.VisibleForTesting;
96 import com.android.internal.colorextraction.ColorExtractor;
97 import com.android.internal.logging.MetricsLogger;
98 import com.android.internal.logging.UiEvent;
99 import com.android.internal.logging.UiEventLogger;
100 import com.android.internal.logging.UiEventLoggerImpl;
101 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
102 import com.android.internal.statusbar.IStatusBarService;
103 import com.android.internal.statusbar.RegisterStatusBarResult;
104 import com.android.keyguard.AuthKeyguardMessageArea;
105 import com.android.keyguard.KeyguardUpdateMonitor;
106 import com.android.keyguard.KeyguardUpdateMonitorCallback;
107 import com.android.keyguard.ViewMediatorCallback;
108 import com.android.systemui.ActivityIntentHelper;
109 import com.android.systemui.AutoReinflateContainer;
110 import com.android.systemui.CoreStartable;
111 import com.android.systemui.DejankUtils;
112 import com.android.systemui.EventLogTags;
113 import com.android.systemui.InitController;
114 import com.android.systemui.Prefs;
115 import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
116 import com.android.systemui.animation.ActivityTransitionAnimator;
117 import com.android.systemui.assist.AssistManager;
118 import com.android.systemui.back.domain.interactor.BackActionInteractor;
119 import com.android.systemui.biometrics.AuthRippleController;
120 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
121 import com.android.systemui.broadcast.BroadcastDispatcher;
122 import com.android.systemui.camera.CameraIntents;
123 import com.android.systemui.charging.WiredChargingRippleController;
124 import com.android.systemui.charging.WirelessChargingAnimation;
125 import com.android.systemui.classifier.FalsingCollector;
126 import com.android.systemui.colorextraction.SysuiColorExtractor;
127 import com.android.systemui.communal.domain.interactor.CommunalInteractor;
128 import com.android.systemui.dagger.SysUISingleton;
129 import com.android.systemui.dagger.qualifiers.Main;
130 import com.android.systemui.dagger.qualifiers.UiBackground;
131 import com.android.systemui.demomode.DemoMode;
132 import com.android.systemui.demomode.DemoModeController;
133 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor;
134 import com.android.systemui.emergency.EmergencyGesture;
135 import com.android.systemui.emergency.EmergencyGestureModule.EmergencyGestureIntentFactory;
136 import com.android.systemui.flags.FeatureFlags;
137 import com.android.systemui.flags.Flags;
138 import com.android.systemui.fragments.ExtensionFragmentListener;
139 import com.android.systemui.fragments.FragmentHostManager;
140 import com.android.systemui.fragments.FragmentService;
141 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
142 import com.android.systemui.keyguard.KeyguardViewMediator;
143 import com.android.systemui.keyguard.MigrateClocksToBlueprint;
144 import com.android.systemui.keyguard.ScreenLifecycle;
145 import com.android.systemui.keyguard.WakefulnessLifecycle;
146 import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder;
147 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
148 import com.android.systemui.navigationbar.NavigationBarController;
149 import com.android.systemui.navigationbar.NavigationBarView;
150 import com.android.systemui.notetask.NoteTaskController;
151 import com.android.systemui.plugins.ActivityStarter;
152 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
153 import com.android.systemui.plugins.DarkIconDispatcher;
154 import com.android.systemui.plugins.FalsingManager;
155 import com.android.systemui.plugins.OverlayPlugin;
156 import com.android.systemui.plugins.PluginDependencyProvider;
157 import com.android.systemui.plugins.PluginListener;
158 import com.android.systemui.plugins.PluginManager;
159 import com.android.systemui.plugins.qs.QS;
160 import com.android.systemui.plugins.statusbar.StatusBarStateController;
161 import com.android.systemui.power.domain.interactor.PowerInteractor;
162 import com.android.systemui.qs.QSFragmentLegacy;
163 import com.android.systemui.qs.QSPanelController;
164 import com.android.systemui.res.R;
165 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
166 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
167 import com.android.systemui.scrim.ScrimView;
168 import com.android.systemui.settings.UserTracker;
169 import com.android.systemui.settings.brightness.BrightnessSliderController;
170 import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor;
171 import com.android.systemui.shade.CameraLauncher;
172 import com.android.systemui.shade.GlanceableHubContainerController;
173 import com.android.systemui.shade.NotificationShadeWindowView;
174 import com.android.systemui.shade.NotificationShadeWindowViewController;
175 import com.android.systemui.shade.QuickSettingsController;
176 import com.android.systemui.shade.ShadeController;
177 import com.android.systemui.shade.ShadeExpansionChangeEvent;
178 import com.android.systemui.shade.ShadeExpansionListener;
179 import com.android.systemui.shade.ShadeExpansionStateManager;
180 import com.android.systemui.shade.ShadeLogger;
181 import com.android.systemui.shade.ShadeSurface;
182 import com.android.systemui.shade.ShadeViewController;
183 import com.android.systemui.shared.recents.utilities.Utilities;
184 import com.android.systemui.statusbar.AutoHideUiElement;
185 import com.android.systemui.statusbar.CircleReveal;
186 import com.android.systemui.statusbar.CommandQueue;
187 import com.android.systemui.statusbar.GestureRecorder;
188 import com.android.systemui.statusbar.KeyboardShortcutListSearch;
189 import com.android.systemui.statusbar.KeyboardShortcuts;
190 import com.android.systemui.statusbar.KeyguardIndicationController;
191 import com.android.systemui.statusbar.LiftReveal;
192 import com.android.systemui.statusbar.LightRevealScrim;
193 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
194 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
195 import com.android.systemui.statusbar.NotificationMediaManager;
196 import com.android.systemui.statusbar.NotificationPresenter;
197 import com.android.systemui.statusbar.NotificationRemoteInputManager;
198 import com.android.systemui.statusbar.NotificationShadeDepthController;
199 import com.android.systemui.statusbar.NotificationShadeWindowController;
200 import com.android.systemui.statusbar.PowerButtonReveal;
201 import com.android.systemui.statusbar.PulseExpansionHandler;
202 import com.android.systemui.statusbar.StatusBarState;
203 import com.android.systemui.statusbar.SysuiStatusBarStateController;
204 import com.android.systemui.statusbar.core.StatusBarInitializer;
205 import com.android.systemui.statusbar.data.model.StatusBarMode;
206 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore;
207 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
208 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
209 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
210 import com.android.systemui.statusbar.notification.init.NotificationsController;
211 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
212 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
213 import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor;
214 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
215 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
216 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
217 import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
218 import com.android.systemui.statusbar.policy.BatteryController;
219 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
220 import com.android.systemui.statusbar.policy.ConfigurationController;
221 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
222 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
223 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
224 import com.android.systemui.statusbar.policy.ExtensionController;
225 import com.android.systemui.statusbar.policy.HeadsUpManager;
226 import com.android.systemui.statusbar.policy.KeyguardStateController;
227 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
228 import com.android.systemui.statusbar.window.StatusBarWindowController;
229 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
230 import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape;
231 import com.android.systemui.util.DumpUtilsKt;
232 import com.android.systemui.util.WallpaperController;
233 import com.android.systemui.util.concurrency.DelayableExecutor;
234 import com.android.systemui.util.concurrency.MessageRouter;
235 import com.android.systemui.util.kotlin.JavaAdapter;
236 import com.android.systemui.volume.VolumeComponent;
237 import com.android.wm.shell.bubbles.Bubbles;
238 import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
239 import com.android.wm.shell.startingsurface.StartingSurface;
240 
241 import dalvik.annotation.optimization.NeverCompile;
242 
243 import dagger.Lazy;
244 
245 import java.io.PrintWriter;
246 import java.io.StringWriter;
247 import java.util.Map;
248 import java.util.Optional;
249 import java.util.concurrent.Executor;
250 import java.util.function.Consumer;
251 
252 import javax.inject.Inject;
253 import javax.inject.Named;
254 import javax.inject.Provider;
255 
256 /**
257  * A class handling initialization and coordination between some of the key central surfaces in
258  * System UI: The notification shade, the keyguard (lockscreen), and the status bar.
259  *
260  * This class is not our ideal architecture because it doesn't enforce much isolation between these
261  * three mostly disparate surfaces. In an ideal world, this class would not exist. Instead, we would
262  * break it up into three modules -- one for each of those three surfaces -- and we would define any
263  * APIs that are needed for these surfaces to communicate with each other when necessary.
264  *
265  * <b>If at all possible, please avoid adding additional code to this monstrous class! Our goal is
266  * to break up this class into many small classes, and any code added here will slow down that goal.
267  * </b>
268  *
269  * Note that ActivityStarter logic here is deprecated and should be added here as well as
270  * {@link ActivityStarterImpl}
271  */
272 @SysUISingleton
273 public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
274 
275     private static final String BANNER_ACTION_CANCEL =
276             "com.android.systemui.statusbar.banner_action_cancel";
277     private static final String BANNER_ACTION_SETUP =
278             "com.android.systemui.statusbar.banner_action_setup";
279 
280     private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
281     // 1020-1040 reserved for BaseStatusBar
282 
283     private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
284 
285     private final Context mContext;
286     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
287     private final DeviceStateManager mDeviceStateManager;
288     private final Lazy<CentralSurfacesCommandQueueCallbacks> mCommandQueueCallbacksLazy;
289     private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
290     private float mTransitionToFullShadeProgress = 0f;
291     private final NotificationListContainer mNotifListContainer;
292 
293     private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
294             new KeyguardStateController.Callback() {
295                 @Override
296                 public void onKeyguardShowingChanged() {
297                     boolean occluded = mKeyguardStateController.isOccluded();
298                     mStatusBarHideIconsForBouncerManager.setIsOccludedAndTriggerUpdate(occluded);
299                     mScrimController.setKeyguardOccluded(occluded);
300                 }
301             };
302 
onStatusBarWindowStateChanged(@indowVisibleState int state)303     void onStatusBarWindowStateChanged(@WindowVisibleState int state) {
304         mStatusBarWindowState = state;
305         updateBubblesVisibility();
306     }
307 
308     @Override
acquireGestureWakeLock(long time)309     public void acquireGestureWakeLock(long time) {
310         mGestureWakeLock.acquire(time);
311     }
312 
313     @Override
resendMessage(int msg)314     public void resendMessage(int msg) {
315         mMessageRouter.cancelMessages(msg);
316         mMessageRouter.sendMessage(msg);
317     }
318 
319     @Override
resendMessage(Object msg)320     public void resendMessage(Object msg) {
321         mMessageRouter.cancelMessages(msg.getClass());
322         mMessageRouter.sendMessage(msg);
323     }
324 
325     @Override
setLastCameraLaunchSource(int source)326     public void setLastCameraLaunchSource(int source) {
327         mLastCameraLaunchSource = source;
328     }
329 
330     @Override
setLaunchCameraOnFinishedGoingToSleep(boolean launch)331     public void setLaunchCameraOnFinishedGoingToSleep(boolean launch) {
332         mLaunchCameraOnFinishedGoingToSleep = launch;
333     }
334 
335     @Override
setLaunchCameraOnFinishedWaking(boolean launch)336     public void setLaunchCameraOnFinishedWaking(boolean launch) {
337         mLaunchCameraWhenFinishedWaking = launch;
338     }
339 
340     @Override
setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch)341     public void setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch) {
342         mLaunchEmergencyActionOnFinishedGoingToSleep = launch;
343     }
344 
345     @Override
setLaunchEmergencyActionOnFinishedWaking(boolean launch)346     public void setLaunchEmergencyActionOnFinishedWaking(boolean launch) {
347         mLaunchEmergencyActionWhenFinishedWaking = launch;
348     }
349 
350     @Override
getQSPanelController()351     public QSPanelController getQSPanelController() {
352         return mQSPanelController;
353     }
354 
355     /**
356      * The {@link StatusBarState} of the status bar.
357      */
358     protected int mState; // TODO: remove this. Just use StatusBarStateController
359     protected boolean mBouncerShowing;
360 
361     private final PhoneStatusBarPolicy mIconPolicy;
362 
363     private final VolumeComponent mVolumeComponent;
364     private BrightnessMirrorController mBrightnessMirrorController;
365     private boolean mBrightnessMirrorVisible;
366     private BiometricUnlockController mBiometricUnlockController;
367     private final LightBarController mLightBarController;
368     private final AutoHideController mAutoHideController;
369 
370     private final Point mCurrentDisplaySize = new Point();
371 
372     protected PhoneStatusBarView mStatusBarView;
373     private PhoneStatusBarViewController mPhoneStatusBarViewController;
374     private PhoneStatusBarTransitions mStatusBarTransitions;
375     private final AuthRippleController mAuthRippleController;
376     @WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
377     private final NotificationShadeWindowController mNotificationShadeWindowController;
378     private final StatusBarInitializer mStatusBarInitializer;
379     private final StatusBarWindowController mStatusBarWindowController;
380     private final StatusBarModeRepositoryStore mStatusBarModeRepository;
381     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
382     @VisibleForTesting
383     DozeServiceHost mDozeServiceHost;
384     private final LightRevealScrim mLightRevealScrim;
385     private PowerButtonReveal mPowerButtonReveal;
386 
387     /**
388      * Whether we should delay the wakeup animation (which shows the notifications and moves the
389      * clock view). This is typically done when waking up from a 'press to unlock' gesture on a
390      * device with a side fingerprint sensor, so that if the fingerprint scan is successful, we
391      * can play the unlock animation directly rather than interrupting the wakeup animation part
392      * way through.
393      */
394     private boolean mShouldDelayWakeUpAnimation = false;
395 
396     /**
397      * Whether we should delay the AOD->Lockscreen animation.
398      * If false, the animation will start in onStartedWakingUp().
399      * If true, the animation will start in onFinishedWakingUp().
400      */
401     private boolean mShouldDelayLockscreenTransitionFromAod = false;
402 
403     private final Object mQueueLock = new Object();
404 
405     private final PulseExpansionHandler mPulseExpansionHandler;
406     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
407     private final KeyguardBypassController mKeyguardBypassController;
408     private final KeyguardStateController mKeyguardStateController;
409     private final HeadsUpManager mHeadsUpManager;
410     private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
411     private final FalsingCollector mFalsingCollector;
412     private final FalsingManager mFalsingManager;
413     private final BroadcastDispatcher mBroadcastDispatcher;
414     private final ConfigurationController mConfigurationController;
415     private final Lazy<NotificationShadeWindowViewController>
416             mNotificationShadeWindowViewControllerLazy;
417     private final DozeParameters mDozeParameters;
418     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
419     private final PluginManager mPluginManager;
420     private final ShadeController mShadeController;
421     private final WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
422     private final InitController mInitController;
423     private final Lazy<CameraLauncher> mCameraLauncherLazy;
424     private final AlternateBouncerInteractor mAlternateBouncerInteractor;
425 
426     private final PluginDependencyProvider mPluginDependencyProvider;
427     private final ExtensionController mExtensionController;
428     private final UserInfoControllerImpl mUserInfoControllerImpl;
429     private final DemoModeController mDemoModeController;
430     private final NotificationsController mNotificationsController;
431     private final StatusBarSignalPolicy mStatusBarSignalPolicy;
432     private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
433     private final Lazy<LightRevealScrimViewModel> mLightRevealScrimViewModelLazy;
434 
435     /** Controller for the Shade. */
436     private final ShadeSurface mShadeSurface;
437     private final ShadeLogger mShadeLogger;
438 
439     // settings
440     private QSPanelController mQSPanelController;
441     private final QuickSettingsController mQsController;
442 
443     KeyguardIndicationController mKeyguardIndicationController;
444 
445     private View mReportRejectedTouch;
446 
447     private final NotificationGutsManager mGutsManager;
448     private final ShadeExpansionStateManager mShadeExpansionStateManager;
449     private final KeyguardViewMediator mKeyguardViewMediator;
450     private final BrightnessSliderController.Factory mBrightnessSliderFactory;
451     private final FeatureFlags mFeatureFlags;
452     private final FragmentService mFragmentService;
453     private final ScreenOffAnimationController mScreenOffAnimationController;
454     private final WallpaperController mWallpaperController;
455     private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
456     private final MessageRouter mMessageRouter;
457     private final WallpaperManager mWallpaperManager;
458     private final UserTracker mUserTracker;
459     private final Provider<FingerprintManager> mFingerprintManager;
460     private final ActivityStarter mActivityStarter;
461 
462     private final DisplayMetrics mDisplayMetrics;
463 
464     // XXX: gesture research
465     private final GestureRecorder mGestureRec = DEBUG_GESTURES
466         ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
467         : null;
468 
469     private final MetricsLogger mMetricsLogger;
470 
471     // ensure quick settings is disabled until the current user makes it through the setup wizard
472     @VisibleForTesting
473     protected boolean mUserSetup = false;
474 
475     @VisibleForTesting
476     public enum StatusBarUiEvent implements UiEventLogger.UiEventEnum {
477         @UiEvent(doc = "Secured lockscreen is opened.")
478         LOCKSCREEN_OPEN_SECURE(405),
479 
480         @UiEvent(doc = "Lockscreen without security is opened.")
481         LOCKSCREEN_OPEN_INSECURE(406),
482 
483         @UiEvent(doc = "Secured lockscreen is closed.")
484         LOCKSCREEN_CLOSE_SECURE(407),
485 
486         @UiEvent(doc = "Lockscreen without security is closed.")
487         LOCKSCREEN_CLOSE_INSECURE(408),
488 
489         @UiEvent(doc = "Secured bouncer is opened.")
490         BOUNCER_OPEN_SECURE(409),
491 
492         @UiEvent(doc = "Bouncer without security is opened.")
493         BOUNCER_OPEN_INSECURE(410),
494 
495         @UiEvent(doc = "Secured bouncer is closed.")
496         BOUNCER_CLOSE_SECURE(411),
497 
498         @UiEvent(doc = "Bouncer without security is closed.")
499         BOUNCER_CLOSE_INSECURE(412);
500 
501         private final int mId;
502 
StatusBarUiEvent(int id)503         StatusBarUiEvent(int id) {
504             mId = id;
505         }
506 
507         @Override
getId()508         public int getId() {
509             return mId;
510         }
511     }
512 
513     private final DelayableExecutor mMainExecutor;
514 
515     private int mInteractingWindows;
516 
517     private final ViewMediatorCallback mKeyguardViewMediatorCallback;
518     private final ScrimController mScrimController;
519     protected DozeScrimController mDozeScrimController;
520     private final BackActionInteractor mBackActionInteractor;
521     private final JavaAdapter mJavaAdapter;
522     private final Executor mUiBgExecutor;
523 
524     protected boolean mDozing;
525     boolean mCloseQsBeforeScreenOff;
526 
527     private final NotificationMediaManager mMediaManager;
528     private final NotificationLockscreenUserManager mLockscreenUserManager;
529     private final NotificationRemoteInputManager mRemoteInputManager;
530     private boolean mWallpaperSupported;
531 
532     private Runnable mLaunchTransitionEndRunnable;
533     private Runnable mLaunchTransitionCancelRunnable;
534     private boolean mLaunchCameraWhenFinishedWaking;
535     private boolean mLaunchCameraOnFinishedGoingToSleep;
536     private boolean mLaunchEmergencyActionWhenFinishedWaking;
537     private boolean mLaunchEmergencyActionOnFinishedGoingToSleep;
538     private int mLastCameraLaunchSource;
539     protected PowerManager.WakeLock mGestureWakeLock;
540 
541     // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
542     private int mLastLoggedStateFingerprint;
543     private boolean mIsLaunchingActivityOverLockscreen;
544     private boolean mDismissingShadeForActivityLaunch;
545 
546     private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
547     protected final BatteryController mBatteryController;
548     private UiModeManager mUiModeManager;
549     private LogMaker mStatusBarStateLog;
550     protected final NotificationIconAreaController mNotificationIconAreaController;
551     @Nullable private View mAmbientIndicationContainer;
552     private final SysuiColorExtractor mColorExtractor;
553     private final ScreenLifecycle mScreenLifecycle;
554     private final WakefulnessLifecycle mWakefulnessLifecycle;
555     protected final PowerInteractor mPowerInteractor;
556 
557     private final CommunalInteractor mCommunalInteractor;
558 
559     /**
560      * True if the device is showing the glanceable hub. See
561      * {@link CommunalInteractor#isIdleOnCommunal()} for more details.
562      */
563     private boolean mIsIdleOnCommunal = false;
564     private final Consumer<Boolean> mIdleOnCommunalConsumer = (Boolean idleOnCommunal) -> {
565         if (idleOnCommunal == mIsIdleOnCommunal) {
566             // Ignore initial value coming through the flow.
567             return;
568         }
569 
570         mIsIdleOnCommunal = idleOnCommunal;
571         // Trigger an update for the scrim state when we enter or exit glanceable hub, so that we
572         // can transition to/from ScrimState.GLANCEABLE_HUB if needed.
573         updateScrimController();
574     };
575 
576     private boolean mNoAnimationOnNextBarModeChange;
577     private final SysuiStatusBarStateController mStatusBarStateController;
578 
579     private final ActivityTransitionAnimator mActivityTransitionAnimator;
580     private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
581     private final Lazy<NotificationPresenter> mPresenterLazy;
582     private final Lazy<NotificationActivityStarter> mNotificationActivityStarterLazy;
583     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
584     private final Optional<Bubbles> mBubblesOptional;
585     private final Lazy<NoteTaskController> mNoteTaskControllerLazy;
586     private final Optional<StartingSurface> mStartingSurfaceOptional;
587 
588     private final ActivityIntentHelper mActivityIntentHelper;
589 
590     public final NotificationStackScrollLayoutController mStackScrollerController;
591 
592     private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
593             (extractor, which) -> updateTheme();
594     private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor;
595     private final GlanceableHubContainerController mGlanceableHubContainerController;
596 
597     private final EmergencyGestureIntentFactory mEmergencyGestureIntentFactory;
598 
599     /**
600      * Public constructor for CentralSurfaces.
601      *
602      * CentralSurfaces is considered optional, and therefore can not be marked as @Inject directly.
603      * Instead, an @Provide method is included. See {@link StatusBarPhoneModule}.
604      */
605     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
606     @Inject
CentralSurfacesImpl( Context context, NotificationsController notificationsController, FragmentService fragmentService, LightBarController lightBarController, AutoHideController autoHideController, StatusBarInitializer statusBarInitializer, StatusBarWindowController statusBarWindowController, StatusBarWindowStateController statusBarWindowStateController, StatusBarModeRepositoryStore statusBarModeRepository, KeyguardUpdateMonitor keyguardUpdateMonitor, StatusBarSignalPolicy statusBarSignalPolicy, PulseExpansionHandler pulseExpansionHandler, NotificationWakeUpCoordinator notificationWakeUpCoordinator, KeyguardBypassController keyguardBypassController, KeyguardStateController keyguardStateController, HeadsUpManager headsUpManager, FalsingManager falsingManager, FalsingCollector falsingCollector, BroadcastDispatcher broadcastDispatcher, NotificationGutsManager notificationGutsManager, ShadeExpansionStateManager shadeExpansionStateManager, KeyguardViewMediator keyguardViewMediator, DisplayMetrics displayMetrics, MetricsLogger metricsLogger, ShadeLogger shadeLogger, JavaAdapter javaAdapter, @UiBackground Executor uiBgExecutor, ShadeSurface shadeSurface, NotificationMediaManager notificationMediaManager, NotificationLockscreenUserManager lockScreenUserManager, NotificationRemoteInputManager remoteInputManager, QuickSettingsController quickSettingsController, BatteryController batteryController, SysuiColorExtractor colorExtractor, ScreenLifecycle screenLifecycle, WakefulnessLifecycle wakefulnessLifecycle, PowerInteractor powerInteractor, CommunalInteractor communalInteractor, SysuiStatusBarStateController statusBarStateController, Optional<Bubbles> bubblesOptional, Lazy<NoteTaskController> noteTaskControllerLazy, DeviceProvisionedController deviceProvisionedController, NavigationBarController navigationBarController, AccessibilityFloatingMenuController accessibilityFloatingMenuController, Lazy<AssistManager> assistManagerLazy, ConfigurationController configurationController, NotificationShadeWindowController notificationShadeWindowController, Lazy<NotificationShadeWindowViewController> notificationShadeWindowViewControllerLazy, NotificationStackScrollLayoutController notificationStackScrollLayoutController, Lazy<NotificationPresenter> notificationPresenterLazy, Lazy<NotificationActivityStarter> notificationActivityStarterLazy, NotificationLaunchAnimatorControllerProvider notifTransitionAnimatorControllerProvider, DozeParameters dozeParameters, ScrimController scrimController, Lazy<BiometricUnlockController> biometricUnlockControllerLazy, AuthRippleController authRippleController, DozeServiceHost dozeServiceHost, BackActionInteractor backActionInteractor, PowerManager powerManager, DozeScrimController dozeScrimController, VolumeComponent volumeComponent, CommandQueue commandQueue, Lazy<CentralSurfacesCommandQueueCallbacks> commandQueueCallbacksLazy, PluginManager pluginManager, ShadeController shadeController, WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor, StatusBarKeyguardViewManager statusBarKeyguardViewManager, ViewMediatorCallback viewMediatorCallback, InitController initController, @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler, PluginDependencyProvider pluginDependencyProvider, ExtensionController extensionController, UserInfoControllerImpl userInfoControllerImpl, PhoneStatusBarPolicy phoneStatusBarPolicy, KeyguardIndicationController keyguardIndicationController, DemoModeController demoModeController, Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy, StatusBarTouchableRegionManager statusBarTouchableRegionManager, NotificationIconAreaController notificationIconAreaController, BrightnessSliderController.Factory brightnessSliderFactory, ScreenOffAnimationController screenOffAnimationController, WallpaperController wallpaperController, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, LockscreenShadeTransitionController lockscreenShadeTransitionController, FeatureFlags featureFlags, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @Main DelayableExecutor delayableExecutor, @Main MessageRouter messageRouter, WallpaperManager wallpaperManager, Optional<StartingSurface> startingSurfaceOptional, ActivityTransitionAnimator activityTransitionAnimator, DeviceStateManager deviceStateManager, WiredChargingRippleController wiredChargingRippleController, IDreamManager dreamManager, Lazy<CameraLauncher> cameraLauncherLazy, Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy, LightRevealScrim lightRevealScrim, AlternateBouncerInteractor alternateBouncerInteractor, UserTracker userTracker, Provider<FingerprintManager> fingerprintManager, ActivityStarter activityStarter, BrightnessMirrorShowingInteractor brightnessMirrorShowingInteractor, GlanceableHubContainerController glanceableHubContainerController, EmergencyGestureIntentFactory emergencyGestureIntentFactory )607     public CentralSurfacesImpl(
608             Context context,
609             NotificationsController notificationsController,
610             FragmentService fragmentService,
611             LightBarController lightBarController,
612             AutoHideController autoHideController,
613             StatusBarInitializer statusBarInitializer,
614             StatusBarWindowController statusBarWindowController,
615             StatusBarWindowStateController statusBarWindowStateController,
616             StatusBarModeRepositoryStore statusBarModeRepository,
617             KeyguardUpdateMonitor keyguardUpdateMonitor,
618             StatusBarSignalPolicy statusBarSignalPolicy,
619             PulseExpansionHandler pulseExpansionHandler,
620             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
621             KeyguardBypassController keyguardBypassController,
622             KeyguardStateController keyguardStateController,
623             HeadsUpManager headsUpManager,
624             FalsingManager falsingManager,
625             FalsingCollector falsingCollector,
626             BroadcastDispatcher broadcastDispatcher,
627             NotificationGutsManager notificationGutsManager,
628             ShadeExpansionStateManager shadeExpansionStateManager,
629             KeyguardViewMediator keyguardViewMediator,
630             DisplayMetrics displayMetrics,
631             MetricsLogger metricsLogger,
632             ShadeLogger shadeLogger,
633             JavaAdapter javaAdapter,
634             @UiBackground Executor uiBgExecutor,
635             ShadeSurface shadeSurface,
636             NotificationMediaManager notificationMediaManager,
637             NotificationLockscreenUserManager lockScreenUserManager,
638             NotificationRemoteInputManager remoteInputManager,
639             QuickSettingsController quickSettingsController,
640             BatteryController batteryController,
641             SysuiColorExtractor colorExtractor,
642             ScreenLifecycle screenLifecycle,
643             WakefulnessLifecycle wakefulnessLifecycle,
644             PowerInteractor powerInteractor,
645             CommunalInteractor communalInteractor,
646             SysuiStatusBarStateController statusBarStateController,
647             Optional<Bubbles> bubblesOptional,
648             Lazy<NoteTaskController> noteTaskControllerLazy,
649             DeviceProvisionedController deviceProvisionedController,
650             NavigationBarController navigationBarController,
651             AccessibilityFloatingMenuController accessibilityFloatingMenuController,
652             Lazy<AssistManager> assistManagerLazy,
653             ConfigurationController configurationController,
654             NotificationShadeWindowController notificationShadeWindowController,
655             Lazy<NotificationShadeWindowViewController> notificationShadeWindowViewControllerLazy,
656             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
657             // Lazys due to b/298099682.
658             Lazy<NotificationPresenter> notificationPresenterLazy,
659             Lazy<NotificationActivityStarter> notificationActivityStarterLazy,
660             NotificationLaunchAnimatorControllerProvider notifTransitionAnimatorControllerProvider,
661             DozeParameters dozeParameters,
662             ScrimController scrimController,
663             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
664             AuthRippleController authRippleController,
665             DozeServiceHost dozeServiceHost,
666             BackActionInteractor backActionInteractor,
667             PowerManager powerManager,
668             DozeScrimController dozeScrimController,
669             VolumeComponent volumeComponent,
670             CommandQueue commandQueue,
671             Lazy<CentralSurfacesCommandQueueCallbacks> commandQueueCallbacksLazy,
672             PluginManager pluginManager,
673             ShadeController shadeController,
674             WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
675             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
676             ViewMediatorCallback viewMediatorCallback,
677             InitController initController,
678             @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
679             PluginDependencyProvider pluginDependencyProvider,
680             ExtensionController extensionController,
681             UserInfoControllerImpl userInfoControllerImpl,
682             PhoneStatusBarPolicy phoneStatusBarPolicy,
683             KeyguardIndicationController keyguardIndicationController,
684             DemoModeController demoModeController,
685             Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
686             StatusBarTouchableRegionManager statusBarTouchableRegionManager,
687             NotificationIconAreaController notificationIconAreaController,
688             BrightnessSliderController.Factory brightnessSliderFactory,
689             ScreenOffAnimationController screenOffAnimationController,
690             WallpaperController wallpaperController,
691             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
692             LockscreenShadeTransitionController lockscreenShadeTransitionController,
693             FeatureFlags featureFlags,
694             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
695             @Main DelayableExecutor delayableExecutor,
696             @Main MessageRouter messageRouter,
697             WallpaperManager wallpaperManager,
698             Optional<StartingSurface> startingSurfaceOptional,
699             ActivityTransitionAnimator activityTransitionAnimator,
700             DeviceStateManager deviceStateManager,
701             WiredChargingRippleController wiredChargingRippleController,
702             IDreamManager dreamManager,
703             Lazy<CameraLauncher> cameraLauncherLazy,
704             Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy,
705             LightRevealScrim lightRevealScrim,
706             AlternateBouncerInteractor alternateBouncerInteractor,
707             UserTracker userTracker,
708             Provider<FingerprintManager> fingerprintManager,
709             ActivityStarter activityStarter,
710             BrightnessMirrorShowingInteractor brightnessMirrorShowingInteractor,
711             GlanceableHubContainerController glanceableHubContainerController,
712             EmergencyGestureIntentFactory emergencyGestureIntentFactory
713     ) {
714         mContext = context;
715         mNotificationsController = notificationsController;
716         mFragmentService = fragmentService;
717         mLightBarController = lightBarController;
718         mAutoHideController = autoHideController;
719         mStatusBarInitializer = statusBarInitializer;
720         mStatusBarWindowController = statusBarWindowController;
721         mStatusBarModeRepository = statusBarModeRepository;
722         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
723         mPulseExpansionHandler = pulseExpansionHandler;
724         mWakeUpCoordinator = notificationWakeUpCoordinator;
725         mKeyguardBypassController = keyguardBypassController;
726         mKeyguardStateController = keyguardStateController;
727         mHeadsUpManager = headsUpManager;
728         mBackActionInteractor = backActionInteractor;
729         mKeyguardIndicationController = keyguardIndicationController;
730         mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
731         mFalsingCollector = falsingCollector;
732         mFalsingManager = falsingManager;
733         mBroadcastDispatcher = broadcastDispatcher;
734         mGutsManager = notificationGutsManager;
735         mShadeExpansionStateManager = shadeExpansionStateManager;
736         mKeyguardViewMediator = keyguardViewMediator;
737         mDisplayMetrics = displayMetrics;
738         mMetricsLogger = metricsLogger;
739         mShadeLogger = shadeLogger;
740         mJavaAdapter = javaAdapter;
741         mUiBgExecutor = uiBgExecutor;
742         mShadeSurface = shadeSurface;
743         mMediaManager = notificationMediaManager;
744         mLockscreenUserManager = lockScreenUserManager;
745         mRemoteInputManager = remoteInputManager;
746         mQsController = quickSettingsController;
747         mBatteryController = batteryController;
748         mColorExtractor = colorExtractor;
749         mScreenLifecycle = screenLifecycle;
750         mWakefulnessLifecycle = wakefulnessLifecycle;
751         mPowerInteractor = powerInteractor;
752         mCommunalInteractor = communalInteractor;
753         mStatusBarStateController = statusBarStateController;
754         mBubblesOptional = bubblesOptional;
755         mNoteTaskControllerLazy = noteTaskControllerLazy;
756         mDeviceProvisionedController = deviceProvisionedController;
757         mNavigationBarController = navigationBarController;
758         mAccessibilityFloatingMenuController = accessibilityFloatingMenuController;
759         mAssistManagerLazy = assistManagerLazy;
760         mConfigurationController = configurationController;
761         mNotificationShadeWindowController = notificationShadeWindowController;
762         mNotificationShadeWindowViewControllerLazy = notificationShadeWindowViewControllerLazy;
763         mStackScrollerController = notificationStackScrollLayoutController;
764         mStackScroller = mStackScrollerController.getView();
765         mNotifListContainer = mStackScrollerController.getNotificationListContainer();
766         mPresenterLazy = notificationPresenterLazy;
767         mNotificationActivityStarterLazy = notificationActivityStarterLazy;
768         mNotificationAnimationProvider = notifTransitionAnimatorControllerProvider;
769         mDozeServiceHost = dozeServiceHost;
770         mPowerManager = powerManager;
771         mDozeParameters = dozeParameters;
772         mScrimController = scrimController;
773         mDozeScrimController = dozeScrimController;
774         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
775         mAuthRippleController = authRippleController;
776         mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy;
777         mVolumeComponent = volumeComponent;
778         mCommandQueue = commandQueue;
779         mCommandQueueCallbacksLazy = commandQueueCallbacksLazy;
780         mPluginManager = pluginManager;
781         mShadeController = shadeController;
782         mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
783         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
784         mKeyguardViewMediatorCallback = viewMediatorCallback;
785         mInitController = initController;
786         mPluginDependencyProvider = pluginDependencyProvider;
787         mExtensionController = extensionController;
788         mUserInfoControllerImpl = userInfoControllerImpl;
789         mIconPolicy = phoneStatusBarPolicy;
790         mDemoModeController = demoModeController;
791         mNotificationIconAreaController = notificationIconAreaController;
792         mBrightnessSliderFactory = brightnessSliderFactory;
793         mWallpaperController = wallpaperController;
794         mStatusBarSignalPolicy = statusBarSignalPolicy;
795         mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
796         mFeatureFlags = featureFlags;
797         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
798         mMainExecutor = delayableExecutor;
799         mMessageRouter = messageRouter;
800         mWallpaperManager = wallpaperManager;
801         mCameraLauncherLazy = cameraLauncherLazy;
802         mAlternateBouncerInteractor = alternateBouncerInteractor;
803         mUserTracker = userTracker;
804         mFingerprintManager = fingerprintManager;
805         mActivityStarter = activityStarter;
806         mBrightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor;
807         mGlanceableHubContainerController = glanceableHubContainerController;
808         mEmergencyGestureIntentFactory = emergencyGestureIntentFactory;
809 
810         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
811         mStartingSurfaceOptional = startingSurfaceOptional;
812         mDreamManager = dreamManager;
813         lockscreenShadeTransitionController.setCentralSurfaces(this);
814         statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
815 
816         mScreenOffAnimationController = screenOffAnimationController;
817 
818         ShadeExpansionListener shadeExpansionListener = this::onPanelExpansionChanged;
819         ShadeExpansionChangeEvent currentState =
820                 mShadeExpansionStateManager.addExpansionListener(shadeExpansionListener);
821         shadeExpansionListener.onPanelExpansionChanged(currentState);
822 
823         mActivityIntentHelper = new ActivityIntentHelper(mContext);
824         mActivityTransitionAnimator = activityTransitionAnimator;
825 
826         // TODO(b/190746471): Find a better home for this.
827         DateTimeView.setReceiverHandler(timeTickHandler);
828 
829         if (!keyboardShortcutHelperRewrite()) {
830             mMessageRouter.subscribeTo(
831                     KeyboardShortcutsMessage.class,
832                     data -> toggleKeyboardShortcuts(data.mDeviceId));
833             mMessageRouter.subscribeTo(
834                     MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU, id -> dismissKeyboardShortcuts());
835         }
836         mMessageRouter.subscribeTo(AnimateExpandSettingsPanelMessage.class,
837                 data -> mCommandQueueCallbacks.animateExpandSettingsPanel(data.mSubpanel));
838         mMessageRouter.subscribeTo(MSG_LAUNCH_TRANSITION_TIMEOUT,
839                 id -> onLaunchTransitionTimeout());
840 
841         mDeviceStateManager = deviceStateManager;
842         wiredChargingRippleController.registerCallbacks();
843 
844         mLightRevealScrimViewModelLazy = lightRevealScrimViewModelLazy;
845         mLightRevealScrim = lightRevealScrim;
846 
847         if (PredictiveBackSysUiFlag.isEnabled()) {
848             mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
849         }
850     }
851 
initBubbles(Bubbles bubbles)852     private void initBubbles(Bubbles bubbles) {
853         final Bubbles.BubbleExpandListener listener = (isExpanding, key) ->
854                 mContext.getMainExecutor().execute(() -> {
855                     updateScrimController();
856                     mNoteTaskControllerLazy.get().onBubbleExpandChanged(isExpanding, key);
857                 });
858         bubbles.setExpandListener(listener);
859     }
860 
861     @Override
start()862     public void start() {
863         mScreenLifecycle.addObserver(mScreenObserver);
864         mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
865         mUiModeManager = mContext.getSystemService(UiModeManager.class);
866         mBubblesOptional.ifPresent(this::initBubbles);
867         mKeyguardBypassController.listenForQsExpandedChange();
868 
869         mStatusBarSignalPolicy.init();
870         mKeyguardIndicationController.init();
871 
872         mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
873 
874         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
875 
876         mDisplay = mContext.getDisplay();
877         mDisplayId = mDisplay.getDisplayId();
878         updateDisplaySize();
879         mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);
880 
881         initShadeVisibilityListener();
882 
883         // start old BaseStatusBar.start().
884         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
885         mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
886                 Context.DEVICE_POLICY_SERVICE);
887 
888         mAccessibilityManager = (AccessibilityManager)
889                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
890 
891         mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
892         mBarService = IStatusBarService.Stub.asInterface(
893                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
894 
895         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
896         mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
897 
898         RegisterStatusBarResult result = null;
899         try {
900             result = mBarService.registerStatusBar(mCommandQueue);
901         } catch (RemoteException ex) {
902             ex.rethrowFromSystemServer();
903         }
904 
905         createAndAddWindows(result);
906 
907         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
908         setUpPresenter();
909 
910         if ((result.mTransientBarTypes & WindowInsets.Type.statusBars()) != 0) {
911             mStatusBarModeRepository.getDefaultDisplay().showTransient();
912         }
913         mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
914                 result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
915                 result.mRequestedVisibleTypes, result.mPackageName, result.mLetterboxDetails);
916 
917         // StatusBarManagerService has a back up of IME token and it's restored here.
918         mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken,
919                 result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher);
920 
921         // Set up the initial icon state
922         int numIcons = result.mIcons.size();
923         for (int i = 0; i < numIcons; i++) {
924             mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
925         }
926 
927         if (DEBUG) {
928             Log.d(TAG, String.format(
929                     "init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x",
930                     numIcons,
931                     result.mDisabledFlags1,
932                     result.mAppearance,
933                     result.mImeWindowVis));
934         }
935 
936         IntentFilter internalFilter = new IntentFilter();
937         internalFilter.addAction(BANNER_ACTION_CANCEL);
938         internalFilter.addAction(BANNER_ACTION_SETUP);
939         mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
940                 null, Context.RECEIVER_EXPORTED_UNAUDITED);
941 
942         if (mWallpaperSupported) {
943             IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
944                     ServiceManager.getService(Context.WALLPAPER_SERVICE));
945             try {
946                 wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
947             } catch (RemoteException e) {
948                 // Just pass, nothing critical.
949             }
950         }
951 
952         // end old BaseStatusBar.start().
953 
954         // Lastly, call to the icon policy to install/update all the icons.
955         mIconPolicy.init();
956 
957         mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
958             @Override
959             public void onUnlockedChanged() {
960                 logStateToEventlog();
961             }
962 
963             @Override
964             public void onKeyguardGoingAwayChanged() {
965                 if (lightRevealMigration()) {
966                     // This code path is not used if the KeyguardTransitionRepository is managing
967                     // the lightreveal scrim.
968                     return;
969                 }
970 
971                 // The light reveal scrim should always be fully revealed by the time the keyguard
972                 // is done going away. Double check that this is true.
973                 if (!mKeyguardStateController.isKeyguardGoingAway()) {
974                     if (mLightRevealScrim.getRevealAmount() != 1f) {
975                         Log.e(TAG, "Keyguard is done going away, but someone left the light reveal "
976                                 + "scrim at reveal amount: " + mLightRevealScrim.getRevealAmount());
977                     }
978 
979                     // If the auth ripple is still playing, let it finish.
980                     if (!mAuthRippleController.isAnimatingLightRevealScrim()) {
981                         mLightRevealScrim.setRevealAmount(1f);
982                     }
983                 }
984             }
985         });
986         startKeyguard();
987 
988         mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
989         mDozeServiceHost.initialize(
990                 this,
991                 mStatusBarKeyguardViewManager,
992                 getNotificationShadeWindowViewController(),
993                 mAmbientIndicationContainer);
994         updateLightRevealScrimVisibility();
995 
996         mConfigurationController.addCallback(mConfigurationListener);
997 
998         mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback);
999         mLifecycle.setCurrentState(RESUMED);
1000 
1001         mAccessibilityFloatingMenuController.init();
1002 
1003         // set the initial view visibility
1004         int disabledFlags1 = result.mDisabledFlags1;
1005         int disabledFlags2 = result.mDisabledFlags2;
1006         mInitController.addPostInitTask(() -> {
1007             setUpDisableFlags(disabledFlags1, disabledFlags2);
1008             try {
1009                 // NOTE(b/262059863): Force-update the disable flags after applying the flags
1010                 // returned from registerStatusBar(). The result's disabled flags may be stale
1011                 // if StatusBarManager's disabled flags are updated between registering the bar and
1012                 // this handling this post-init task. We force an update in this case, and use a new
1013                 // token to not conflict with any other disabled flags already requested by SysUI
1014                 Binder token = new Binder();
1015                 mBarService.disable(DISABLE_HOME, token, mContext.getPackageName());
1016                 mBarService.disable(0, token, mContext.getPackageName());
1017             } catch (RemoteException ex) {
1018                 ex.rethrowFromSystemServer();
1019             }
1020         });
1021 
1022         registerCallbacks();
1023 
1024         mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);
1025 
1026         mPluginManager.addPluginListener(
1027                 new PluginListener<OverlayPlugin>() {
1028                     private final ArraySet<OverlayPlugin> mOverlays = new ArraySet<>();
1029 
1030                     @Override
1031                     public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
1032                         mMainExecutor.execute(
1033                                 () -> plugin.setup(
1034                                         mNotificationShadeWindowController.getWindowRootView(),
1035                                         getNavigationBarView(),
1036                                         new Callback(plugin), mDozeParameters));
1037                     }
1038 
1039                     @Override
1040                     public void onPluginDisconnected(OverlayPlugin plugin) {
1041                         mMainExecutor.execute(() -> {
1042                             mOverlays.remove(plugin);
1043                             mNotificationShadeWindowController
1044                                     .setForcePluginOpen(mOverlays.size() != 0, this);
1045                         });
1046                     }
1047 
1048                     class Callback implements OverlayPlugin.Callback {
1049                         private final OverlayPlugin mPlugin;
1050 
1051                         Callback(OverlayPlugin plugin) {
1052                             mPlugin = plugin;
1053                         }
1054 
1055                         @Override
1056                         public void onHoldStatusBarOpenChange() {
1057                             if (mPlugin.holdStatusBarOpen()) {
1058                                 mOverlays.add(mPlugin);
1059                             } else {
1060                                 mOverlays.remove(mPlugin);
1061                             }
1062                             mMainExecutor.execute(() -> {
1063                                 mNotificationShadeWindowController
1064                                         .setStateListener(b -> mOverlays.forEach(
1065                                                 o -> o.setCollapseDesired(b)));
1066                                 mNotificationShadeWindowController
1067                                         .setForcePluginOpen(mOverlays.size() != 0, this);
1068                             });
1069                         }
1070                     }
1071                 }, OverlayPlugin.class, true /* Allow multiple plugins */);
1072 
1073         mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
1074                 (requestTopUi, componentTag) -> mMainExecutor.execute(() ->
1075                         mNotificationShadeWindowController.setRequestTopUi(
1076                                 requestTopUi, componentTag))));
1077     }
1078 
1079     @VisibleForTesting
1080     /** Registers listeners/callbacks with external dependencies. */
registerCallbacks()1081     void registerCallbacks() {
1082         //TODO(b/264502026) move the rest of the listeners here.
1083         mDeviceStateManager.registerCallback(mMainExecutor,
1084                 new FoldStateListener(mContext, this::onFoldedStateChanged));
1085 
1086         mJavaAdapter.alwaysCollectFlow(
1087                 mCommunalInteractor.isIdleOnCommunal(),
1088                 mIdleOnCommunalConsumer);
1089         if (SceneContainerFlag.isEnabled()) {
1090             mJavaAdapter.alwaysCollectFlow(
1091                     mBrightnessMirrorShowingInteractor.isShowing(),
1092                     this::setBrightnessMirrorShowing
1093             );
1094         }
1095     }
1096 
1097     /**
1098      * @deprecated use {@link
1099      * WindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible} instead.
1100      */    @VisibleForTesting
1101     @Deprecated
initShadeVisibilityListener()1102     void initShadeVisibilityListener() {
1103         mShadeController.setVisibilityListener(new ShadeController.ShadeVisibilityListener() {
1104             @Override
1105             public void expandedVisibleChanged(boolean expandedVisible) {
1106                 if (expandedVisible) {
1107                     setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1108                 } else {
1109                     onExpandedInvisible();
1110                 }
1111             }
1112         });
1113     }
1114 
onFoldedStateChanged(boolean isFolded, boolean willGoToSleep)1115     private void onFoldedStateChanged(boolean isFolded, boolean willGoToSleep) {
1116         Trace.beginSection("CentralSurfaces#onFoldedStateChanged");
1117         onFoldedStateChangedInternal(isFolded, willGoToSleep);
1118         Trace.endSection();
1119     }
1120 
onFoldedStateChangedInternal(boolean isFolded, boolean willGoToSleep)1121     private void onFoldedStateChangedInternal(boolean isFolded, boolean willGoToSleep) {
1122         // Folded state changes are followed by a screen off event.
1123         // By default turning off the screen also closes the shade.
1124         // We want to make sure that the shade status is kept after folding/unfolding.
1125         boolean isShadeOpen = mShadeController.isShadeFullyOpen();
1126         boolean isShadeExpandingOrCollapsing = mShadeController.isExpandingOrCollapsing();
1127         boolean leaveOpen = isShadeOpen && !willGoToSleep && mState == SHADE;
1128         if (DEBUG) {
1129             Log.d(TAG, String.format(
1130                     "#onFoldedStateChanged(): "
1131                             + "isFolded=%s, "
1132                             + "willGoToSleep=%s, "
1133                             + "isShadeOpen=%s, "
1134                             + "isShadeExpandingOrCollapsing=%s, "
1135                             + "leaveOpen=%s",
1136                     isFolded, willGoToSleep, isShadeOpen, isShadeExpandingOrCollapsing, leaveOpen));
1137         }
1138         if (leaveOpen) {
1139             // below makes shade stay open when going from folded to unfolded
1140             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
1141         }
1142         if (mState != SHADE && (isShadeOpen || isShadeExpandingOrCollapsing)) {
1143             // When device state changes on KEYGUARD/SHADE_LOCKED we don't want to keep the state of
1144             // the shade and instead we open clean state of keyguard with shade closed.
1145             // Normally some parts of QS state (like expanded/collapsed) are persisted and
1146             // that causes incorrect UI rendering, especially when changing state with QS
1147             // expanded. To prevent that we can close QS which resets QS and some parts of
1148             // the shade to its default state. Read more in b/201537421
1149             mCloseQsBeforeScreenOff = true;
1150         }
1151     }
1152 
1153     // ================================================================================
1154     // Constructing the view
1155     // ================================================================================
makeStatusBarView(@ullable RegisterStatusBarResult result)1156     protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
1157         updateDisplaySize(); // populates mDisplayMetrics
1158         updateResources();
1159         updateTheme();
1160 
1161         setUpShade();
1162         getNotificationShadeWindowView().setOnTouchListener(getStatusBarWindowTouchListener());
1163         mWallpaperController.setRootView(getNotificationShadeWindowView());
1164 
1165         mDemoModeController.addCallback(mDemoModeCallback);
1166         mJavaAdapter.alwaysCollectFlow(
1167                 mStatusBarModeRepository.getDefaultDisplay().isTransientShown(),
1168                 this::onTransientShownChanged);
1169         mJavaAdapter.alwaysCollectFlow(
1170                 mStatusBarModeRepository.getDefaultDisplay().getStatusBarMode(),
1171                 this::updateBarMode);
1172 
1173         mCommandQueueCallbacks = mCommandQueueCallbacksLazy.get();
1174         mCommandQueue.addCallback(mCommandQueueCallbacks);
1175 
1176         // TODO: Deal with the ugliness that comes from having some of the status bar broken out
1177         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
1178         ShadeExpansionChangeEvent currentState =
1179                 mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
1180         mWakeUpCoordinator.onPanelExpansionChanged(currentState);
1181 
1182         // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
1183         mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
1184         mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
1185 
1186         // Set up CollapsedStatusBarFragment and PhoneStatusBarView
1187         mStatusBarInitializer.setStatusBarViewUpdatedListener(
1188                 (statusBarView, statusBarViewController, statusBarTransitions) -> {
1189                     mStatusBarView = statusBarView;
1190                     mPhoneStatusBarViewController = statusBarViewController;
1191                     mStatusBarTransitions = statusBarTransitions;
1192                     getNotificationShadeWindowViewController()
1193                             .setStatusBarViewController(mPhoneStatusBarViewController);
1194                     // Ensure we re-propagate panel expansion values to the panel controller and
1195                     // any listeners it may have, such as PanelBar. This will also ensure we
1196                     // re-display the notification panel if necessary (for example, if
1197                     // a heads-up notification was being displayed and should continue being
1198                     // displayed).
1199                     mShadeSurface.updateExpansionAndVisibility();
1200                     setBouncerShowingForStatusBarComponents(mBouncerShowing);
1201                     checkBarModes();
1202                 });
1203         mStatusBarInitializer.initializeStatusBar();
1204 
1205         mStatusBarTouchableRegionManager.setup(getNotificationShadeWindowView());
1206 
1207         createNavigationBar(result);
1208 
1209         mAmbientIndicationContainer = getNotificationShadeWindowView().findViewById(
1210                 R.id.ambient_indication_container);
1211 
1212         mAutoHideController.setStatusBar(new AutoHideUiElement() {
1213             @Override
1214             public void synchronizeState() {
1215                 checkBarModes();
1216             }
1217 
1218             @Override
1219             public boolean shouldHideOnTouch() {
1220                 return !mRemoteInputManager.isRemoteInputActive();
1221             }
1222 
1223             @Override
1224             public boolean isVisible() {
1225                 return isTransientShown();
1226             }
1227 
1228             @Override
1229             public void hide() {
1230                 mStatusBarModeRepository.getDefaultDisplay().clearTransient();
1231             }
1232         });
1233 
1234         ScrimView scrimBehind = getNotificationShadeWindowView().findViewById(R.id.scrim_behind);
1235         ScrimView notificationsScrim = getNotificationShadeWindowView()
1236                 .findViewById(R.id.scrim_notifications);
1237         ScrimView scrimInFront = getNotificationShadeWindowView().findViewById(R.id.scrim_in_front);
1238 
1239         mScrimController.setScrimVisibleListener(scrimsVisible -> {
1240             mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
1241         });
1242         mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
1243 
1244         if (lightRevealMigration()) {
1245             LightRevealScrimViewBinder.bind(
1246                     mLightRevealScrim, mLightRevealScrimViewModelLazy.get());
1247         }
1248 
1249         mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
1250             Runnable updateOpaqueness = () -> {
1251                 mNotificationShadeWindowController.setLightRevealScrimOpaque(
1252                         mLightRevealScrim.isScrimOpaque());
1253                 mScreenOffAnimationController
1254                         .onScrimOpaqueChanged(mLightRevealScrim.isScrimOpaque());
1255             };
1256             if (opaque) {
1257                 // Delay making the view opaque for a frame, because it needs some time to render
1258                 // otherwise this can lead to a flicker where the scrim doesn't cover the screen
1259                 mLightRevealScrim.post(updateOpaqueness);
1260             } else {
1261                 updateOpaqueness.run();
1262             }
1263         });
1264 
1265         mScreenOffAnimationController.initialize(this, mShadeSurface, mLightRevealScrim);
1266         updateLightRevealScrimVisibility();
1267 
1268         if (!SceneContainerFlag.isEnabled()) {
1269             mShadeSurface.initDependencies(
1270                     this,
1271                     mGestureRec,
1272                     mShadeController::makeExpandedInvisible,
1273                     mHeadsUpManager);
1274         }
1275 
1276         // Set up the quick settings tile panel
1277         final View container = getNotificationShadeWindowView().findViewById(R.id.qs_frame);
1278         if (container != null && !SceneContainerFlag.isEnabled()) {
1279             FragmentHostManager fragmentHostManager =
1280                     mFragmentService.getFragmentHostManager(container);
1281             ExtensionFragmentListener.attachExtensonToFragment(
1282                     mFragmentService,
1283                     container,
1284                     QS.TAG,
1285                     R.id.qs_frame,
1286                     mExtensionController
1287                             .newExtension(QS.class)
1288                             .withPlugin(QS.class)
1289                             .withDefault(this::createDefaultQSFragment)
1290                             .build());
1291             mBrightnessMirrorController = new BrightnessMirrorController(
1292                     getNotificationShadeWindowView(),
1293                     mShadeSurface,
1294                     mNotificationShadeDepthControllerLazy.get(),
1295                     mBrightnessSliderFactory,
1296                     this::setBrightnessMirrorShowing);
1297             fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
1298                 QS qs = (QS) f;
1299                 if (qs instanceof QSFragmentLegacy) {
1300                     QSFragmentLegacy qsFragment = (QSFragmentLegacy) qs;
1301                     mQSPanelController = qsFragment.getQSPanelController();
1302                     qsFragment.setBrightnessMirrorController(mBrightnessMirrorController);
1303                 }
1304             });
1305         }
1306 
1307         mReportRejectedTouch = getNotificationShadeWindowView()
1308                 .findViewById(R.id.report_rejected_touch);
1309         if (mReportRejectedTouch != null) {
1310             updateReportRejectedTouchVisibility();
1311             mReportRejectedTouch.setOnClickListener(v -> {
1312                 Uri session = mFalsingManager.reportRejectedTouch();
1313                 if (session == null) { return; }
1314 
1315                 StringWriter message = new StringWriter();
1316                 message.write("Build info: ");
1317                 message.write(SystemProperties.get("ro.build.description"));
1318                 message.write("\nSerial number: ");
1319                 message.write(SystemProperties.get("ro.serialno"));
1320                 message.write("\n");
1321 
1322                 mActivityStarter.startActivityDismissingKeyguard(Intent.createChooser(new Intent(
1323                                                 Intent.ACTION_SEND)
1324                                                 .setType("*/*")
1325                                                 .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch "
1326                                                         + "report")
1327                                                 .putExtra(Intent.EXTRA_STREAM, session)
1328                                                 .putExtra(Intent.EXTRA_TEXT, message.toString()),
1329                                         "Share rejected touch report")
1330                                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
1331                         true /* onlyProvisioned */, true /* dismissShade */);
1332             });
1333         }
1334 
1335         if (!mPowerManager.isInteractive()) {
1336             mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
1337         }
1338         mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1339                 "sysui:GestureWakeLock");
1340 
1341         // receive broadcasts
1342         registerBroadcastReceiver();
1343 
1344         // listen for USER_SETUP_COMPLETE setting (per-user)
1345         mDeviceProvisionedController.addCallback(mUserSetupObserver);
1346         mUserSetupObserver.onUserSetupChanged();
1347 
1348         // disable profiling bars, since they overlap and clutter the output on app windows
1349         ThreadedRenderer.overrideProperty("disableProfileBars", "true");
1350 
1351         // Private API call to make the shadows look better for Recents
1352         ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
1353     }
1354 
setBrightnessMirrorShowing(boolean showing)1355     private void setBrightnessMirrorShowing(boolean showing) {
1356         mBrightnessMirrorVisible = showing;
1357         updateScrimController();
1358     }
1359 
1360     /**
1361      * When swiping up to dismiss the lock screen, the panel expansion fraction goes from 1f to 0f.
1362      * This results in the clock/notifications/other content disappearing off the top of the screen.
1363      *
1364      * We also use the expansion fraction to animate in the app/launcher surface from the bottom of
1365      * the screen, 'pushing' off the notifications and other content. To do this, we dispatch the
1366      * expansion fraction to the KeyguardViewMediator if we're in the process of dismissing the
1367      * keyguard.
1368      */
dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch)1369     private void dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch) {
1370         // Things that mean we're not swiping to dismiss the keyguard, and should ignore this
1371         // expansion:
1372         // - Keyguard isn't even visible.
1373         // - We're swiping on the bouncer, not the lockscreen.
1374         // - Keyguard is occluded. Expansion changes here are the shade being expanded over the
1375         //   occluding activity.
1376         // - Keyguard is visible, but can't be dismissed (swiping up will show PIN/password prompt).
1377         // - The SIM is locked, you can't swipe to unlock. If the SIM is locked but there is no
1378         //   device lock set, canDismissLockScreen returns true even though you should not be able
1379         //   to dismiss the lock screen until entering the SIM PIN.
1380         // - QS is expanded and we're swiping - swiping up now will hide QS, not dismiss the
1381         //   keyguard.
1382         // - Shade is in QQS over keyguard - swiping up should take us back to keyguard
1383         if (!mKeyguardStateController.isShowing()
1384                 || mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing()
1385                 || mKeyguardStateController.isOccluded()
1386                 || !mKeyguardStateController.canDismissLockScreen()
1387                 || mKeyguardViewMediator.isAnySimPinSecure()
1388                 || (mQsController.getExpanded() && trackingTouch)
1389                 || mShadeSurface.getBarState() == StatusBarState.SHADE_LOCKED
1390                 // This last one causes a race condition when the shade resets. Don't send a 0
1391                 // and let StatusBarStateController process a keyguard state change instead
1392                 || 1f - fraction == 0f) {
1393             return;
1394         }
1395 
1396         // Otherwise, we should let the keyguard know about this if we're tracking touch, or if we
1397         // are already animating the keyguard dismiss (since we will need to either finish or cancel
1398         // the animation).
1399         if (trackingTouch
1400                 || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()
1401                 || mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
1402             mKeyguardStateController.notifyKeyguardDismissAmountChanged(
1403                     1f - fraction, trackingTouch);
1404         }
1405     }
1406 
onPanelExpansionChanged(ShadeExpansionChangeEvent event)1407     private void onPanelExpansionChanged(ShadeExpansionChangeEvent event) {
1408         float fraction = event.getFraction();
1409         boolean tracking = event.getTracking();
1410         dispatchPanelExpansionForKeyguardDismiss(fraction, tracking);
1411 
1412         if (fraction == 0 || fraction == 1) {
1413             if (getNavigationBarView() != null) {
1414                 getNavigationBarView().onStatusBarPanelStateChanged();
1415             }
1416             if (getShadeViewController() != null) {
1417                 // Needed to update SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED and
1418                 // SYSUI_STATE_QUICK_SETTINGS_EXPANDED
1419                 getShadeViewController().updateSystemUiStateFlags();
1420             }
1421         }
1422     }
1423 
1424     @NonNull
1425     @Override
getLifecycle()1426     public Lifecycle getLifecycle() {
1427         return mLifecycle;
1428     }
1429 
1430     @VisibleForTesting
registerBroadcastReceiver()1431     protected void registerBroadcastReceiver() {
1432         IntentFilter filter = new IntentFilter();
1433         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
1434         filter.addAction(Intent.ACTION_SCREEN_OFF);
1435         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
1436     }
1437 
createDefaultQSFragment()1438     protected QS createDefaultQSFragment() {
1439         return mFragmentService
1440                 .getFragmentHostManager(getNotificationShadeWindowView())
1441                 .create(QSFragmentLegacy.class);
1442     }
1443 
setUpPresenter()1444     private void setUpPresenter() {
1445         // Set up the initial notification state.
1446         mActivityTransitionAnimator.setCallback(mActivityTransitionAnimatorCallback);
1447         mActivityTransitionAnimator.addListener(mActivityTransitionAnimatorListener);
1448         mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
1449         mStackScrollerController.setNotificationActivityStarter(
1450                 mNotificationActivityStarterLazy.get());
1451         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarterLazy.get());
1452         mShadeController.setNotificationPresenter(mPresenterLazy.get());
1453         mNotificationsController.initialize(
1454                 mPresenterLazy.get(),
1455                 mNotifListContainer,
1456                 mStackScrollerController.getNotifStackController(),
1457                 mNotificationActivityStarterLazy.get());
1458         mWindowRootViewVisibilityInteractor.setUp(mPresenterLazy.get(), mNotificationsController);
1459     }
1460 
1461     /**
1462      * Post-init task of {@link #start()}
1463      * @param state1 disable1 flags
1464      * @param state2 disable2 flags
1465      */
setUpDisableFlags(int state1, int state2)1466     protected void setUpDisableFlags(int state1, int state2) {
1467         mCommandQueue.disable(mDisplayId, state1, state2, false /* animate */);
1468     }
1469 
1470     // TODO(b/117478341): This was left such that CarStatusBar can override this method.
1471     // Try to remove this.
createNavigationBar(@ullable RegisterStatusBarResult result)1472     protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
1473         mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
1474     }
1475 
1476     /**
1477      * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
1478      * background window of the status bar is clicked.
1479      */
getStatusBarWindowTouchListener()1480     protected View.OnTouchListener getStatusBarWindowTouchListener() {
1481         return (v, event) -> {
1482             mAutoHideController.checkUserAutoHide(event);
1483             mRemoteInputManager.checkRemoteInputOutside(event);
1484             if (!MigrateClocksToBlueprint.isEnabled()) {
1485                 mShadeController.onStatusBarTouch(event);
1486             }
1487             return getNotificationShadeWindowView().onTouchEvent(event);
1488         };
1489     }
1490 
setUpShade()1491     private void setUpShade() {
1492         // Ideally, NotificationShadeWindowController could automatically fetch the window root view
1493         // in #attach or a CoreStartable.start method or something similar. But for now, to avoid
1494         // regressions, we'll continue standing up the root view in CentralSurfaces.
1495         mNotificationShadeWindowController.fetchWindowRootView();
1496         getNotificationShadeWindowViewController().setupExpandedStatusBar();
1497         getNotificationShadeWindowViewController().setupCommunalHubLayout();
1498         mShadeController.setNotificationShadeWindowViewController(
1499                 getNotificationShadeWindowViewController());
1500         mBackActionInteractor.setup(mQsController, mShadeSurface);
1501     }
1502 
getNotificationShadeWindowViewController()1503     protected NotificationShadeWindowViewController getNotificationShadeWindowViewController() {
1504         return mNotificationShadeWindowViewControllerLazy.get();
1505     }
1506 
getNotificationShadeWindowView()1507     protected NotificationShadeWindowView getNotificationShadeWindowView() {
1508         return getNotificationShadeWindowViewController().getView();
1509     }
1510 
startKeyguard()1511     protected void startKeyguard() {
1512         Trace.beginSection("CentralSurfaces#startKeyguard");
1513         mStatusBarStateController.addCallback(mStateListener,
1514                 SysuiStatusBarStateController.RANK_STATUS_BAR);
1515         mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
1516         mBiometricUnlockController.addListener(
1517                 new BiometricUnlockController.BiometricUnlockEventsListener() {
1518                     @Override
1519                     public void onResetMode() {
1520                         setWakeAndUnlocking(false);
1521                         notifyBiometricAuthModeChanged();
1522                     }
1523 
1524                     @Override
1525                     public void onModeChanged(int mode) {
1526                         switch (mode) {
1527                             case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM:
1528                             case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING:
1529                             case BiometricUnlockController.MODE_WAKE_AND_UNLOCK:
1530                                 setWakeAndUnlocking(true);
1531                         }
1532                         notifyBiometricAuthModeChanged();
1533                     }
1534 
1535                     private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
1536                         if (getNavigationBarView() != null) {
1537                             getNavigationBarView().setWakeAndUnlocking(wakeAndUnlocking);
1538                         }
1539                     }
1540                 });
1541         mKeyguardViewMediator.registerCentralSurfaces(
1542                 /* statusBar= */ this,
1543                 mShadeSurface,
1544                 mShadeExpansionStateManager,
1545                 mBiometricUnlockController,
1546                 mStackScroller);
1547         mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
1548         mKeyguardIndicationController
1549                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
1550         mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
1551         mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager);
1552 
1553         mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
1554         Trace.endSection();
1555     }
1556 
getShadeViewController()1557     protected ShadeViewController getShadeViewController() {
1558         return mShadeSurface;
1559     }
1560 
1561     @Override
getKeyguardMessageArea()1562     public AuthKeyguardMessageArea getKeyguardMessageArea() {
1563         return getNotificationShadeWindowViewController().getKeyguardMessageArea();
1564     }
1565 
updateReportRejectedTouchVisibility()1566     private void updateReportRejectedTouchVisibility() {
1567         if (mReportRejectedTouch == null) {
1568             return;
1569         }
1570         mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD && !mDozing
1571                 && mFalsingCollector.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
1572     }
1573 
1574     /**
1575      * Whether we are currently animating an activity launch above the lockscreen (occluding
1576      * activity).
1577      */
1578     @Override
isLaunchingActivityOverLockscreen()1579     public boolean isLaunchingActivityOverLockscreen() {
1580         return mIsLaunchingActivityOverLockscreen;
1581     }
1582 
1583     @Override
isDismissingShadeForActivityLaunch()1584     public boolean isDismissingShadeForActivityLaunch() {
1585         return mDismissingShadeForActivityLaunch;
1586     }
1587 
1588     /**
1589      * To be called when there's a state change in StatusBarKeyguardViewManager.
1590      */
1591     @Override
onKeyguardViewManagerStatesUpdated()1592     public void onKeyguardViewManagerStatesUpdated() {
1593         logStateToEventlog();
1594     }
1595 
1596     @VisibleForTesting
1597     @Override
setBarStateForTest(int state)1598     public void setBarStateForTest(int state) {
1599         mState = state;
1600     }
1601 
1602     static class AnimateExpandSettingsPanelMessage {
1603         final String mSubpanel;
1604 
AnimateExpandSettingsPanelMessage(String subpanel)1605         AnimateExpandSettingsPanelMessage(String subpanel) {
1606             mSubpanel = subpanel;
1607         }
1608     }
1609 
maybeEscalateHeadsUp()1610     private void maybeEscalateHeadsUp() {
1611         mHeadsUpManager.getAllEntries().forEach(entry -> {
1612             final StatusBarNotification sbn = entry.getSbn();
1613             final Notification notification = sbn.getNotification();
1614             if (notification.fullScreenIntent != null) {
1615                 if (DEBUG) {
1616                     Log.d(TAG, "converting a heads up to fullScreen");
1617                 }
1618                 try {
1619                     EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
1620                             sbn.getKey());
1621                     mPowerInteractor.wakeUpForFullScreenIntent();
1622                     ActivityOptions opts = ActivityOptions.makeBasic();
1623                     opts.setPendingIntentBackgroundActivityStartMode(
1624                             ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
1625                     notification.fullScreenIntent.send(opts.toBundle());
1626                     entry.notifyFullScreenIntentLaunched();
1627                 } catch (PendingIntent.CanceledException e) {
1628                 }
1629             }
1630         });
1631         mHeadsUpManager.releaseAllImmediately();
1632     }
1633 
onExpandedInvisible()1634     private void onExpandedInvisible() {
1635         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
1636         if (!mNotificationActivityStarterLazy.get().isCollapsingToShowActivityOverLockscreen()) {
1637             showBouncerOrLockScreenIfKeyguard();
1638         } else if (DEBUG) {
1639             Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");
1640         }
1641     }
1642 
1643     @Override
getCommandQueuePanelsEnabled()1644     public boolean getCommandQueuePanelsEnabled() {
1645         return mCommandQueue.panelsEnabled();
1646     }
1647 
onTransientShownChanged(boolean transientShown)1648     private void onTransientShownChanged(boolean transientShown) {
1649         if (transientShown) {
1650             mNoAnimationOnNextBarModeChange = true;
1651         }
1652     }
1653 
updateBarMode(StatusBarMode barMode)1654     private void updateBarMode(StatusBarMode barMode) {
1655         checkBarModes();
1656         mAutoHideController.touchAutoHide();
1657         updateBubblesVisibility();
1658     }
1659 
1660     @Override
showWirelessChargingAnimation(int batteryLevel)1661     public void showWirelessChargingAnimation(int batteryLevel) {
1662         showChargingAnimation(batteryLevel, UNKNOWN_BATTERY_LEVEL, 0);
1663     }
1664 
showChargingAnimation(int batteryLevel, int transmittingBatteryLevel, long animationDelay)1665     protected void showChargingAnimation(int batteryLevel, int transmittingBatteryLevel,
1666             long animationDelay) {
1667         WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
1668                 transmittingBatteryLevel, batteryLevel,
1669                 new WirelessChargingAnimation.Callback() {
1670                     @Override
1671                     public void onAnimationStarting() {
1672                         mNotificationShadeWindowController.setRequestTopUi(true, TAG);
1673                     }
1674 
1675                     @Override
1676                     public void onAnimationEnded() {
1677                         mNotificationShadeWindowController.setRequestTopUi(false, TAG);
1678                     }
1679                 }, /* isDozing= */ false, RippleShape.CIRCLE,
1680                 sUiEventLogger).show(animationDelay);
1681     }
1682 
1683     @Override
checkBarModes()1684     public void checkBarModes() {
1685         if (mDemoModeController.isInDemoMode()) return;
1686         if (mStatusBarTransitions != null) {
1687             checkBarMode(
1688                     mStatusBarModeRepository.getDefaultDisplay().getStatusBarMode().getValue(),
1689                     mStatusBarWindowState,
1690                     mStatusBarTransitions);
1691         }
1692         mNavigationBarController.checkNavBarModes(mDisplayId);
1693         mNoAnimationOnNextBarModeChange = false;
1694     }
1695 
1696     /** Temporarily hides Bubbles if the status bar is hidden. */
1697     @Override
updateBubblesVisibility()1698     public void updateBubblesVisibility() {
1699         StatusBarMode mode =
1700                 mStatusBarModeRepository.getDefaultDisplay().getStatusBarMode().getValue();
1701         mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
1702                 mode != StatusBarMode.LIGHTS_OUT
1703                         && mode != StatusBarMode.LIGHTS_OUT_TRANSPARENT
1704                         && mStatusBarWindowState != WINDOW_STATE_HIDDEN));
1705     }
1706 
checkBarMode( StatusBarMode mode, @WindowVisibleState int windowState, BarTransitions transitions)1707     void checkBarMode(
1708             StatusBarMode mode,
1709             @WindowVisibleState int windowState,
1710             BarTransitions transitions) {
1711         final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive
1712                 && windowState != WINDOW_STATE_HIDDEN;
1713         transitions.transitionTo(mode.toTransitionModeInt(), anim);
1714     }
1715 
finishBarAnimations()1716     private void finishBarAnimations() {
1717         if (mStatusBarTransitions != null) {
1718             mStatusBarTransitions.finishAnimations();
1719         }
1720         mNavigationBarController.finishBarAnimations(mDisplayId);
1721     }
1722 
1723     private final Runnable mCheckBarModes = this::checkBarModes;
1724 
1725     @Override
setInteracting(int barWindow, boolean interacting)1726     public void setInteracting(int barWindow, boolean interacting) {
1727         mInteractingWindows = interacting
1728                 ? (mInteractingWindows | barWindow)
1729                 : (mInteractingWindows & ~barWindow);
1730         if (mInteractingWindows != 0) {
1731             mAutoHideController.suspendAutoHide();
1732         } else {
1733             mAutoHideController.resumeSuspendedAutoHide();
1734         }
1735         checkBarModes();
1736     }
1737 
dismissVolumeDialog()1738     private void dismissVolumeDialog() {
1739         if (mVolumeComponent != null) {
1740             mVolumeComponent.dismissNow();
1741         }
1742     }
1743 
1744     @NeverCompile
1745     @Override
dump(PrintWriter pwOriginal, String[] args)1746     public void dump(PrintWriter pwOriginal, String[] args) {
1747         IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
1748         synchronized (mQueueLock) {
1749             pw.println("Current Status Bar state:");
1750             pw.println("  mExpandedVisible=" + mShadeController.isExpandedVisible());
1751             pw.println("  mDisplayMetrics=" + mDisplayMetrics);
1752             pw.print("  mStackScroller: " + CentralSurfaces.viewInfo(mStackScroller));
1753             pw.print(" scroll " + mStackScroller.getScrollX()
1754                     + "," + mStackScroller.getScrollY());
1755             pw.println(" translationX " + mStackScroller.getTranslationX());
1756         }
1757 
1758         pw.print("  mInteractingWindows="); pw.println(mInteractingWindows);
1759         pw.print("  mStatusBarWindowState=");
1760         pw.println(windowStateToString(mStatusBarWindowState));
1761         pw.print("  mDozing="); pw.println(mDozing);
1762         pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
1763 
1764         CentralSurfaces.dumpBarTransitions(
1765                 pw, "PhoneStatusBarTransitions", mStatusBarTransitions);
1766 
1767         pw.println("  mMediaManager: ");
1768         if (mMediaManager != null) {
1769             mMediaManager.dump(pw, args);
1770         }
1771 
1772         pw.println("  Panels: ");
1773         pw.println("  mStackScroller: " + mStackScroller + " (dump moved)");
1774         pw.println("  Theme:");
1775         String nightMode = mUiModeManager == null ? "null" : mUiModeManager.getNightMode() + "";
1776         pw.println("    dark theme: " + nightMode +
1777                 " (auto: " + UiModeManager.MODE_NIGHT_AUTO +
1778                 ", yes: " + UiModeManager.MODE_NIGHT_YES +
1779                 ", no: " + UiModeManager.MODE_NIGHT_NO + ")");
1780         final boolean lightWpTheme = mContext.getThemeResId()
1781                 == R.style.Theme_SystemUI_LightWallpaper;
1782         pw.println("    light wallpaper theme: " + lightWpTheme);
1783 
1784         if (mKeyguardIndicationController != null) {
1785             mKeyguardIndicationController.dump(pw, args);
1786         }
1787 
1788         if (mScrimController != null) {
1789             mScrimController.dump(pw, args);
1790         }
1791 
1792         if (mLightRevealScrim != null) {
1793             pw.println(
1794                     "mLightRevealScrim.getRevealEffect(): " + mLightRevealScrim.getRevealEffect());
1795             pw.println(
1796                     "mLightRevealScrim.getRevealAmount(): " + mLightRevealScrim.getRevealAmount());
1797         }
1798 
1799         if (mStatusBarKeyguardViewManager != null) {
1800             mStatusBarKeyguardViewManager.dump(pw);
1801         }
1802 
1803         if (DEBUG_GESTURES) {
1804             pw.print("  status bar gestures: ");
1805             mGestureRec.dump(pw, args);
1806         }
1807 
1808         if (mHeadsUpManager != null) {
1809             mHeadsUpManager.dump(pw, args);
1810         } else {
1811             pw.println("  mHeadsUpManager: null");
1812         }
1813 
1814         if (mStatusBarTouchableRegionManager != null) {
1815             mStatusBarTouchableRegionManager.dump(pw, args);
1816         } else {
1817             pw.println("  mStatusBarTouchableRegionManager: null");
1818         }
1819 
1820         if (mLightBarController != null) {
1821             mLightBarController.dump(pw, args);
1822         }
1823 
1824         pw.println("SharedPreferences:");
1825         for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
1826             pw.print("  "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
1827         }
1828 
1829         pw.println("Camera gesture intents:");
1830         pw.println("   Insecure camera: " + CameraIntents.getInsecureCameraIntent(mContext, mUserTracker.getUserId()));
1831         pw.println("   Secure camera: " + CameraIntents.getSecureCameraIntent(mContext, mUserTracker.getUserId()));
1832         pw.println("   Override package: "
1833                 + CameraIntents.getOverrideCameraPackage(mContext, mUserTracker.getUserId()));
1834     }
1835 
createAndAddWindows(@ullable RegisterStatusBarResult result)1836     private void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
1837         makeStatusBarView(result);
1838         mNotificationShadeWindowController.attach();
1839         mStatusBarWindowController.attach();
1840     }
1841 
1842     // called by makeStatusbar and also by PhoneStatusBarView
updateDisplaySize()1843     void updateDisplaySize() {
1844         mDisplay.getMetrics(mDisplayMetrics);
1845         mDisplay.getSize(mCurrentDisplaySize);
1846         if (DEBUG_GESTURES) {
1847             mGestureRec.tag("display",
1848                     String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
1849         }
1850     }
1851 
1852     @Override
1853     @Deprecated
getDisplayDensity()1854     public float getDisplayDensity() {
1855         return mDisplayMetrics.density;
1856     }
1857 
1858     @Override
1859     @Deprecated
getDisplayWidth()1860     public float getDisplayWidth() {
1861         return mDisplayMetrics.widthPixels;
1862     }
1863 
1864     @Override
1865     @Deprecated
getDisplayHeight()1866     public float getDisplayHeight() {
1867         return mDisplayMetrics.heightPixels;
1868     }
1869 
1870     @Override
getRotation()1871     public int getRotation() {
1872         return mDisplay.getRotation();
1873     }
1874 
1875     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1876         @Override
1877         public void onReceive(Context context, Intent intent) {
1878             Trace.beginSection("CentralSurfaces#onReceive");
1879             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
1880             String action = intent.getAction();
1881             String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
1882             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
1883                 if (!keyboardShortcutHelperRewrite()) {
1884                     if (shouldUseTabletKeyboardShortcuts()) {
1885                         KeyboardShortcutListSearch.dismiss();
1886                     } else {
1887                         KeyboardShortcuts.dismiss();
1888                     }
1889                 }
1890                 mRemoteInputManager.closeRemoteInputs();
1891                 if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
1892                     mShadeLogger.d("ACTION_CLOSE_SYSTEM_DIALOGS intent: closing shade");
1893                     int flags = CommandQueue.FLAG_EXCLUDE_NONE;
1894                     if (reason != null) {
1895                         if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
1896                             flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
1897                         }
1898                         // Do not collapse notifications when starting dreaming if the notifications
1899                         // shade is used for the screen off animation. It might require expanded
1900                         // state for the scrims to be visible
1901                         if (reason.equals(SYSTEM_DIALOG_REASON_DREAM)
1902                                 && mScreenOffAnimationController.shouldExpandNotifications()) {
1903                             flags |= CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL;
1904                         }
1905                     }
1906                     mShadeController.animateCollapseShade(flags);
1907                 } else {
1908                     mShadeLogger.d("ACTION_CLOSE_SYSTEM_DIALOGS intent: non-matching user ID");
1909                 }
1910             } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
1911                 if (mNotificationShadeWindowController != null) {
1912                     mNotificationShadeWindowController.setNotTouchable(false);
1913                 }
1914                 finishBarAnimations();
1915                 mNotificationsController.resetUserExpandedStates();
1916             }
1917             Trace.endSection();
1918         }
1919     };
1920 
1921     /**
1922      * Reload some of our resources when the configuration changes.
1923      *
1924      * We don't reload everything when the configuration changes -- we probably
1925      * should, but getting that smooth is tough.  Someday we'll fix that.  In the
1926      * meantime, just update the things that we know change.
1927      */
updateResources()1928     void updateResources() {
1929         // Update the quick setting tiles
1930         if (mQSPanelController != null) {
1931             mQSPanelController.updateResources();
1932         }
1933 
1934         if (!truncatedStatusBarIconsFix()) {
1935             if (mStatusBarWindowController != null) {
1936                 mStatusBarWindowController.refreshStatusBarHeight();
1937             }
1938         }
1939         if (mShadeSurface != null) {
1940             mShadeSurface.updateResources();
1941         }
1942         if (mBrightnessMirrorController != null) {
1943             mBrightnessMirrorController.updateResources();
1944         }
1945         if (mStatusBarKeyguardViewManager != null) {
1946             mStatusBarKeyguardViewManager.updateResources();
1947         }
1948 
1949         mPowerButtonReveal = new PowerButtonReveal(mContext.getResources().getDimensionPixelSize(
1950                 com.android.systemui.res.R.dimen.physical_power_button_center_screen_location_y));
1951     }
1952 
logStateToEventlog()1953     private void logStateToEventlog() {
1954         boolean isShowing = mKeyguardStateController.isShowing();
1955         boolean isOccluded = mKeyguardStateController.isOccluded();
1956         boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
1957         boolean isSecure = mKeyguardStateController.isMethodSecure();
1958         boolean unlocked = mKeyguardStateController.canDismissLockScreen();
1959         int stateFingerprint = getLoggingFingerprint(mState,
1960                 isShowing,
1961                 isOccluded,
1962                 isBouncerShowing,
1963                 isSecure,
1964                 unlocked);
1965         if (stateFingerprint != mLastLoggedStateFingerprint) {
1966             if (mStatusBarStateLog == null) {
1967                 mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
1968             }
1969             mMetricsLogger.write(mStatusBarStateLog
1970                     .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
1971                     .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
1972                     .setSubtype(isSecure ? 1 : 0));
1973             EventLogTags.writeSysuiStatusBarState(mState,
1974                     isShowing ? 1 : 0,
1975                     isOccluded ? 1 : 0,
1976                     isBouncerShowing ? 1 : 0,
1977                     isSecure ? 1 : 0,
1978                     unlocked ? 1 : 0);
1979             mLastLoggedStateFingerprint = stateFingerprint;
1980 
1981             StringBuilder uiEventValueBuilder = new StringBuilder();
1982             uiEventValueBuilder.append(isBouncerShowing ? "BOUNCER" : "LOCKSCREEN");
1983             uiEventValueBuilder.append(isShowing ? "_OPEN" : "_CLOSE");
1984             uiEventValueBuilder.append(isSecure ? "_SECURE" : "_INSECURE");
1985             sUiEventLogger.log(StatusBarUiEvent.valueOf(uiEventValueBuilder.toString()));
1986         }
1987     }
1988 
1989     /**
1990      * Returns a fingerprint of fields logged to eventlog
1991      */
getLoggingFingerprint(int statusBarState, boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing, boolean secure, boolean currentlyInsecure)1992     private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
1993             boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
1994             boolean currentlyInsecure) {
1995         // Reserve 8 bits for statusBarState. We'll never go higher than
1996         // that, right? Riiiight.
1997         return (statusBarState & 0xFF)
1998                 | ((keyguardShowing   ? 1 : 0) <<  8)
1999                 | ((keyguardOccluded  ? 1 : 0) <<  9)
2000                 | ((bouncerShowing    ? 1 : 0) << 10)
2001                 | ((secure            ? 1 : 0) << 11)
2002                 | ((currentlyInsecure ? 1 : 0) << 12);
2003     }
2004 
2005     @Override
showKeyguard()2006     public void showKeyguard() {
2007         mStatusBarStateController.setKeyguardRequested(true);
2008         mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
2009         updateIsKeyguard();
2010         mAssistManagerLazy.get().onLockscreenShown();
2011     }
2012 
2013     @Override
hideKeyguard()2014     public boolean hideKeyguard() {
2015         mStatusBarStateController.setKeyguardRequested(false);
2016         return updateIsKeyguard();
2017     }
2018 
2019     @Override
updateIsKeyguard()2020     public boolean updateIsKeyguard() {
2021         return updateIsKeyguard(false /* forceStateChange */);
2022     }
2023 
2024     @Override
updateIsKeyguard(boolean forceStateChange)2025     public boolean updateIsKeyguard(boolean forceStateChange) {
2026         boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
2027 
2028         // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
2029         // there's no surface we can show to the user. Note that the device goes fully interactive
2030         // late in the transition, so we also allow the device to start dozing once the screen has
2031         // turned off fully.
2032         boolean keyguardShowingUnOccluded =
2033                 mKeyguardStateController.isShowing() && !mKeyguardStateController.isOccluded();
2034         boolean keyguardForDozing = mDozeServiceHost.getDozingRequested()
2035                 && (!mDeviceInteractive || (isGoingToSleep()
2036                 && (isScreenFullyOff() || keyguardShowingUnOccluded)));
2037         boolean isWakingAndOccluded = mKeyguardStateController.isOccluded() && isWakingOrAwake();
2038         boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
2039                 || keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded;
2040         if (keyguardForDozing) {
2041             updatePanelExpansionForKeyguard();
2042         }
2043         if (shouldBeKeyguard) {
2044             if (mScreenOffAnimationController.isKeyguardShowDelayed()
2045                     || (isGoingToSleep()
2046                     && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF)) {
2047                 // Delay showing the keyguard until screen turned off.
2048             } else {
2049                 showKeyguardImpl();
2050             }
2051         } else {
2052             // During folding a foldable device this might be called as a result of
2053             // 'onScreenTurnedOff' call for the inner display.
2054             // In this case:
2055             //  * When phone is locked on folding: it doesn't make sense to hide keyguard as it
2056             //    will be immediately locked again
2057             //  * When phone is unlocked: we still don't want to execute hiding of the keyguard
2058             //    as the animation could prepare 'fake AOD' interface (without actually
2059             //    transitioning to keyguard state) and this might reset the view states
2060             // Log for b/290627350
2061             Log.d(TAG, "!shouldBeKeyguard mStatusBarStateController.isKeyguardRequested() "
2062                     + mStatusBarStateController.isKeyguardRequested() + " keyguardForDozing "
2063                     + keyguardForDozing + " wakeAndUnlocking " + wakeAndUnlocking
2064                     + " isWakingAndOccluded " + isWakingAndOccluded);
2065             if (!mScreenOffAnimationController.isKeyguardHideDelayed()
2066                     // If we're animating occluded, there's an activity launching over the keyguard
2067                     // UI. Wait to hide it until after the animation concludes.
2068                     && !mKeyguardViewMediator.isOccludeAnimationPlaying()) {
2069                 Log.d(TAG, "hideKeyguardImpl " + forceStateChange);
2070                 return hideKeyguardImpl(forceStateChange);
2071             }
2072         }
2073         return false;
2074     }
2075 
2076     @Override
showKeyguardImpl()2077     public void showKeyguardImpl() {
2078         Trace.beginSection("CentralSurfaces#showKeyguard");
2079         if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
2080             mShadeSurface.cancelAnimation();
2081             onLaunchTransitionFadingEnded();
2082         }
2083         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
2084         if (!mLockscreenShadeTransitionController.isWakingToShadeLocked()) {
2085             mStatusBarStateController.setState(StatusBarState.KEYGUARD);
2086         }
2087         updatePanelExpansionForKeyguard();
2088         Trace.endSection();
2089     }
2090 
updatePanelExpansionForKeyguard()2091     private void updatePanelExpansionForKeyguard() {
2092         if (mState == StatusBarState.KEYGUARD && mBiometricUnlockController.getMode()
2093                 != BiometricUnlockController.MODE_WAKE_AND_UNLOCK && !mBouncerShowing) {
2094             mShadeController.instantExpandShade();
2095         }
2096     }
2097 
onLaunchTransitionFadingEnded()2098     private void onLaunchTransitionFadingEnded() {
2099         mShadeSurface.resetAlpha();
2100         mCameraLauncherLazy.get().setLaunchingAffordance(false);
2101         releaseGestureWakeLock();
2102         runLaunchTransitionEndRunnable();
2103         mKeyguardStateController.setLaunchTransitionFadingAway(false);
2104     }
2105 
2106     /**
2107      * Fades the content of the keyguard away after the launch transition is done.
2108      *
2109      * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
2110      *                     starts
2111      * @param endRunnable the runnable to be run when the transition is done. Will not run
2112      *                    if the transition is cancelled, instead cancelRunnable will run
2113      * @param cancelRunnable the runnable to be run if the transition is cancelled
2114      */
2115     @Override
fadeKeyguardAfterLaunchTransition(final Runnable beforeFading, Runnable endRunnable, Runnable cancelRunnable)2116     public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
2117             Runnable endRunnable, Runnable cancelRunnable) {
2118         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
2119         mLaunchTransitionEndRunnable = endRunnable;
2120         mLaunchTransitionCancelRunnable = cancelRunnable;
2121         Runnable hideRunnable = () -> {
2122             mKeyguardStateController.setLaunchTransitionFadingAway(true);
2123             if (beforeFading != null) {
2124                 beforeFading.run();
2125             }
2126             updateScrimController();
2127             mShadeSurface.resetAlpha();
2128             mShadeSurface.fadeOut(
2129                     FADE_KEYGUARD_START_DELAY, FADE_KEYGUARD_DURATION,
2130                     this::onLaunchTransitionFadingEnded);
2131             mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(),
2132                     LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
2133         };
2134         hideRunnable.run();
2135     }
2136 
cancelAfterLaunchTransitionRunnables()2137     private void cancelAfterLaunchTransitionRunnables() {
2138         if (mLaunchTransitionCancelRunnable != null) {
2139             mLaunchTransitionCancelRunnable.run();
2140         }
2141         mLaunchTransitionEndRunnable = null;
2142         mLaunchTransitionCancelRunnable = null;
2143     }
2144 
2145     /**
2146      * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
2147      * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
2148      * because the launched app crashed or something else went wrong.
2149      */
2150     @Override
startLaunchTransitionTimeout()2151     public void startLaunchTransitionTimeout() {
2152         mMessageRouter.sendMessageDelayed(
2153                 MSG_LAUNCH_TRANSITION_TIMEOUT, LAUNCH_TRANSITION_TIMEOUT_MS);
2154     }
2155 
onLaunchTransitionTimeout()2156     private void onLaunchTransitionTimeout() {
2157         Log.w(TAG, "Launch transition: Timeout!");
2158         mCameraLauncherLazy.get().setLaunchingAffordance(false);
2159         releaseGestureWakeLock();
2160         mShadeSurface.resetViews(false /* animate */);
2161     }
2162 
runLaunchTransitionEndRunnable()2163     private void runLaunchTransitionEndRunnable() {
2164         mLaunchTransitionCancelRunnable = null;
2165         if (mLaunchTransitionEndRunnable != null) {
2166             Runnable r = mLaunchTransitionEndRunnable;
2167 
2168             // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
2169             // which would lead to infinite recursion. Protect against it.
2170             mLaunchTransitionEndRunnable = null;
2171             r.run();
2172         }
2173     }
2174 
2175     /**
2176      * @return true if we would like to stay in the shade, false if it should go away entirely
2177      */
2178     @Override
hideKeyguardImpl(boolean forceStateChange)2179     public boolean hideKeyguardImpl(boolean forceStateChange) {
2180         Trace.beginSection("CentralSurfaces#hideKeyguard");
2181         boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
2182         int previousState = mStatusBarStateController.getState();
2183         if (!(mStatusBarStateController.setState(StatusBarState.SHADE, forceStateChange))) {
2184             //TODO: StatusBarStateController should probably know about hiding the keyguard and
2185             // notify listeners.
2186 
2187             // If the state didn't change, we may still need to update public mode
2188             mLockscreenUserManager.updatePublicMode();
2189         }
2190         if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
2191             if (!mStatusBarStateController.isKeyguardRequested()) {
2192                 if (!MigrateClocksToBlueprint.isEnabled()) {
2193                     mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
2194                 }
2195             }
2196             long delay = mKeyguardStateController.calculateGoingToFullShadeDelay();
2197             mLockscreenShadeTransitionController.onHideKeyguard(delay, previousState);
2198 
2199             // Disable layout transitions in navbar for this transition because the load is just
2200             // too heavy for the CPU and GPU on any device.
2201             mNavigationBarController.disableAnimationsDuringHide(mDisplayId, delay);
2202         } else if (!mShadeSurface.isCollapsing()) {
2203             mShadeController.instantCollapseShade();
2204         }
2205 
2206         // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
2207         // visibilities so next time we open the panel we know the correct height already.
2208         if (mQSPanelController != null) {
2209             mQSPanelController.refreshAllTiles();
2210         }
2211         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
2212         releaseGestureWakeLock();
2213         mCameraLauncherLazy.get().setLaunchingAffordance(false);
2214         mShadeSurface.resetAlpha();
2215         mShadeSurface.resetTranslation();
2216         mShadeSurface.resetViewGroupFade();
2217         updateDozingState();
2218         updateScrimController();
2219         Trace.endSection();
2220         return staying;
2221     }
2222 
releaseGestureWakeLock()2223     private void releaseGestureWakeLock() {
2224         if (mGestureWakeLock.isHeld()) {
2225             mGestureWakeLock.release();
2226         }
2227     }
2228 
2229     /**
2230      * Notifies the status bar that Keyguard is going away very soon.
2231      */
2232     @Override
keyguardGoingAway()2233     public void keyguardGoingAway() {
2234         // Treat Keyguard exit animation as an app transition to achieve nice transition for status
2235         // bar.
2236         mKeyguardStateController.notifyKeyguardGoingAway(true);
2237         mCommandQueue.appTransitionPending(mDisplayId, true /* forced */);
2238         updateScrimController();
2239     }
2240 
2241     /**
2242      * Notifies the status bar the Keyguard is fading away with the specified timings.
2243      * @param startTime the start time of the animations in uptime millis
2244      * @param delay the precalculated animation delay in milliseconds
2245      * @param fadeoutDuration the duration of the exit animation, in milliseconds
2246      */
2247     @Override
setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration)2248     public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
2249         mCommandQueue.appTransitionStarting(mDisplayId, startTime + fadeoutDuration
2250                         - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
2251                 LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
2252         mCommandQueue.recomputeDisableFlags(mDisplayId, fadeoutDuration > 0 /* animate */);
2253         mCommandQueue.appTransitionStarting(mDisplayId,
2254                     startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
2255                     LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
2256         mKeyguardStateController.notifyKeyguardFadingAway(delay, fadeoutDuration);
2257     }
2258 
2259     /**
2260      * Notifies that the Keyguard fading away animation is done.
2261      */
2262     @Override
finishKeyguardFadingAway()2263     public void finishKeyguardFadingAway() {
2264         mKeyguardStateController.notifyKeyguardDoneFading();
2265         mScrimController.setExpansionAffectsAlpha(true);
2266 
2267         // If the device was re-locked while unlocking, we might have a pending lock that was
2268         // delayed because the keyguard was in the middle of going away.
2269         mKeyguardViewMediator.maybeHandlePendingLock();
2270     }
2271 
2272     /**
2273      * Switches theme from light to dark and vice-versa.
2274      */
updateTheme()2275     protected void updateTheme() {
2276         // Set additional scrim only if the lock and system wallpaper are different to prevent
2277         // applying the dimming effect twice.
2278         mUiBgExecutor.execute(() -> {
2279             float dimAmount = 0f;
2280             if (mWallpaperManager.lockScreenWallpaperExists()) {
2281                 dimAmount = mWallpaperManager.getWallpaperDimAmount();
2282             }
2283             final float scrimDimAmount = dimAmount;
2284             mMainExecutor.execute(() -> {
2285                 mScrimController.setAdditionalScrimBehindAlphaKeyguard(scrimDimAmount);
2286                 mScrimController.applyCompositeAlphaOnScrimBehindKeyguard();
2287             });
2288         });
2289 
2290         // Lock wallpaper defines the color of the majority of the views, hence we'll use it
2291         // to set our default theme.
2292         final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
2293         final int themeResId = lockDarkText ? R.style.Theme_SystemUI_LightWallpaper
2294                 : R.style.Theme_SystemUI;
2295         if (mContext.getThemeResId() != themeResId) {
2296             mContext.setTheme(themeResId);
2297             mConfigurationController.notifyThemeChanged();
2298         }
2299     }
2300 
shouldDelayWakeUpAnimation()2301     public boolean shouldDelayWakeUpAnimation() {
2302         return mShouldDelayWakeUpAnimation;
2303     }
2304 
updateDozingState()2305     private void updateDozingState() {
2306         if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
2307             Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, "Dozing", 0);
2308             Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, "Dozing", String.valueOf(mDozing),
2309                     0);
2310         }
2311         Trace.beginSection("CentralSurfaces#updateDozingState");
2312 
2313         boolean keyguardVisible = mKeyguardStateController.isVisible();
2314         // If we're dozing and we'll be animating the screen off, the keyguard isn't currently
2315         // visible but will be shortly for the animation, so we should proceed as if it's visible.
2316         boolean keyguardVisibleOrWillBe =
2317                 keyguardVisible || (mDozing && mDozeParameters.shouldDelayKeyguardShow());
2318 
2319         boolean animate = (!mDozing && shouldAnimateDozeWakeup())
2320                 || (mDozing && mDozeParameters.shouldControlScreenOff() && keyguardVisibleOrWillBe);
2321 
2322         mShadeSurface.setDozing(mDozing, animate);
2323         Trace.endSection();
2324     }
2325 
2326     @Override
userActivity()2327     public void userActivity() {
2328         if (mState == StatusBarState.KEYGUARD) {
2329             mKeyguardViewMediatorCallback.userActivity();
2330         }
2331     }
2332 
2333     @Override
endAffordanceLaunch()2334     public void endAffordanceLaunch() {
2335         releaseGestureWakeLock();
2336         mCameraLauncherLazy.get().setLaunchingAffordance(false);
2337     }
2338 
2339     /**
2340      * Returns whether the keyguard should hide immediately (as opposed to via an animation).
2341      * Non-scrimmed bouncers have a special animation tied to the notification panel expansion.
2342      * @return whether the keyguard should be immediately hidden.
2343      */
2344     @Override
shouldKeyguardHideImmediately()2345     public boolean shouldKeyguardHideImmediately() {
2346         return mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
2347     }
2348 
showBouncerOrLockScreenIfKeyguard()2349     private void showBouncerOrLockScreenIfKeyguard() {
2350         // If the keyguard is animating away, we aren't really the keyguard anymore and should not
2351         // show the bouncer/lockscreen.
2352         if (!mKeyguardViewMediator.isHiding() && !mKeyguardUpdateMonitor.isKeyguardGoingAway()) {
2353             if (mState == StatusBarState.SHADE_LOCKED) {
2354                 // shade is showing while locked on the keyguard, so go back to showing the
2355                 // lock screen where users can use the UDFPS affordance to enter the device
2356                 mStatusBarKeyguardViewManager.reset(true);
2357             } else if (mState == StatusBarState.KEYGUARD
2358                     && !mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing()
2359                     && mStatusBarKeyguardViewManager.isSecure()) {
2360                 Log.d(TAG, "showBouncerOrLockScreenIfKeyguard, showingBouncer");
2361                 mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */);
2362             }
2363         }
2364     }
2365 
2366     /**
2367      * Show the bouncer if we're currently on the keyguard or shade locked and aren't hiding.
2368      * @param performAction the action to perform when the bouncer is dismissed.
2369      * @param cancelAction the action to perform when unlock is aborted.
2370      */
2371     @Override
showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction, Runnable cancelAction)2372     public void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
2373             Runnable cancelAction) {
2374         if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
2375                 && !mKeyguardViewMediator.isHiding()) {
2376             mStatusBarKeyguardViewManager.dismissWithAction(performAction, cancelAction,
2377                     false /* afterKeyguardGone */);
2378         } else if (cancelAction != null) {
2379             cancelAction.run();
2380         }
2381     }
2382 
2383     /**
2384      * Updates the light reveal effect to reflect the reason we're waking or sleeping (for example,
2385      * from the power button).
2386      * @param wakingUp Whether we're updating because we're waking up (true) or going to sleep
2387      *                 (false).
2388      */
updateRevealEffect(boolean wakingUp)2389     private void updateRevealEffect(boolean wakingUp) {
2390         if (mLightRevealScrim == null) {
2391             return;
2392         }
2393 
2394         if (lightRevealMigration()) {
2395             return;
2396         }
2397 
2398         final boolean wakingUpFromPowerButton = wakingUp
2399                 && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)
2400                 && mWakefulnessLifecycle.getLastWakeReason()
2401                 == PowerManager.WAKE_REASON_POWER_BUTTON;
2402         final boolean sleepingFromPowerButton = !wakingUp
2403                 && mWakefulnessLifecycle.getLastSleepReason()
2404                 == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON;
2405 
2406         if (wakingUpFromPowerButton || sleepingFromPowerButton) {
2407             mLightRevealScrim.setRevealEffect(mPowerButtonReveal);
2408             mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
2409         } else if (!wakingUp || !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
2410             // If we're going to sleep, but it's not from the power button, use the default reveal.
2411             // If we're waking up, only use the default reveal if the biometric controller didn't
2412             // already set it to the circular reveal because we're waking up from a fingerprint/face
2413             // auth.
2414             mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
2415             mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
2416         }
2417     }
2418 
2419     // TODO: Figure out way to remove these.
2420     @Override
getNavigationBarView()2421     public NavigationBarView getNavigationBarView() {
2422         return mNavigationBarController.getNavigationBarView(mDisplayId);
2423     }
2424 
2425     /**
2426      * Propagation of the bouncer state, indicating that it's fully visible.
2427      */
2428     @Override
setBouncerShowing(boolean bouncerShowing)2429     public void setBouncerShowing(boolean bouncerShowing) {
2430         mBouncerShowing = bouncerShowing;
2431         mKeyguardBypassController.setBouncerShowing(bouncerShowing);
2432         mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
2433         setBouncerShowingForStatusBarComponents(bouncerShowing);
2434         mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
2435         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
2436         if (mBouncerShowing) {
2437             mPowerInteractor.wakeUpIfDozing("BOUNCER_VISIBLE", PowerManager.WAKE_REASON_GESTURE);
2438         }
2439         updateScrimController();
2440         if (!mBouncerShowing) {
2441             updatePanelExpansionForKeyguard();
2442         }
2443     }
2444 
2445     /**
2446      * Propagate the bouncer state to status bar components.
2447      *
2448      * Separate from {@link #setBouncerShowing} because we sometimes re-create the status bar and
2449      * should update only the status bar components.
2450      */
setBouncerShowingForStatusBarComponents(boolean bouncerShowing)2451     private void setBouncerShowingForStatusBarComponents(boolean bouncerShowing) {
2452         int importance = bouncerShowing
2453                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2454                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO;
2455         if (mPhoneStatusBarViewController != null) {
2456             mPhoneStatusBarViewController.setImportantForAccessibility(importance);
2457         }
2458         mShadeSurface.setImportantForAccessibility(importance);
2459         mShadeSurface.setBouncerShowing(bouncerShowing);
2460     }
2461 
2462     @VisibleForTesting
2463     final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
2464         @Override
2465         public void onFinishedGoingToSleep() {
2466             mCameraLauncherLazy.get().setLaunchingAffordance(false);
2467             releaseGestureWakeLock();
2468             mLaunchCameraWhenFinishedWaking = false;
2469             mDeviceInteractive = false;
2470 
2471             updateNotificationPanelTouchState();
2472             getNotificationShadeWindowViewController().cancelCurrentTouch();
2473             if (mLaunchCameraOnFinishedGoingToSleep) {
2474                 mLaunchCameraOnFinishedGoingToSleep = false;
2475 
2476                 // This gets executed before we will show Keyguard, so post it in order that the state
2477                 // is correct.
2478                 mMainExecutor.execute(() -> mCommandQueueCallbacks.onCameraLaunchGestureDetected(
2479                         mLastCameraLaunchSource));
2480             }
2481 
2482             if (mLaunchEmergencyActionOnFinishedGoingToSleep) {
2483                 mLaunchEmergencyActionOnFinishedGoingToSleep = false;
2484 
2485                 // This gets executed before we will show Keyguard, so post it in order that the
2486                 // state is correct.
2487                 mMainExecutor.execute(
2488                         () -> mCommandQueueCallbacks.onEmergencyActionLaunchGestureDetected());
2489             }
2490             updateIsKeyguard();
2491         }
2492 
2493         @Override
2494         public void onStartedGoingToSleep() {
2495             String tag = "CentralSurfaces#onStartedGoingToSleep";
2496             DejankUtils.startDetectingBlockingIpcs(tag);
2497 
2498             //  cancel stale runnables that could put the device in the wrong state
2499             cancelAfterLaunchTransitionRunnables();
2500 
2501             updateRevealEffect(false /* wakingUp */);
2502             updateNotificationPanelTouchState();
2503             maybeEscalateHeadsUp();
2504             dismissVolumeDialog();
2505             mWakeUpCoordinator.setFullyAwake(false);
2506             mKeyguardBypassController.onStartedGoingToSleep();
2507             mStatusBarTouchableRegionManager.updateTouchableRegion();
2508 
2509             // The unlocked screen off and fold to aod animations might use our LightRevealScrim -
2510             // we need to be expanded for it to be visible.
2511             if (mDozeParameters.shouldShowLightRevealScrim()) {
2512                 mShadeController.makeExpandedVisible(true);
2513             }
2514 
2515             DejankUtils.stopDetectingBlockingIpcs(tag);
2516         }
2517 
2518         @Override
2519         public void onStartedWakingUp() {
2520             // Between onStartedWakingUp() and onFinishedWakingUp(), the system is changing the
2521             // display power mode. To avoid jank, animations should NOT run during these power
2522             // mode transitions, which means that whenever possible, animations should
2523             // start running during the onFinishedWakingUp() callback instead of this callback.
2524             String tag = "CentralSurfaces#onStartedWakingUp";
2525             DejankUtils.startDetectingBlockingIpcs(tag);
2526             mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
2527                 mDeviceInteractive = true;
2528 
2529                 boolean isFlaggedOff = newAodTransition() && MigrateClocksToBlueprint.isEnabled();
2530                 if (!isFlaggedOff && shouldAnimateDozeWakeup()) {
2531                     // If this is false, the power button must be physically pressed in order to
2532                     // trigger fingerprint authentication.
2533                     final boolean touchToUnlockAnytime = Settings.Secure.getIntForUser(
2534                             mContext.getContentResolver(),
2535                             Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
2536                             -1,
2537                             mUserTracker.getUserId()) > 0;
2538 
2539                     // Delay if we're waking up, not mid-doze animation (which means we are
2540                     // cancelling a sleep), from the power button, on a device with a power button
2541                     // FPS, and 'press to unlock' is required.
2542                     mShouldDelayWakeUpAnimation =
2543                             !mDozeServiceHost.isPulsing()
2544                                     && mStatusBarStateController.getDozeAmount() == 1f
2545                                     && mWakefulnessLifecycle.getLastWakeReason()
2546                                     == PowerManager.WAKE_REASON_POWER_BUTTON
2547                                     && mFingerprintManager.get() != null
2548                                     && mFingerprintManager.get().isPowerbuttonFps()
2549                                     && mKeyguardUpdateMonitor
2550                                     .isUnlockWithFingerprintPossible(
2551                                             mUserTracker.getUserId())
2552                                     && !touchToUnlockAnytime;
2553                     if (DEBUG_WAKEUP_DELAY) {
2554                         Log.d(TAG, "mShouldDelayWakeUpAnimation=" + mShouldDelayWakeUpAnimation);
2555                     }
2556                 } else {
2557                     // If we're not animating anyway, we do not need to delay it.
2558                     mShouldDelayWakeUpAnimation = false;
2559                     if (DEBUG_WAKEUP_DELAY) {
2560                         Log.d(TAG, "mShouldDelayWakeUpAnimation CLEARED");
2561                     }
2562                 }
2563 
2564                 mShadeSurface.setWillPlayDelayedDozeAmountAnimation(
2565                         mShouldDelayWakeUpAnimation);
2566                 mWakeUpCoordinator.setWakingUp(
2567                         /* wakingUp= */ true,
2568                         mShouldDelayWakeUpAnimation);
2569 
2570                 updateIsKeyguard();
2571                 // TODO(b/301913237): can't delay transition if config_displayBlanksAfterDoze=true,
2572                 // otherwise, the clock will flicker during LOCKSCREEN_TRANSITION_FROM_AOD
2573                 mShouldDelayLockscreenTransitionFromAod = mDozeParameters.getAlwaysOn()
2574                         && !mDozeParameters.getDisplayNeedsBlanking()
2575                         && mFeatureFlags.isEnabled(
2576                                 Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD);
2577                 if (!mShouldDelayLockscreenTransitionFromAod) {
2578                     startLockscreenTransitionFromAod();
2579                 }
2580             });
2581             DejankUtils.stopDetectingBlockingIpcs(tag);
2582         }
2583 
2584         /**
2585          * Private helper for starting the LOCKSCREEN_TRANSITION_FROM_AOD animation - only necessary
2586          * so we can start it from either onFinishedWakingUp() or onFinishedWakingUp().
2587          */
2588         private void startLockscreenTransitionFromAod() {
2589             // stopDozing() starts the LOCKSCREEN_TRANSITION_FROM_AOD animation.
2590             mDozeServiceHost.stopDozing();
2591             // This is intentionally below the stopDozing call above, since it avoids that we're
2592             // unnecessarily animating the wakeUp transition. Animations should only be enabled
2593             // once we fully woke up.
2594             updateRevealEffect(true /* wakingUp */);
2595             updateNotificationPanelTouchState();
2596             mStatusBarTouchableRegionManager.updateTouchableRegion();
2597 
2598             // If we are waking up during the screen off animation, we should undo making the
2599             // expanded visible (we did that so the LightRevealScrim would be visible).
2600             if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
2601                 mShadeController.makeExpandedInvisible();
2602             }
2603         }
2604 
2605         @Override
2606         public void onFinishedWakingUp() {
2607             if (mShouldDelayLockscreenTransitionFromAod) {
2608                 mNotificationShadeWindowController.batchApplyWindowLayoutParams(
2609                         this::startLockscreenTransitionFromAod);
2610             }
2611             mWakeUpCoordinator.setFullyAwake(true);
2612             mWakeUpCoordinator.setWakingUp(false, false);
2613             if (mKeyguardStateController.isOccluded()
2614                     && !mDozeParameters.canControlUnlockedScreenOff()) {
2615                 // When the keyguard is occluded we don't use the KEYGUARD state which would
2616                 // normally cause these redaction updates.  If AOD is on, the KEYGUARD state is used
2617                 // to show the doze, AND UnlockedScreenOffAnimationController.onFinishedWakingUp()
2618                 // would force a KEYGUARD state that would take care of recalculating redaction.
2619                 // So if AOD is off or unsupported we need to trigger these updates at screen on
2620                 // when the keyguard is occluded.
2621                 mLockscreenUserManager.updatePublicMode();
2622                 mStackScrollerController.updateSensitivenessForOccludedWakeup();
2623             }
2624             if (mLaunchCameraWhenFinishedWaking) {
2625                 mCameraLauncherLazy.get().launchCamera(mLastCameraLaunchSource,
2626                         mShadeSurface.isFullyCollapsed());
2627                 mLaunchCameraWhenFinishedWaking = false;
2628             }
2629             if (mLaunchEmergencyActionWhenFinishedWaking) {
2630                 mLaunchEmergencyActionWhenFinishedWaking = false;
2631                 Intent emergencyIntent = mEmergencyGestureIntentFactory.invoke(
2632                         EmergencyGesture.ACTION_LAUNCH_EMERGENCY);
2633                 if (emergencyIntent != null) {
2634                     mContext.startActivityAsUser(emergencyIntent,
2635                             getActivityUserHandle(emergencyIntent));
2636                 }
2637             }
2638             updateScrimController();
2639         }
2640     };
2641 
2642     /**
2643      * We need to disable touch events because these might
2644      * collapse the panel after we expanded it, and thus we would end up with a blank
2645      * Keyguard.
2646      */
2647     @Override
updateNotificationPanelTouchState()2648     public void updateNotificationPanelTouchState() {
2649         boolean goingToSleepWithoutAnimation = isGoingToSleep()
2650                 && !mDozeParameters.shouldControlScreenOff();
2651         boolean disabled = (!mDeviceInteractive && !mDozeServiceHost.isPulsing())
2652                 || goingToSleepWithoutAnimation;
2653         mShadeLogger.logUpdateNotificationPanelTouchState(disabled, isGoingToSleep(),
2654                 !mDozeParameters.shouldControlScreenOff(), !mDeviceInteractive,
2655                 !mDozeServiceHost.isPulsing());
2656 
2657         mShadeSurface.setTouchAndAnimationDisabled(disabled);
2658         if (!NotificationIconContainerRefactor.isEnabled()) {
2659             mNotificationIconAreaController.setAnimationsEnabled(!disabled);
2660         }
2661     }
2662 
2663     final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
2664         @Override
2665         public void onScreenTurningOn() {
2666             mFalsingCollector.onScreenTurningOn();
2667             mShadeSurface.onScreenTurningOn();
2668         }
2669 
2670         @Override
2671         public void onScreenTurnedOn() {
2672             mScrimController.onScreenTurnedOn();
2673         }
2674 
2675         @Override
2676         public void onScreenTurnedOff() {
2677             Trace.beginSection("CentralSurfaces#onScreenTurnedOff");
2678             mFalsingCollector.onScreenOff();
2679             mScrimController.onScreenTurnedOff();
2680             if (mCloseQsBeforeScreenOff) {
2681                 mQsController.closeQs();
2682                 mCloseQsBeforeScreenOff = false;
2683             }
2684             updateIsKeyguard();
2685             Trace.endSection();
2686         }
2687     };
2688 
2689     /**
2690      * @return true if the screen is currently fully off, i.e. has finished turning off and has
2691      * since not started turning on.
2692      */
2693     @Override
isScreenFullyOff()2694     public boolean isScreenFullyOff() {
2695         return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF;
2696     }
2697 
2698     @Override
isCameraAllowedByAdmin()2699     public boolean isCameraAllowedByAdmin() {
2700         if (mDevicePolicyManager.getCameraDisabled(null,
2701                 mLockscreenUserManager.getCurrentUserId())) {
2702             return false;
2703         } else if (mKeyguardStateController.isShowing()
2704                 && mStatusBarKeyguardViewManager.isSecure()) {
2705             // Check if the admin has disabled the camera specifically for the keyguard
2706             return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
2707                     mLockscreenUserManager.getCurrentUserId())
2708                     & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
2709         }
2710         return true;
2711     }
2712 
2713     @Override
isGoingToSleep()2714     public boolean isGoingToSleep() {
2715         return mWakefulnessLifecycle.getWakefulness()
2716                 == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
2717     }
2718 
isWakingOrAwake()2719     boolean isWakingOrAwake() {
2720         return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING
2721                 || mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
2722     }
2723 
2724     @Override
notifyBiometricAuthModeChanged()2725     public void notifyBiometricAuthModeChanged() {
2726         mDozeServiceHost.updateDozing();
2727         if (mBiometricUnlockController.getMode()
2728                 == BiometricUnlockController.MODE_DISMISS_BOUNCER) {
2729             // Don't update the scrim controller at this time, in favor of the transition repository
2730             // updating the scrim
2731             return;
2732         }
2733         updateScrimController();
2734     }
2735 
2736     /**
2737      * Set the amount of progress we are currently in if we're transitioning to the full shade.
2738      * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
2739      * shade.
2740      */
2741     @Override
setTransitionToFullShadeProgress(float transitionToFullShadeProgress)2742     public void setTransitionToFullShadeProgress(float transitionToFullShadeProgress) {
2743         mTransitionToFullShadeProgress = transitionToFullShadeProgress;
2744     }
2745 
2746     /**
2747      * Sets the amount of progress to the bouncer being fully hidden/visible. 1 means the bouncer
2748      * is fully hidden, while 0 means the bouncer is visible.
2749      */
2750     @Override
setPrimaryBouncerHiddenFraction(float expansion)2751     public void setPrimaryBouncerHiddenFraction(float expansion) {
2752         mScrimController.setBouncerHiddenFraction(expansion);
2753     }
2754 
2755     @Override
2756     @VisibleForTesting
updateScrimController()2757     public void updateScrimController() {
2758         if (SceneContainerFlag.isEnabled()) {
2759             return;
2760         }
2761 
2762         Trace.beginSection("CentralSurfaces#updateScrimController");
2763 
2764         boolean unlocking = mKeyguardStateController.isShowing() && (
2765                 mBiometricUnlockController.isWakeAndUnlock()
2766                         || mKeyguardStateController.isKeyguardFadingAway()
2767                         || mKeyguardStateController.isKeyguardGoingAway()
2768                         || mKeyguardViewMediator.requestedShowSurfaceBehindKeyguard()
2769                         || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
2770         boolean dreaming =
2771                 mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()
2772                         && !unlocking;
2773 
2774         mScrimController.setExpansionAffectsAlpha(!unlocking);
2775 
2776         if (mAlternateBouncerInteractor.isVisibleState()) {
2777             if (DeviceEntryUdfpsRefactor.isEnabled()) {
2778                 if ((!mKeyguardStateController.isOccluded() || mShadeSurface.isPanelExpanded())
2779                         && (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
2780                         || mTransitionToFullShadeProgress > 0f)) {
2781                     // Assume scrim state for shade is already correct and do nothing
2782                 } else {
2783                     // Safeguard which prevents the scrim from being stuck in the wrong state
2784                     mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
2785                 }
2786             } else {
2787                 if ((!mKeyguardStateController.isOccluded() || mShadeSurface.isPanelExpanded())
2788                         && (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
2789                         || mTransitionToFullShadeProgress > 0f)) {
2790                     mScrimController.legacyTransitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
2791                 } else {
2792                     mScrimController.legacyTransitionTo(ScrimState.AUTH_SCRIMMED);
2793                 }
2794             }
2795             // This will cancel the keyguardFadingAway animation if it is running. We need to do
2796             // this as otherwise it can remain pending and leave keyguard in a weird state.
2797             mUnlockScrimCallback.onCancelled();
2798         } else if (mBouncerShowing && !unlocking) {
2799             // Bouncer needs the front scrim when it's on top of an activity,
2800             // tapping on a notification, editing QS or being dismissed by
2801             // FLAG_DISMISS_KEYGUARD_ACTIVITY.
2802             ScrimState state = mStatusBarKeyguardViewManager.primaryBouncerNeedsScrimming()
2803                     ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
2804             mScrimController.legacyTransitionTo(state);
2805         } else if (mBrightnessMirrorVisible) {
2806             mScrimController.legacyTransitionTo(ScrimState.BRIGHTNESS_MIRROR);
2807         } else if (mState == StatusBarState.SHADE_LOCKED) {
2808             mScrimController.legacyTransitionTo(ScrimState.SHADE_LOCKED);
2809         } else if (mDozeServiceHost.isPulsing()) {
2810             mScrimController.legacyTransitionTo(ScrimState.PULSING,
2811                     mDozeScrimController.getScrimCallback());
2812         } else if (mDozeServiceHost.hasPendingScreenOffCallback()) {
2813             mScrimController.legacyTransitionTo(ScrimState.OFF, new ScrimController.Callback() {
2814                 @Override
2815                 public void onFinished() {
2816                     mDozeServiceHost.executePendingScreenOffCallback();
2817                 }
2818             });
2819         } else if (mDozing && !unlocking) {
2820             mScrimController.legacyTransitionTo(ScrimState.AOD);
2821             // This will cancel the keyguardFadingAway animation if it is running. We need to do
2822             // this as otherwise it can remain pending and leave keyguard in a weird state.
2823             mUnlockScrimCallback.onCancelled();
2824         } else if (mIsIdleOnCommunal) {
2825             if (dreaming) {
2826                 mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
2827             } else {
2828                 mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB);
2829             }
2830         } else if (mKeyguardStateController.isShowing()
2831                 && !mKeyguardStateController.isOccluded()
2832                 && !unlocking) {
2833             mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
2834         } else if (dreaming) {
2835             mScrimController.legacyTransitionTo(ScrimState.DREAMING);
2836         } else {
2837             mScrimController.legacyTransitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
2838         }
2839         updateLightRevealScrimVisibility();
2840 
2841         Trace.endSection();
2842     }
2843     @Override
shouldIgnoreTouch()2844     public boolean shouldIgnoreTouch() {
2845         return (mStatusBarStateController.isDozing()
2846                 && mDozeServiceHost.getIgnoreTouchWhilePulsing())
2847                 || mScreenOffAnimationController.shouldIgnoreKeyguardTouches();
2848     }
2849 
2850     // Begin Extra BaseStatusBar methods.
2851 
2852     protected final CommandQueue mCommandQueue;
2853     protected IStatusBarService mBarService;
2854 
2855     // all notifications
2856     private final NotificationStackScrollLayout mStackScroller;
2857 
2858     protected AccessibilityManager mAccessibilityManager;
2859 
2860     protected boolean mDeviceInteractive;
2861 
2862     protected DevicePolicyManager mDevicePolicyManager;
2863     private final PowerManager mPowerManager;
2864     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
2865 
2866     protected KeyguardManager mKeyguardManager;
2867     private final DeviceProvisionedController mDeviceProvisionedController;
2868 
2869     private final NavigationBarController mNavigationBarController;
2870     private final AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
2871 
2872     // UI-specific methods
2873 
2874     protected WindowManager mWindowManager;
2875     protected IWindowManager mWindowManagerService;
2876     private final IDreamManager mDreamManager;
2877 
2878     protected Display mDisplay;
2879     private int mDisplayId;
2880 
2881     private final Lazy<AssistManager> mAssistManagerLazy;
2882 
2883     @Override
isDeviceInteractive()2884     public boolean isDeviceInteractive() {
2885         return mDeviceInteractive;
2886     }
2887 
2888     private final BroadcastReceiver mBannerActionBroadcastReceiver = new BroadcastReceiver() {
2889         @Override
2890         public void onReceive(Context context, Intent intent) {
2891             String action = intent.getAction();
2892             if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
2893                 NotificationManager noMan = (NotificationManager)
2894                         mContext.getSystemService(Context.NOTIFICATION_SERVICE);
2895                 noMan.cancel(com.android.internal.messages.nano.SystemMessageProto.SystemMessage.
2896                         NOTE_HIDDEN_NOTIFICATIONS);
2897 
2898                 Settings.Secure.putInt(mContext.getContentResolver(),
2899                         Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
2900                 if (BANNER_ACTION_SETUP.equals(action)) {
2901                     mShadeController.animateCollapseShadeForced();
2902                     mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
2903                             .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
2904 
2905                     );
2906                 }
2907             }
2908         }
2909     };
2910 
2911     @Override
handleExternalShadeWindowTouch(MotionEvent event)2912     public void handleExternalShadeWindowTouch(MotionEvent event) {
2913         getNotificationShadeWindowViewController().handleExternalTouch(event);
2914     }
2915 
2916     @Override
handleCommunalHubTouch(MotionEvent event)2917     public void handleCommunalHubTouch(MotionEvent event) {
2918         mGlanceableHubContainerController.onTouchEvent(event);
2919     }
2920 
2921     @Override
awakenDreams()2922     public void awakenDreams() {
2923         mUiBgExecutor.execute(() -> {
2924             try {
2925                 mDreamManager.awaken();
2926             } catch (RemoteException e) {
2927                 e.printStackTrace();
2928             }
2929         });
2930     }
2931 
toggleKeyboardShortcuts(int deviceId)2932     protected void toggleKeyboardShortcuts(int deviceId) {
2933         if (shouldUseTabletKeyboardShortcuts()) {
2934             KeyboardShortcutListSearch.toggle(mContext, deviceId);
2935         } else {
2936             KeyboardShortcuts.toggle(mContext, deviceId);
2937         }
2938     }
2939 
dismissKeyboardShortcuts()2940     protected void dismissKeyboardShortcuts() {
2941         if (shouldUseTabletKeyboardShortcuts()) {
2942             KeyboardShortcutListSearch.dismiss();
2943         } else {
2944             KeyboardShortcuts.dismiss();
2945         }
2946     }
2947 
shouldUseTabletKeyboardShortcuts()2948     private boolean shouldUseTabletKeyboardShortcuts() {
2949         return mFeatureFlags.isEnabled(SHORTCUT_LIST_SEARCH_LAYOUT)
2950                 && Utilities.isLargeScreen(mContext);
2951     }
2952 
clearNotificationEffects()2953     private void clearNotificationEffects() {
2954         try {
2955             mBarService.clearNotificationEffects();
2956         } catch (RemoteException e) {
2957             // Won't fail unless the world has ended.
2958         }
2959     }
2960 
2961     /**
2962      * @return Whether the security bouncer from Keyguard is showing.
2963      */
2964     @Override
isBouncerShowing()2965     public boolean isBouncerShowing() {
2966         return mBouncerShowing;
2967     }
2968 
2969     /**
2970      * @return Whether the security bouncer from Keyguard is showing.
2971      */
2972     @Override
isBouncerShowingScrimmed()2973     public boolean isBouncerShowingScrimmed() {
2974         return isBouncerShowing() && mStatusBarKeyguardViewManager.primaryBouncerNeedsScrimming();
2975     }
2976 
2977     // End Extra BaseStatusBarMethods.
2978 
isTransientShown()2979     boolean isTransientShown() {
2980         return mStatusBarModeRepository.getDefaultDisplay().isTransientShown().getValue();
2981     }
2982 
updateLightRevealScrimVisibility()2983     private void updateLightRevealScrimVisibility() {
2984         if (mLightRevealScrim == null) {
2985             // status bar may not be inflated yet
2986             return;
2987         }
2988 
2989         if (!lightRevealMigration()) {
2990             mLightRevealScrim.setAlpha(mScrimController.getState().getMaxLightRevealScrimAlpha());
2991         }
2992     }
2993 
2994     private final KeyguardUpdateMonitorCallback mUpdateCallback =
2995             new KeyguardUpdateMonitorCallback() {
2996                 @Override
2997                 public void onDreamingStateChanged(boolean dreaming) {
2998                     updateScrimController();
2999                     if (dreaming) {
3000                         maybeEscalateHeadsUp();
3001                     }
3002                 }
3003             };
3004 
3005 
3006     private final FalsingManager.FalsingBeliefListener mFalsingBeliefListener =
3007             new FalsingManager.FalsingBeliefListener() {
3008                 @Override
3009                 public void onFalse() {
3010                     // Hides quick settings, bouncer, and quick-quick settings.
3011                     mStatusBarKeyguardViewManager.reset(true);
3012                 }
3013             };
3014 
3015     // Notifies StatusBarKeyguardViewManager every time the keyguard transition is over,
3016     // this animation is tied to the scrim for historic reasons.
3017     // TODO: notify when keyguard has faded away instead of the scrim.
3018     private final ScrimController.Callback mUnlockScrimCallback = new ScrimController
3019             .Callback() {
3020         @Override
3021         public void onFinished() {
3022             if (mKeyguardStateController.isKeyguardFadingAway()) {
3023                 mStatusBarKeyguardViewManager.onKeyguardFadedAway();
3024             }
3025         }
3026 
3027         @Override
3028         public void onCancelled() {
3029             onFinished();
3030         }
3031     };
3032 
3033     private final DeviceProvisionedListener mUserSetupObserver = new DeviceProvisionedListener() {
3034         @Override
3035         public void onUserSetupChanged() {
3036             final boolean userSetup = mDeviceProvisionedController.isCurrentUserSetup();
3037             Log.d(TAG, "mUserSetupObserver - DeviceProvisionedListener called for "
3038                     + "current user");
3039             if (MULTIUSER_DEBUG) {
3040                 Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s",
3041                         userSetup, mUserSetup));
3042             }
3043 
3044             if (userSetup != mUserSetup) {
3045                 mUserSetup = userSetup;
3046                 if (!mUserSetup && mState == StatusBarState.SHADE) {
3047                     mShadeController.animateCollapseShade();
3048                 }
3049             }
3050         }
3051     };
3052 
3053     private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
3054         @Override
3055         public void onConfigChanged(Configuration newConfig) {
3056             updateResources();
3057             updateDisplaySize(); // populates mDisplayMetrics
3058             if (PredictiveBackSysUiFlag.isEnabled()) {
3059                 mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
3060             }
3061 
3062             if (DEBUG) {
3063                 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
3064             }
3065         }
3066 
3067         @Override
3068         public void onDensityOrFontScaleChanged() {
3069             // TODO: Remove this.
3070             if (mBrightnessMirrorController != null) {
3071                 mBrightnessMirrorController.onDensityOrFontScaleChanged();
3072             }
3073             // TODO: Bring these out of CentralSurfaces.
3074             mUserInfoControllerImpl.onDensityOrFontScaleChanged();
3075             if (!NotificationIconContainerRefactor.isEnabled()) {
3076                 mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
3077             }
3078         }
3079 
3080         @Override
3081         public void onThemeChanged() {
3082             if (mBrightnessMirrorController != null) {
3083                 mBrightnessMirrorController.onOverlayChanged();
3084             }
3085             // We need the new R.id.keyguard_indication_area before recreating
3086             // mKeyguardIndicationController
3087             mShadeSurface.onThemeChanged();
3088 
3089             if (mStatusBarKeyguardViewManager != null) {
3090                 mStatusBarKeyguardViewManager.onThemeChanged();
3091             }
3092             if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
3093                 ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
3094             }
3095             if (!NotificationIconContainerRefactor.isEnabled()) {
3096                 mNotificationIconAreaController.onThemeChanged();
3097             }
3098         }
3099 
3100         @Override
3101         public void onUiModeChanged() {
3102             if (mBrightnessMirrorController != null) {
3103                 mBrightnessMirrorController.onUiModeChanged();
3104             }
3105         }
3106     };
3107 
3108     private final StatusBarStateController.StateListener mStateListener =
3109             new StatusBarStateController.StateListener() {
3110                 @Override
3111                 public void onStatePreChange(int oldState, int newState) {
3112                     // If we're visible and switched to SHADE_LOCKED (the user dragged
3113                     // down on the lockscreen), clear notification LED, vibration,
3114                     // ringing.
3115                     // Other transitions are covered in WindowRootViewVisibilityInteractor.
3116                     if (mWindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible().getValue()
3117                             && (newState == StatusBarState.SHADE_LOCKED
3118                             || mStatusBarStateController.goingToFullShade())) {
3119                         clearNotificationEffects();
3120                     }
3121                     if (newState == StatusBarState.KEYGUARD) {
3122                         mRemoteInputManager.onPanelCollapsed();
3123                         maybeEscalateHeadsUp();
3124                     }
3125                 }
3126 
3127                 @Override
3128                 public void onStateChanged(int newState) {
3129                     mState = newState;
3130                     updateReportRejectedTouchVisibility();
3131                     mDozeServiceHost.updateDozing();
3132                     updateTheme();
3133                     mNavigationBarController.touchAutoDim(mDisplayId);
3134                     Trace.beginSection("CentralSurfaces#updateKeyguardState");
3135                     if (mState == StatusBarState.KEYGUARD) {
3136                         mShadeSurface.cancelPendingCollapse();
3137                     }
3138                     updateDozingState();
3139                     checkBarModes();
3140                     updateScrimController();
3141                     Trace.endSection();
3142                 }
3143 
3144                 @Override
3145                 public void onDozeAmountChanged(float linear, float eased) {
3146                     if (!lightRevealMigration()
3147                             && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
3148                         if (DeviceEntryUdfpsRefactor.isEnabled()) {
3149                             // If wakeAndUnlocking, this is handled in AuthRippleInteractor
3150                             if (!mBiometricUnlockController.isWakeAndUnlock()) {
3151                                 mLightRevealScrim.setRevealAmount(1f - linear);
3152                             }
3153                         } else {
3154                             mLightRevealScrim.setRevealAmount(1f - linear);
3155                         }
3156                     }
3157                 }
3158 
3159                 @Override
3160                 public void onDozingChanged(boolean isDozing) {
3161                     Trace.beginSection("CentralSurfaces#updateDozing");
3162                     mDozing = isDozing;
3163 
3164                     boolean dozingAnimated = mDozeServiceHost.getDozingRequested()
3165                             && mDozeParameters.shouldControlScreenOff();
3166                     // resetting views is already done when going into doze, there's no need to
3167                     // reset them again when we're waking up
3168                     mShadeSurface.resetViews(dozingAnimated && isDozing);
3169 
3170                     mKeyguardViewMediator.setDozing(mDozing);
3171 
3172                     updateDozingState();
3173                     mDozeServiceHost.updateDozing();
3174                     updateScrimController();
3175 
3176                     if (mBiometricUnlockController.isWakeAndUnlock()) {
3177                         // Usually doze changes are to/from lockscreen/AOD, but if we're wake and
3178                         // unlocking we should hide the keyguard ASAP if necessary.
3179                         updateIsKeyguard();
3180                     }
3181 
3182                     updateReportRejectedTouchVisibility();
3183                     Trace.endSection();
3184                 }
3185             };
3186 
3187     private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback =
3188             new BatteryController.BatteryStateChangeCallback() {
3189                 @Override
3190                 public void onPowerSaveChanged(boolean isPowerSave) {
3191                     mMainExecutor.execute(mCheckBarModes);
3192                     if (mDozeServiceHost != null) {
3193                         mDozeServiceHost.firePowerSaveChanged(isPowerSave);
3194                     }
3195                 }
3196             };
3197 
3198     private final ActivityTransitionAnimator.Callback mActivityTransitionAnimatorCallback =
3199             new ActivityTransitionAnimator.Callback() {
3200                 @Override
3201                 public boolean isOnKeyguard() {
3202                     return mKeyguardStateController.isShowing();
3203                 }
3204 
3205                 @Override
3206                 public void hideKeyguardWithAnimation(IRemoteAnimationRunner runner) {
3207                     // We post to the main thread for 2 reasons:
3208                     //   1. KeyguardViewMediator is not thread-safe.
3209                     //   2. To ensure that ViewMediatorCallback#keyguardDonePending is called before
3210                     //      ViewMediatorCallback#readyForKeyguardDone. The wrong order could occur
3211                     //      when doing
3212                     //      dismissKeyguardThenExecute { hideKeyguardWithAnimation(runner) }.
3213                     mMainExecutor.execute(() -> mKeyguardViewMediator.hideWithAnimation(runner));
3214                 }
3215 
3216                 @Override
3217                 public int getBackgroundColor(TaskInfo task) {
3218                     if (!mStartingSurfaceOptional.isPresent()) {
3219                         Log.w(TAG, "No starting surface, defaulting to SystemBGColor");
3220                         return SplashscreenContentDrawer.getSystemBGColor();
3221                     }
3222 
3223                     return mStartingSurfaceOptional.get().getBackgroundColor(task);
3224                 }
3225             };
3226 
3227     private final ActivityTransitionAnimator.Listener mActivityTransitionAnimatorListener =
3228             new ActivityTransitionAnimator.Listener() {
3229                 @Override
3230                 public void onTransitionAnimationStart() {
3231                     mKeyguardViewMediator.setBlursDisabledForAppLaunch(true);
3232                 }
3233 
3234                 @Override
3235                 public void onTransitionAnimationEnd() {
3236                     mKeyguardViewMediator.setBlursDisabledForAppLaunch(false);
3237                 }
3238             };
3239 
3240     private final DemoMode mDemoModeCallback = new DemoMode() {
3241         @Override
3242         public void onDemoModeFinished() {
3243             checkBarModes();
3244         }
3245 
3246         @Override
3247         public void dispatchDemoCommand(String command, Bundle args) { }
3248     };
3249 
3250     /**
3251      *  Determines what UserHandle to use when launching an activity.
3252      *
3253      *  We want to ensure that activities that are launched within the systemui process should be
3254      *  launched as user of the current process.
3255      * @param intent
3256      * @return UserHandle
3257      *
3258      * Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too.
3259      */
getActivityUserHandle(Intent intent)3260     private UserHandle getActivityUserHandle(Intent intent) {
3261         String[] packages = mContext.getResources().getStringArray(R.array.system_ui_packages);
3262         for (String pkg : packages) {
3263             if (intent.getComponent() == null) break;
3264             if (pkg.equals(intent.getComponent().getPackageName())) {
3265                 return new UserHandle(UserHandle.myUserId());
3266             }
3267         }
3268         return mUserTracker.getUserHandle();
3269     }
3270 
3271     /**
3272      * Whether we want to animate the wake animation AOD to lockscreen. This is done only if the
3273      * doze service host says we can, and also we're not wake and unlocking (in which case the
3274      * AOD instantly hides).
3275      */
shouldAnimateDozeWakeup()3276     private boolean shouldAnimateDozeWakeup() {
3277         return mDozeServiceHost.shouldAnimateWakeup()
3278                 && mBiometricUnlockController.getMode()
3279                 != BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
3280     }
3281 
3282     @Override
setIsLaunchingActivityOverLockscreen( boolean isLaunchingActivityOverLockscreen, boolean dismissShade)3283     public void setIsLaunchingActivityOverLockscreen(
3284             boolean isLaunchingActivityOverLockscreen, boolean dismissShade) {
3285         mIsLaunchingActivityOverLockscreen = isLaunchingActivityOverLockscreen;
3286         mDismissingShadeForActivityLaunch = dismissShade;
3287         mKeyguardViewMediator.launchingActivityOverLockscreen(mIsLaunchingActivityOverLockscreen);
3288     }
3289 
3290     @Override
getAnimatorControllerFromNotification( ExpandableNotificationRow associatedView)3291     public ActivityTransitionAnimator.Controller getAnimatorControllerFromNotification(
3292             ExpandableNotificationRow associatedView) {
3293         return mNotificationAnimationProvider.getAnimatorController(associatedView);
3294     }
3295 }
3296