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.WINDOW_STATE_HIDDEN;
20 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
21 import static android.app.StatusBarManager.WindowVisibleState;
22 import static android.app.StatusBarManager.windowStateToString;
23 import static android.view.InsetsState.ITYPE_STATUS_BAR;
24 import static android.view.InsetsState.containsType;
25 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
26 import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
27 import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
28 
29 import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
30 import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
31 import static androidx.lifecycle.Lifecycle.State.RESUMED;
32 
33 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
34 import static com.android.systemui.charging.WirelessChargingLayout.UNKNOWN_BATTERY_LEVEL;
35 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
36 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
37 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
38 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
39 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
40 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
41 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
42 import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
43 
44 import android.annotation.Nullable;
45 import android.app.ActivityManager;
46 import android.app.ActivityOptions;
47 import android.app.ActivityTaskManager;
48 import android.app.IWallpaperManager;
49 import android.app.KeyguardManager;
50 import android.app.Notification;
51 import android.app.NotificationManager;
52 import android.app.PendingIntent;
53 import android.app.StatusBarManager;
54 import android.app.TaskInfo;
55 import android.app.TaskStackBuilder;
56 import android.app.UiModeManager;
57 import android.app.WallpaperInfo;
58 import android.app.WallpaperManager;
59 import android.app.admin.DevicePolicyManager;
60 import android.content.BroadcastReceiver;
61 import android.content.ComponentCallbacks2;
62 import android.content.ComponentName;
63 import android.content.Context;
64 import android.content.Intent;
65 import android.content.IntentFilter;
66 import android.content.pm.IPackageManager;
67 import android.content.pm.PackageManager;
68 import android.content.pm.PackageManager.NameNotFoundException;
69 import android.content.pm.ResolveInfo;
70 import android.content.res.Configuration;
71 import android.graphics.Point;
72 import android.graphics.PointF;
73 import android.metrics.LogMaker;
74 import android.net.Uri;
75 import android.os.Bundle;
76 import android.os.Handler;
77 import android.os.Looper;
78 import android.os.PowerManager;
79 import android.os.RemoteException;
80 import android.os.ServiceManager;
81 import android.os.SystemClock;
82 import android.os.SystemProperties;
83 import android.os.Trace;
84 import android.os.UserHandle;
85 import android.provider.Settings;
86 import android.service.dreams.DreamService;
87 import android.service.dreams.IDreamManager;
88 import android.service.notification.StatusBarNotification;
89 import android.text.TextUtils;
90 import android.util.ArraySet;
91 import android.util.DisplayMetrics;
92 import android.util.EventLog;
93 import android.util.Log;
94 import android.util.MathUtils;
95 import android.util.Slog;
96 import android.view.Display;
97 import android.view.IRemoteAnimationRunner;
98 import android.view.IWindowManager;
99 import android.view.KeyEvent;
100 import android.view.MotionEvent;
101 import android.view.RemoteAnimationAdapter;
102 import android.view.ThreadedRenderer;
103 import android.view.View;
104 import android.view.ViewGroup;
105 import android.view.WindowInsetsController.Appearance;
106 import android.view.WindowManager;
107 import android.view.WindowManagerGlobal;
108 import android.view.accessibility.AccessibilityManager;
109 import android.widget.DateTimeView;
110 
111 import androidx.annotation.NonNull;
112 import androidx.lifecycle.Lifecycle;
113 import androidx.lifecycle.LifecycleOwner;
114 import androidx.lifecycle.LifecycleRegistry;
115 
116 import com.android.internal.annotations.VisibleForTesting;
117 import com.android.internal.colorextraction.ColorExtractor;
118 import com.android.internal.logging.MetricsLogger;
119 import com.android.internal.logging.UiEvent;
120 import com.android.internal.logging.UiEventLogger;
121 import com.android.internal.logging.UiEventLoggerImpl;
122 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
123 import com.android.internal.statusbar.IStatusBarService;
124 import com.android.internal.statusbar.RegisterStatusBarResult;
125 import com.android.keyguard.KeyguardUpdateMonitor;
126 import com.android.keyguard.KeyguardUpdateMonitorCallback;
127 import com.android.keyguard.ViewMediatorCallback;
128 import com.android.systemui.ActivityIntentHelper;
129 import com.android.systemui.AutoReinflateContainer;
130 import com.android.systemui.DejankUtils;
131 import com.android.systemui.EventLogTags;
132 import com.android.systemui.InitController;
133 import com.android.systemui.Prefs;
134 import com.android.systemui.R;
135 import com.android.systemui.SystemUI;
136 import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
137 import com.android.systemui.animation.ActivityLaunchAnimator;
138 import com.android.systemui.animation.DelegateLaunchAnimatorController;
139 import com.android.systemui.assist.AssistManager;
140 import com.android.systemui.biometrics.AuthRippleController;
141 import com.android.systemui.broadcast.BroadcastDispatcher;
142 import com.android.systemui.camera.CameraIntents;
143 import com.android.systemui.charging.WirelessChargingAnimation;
144 import com.android.systemui.classifier.FalsingCollector;
145 import com.android.systemui.colorextraction.SysuiColorExtractor;
146 import com.android.systemui.dagger.qualifiers.Main;
147 import com.android.systemui.dagger.qualifiers.UiBackground;
148 import com.android.systemui.demomode.DemoModeController;
149 import com.android.systemui.dump.DumpManager;
150 import com.android.systemui.emergency.EmergencyGesture;
151 import com.android.systemui.flags.FeatureFlags;
152 import com.android.systemui.fragments.ExtensionFragmentListener;
153 import com.android.systemui.fragments.FragmentHostManager;
154 import com.android.systemui.fragments.FragmentService;
155 import com.android.systemui.keyguard.KeyguardService;
156 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
157 import com.android.systemui.keyguard.KeyguardViewMediator;
158 import com.android.systemui.keyguard.ScreenLifecycle;
159 import com.android.systemui.keyguard.WakefulnessLifecycle;
160 import com.android.systemui.navigationbar.NavigationBarController;
161 import com.android.systemui.navigationbar.NavigationBarView;
162 import com.android.systemui.plugins.ActivityStarter;
163 import com.android.systemui.plugins.DarkIconDispatcher;
164 import com.android.systemui.plugins.FalsingManager;
165 import com.android.systemui.plugins.OverlayPlugin;
166 import com.android.systemui.plugins.PluginDependencyProvider;
167 import com.android.systemui.plugins.PluginListener;
168 import com.android.systemui.plugins.qs.QS;
169 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
170 import com.android.systemui.plugins.statusbar.StatusBarStateController;
171 import com.android.systemui.qs.QSFragment;
172 import com.android.systemui.qs.QSPanelController;
173 import com.android.systemui.recents.ScreenPinningRequest;
174 import com.android.systemui.scrim.ScrimView;
175 import com.android.systemui.settings.brightness.BrightnessSliderController;
176 import com.android.systemui.shared.plugins.PluginManager;
177 import com.android.systemui.statusbar.AutoHideUiElement;
178 import com.android.systemui.statusbar.BackDropView;
179 import com.android.systemui.statusbar.CircleReveal;
180 import com.android.systemui.statusbar.CommandQueue;
181 import com.android.systemui.statusbar.GestureRecorder;
182 import com.android.systemui.statusbar.KeyboardShortcuts;
183 import com.android.systemui.statusbar.KeyguardIndicationController;
184 import com.android.systemui.statusbar.LiftReveal;
185 import com.android.systemui.statusbar.LightRevealScrim;
186 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
187 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
188 import com.android.systemui.statusbar.NotificationMediaManager;
189 import com.android.systemui.statusbar.NotificationPresenter;
190 import com.android.systemui.statusbar.NotificationRemoteInputManager;
191 import com.android.systemui.statusbar.NotificationShadeDepthController;
192 import com.android.systemui.statusbar.NotificationShadeWindowController;
193 import com.android.systemui.statusbar.NotificationShelfController;
194 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
195 import com.android.systemui.statusbar.OperatorNameViewController;
196 import com.android.systemui.statusbar.PowerButtonReveal;
197 import com.android.systemui.statusbar.PulseExpansionHandler;
198 import com.android.systemui.statusbar.StatusBarState;
199 import com.android.systemui.statusbar.SysuiStatusBarStateController;
200 import com.android.systemui.statusbar.connectivity.NetworkController;
201 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
202 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
203 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
204 import com.android.systemui.statusbar.notification.NotificationEntryManager;
205 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
206 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
207 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
208 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
209 import com.android.systemui.statusbar.notification.init.NotificationsController;
210 import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
211 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
212 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
213 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
214 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
215 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
216 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
217 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
218 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
219 import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
220 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
221 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
222 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
223 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
224 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
225 import com.android.systemui.statusbar.policy.BatteryController;
226 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
227 import com.android.systemui.statusbar.policy.ConfigurationController;
228 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
229 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
230 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
231 import com.android.systemui.statusbar.policy.ExtensionController;
232 import com.android.systemui.statusbar.policy.KeyguardStateController;
233 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
234 import com.android.systemui.statusbar.policy.UserSwitcherController;
235 import com.android.systemui.statusbar.window.StatusBarWindowController;
236 import com.android.systemui.tuner.TunerService;
237 import com.android.systemui.util.DumpUtilsKt;
238 import com.android.systemui.util.WallpaperController;
239 import com.android.systemui.util.concurrency.DelayableExecutor;
240 import com.android.systemui.util.concurrency.MessageRouter;
241 import com.android.systemui.volume.VolumeComponent;
242 import com.android.systemui.wmshell.BubblesManager;
243 import com.android.wm.shell.bubbles.Bubbles;
244 import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
245 import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
246 import com.android.wm.shell.startingsurface.StartingSurface;
247 
248 import java.io.FileDescriptor;
249 import java.io.PrintWriter;
250 import java.io.StringWriter;
251 import java.util.List;
252 import java.util.Map;
253 import java.util.Optional;
254 import java.util.concurrent.Executor;
255 
256 import javax.inject.Named;
257 
258 import dagger.Lazy;
259 
260 /** */
261 public class StatusBar extends SystemUI implements
262         ActivityStarter,
263         LifecycleOwner {
264     public static final boolean MULTIUSER_DEBUG = false;
265 
266     protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
267 
268     // Should match the values in PhoneWindowManager
269     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
270     static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
271 
272     private static final String BANNER_ACTION_CANCEL =
273             "com.android.systemui.statusbar.banner_action_cancel";
274     private static final String BANNER_ACTION_SETUP =
275             "com.android.systemui.statusbar.banner_action_setup";
276     public static final String TAG = "StatusBar";
277     public static final boolean DEBUG = false;
278     public static final boolean SPEW = false;
279     public static final boolean DUMPTRUCK = true; // extra dumpsys info
280     public static final boolean DEBUG_GESTURES = false;
281     public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
282     public static final boolean DEBUG_CAMERA_LIFT = false;
283 
284     public static final boolean DEBUG_WINDOW_STATE = false;
285 
286     // additional instrumentation for testing purposes; intended to be left on during development
287     public static final boolean CHATTY = DEBUG;
288 
289     public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
290 
291     public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
292 
293     private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
294     private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
295     // 1020-1040 reserved for BaseStatusBar
296 
297     // Time after we abort the launch transition.
298     static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
299 
300     protected static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
301 
302     /**
303      * The delay to reset the hint text when the hint animation is finished running.
304      */
305     private static final int HINT_RESET_DELAY_MS = 1200;
306 
307     public static final int FADE_KEYGUARD_START_DELAY = 100;
308     public static final int FADE_KEYGUARD_DURATION = 300;
309     public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
310 
311     public static final long[] CAMERA_LAUNCH_GESTURE_VIBRATION_TIMINGS =
312             new long[]{20, 20, 20, 20, 100, 20};
313     public static final int[] CAMERA_LAUNCH_GESTURE_VIBRATION_AMPLITUDES =
314             new int[]{39, 82, 139, 213, 0, 127};
315 
316     /**
317      * If true, the system is in the half-boot-to-decryption-screen state.
318      * Prudently disable QS and notifications.
319      */
320     public static final boolean ONLY_CORE_APPS;
321 
322     /** If true, the lockscreen will show a distinct wallpaper */
323     public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
324 
325     private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
326 
327     static {
328         boolean onlyCoreApps;
329         try {
330             IPackageManager packageManager =
331                     IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
332             onlyCoreApps = packageManager != null && packageManager.isOnlyCoreApps();
333         } catch (RemoteException e) {
334             onlyCoreApps = false;
335         }
336         ONLY_CORE_APPS = onlyCoreApps;
337     }
338 
339     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
340     private StatusBarCommandQueueCallbacks mCommandQueueCallbacks;
341 
setWindowState(int state)342     void setWindowState(int state) {
343         mStatusBarWindowState =  state;
344         mStatusBarWindowHidden = state == WINDOW_STATE_HIDDEN;
345         mStatusBarHideIconsForBouncerManager.setStatusBarWindowHidden(mStatusBarWindowHidden);
346         if (getStatusBarView() != null) {
347             // Should #updateHideIconsForBouncer always be called, regardless of whether we have a
348             //   status bar view? If so, we can make #updateHideIconsForBouncer private.
349             mStatusBarHideIconsForBouncerManager.updateHideIconsForBouncer(/* animate= */ false);
350         }
351     }
352 
acquireGestureWakeLock(long time)353     void acquireGestureWakeLock(long time) {
354         mGestureWakeLock.acquire(time);
355     }
356 
setAppearance(int appearance)357     boolean setAppearance(int appearance) {
358         if (mAppearance != appearance) {
359             mAppearance = appearance;
360             return updateBarMode(barMode(isTransientShown(), appearance));
361         }
362 
363         return false;
364     }
365 
getBarMode()366     int getBarMode() {
367         return mStatusBarMode;
368     }
369 
resendMessage(int msg)370     void resendMessage(int msg) {
371         mMessageRouter.cancelMessages(msg);
372         mMessageRouter.sendMessage(msg);
373     }
374 
resendMessage(Object msg)375     void resendMessage(Object msg) {
376         mMessageRouter.cancelMessages(msg.getClass());
377         mMessageRouter.sendMessage(msg);
378     }
379 
getDisabled1()380     int getDisabled1() {
381         return mDisabled1;
382     }
383 
setDisabled1(int disabled)384     void setDisabled1(int disabled) {
385         mDisabled1 = disabled;
386     }
387 
getDisabled2()388     int getDisabled2() {
389         return mDisabled2;
390     }
391 
setDisabled2(int disabled)392     void setDisabled2(int disabled) {
393         mDisabled2 = disabled;
394     }
395 
setLastCameraLaunchSource(int source)396     void setLastCameraLaunchSource(int source) {
397         mLastCameraLaunchSource = source;
398     }
399 
setLaunchCameraOnFinishedGoingToSleep(boolean launch)400     void setLaunchCameraOnFinishedGoingToSleep(boolean launch) {
401         mLaunchCameraOnFinishedGoingToSleep = launch;
402     }
403 
setLaunchCameraOnFinishedWaking(boolean launch)404     void setLaunchCameraOnFinishedWaking(boolean launch) {
405         mLaunchCameraWhenFinishedWaking = launch;
406     }
407 
setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch)408     void setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch) {
409         mLaunchEmergencyActionOnFinishedGoingToSleep = launch;
410     }
411 
setLaunchEmergencyActionOnFinishedWaking(boolean launch)412     void setLaunchEmergencyActionOnFinishedWaking(boolean launch) {
413         mLaunchEmergencyActionWhenFinishedWaking = launch;
414     }
415 
setTopHidesStatusBar(boolean hides)416     void setTopHidesStatusBar(boolean hides) {
417         mTopHidesStatusBar = hides;
418     }
419 
getQSPanelController()420     QSPanelController getQSPanelController() {
421         return mQSPanelController;
422     }
423 
424     /** */
animateExpandNotificationsPanel()425     public void animateExpandNotificationsPanel() {
426         mCommandQueueCallbacks.animateExpandNotificationsPanel();
427     }
428 
429     /** */
animateExpandSettingsPanel(@ullable String subpanel)430     public void animateExpandSettingsPanel(@Nullable String subpanel) {
431         mCommandQueueCallbacks.animateExpandSettingsPanel(subpanel);
432     }
433 
434     /** */
animateCollapsePanels(int flags, boolean force)435     public void animateCollapsePanels(int flags, boolean force) {
436         mCommandQueueCallbacks.animateCollapsePanels(flags, force);
437     }
438 
439     /**
440      * The {@link StatusBarState} of the status bar.
441      */
442     protected int mState; // TODO: remove this. Just use StatusBarStateController
443     protected boolean mBouncerShowing;
444 
445     private final PhoneStatusBarPolicy mIconPolicy;
446 
447     private final VolumeComponent mVolumeComponent;
448     private BrightnessMirrorController mBrightnessMirrorController;
449     private boolean mBrightnessMirrorVisible;
450     private BiometricUnlockController mBiometricUnlockController;
451     private final LightBarController mLightBarController;
452     private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
453     private final LockscreenGestureLogger mLockscreenGestureLogger;
454     @Nullable
455     protected LockscreenWallpaper mLockscreenWallpaper;
456     private final AutoHideController mAutoHideController;
457     private final CollapsedStatusBarFragmentLogger mCollapsedStatusBarFragmentLogger;
458 
459     private final Point mCurrentDisplaySize = new Point();
460 
461     protected NotificationShadeWindowView mNotificationShadeWindowView;
462     protected PhoneStatusBarView mStatusBarView;
463     private PhoneStatusBarViewController mPhoneStatusBarViewController;
464     private AuthRippleController mAuthRippleController;
465     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
466     protected NotificationShadeWindowController mNotificationShadeWindowController;
467     private final StatusBarWindowController mStatusBarWindowController;
468     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
469     @VisibleForTesting
470     DozeServiceHost mDozeServiceHost;
471     private boolean mWakeUpComingFromTouch;
472     private PointF mWakeUpTouchLocation;
473     private LightRevealScrim mLightRevealScrim;
474     private PowerButtonReveal mPowerButtonReveal;
475 
476     private final Object mQueueLock = new Object();
477 
478     private final PulseExpansionHandler mPulseExpansionHandler;
479     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
480     private final KeyguardBypassController mKeyguardBypassController;
481     private final KeyguardStateController mKeyguardStateController;
482     private final HeadsUpManagerPhone mHeadsUpManager;
483     private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
484     private final DynamicPrivacyController mDynamicPrivacyController;
485     private final BypassHeadsUpNotifier mBypassHeadsUpNotifier;
486     private final FalsingCollector mFalsingCollector;
487     private final FalsingManager mFalsingManager;
488     private final BroadcastDispatcher mBroadcastDispatcher;
489     private final ConfigurationController mConfigurationController;
490     protected NotificationShadeWindowViewController mNotificationShadeWindowViewController;
491     private final DozeParameters mDozeParameters;
492     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
493     private final StatusBarComponent.Factory mStatusBarComponentFactory;
494     private final PluginManager mPluginManager;
495     private final Optional<LegacySplitScreen> mSplitScreenOptional;
496     private final StatusBarNotificationActivityStarter.Builder
497             mStatusBarNotificationActivityStarterBuilder;
498     private final ShadeController mShadeController;
499     private final LightsOutNotifController mLightsOutNotifController;
500     private final InitController mInitController;
501 
502     private final PluginDependencyProvider mPluginDependencyProvider;
503     private final KeyguardDismissUtil mKeyguardDismissUtil;
504     private final ExtensionController mExtensionController;
505     private final UserInfoControllerImpl mUserInfoControllerImpl;
506     private final DemoModeController mDemoModeController;
507     private final NotificationsController mNotificationsController;
508     private final OngoingCallController mOngoingCallController;
509     private final SystemStatusAnimationScheduler mAnimationScheduler;
510     private final StatusBarSignalPolicy mStatusBarSignalPolicy;
511     private final StatusBarLocationPublisher mStatusBarLocationPublisher;
512     private final StatusBarIconController mStatusBarIconController;
513     private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
514 
515     // expanded notifications
516     // the sliding/resizing panel within the notification window
517     protected NotificationPanelViewController mNotificationPanelViewController;
518 
519     // settings
520     private QSPanelController mQSPanelController;
521 
522     private final OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
523     KeyguardIndicationController mKeyguardIndicationController;
524 
525     private View mReportRejectedTouch;
526 
527     private boolean mExpandedVisible;
528 
529     private final int[] mAbsPos = new int[2];
530 
531     private final NotifShadeEventSource mNotifShadeEventSource;
532     protected final NotificationEntryManager mEntryManager;
533     private final NotificationGutsManager mGutsManager;
534     private final NotificationLogger mNotificationLogger;
535     private final NotificationViewHierarchyManager mViewHierarchyManager;
536     private final PanelExpansionStateManager mPanelExpansionStateManager;
537     private final KeyguardViewMediator mKeyguardViewMediator;
538     protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
539     private final BrightnessSliderController.Factory mBrightnessSliderFactory;
540     private final FeatureFlags mFeatureFlags;
541     private final FragmentService mFragmentService;
542     private final WallpaperController mWallpaperController;
543     private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
544     private final MessageRouter mMessageRouter;
545     private final WallpaperManager mWallpaperManager;
546     private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
547     private final TunerService mTunerService;
548 
549     private StatusBarComponent mStatusBarComponent;
550 
551     // Flags for disabling the status bar
552     // Two variables becaseu the first one evidently ran out of room for new flags.
553     private int mDisabled1 = 0;
554     private int mDisabled2 = 0;
555 
556     /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
557     private @Appearance int mAppearance;
558 
559     private boolean mTransientShown;
560 
561     private final DisplayMetrics mDisplayMetrics;
562 
563     // XXX: gesture research
564     private final GestureRecorder mGestureRec = DEBUG_GESTURES
565         ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
566         : null;
567 
568     private final ScreenPinningRequest mScreenPinningRequest;
569 
570     private final MetricsLogger mMetricsLogger;
571 
572     // ensure quick settings is disabled until the current user makes it through the setup wizard
573     @VisibleForTesting
574     protected boolean mUserSetup = false;
575 
576     @VisibleForTesting
577     public enum StatusBarUiEvent implements UiEventLogger.UiEventEnum {
578         @UiEvent(doc = "Secured lockscreen is opened.")
579         LOCKSCREEN_OPEN_SECURE(405),
580 
581         @UiEvent(doc = "Lockscreen without security is opened.")
582         LOCKSCREEN_OPEN_INSECURE(406),
583 
584         @UiEvent(doc = "Secured lockscreen is closed.")
585         LOCKSCREEN_CLOSE_SECURE(407),
586 
587         @UiEvent(doc = "Lockscreen without security is closed.")
588         LOCKSCREEN_CLOSE_INSECURE(408),
589 
590         @UiEvent(doc = "Secured bouncer is opened.")
591         BOUNCER_OPEN_SECURE(409),
592 
593         @UiEvent(doc = "Bouncer without security is opened.")
594         BOUNCER_OPEN_INSECURE(410),
595 
596         @UiEvent(doc = "Secured bouncer is closed.")
597         BOUNCER_CLOSE_SECURE(411),
598 
599         @UiEvent(doc = "Bouncer without security is closed.")
600         BOUNCER_CLOSE_INSECURE(412);
601 
602         private final int mId;
603 
StatusBarUiEvent(int id)604         StatusBarUiEvent(int id) {
605             mId = id;
606         }
607 
608         @Override
getId()609         public int getId() {
610             return mId;
611         }
612     }
613 
614     private Handler mMainHandler;
615     private final DelayableExecutor mMainExecutor;
616 
617     private int mInteractingWindows;
618     private @TransitionMode int mStatusBarMode;
619 
620     private final ViewMediatorCallback mKeyguardViewMediatorCallback;
621     private final ScrimController mScrimController;
622     protected DozeScrimController mDozeScrimController;
623     private final Executor mUiBgExecutor;
624 
625     protected boolean mDozing;
626     private boolean mIsFullscreen;
627 
628     private final NotificationMediaManager mMediaManager;
629     private final NotificationLockscreenUserManager mLockscreenUserManager;
630     private final NotificationRemoteInputManager mRemoteInputManager;
631     private boolean mWallpaperSupported;
632 
633     private Runnable mLaunchTransitionEndRunnable;
634     private boolean mLaunchCameraWhenFinishedWaking;
635     private boolean mLaunchCameraOnFinishedGoingToSleep;
636     private boolean mLaunchEmergencyActionWhenFinishedWaking;
637     private boolean mLaunchEmergencyActionOnFinishedGoingToSleep;
638     private int mLastCameraLaunchSource;
639     protected PowerManager.WakeLock mGestureWakeLock;
640 
641     private final int[] mTmpInt2 = new int[2];
642 
643     // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
644     private int mLastLoggedStateFingerprint;
645     private boolean mTopHidesStatusBar;
646     private boolean mStatusBarWindowHidden;
647     private boolean mIsOccluded;
648     private boolean mIsLaunchingActivityOverLockscreen;
649 
650     private final UserSwitcherController mUserSwitcherController;
651     private final NetworkController mNetworkController;
652     private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
653     protected final BatteryController mBatteryController;
654     protected boolean mPanelExpanded;
655     private UiModeManager mUiModeManager;
656     protected boolean mIsKeyguard;
657     private LogMaker mStatusBarStateLog;
658     protected final NotificationIconAreaController mNotificationIconAreaController;
659     @Nullable private View mAmbientIndicationContainer;
660     private final SysuiColorExtractor mColorExtractor;
661     private final ScreenLifecycle mScreenLifecycle;
662     private final WakefulnessLifecycle mWakefulnessLifecycle;
663 
664     private boolean mNoAnimationOnNextBarModeChange;
665     private final SysuiStatusBarStateController mStatusBarStateController;
666 
667     private final ActivityLaunchAnimator mActivityLaunchAnimator;
668     private NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
669     protected StatusBarNotificationPresenter mPresenter;
670     private NotificationActivityStarter mNotificationActivityStarter;
671     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
672     private final Optional<BubblesManager> mBubblesManagerOptional;
673     private final Optional<Bubbles> mBubblesOptional;
674     private final Bubbles.BubbleExpandListener mBubbleExpandListener;
675     private final Optional<StartingSurface> mStartingSurfaceOptional;
676 
677     private final ActivityIntentHelper mActivityIntentHelper;
678     private NotificationStackScrollLayoutController mStackScrollerController;
679 
680     private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
681             (extractor, which) -> updateTheme();
682 
683 
684     /**
685      * Public constructor for StatusBar.
686      *
687      * StatusBar is considered optional, and therefore can not be marked as @Inject directly.
688      * Instead, an @Provide method is included. See {@link StatusBarPhoneModule}.
689      */
690     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
StatusBar( Context context, NotificationsController notificationsController, FragmentService fragmentService, LightBarController lightBarController, AutoHideController autoHideController, StatusBarWindowController statusBarWindowController, KeyguardUpdateMonitor keyguardUpdateMonitor, StatusBarSignalPolicy statusBarSignalPolicy, PulseExpansionHandler pulseExpansionHandler, NotificationWakeUpCoordinator notificationWakeUpCoordinator, KeyguardBypassController keyguardBypassController, KeyguardStateController keyguardStateController, HeadsUpManagerPhone headsUpManagerPhone, DynamicPrivacyController dynamicPrivacyController, BypassHeadsUpNotifier bypassHeadsUpNotifier, FalsingManager falsingManager, FalsingCollector falsingCollector, BroadcastDispatcher broadcastDispatcher, NotifShadeEventSource notifShadeEventSource, NotificationEntryManager notificationEntryManager, NotificationGutsManager notificationGutsManager, NotificationLogger notificationLogger, NotificationInterruptStateProvider notificationInterruptStateProvider, NotificationViewHierarchyManager notificationViewHierarchyManager, PanelExpansionStateManager panelExpansionStateManager, KeyguardViewMediator keyguardViewMediator, DisplayMetrics displayMetrics, MetricsLogger metricsLogger, @UiBackground Executor uiBgExecutor, NotificationMediaManager notificationMediaManager, NotificationLockscreenUserManager lockScreenUserManager, NotificationRemoteInputManager remoteInputManager, UserSwitcherController userSwitcherController, NetworkController networkController, BatteryController batteryController, SysuiColorExtractor colorExtractor, ScreenLifecycle screenLifecycle, WakefulnessLifecycle wakefulnessLifecycle, SysuiStatusBarStateController statusBarStateController, Optional<BubblesManager> bubblesManagerOptional, Optional<Bubbles> bubblesOptional, VisualStabilityManager visualStabilityManager, DeviceProvisionedController deviceProvisionedController, NavigationBarController navigationBarController, AccessibilityFloatingMenuController accessibilityFloatingMenuController, Lazy<AssistManager> assistManagerLazy, ConfigurationController configurationController, NotificationShadeWindowController notificationShadeWindowController, DozeParameters dozeParameters, ScrimController scrimController, Lazy<LockscreenWallpaper> lockscreenWallpaperLazy, LockscreenGestureLogger lockscreenGestureLogger, Lazy<BiometricUnlockController> biometricUnlockControllerLazy, DozeServiceHost dozeServiceHost, PowerManager powerManager, ScreenPinningRequest screenPinningRequest, DozeScrimController dozeScrimController, VolumeComponent volumeComponent, CommandQueue commandQueue, CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger, StatusBarComponent.Factory statusBarComponentFactory, PluginManager pluginManager, Optional<LegacySplitScreen> splitScreenOptional, LightsOutNotifController lightsOutNotifController, StatusBarNotificationActivityStarter.Builder statusBarNotificationActivityStarterBuilder, ShadeController shadeController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, ViewMediatorCallback viewMediatorCallback, InitController initController, @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler, PluginDependencyProvider pluginDependencyProvider, KeyguardDismissUtil keyguardDismissUtil, ExtensionController extensionController, UserInfoControllerImpl userInfoControllerImpl, OperatorNameViewController.Factory operatorNameViewControllerFactory, PhoneStatusBarPolicy phoneStatusBarPolicy, KeyguardIndicationController keyguardIndicationController, DemoModeController demoModeController, Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy, StatusBarTouchableRegionManager statusBarTouchableRegionManager, NotificationIconAreaController notificationIconAreaController, BrightnessSliderController.Factory brightnessSliderFactory, WallpaperController wallpaperController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, StatusBarLocationPublisher locationPublisher, StatusBarIconController statusBarIconController, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, LockscreenShadeTransitionController lockscreenShadeTransitionController, FeatureFlags featureFlags, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @Main Handler mainHandler, @Main DelayableExecutor delayableExecutor, @Main MessageRouter messageRouter, WallpaperManager wallpaperManager, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, Optional<StartingSurface> startingSurfaceOptional, TunerService tunerService, DumpManager dumpManager, ActivityLaunchAnimator activityLaunchAnimator)691     public StatusBar(
692             Context context,
693             NotificationsController notificationsController,
694             FragmentService fragmentService,
695             LightBarController lightBarController,
696             AutoHideController autoHideController,
697             StatusBarWindowController statusBarWindowController,
698             KeyguardUpdateMonitor keyguardUpdateMonitor,
699             StatusBarSignalPolicy statusBarSignalPolicy,
700             PulseExpansionHandler pulseExpansionHandler,
701             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
702             KeyguardBypassController keyguardBypassController,
703             KeyguardStateController keyguardStateController,
704             HeadsUpManagerPhone headsUpManagerPhone,
705             DynamicPrivacyController dynamicPrivacyController,
706             BypassHeadsUpNotifier bypassHeadsUpNotifier,
707             FalsingManager falsingManager,
708             FalsingCollector falsingCollector,
709             BroadcastDispatcher broadcastDispatcher,
710             NotifShadeEventSource notifShadeEventSource,
711             NotificationEntryManager notificationEntryManager,
712             NotificationGutsManager notificationGutsManager,
713             NotificationLogger notificationLogger,
714             NotificationInterruptStateProvider notificationInterruptStateProvider,
715             NotificationViewHierarchyManager notificationViewHierarchyManager,
716             PanelExpansionStateManager panelExpansionStateManager,
717             KeyguardViewMediator keyguardViewMediator,
718             DisplayMetrics displayMetrics,
719             MetricsLogger metricsLogger,
720             @UiBackground Executor uiBgExecutor,
721             NotificationMediaManager notificationMediaManager,
722             NotificationLockscreenUserManager lockScreenUserManager,
723             NotificationRemoteInputManager remoteInputManager,
724             UserSwitcherController userSwitcherController,
725             NetworkController networkController,
726             BatteryController batteryController,
727             SysuiColorExtractor colorExtractor,
728             ScreenLifecycle screenLifecycle,
729             WakefulnessLifecycle wakefulnessLifecycle,
730             SysuiStatusBarStateController statusBarStateController,
731             Optional<BubblesManager> bubblesManagerOptional,
732             Optional<Bubbles> bubblesOptional,
733             VisualStabilityManager visualStabilityManager,
734             DeviceProvisionedController deviceProvisionedController,
735             NavigationBarController navigationBarController,
736             AccessibilityFloatingMenuController accessibilityFloatingMenuController,
737             Lazy<AssistManager> assistManagerLazy,
738             ConfigurationController configurationController,
739             NotificationShadeWindowController notificationShadeWindowController,
740             DozeParameters dozeParameters,
741             ScrimController scrimController,
742             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
743             LockscreenGestureLogger lockscreenGestureLogger,
744             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
745             DozeServiceHost dozeServiceHost,
746             PowerManager powerManager,
747             ScreenPinningRequest screenPinningRequest,
748             DozeScrimController dozeScrimController,
749             VolumeComponent volumeComponent,
750             CommandQueue commandQueue,
751             CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
752             StatusBarComponent.Factory statusBarComponentFactory,
753             PluginManager pluginManager,
754             Optional<LegacySplitScreen> splitScreenOptional,
755             LightsOutNotifController lightsOutNotifController,
756             StatusBarNotificationActivityStarter.Builder
757                     statusBarNotificationActivityStarterBuilder,
758             ShadeController shadeController,
759             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
760             ViewMediatorCallback viewMediatorCallback,
761             InitController initController,
762             @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
763             PluginDependencyProvider pluginDependencyProvider,
764             KeyguardDismissUtil keyguardDismissUtil,
765             ExtensionController extensionController,
766             UserInfoControllerImpl userInfoControllerImpl,
767             OperatorNameViewController.Factory operatorNameViewControllerFactory,
768             PhoneStatusBarPolicy phoneStatusBarPolicy,
769             KeyguardIndicationController keyguardIndicationController,
770             DemoModeController demoModeController,
771             Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
772             StatusBarTouchableRegionManager statusBarTouchableRegionManager,
773             NotificationIconAreaController notificationIconAreaController,
774             BrightnessSliderController.Factory brightnessSliderFactory,
775             WallpaperController wallpaperController,
776             OngoingCallController ongoingCallController,
777             SystemStatusAnimationScheduler animationScheduler,
778             StatusBarLocationPublisher locationPublisher,
779             StatusBarIconController statusBarIconController,
780             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
781             LockscreenShadeTransitionController lockscreenShadeTransitionController,
782             FeatureFlags featureFlags,
783             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
784             @Main Handler mainHandler,
785             @Main DelayableExecutor delayableExecutor,
786             @Main MessageRouter messageRouter,
787             WallpaperManager wallpaperManager,
788             UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
789             Optional<StartingSurface> startingSurfaceOptional,
790             TunerService tunerService,
791             DumpManager dumpManager,
792             ActivityLaunchAnimator activityLaunchAnimator) {
793         super(context);
794         mNotificationsController = notificationsController;
795         mFragmentService = fragmentService;
796         mLightBarController = lightBarController;
797         mAutoHideController = autoHideController;
798         mStatusBarWindowController = statusBarWindowController;
799         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
800         mPulseExpansionHandler = pulseExpansionHandler;
801         mWakeUpCoordinator = notificationWakeUpCoordinator;
802         mKeyguardBypassController = keyguardBypassController;
803         mKeyguardStateController = keyguardStateController;
804         mHeadsUpManager = headsUpManagerPhone;
805         mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
806         mKeyguardIndicationController = keyguardIndicationController;
807         mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
808         mDynamicPrivacyController = dynamicPrivacyController;
809         mBypassHeadsUpNotifier = bypassHeadsUpNotifier;
810         mFalsingCollector = falsingCollector;
811         mFalsingManager = falsingManager;
812         mBroadcastDispatcher = broadcastDispatcher;
813         mNotifShadeEventSource = notifShadeEventSource;
814         mEntryManager = notificationEntryManager;
815         mGutsManager = notificationGutsManager;
816         mNotificationLogger = notificationLogger;
817         mNotificationInterruptStateProvider = notificationInterruptStateProvider;
818         mViewHierarchyManager = notificationViewHierarchyManager;
819         mPanelExpansionStateManager = panelExpansionStateManager;
820         mKeyguardViewMediator = keyguardViewMediator;
821         mDisplayMetrics = displayMetrics;
822         mMetricsLogger = metricsLogger;
823         mUiBgExecutor = uiBgExecutor;
824         mMediaManager = notificationMediaManager;
825         mLockscreenUserManager = lockScreenUserManager;
826         mRemoteInputManager = remoteInputManager;
827         mUserSwitcherController = userSwitcherController;
828         mNetworkController = networkController;
829         mBatteryController = batteryController;
830         mColorExtractor = colorExtractor;
831         mScreenLifecycle = screenLifecycle;
832         mWakefulnessLifecycle = wakefulnessLifecycle;
833         mStatusBarStateController = statusBarStateController;
834         mBubblesManagerOptional = bubblesManagerOptional;
835         mBubblesOptional = bubblesOptional;
836         mVisualStabilityManager = visualStabilityManager;
837         mDeviceProvisionedController = deviceProvisionedController;
838         mNavigationBarController = navigationBarController;
839         mAccessibilityFloatingMenuController = accessibilityFloatingMenuController;
840         mAssistManagerLazy = assistManagerLazy;
841         mConfigurationController = configurationController;
842         mNotificationShadeWindowController = notificationShadeWindowController;
843         mDozeServiceHost = dozeServiceHost;
844         mPowerManager = powerManager;
845         mDozeParameters = dozeParameters;
846         mScrimController = scrimController;
847         mLockscreenWallpaperLazy = lockscreenWallpaperLazy;
848         mLockscreenGestureLogger = lockscreenGestureLogger;
849         mScreenPinningRequest = screenPinningRequest;
850         mDozeScrimController = dozeScrimController;
851         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
852         mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy;
853         mVolumeComponent = volumeComponent;
854         mCommandQueue = commandQueue;
855         mCollapsedStatusBarFragmentLogger = collapsedStatusBarFragmentLogger;
856         mStatusBarComponentFactory = statusBarComponentFactory;
857         mPluginManager = pluginManager;
858         mSplitScreenOptional = splitScreenOptional;
859         mStatusBarNotificationActivityStarterBuilder = statusBarNotificationActivityStarterBuilder;
860         mShadeController = shadeController;
861         mLightsOutNotifController =  lightsOutNotifController;
862         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
863         mKeyguardViewMediatorCallback = viewMediatorCallback;
864         mInitController = initController;
865         mPluginDependencyProvider = pluginDependencyProvider;
866         mKeyguardDismissUtil = keyguardDismissUtil;
867         mExtensionController = extensionController;
868         mUserInfoControllerImpl = userInfoControllerImpl;
869         mIconPolicy = phoneStatusBarPolicy;
870         mDemoModeController = demoModeController;
871         mNotificationIconAreaController = notificationIconAreaController;
872         mBrightnessSliderFactory = brightnessSliderFactory;
873         mWallpaperController = wallpaperController;
874         mOngoingCallController = ongoingCallController;
875         mAnimationScheduler = animationScheduler;
876         mStatusBarSignalPolicy = statusBarSignalPolicy;
877         mStatusBarLocationPublisher = locationPublisher;
878         mStatusBarIconController = statusBarIconController;
879         mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
880         mFeatureFlags = featureFlags;
881         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
882         mMainHandler = mainHandler;
883         mMainExecutor = delayableExecutor;
884         mMessageRouter = messageRouter;
885         mWallpaperManager = wallpaperManager;
886         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
887         mTunerService = tunerService;
888 
889         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
890         mStartingSurfaceOptional = startingSurfaceOptional;
891         lockscreenShadeTransitionController.setStatusbar(this);
892 
893         mPanelExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
894 
895         mBubbleExpandListener =
896                 (isExpanding, key) -> mContext.getMainExecutor().execute(() -> {
897                     mNotificationsController.requestNotificationUpdate("onBubbleExpandChanged");
898                     updateScrimController();
899                 });
900 
901         mActivityIntentHelper = new ActivityIntentHelper(mContext);
902         mActivityLaunchAnimator = activityLaunchAnimator;
903 
904         // The status bar background may need updating when the ongoing call status changes.
905         mOngoingCallController.addCallback((animate) -> maybeUpdateBarMode());
906 
907         // TODO(b/190746471): Find a better home for this.
908         DateTimeView.setReceiverHandler(timeTickHandler);
909 
910         mMessageRouter.subscribeTo(KeyboardShortcutsMessage.class,
911                 data -> toggleKeyboardShortcuts(data.mDeviceId));
912         mMessageRouter.subscribeTo(MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU,
913                 id -> dismissKeyboardShortcuts());
914         mMessageRouter.subscribeTo(AnimateExpandSettingsPanelMessage.class,
915                 data -> mCommandQueueCallbacks.animateExpandSettingsPanel(data.mSubpanel));
916         mMessageRouter.subscribeTo(MSG_LAUNCH_TRANSITION_TIMEOUT,
917                 id -> onLaunchTransitionTimeout());
918     }
919 
920     @Override
start()921     public void start() {
922         mScreenLifecycle.addObserver(mScreenObserver);
923         mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
924         mUiModeManager = mContext.getSystemService(UiModeManager.class);
925         mBypassHeadsUpNotifier.setUp();
926         if (mBubblesOptional.isPresent()) {
927             mBubblesOptional.get().setExpandListener(mBubbleExpandListener);
928         }
929 
930         mStatusBarSignalPolicy.init();
931         mKeyguardIndicationController.init();
932 
933         mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
934         mStatusBarStateController.addCallback(mStateListener,
935                 SysuiStatusBarStateController.RANK_STATUS_BAR);
936 
937         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
938         mDreamManager = IDreamManager.Stub.asInterface(
939                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
940 
941         mDisplay = mContext.getDisplay();
942         mDisplayId = mDisplay.getDisplayId();
943         updateDisplaySize();
944         mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);
945 
946         // start old BaseStatusBar.start().
947         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
948         mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
949                 Context.DEVICE_POLICY_SERVICE);
950 
951         mAccessibilityManager = (AccessibilityManager)
952                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
953 
954         mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
955         mBarService = IStatusBarService.Stub.asInterface(
956                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
957 
958         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
959         mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
960 
961         RegisterStatusBarResult result = null;
962         try {
963             result = mBarService.registerStatusBar(mCommandQueue);
964         } catch (RemoteException ex) {
965             ex.rethrowFromSystemServer();
966         }
967 
968         createAndAddWindows(result);
969 
970         if (mWallpaperSupported) {
971             // Make sure we always have the most current wallpaper info.
972             IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
973             mBroadcastDispatcher.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter,
974                     null /* handler */, UserHandle.ALL);
975             mWallpaperChangedReceiver.onReceive(mContext, null);
976         } else if (DEBUG) {
977             Log.v(TAG, "start(): no wallpaper service ");
978         }
979 
980         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
981         setUpPresenter();
982 
983         if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
984             showTransientUnchecked();
985         }
986         mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
987                 result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
988                 result.mRequestedVisibilities, result.mPackageName);
989 
990         // StatusBarManagerService has a back up of IME token and it's restored here.
991         mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken,
992                 result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher);
993 
994         // Set up the initial icon state
995         int numIcons = result.mIcons.size();
996         for (int i = 0; i < numIcons; i++) {
997             mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
998         }
999 
1000 
1001         if (DEBUG) {
1002             Log.d(TAG, String.format(
1003                     "init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x",
1004                     numIcons,
1005                     result.mDisabledFlags1,
1006                     result.mAppearance,
1007                     result.mImeWindowVis));
1008         }
1009 
1010         IntentFilter internalFilter = new IntentFilter();
1011         internalFilter.addAction(BANNER_ACTION_CANCEL);
1012         internalFilter.addAction(BANNER_ACTION_SETUP);
1013         mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
1014                 null);
1015 
1016         if (mWallpaperSupported) {
1017             IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
1018                     ServiceManager.getService(Context.WALLPAPER_SERVICE));
1019             try {
1020                 wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
1021             } catch (RemoteException e) {
1022                 // Just pass, nothing critical.
1023             }
1024         }
1025 
1026         // end old BaseStatusBar.start().
1027 
1028         // Lastly, call to the icon policy to install/update all the icons.
1029         mIconPolicy.init();
1030 
1031         mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
1032             @Override
1033             public void onUnlockedChanged() {
1034                 updateKeyguardState();
1035                 logStateToEventlog();
1036             }
1037         });
1038         startKeyguard();
1039 
1040         mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
1041         mDozeServiceHost.initialize(
1042                 this,
1043                 mStatusBarKeyguardViewManager,
1044                 mNotificationShadeWindowViewController,
1045                 mNotificationPanelViewController,
1046                 mAmbientIndicationContainer);
1047         updateLightRevealScrimVisibility();
1048 
1049         mConfigurationController.addCallback(mConfigurationListener);
1050 
1051         mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback);
1052         mLifecycle.setCurrentState(RESUMED);
1053 
1054         mAccessibilityFloatingMenuController.init();
1055 
1056         // set the initial view visibility
1057         int disabledFlags1 = result.mDisabledFlags1;
1058         int disabledFlags2 = result.mDisabledFlags2;
1059         mInitController.addPostInitTask(
1060                 () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
1061 
1062         mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);
1063 
1064         mPluginManager.addPluginListener(
1065                 new PluginListener<OverlayPlugin>() {
1066                     private final ArraySet<OverlayPlugin> mOverlays = new ArraySet<>();
1067 
1068                     @Override
1069                     public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
1070                         mMainExecutor.execute(
1071                                 () -> plugin.setup(getNotificationShadeWindowView(),
1072                                         getNavigationBarView(),
1073                                         new Callback(plugin), mDozeParameters));
1074                     }
1075 
1076                     @Override
1077                     public void onPluginDisconnected(OverlayPlugin plugin) {
1078                         mMainExecutor.execute(() -> {
1079                             mOverlays.remove(plugin);
1080                             mNotificationShadeWindowController
1081                                     .setForcePluginOpen(mOverlays.size() != 0, this);
1082                         });
1083                     }
1084 
1085                     class Callback implements OverlayPlugin.Callback {
1086                         private final OverlayPlugin mPlugin;
1087 
1088                         Callback(OverlayPlugin plugin) {
1089                             mPlugin = plugin;
1090                         }
1091 
1092                         @Override
1093                         public void onHoldStatusBarOpenChange() {
1094                             if (mPlugin.holdStatusBarOpen()) {
1095                                 mOverlays.add(mPlugin);
1096                             } else {
1097                                 mOverlays.remove(mPlugin);
1098                             }
1099                             mMainExecutor.execute(() -> {
1100                                 mNotificationShadeWindowController
1101                                         .setStateListener(b -> mOverlays.forEach(
1102                                                 o -> o.setCollapseDesired(b)));
1103                                 mNotificationShadeWindowController
1104                                         .setForcePluginOpen(mOverlays.size() != 0, this);
1105                             });
1106                         }
1107                     }
1108                 }, OverlayPlugin.class, true /* Allow multiple plugins */);
1109 
1110         mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
1111                 (requestTopUi, componentTag) -> mMainExecutor.execute(() ->
1112                         mNotificationShadeWindowController.setRequestTopUi(
1113                                 requestTopUi, componentTag))));
1114     }
1115 
1116     // ================================================================================
1117     // Constructing the view
1118     // ================================================================================
makeStatusBarView(@ullable RegisterStatusBarResult result)1119     protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
1120         updateDisplaySize(); // populates mDisplayMetrics
1121         updateResources();
1122         updateTheme();
1123 
1124         inflateStatusBarWindow();
1125         mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController);
1126         mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
1127         mWallpaperController.setRootView(mNotificationShadeWindowView);
1128 
1129         // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
1130         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
1131         NotificationListContainer notifListContainer =
1132                 mStackScrollerController.getNotificationListContainer();
1133         mNotificationLogger.setUpWithContainer(notifListContainer);
1134 
1135         mNotificationIconAreaController.setupShelf(mNotificationShelfController);
1136         mPanelExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
1137 
1138         mUserSwitcherController.init(mNotificationShadeWindowView);
1139 
1140         // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
1141         mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
1142         mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
1143         mStatusBarWindowController.getFragmentHostManager()
1144                 .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
1145                     StatusBarFragmentComponent statusBarFragmentComponent =
1146                             ((CollapsedStatusBarFragment) fragment).getStatusBarFragmentComponent();
1147                     if (statusBarFragmentComponent == null) {
1148                         throw new IllegalStateException(
1149                                 "CollapsedStatusBarFragment should have a valid component");
1150                     }
1151 
1152                     mStatusBarView = statusBarFragmentComponent.getPhoneStatusBarView();
1153                     mPhoneStatusBarViewController =
1154                             statusBarFragmentComponent.getPhoneStatusBarViewController();
1155 
1156                     // Ensure we re-propagate panel expansion values to the panel controller and
1157                     // any listeners it may have, such as PanelBar. This will also ensure we
1158                     // re-display the notification panel if necessary (for example, if
1159                     // a heads-up notification was being displayed and should continue being
1160                     // displayed).
1161                     mNotificationPanelViewController.updatePanelExpansionAndVisibility();
1162                     setBouncerShowingForStatusBarComponents(mBouncerShowing);
1163 
1164                     mLightsOutNotifController.setLightsOutNotifView(
1165                             mStatusBarView.findViewById(R.id.notification_lights_out));
1166                     mNotificationShadeWindowViewController.setStatusBarView(mStatusBarView);
1167                     checkBarModes();
1168                 }).getFragmentManager()
1169                 .beginTransaction()
1170                 .replace(R.id.status_bar_container,
1171                         mStatusBarComponent.createCollapsedStatusBarFragment(),
1172                         CollapsedStatusBarFragment.TAG)
1173                 .commit();
1174 
1175         mHeadsUpManager.setup(mVisualStabilityManager);
1176         mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
1177         mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
1178         mHeadsUpManager.addListener(mVisualStabilityManager);
1179         mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
1180 
1181         createNavigationBar(result);
1182 
1183         if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
1184             mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
1185         }
1186 
1187         mNotificationPanelViewController.setKeyguardIndicationController(
1188                 mKeyguardIndicationController);
1189 
1190         mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
1191                 R.id.ambient_indication_container);
1192 
1193         mAutoHideController.setStatusBar(new AutoHideUiElement() {
1194             @Override
1195             public void synchronizeState() {
1196                 checkBarModes();
1197             }
1198 
1199             @Override
1200             public boolean shouldHideOnTouch() {
1201                 return !mRemoteInputManager.isRemoteInputActive();
1202             }
1203 
1204             @Override
1205             public boolean isVisible() {
1206                 return isTransientShown();
1207             }
1208 
1209             @Override
1210             public void hide() {
1211                 clearTransient();
1212             }
1213         });
1214 
1215         ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
1216         ScrimView notificationsScrim = mNotificationShadeWindowView
1217                 .findViewById(R.id.scrim_notifications);
1218         ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
1219 
1220         mScrimController.setScrimVisibleListener(scrimsVisible -> {
1221             mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
1222         });
1223         mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
1224 
1225         mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
1226         mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
1227             Runnable updateOpaqueness = () -> {
1228                 mNotificationShadeWindowController.setLightRevealScrimOpaque(
1229                         mLightRevealScrim.isScrimOpaque());
1230             };
1231             if (opaque) {
1232                 // Delay making the view opaque for a frame, because it needs some time to render
1233                 // otherwise this can lead to a flicker where the scrim doesn't cover the screen
1234                 mLightRevealScrim.post(updateOpaqueness);
1235             } else {
1236                 updateOpaqueness.run();
1237             }
1238         });
1239         mUnlockedScreenOffAnimationController.initialize(this, mLightRevealScrim);
1240         updateLightRevealScrimVisibility();
1241 
1242         mNotificationPanelViewController.initDependencies(
1243                 this,
1244                 this::makeExpandedInvisible,
1245                 mNotificationShelfController);
1246 
1247         BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
1248         mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
1249                 backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
1250         float maxWallpaperZoom = mContext.getResources().getFloat(
1251                 com.android.internal.R.dimen.config_wallpaperMaxScale);
1252         mNotificationShadeDepthControllerLazy.get().addListener(depth -> {
1253             float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth);
1254             backdrop.setPivotX(backdrop.getWidth() / 2f);
1255             backdrop.setPivotY(backdrop.getHeight() / 2f);
1256             backdrop.setScaleX(scale);
1257             backdrop.setScaleY(scale);
1258         });
1259 
1260         mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
1261 
1262         // Set up the quick settings tile panel
1263         final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
1264         if (container != null) {
1265             FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
1266             ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
1267                     mExtensionController
1268                             .newExtension(QS.class)
1269                             .withPlugin(QS.class)
1270                             .withDefault(this::createDefaultQSFragment)
1271                             .build());
1272             mBrightnessMirrorController = new BrightnessMirrorController(
1273                     mNotificationShadeWindowView,
1274                     mNotificationPanelViewController,
1275                     mNotificationShadeDepthControllerLazy.get(),
1276                     mBrightnessSliderFactory,
1277                     (visible) -> {
1278                         mBrightnessMirrorVisible = visible;
1279                         updateScrimController();
1280                     });
1281             fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
1282                 QS qs = (QS) f;
1283                 if (qs instanceof QSFragment) {
1284                     mQSPanelController = ((QSFragment) qs).getQSPanelController();
1285                     ((QSFragment) qs).setBrightnessMirrorController(mBrightnessMirrorController);
1286                 }
1287             });
1288         }
1289 
1290         mReportRejectedTouch = mNotificationShadeWindowView
1291                 .findViewById(R.id.report_rejected_touch);
1292         if (mReportRejectedTouch != null) {
1293             updateReportRejectedTouchVisibility();
1294             mReportRejectedTouch.setOnClickListener(v -> {
1295                 Uri session = mFalsingManager.reportRejectedTouch();
1296                 if (session == null) { return; }
1297 
1298                 StringWriter message = new StringWriter();
1299                 message.write("Build info: ");
1300                 message.write(SystemProperties.get("ro.build.description"));
1301                 message.write("\nSerial number: ");
1302                 message.write(SystemProperties.get("ro.serialno"));
1303                 message.write("\n");
1304 
1305                 startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
1306                                 .setType("*/*")
1307                                 .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
1308                                 .putExtra(Intent.EXTRA_STREAM, session)
1309                                 .putExtra(Intent.EXTRA_TEXT, message.toString()),
1310                         "Share rejected touch report")
1311                                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
1312                         true /* onlyProvisioned */, true /* dismissShade */);
1313             });
1314         }
1315 
1316         if (!mPowerManager.isInteractive()) {
1317             mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
1318         }
1319         mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1320                 "sysui:GestureWakeLock");
1321 
1322         // receive broadcasts
1323         registerBroadcastReceiver();
1324 
1325         IntentFilter demoFilter = new IntentFilter();
1326         if (DEBUG_MEDIA_FAKE_ARTWORK) {
1327             demoFilter.addAction(ACTION_FAKE_ARTWORK);
1328         }
1329         mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
1330                 android.Manifest.permission.DUMP, null);
1331 
1332         // listen for USER_SETUP_COMPLETE setting (per-user)
1333         mDeviceProvisionedController.addCallback(mUserSetupObserver);
1334         mUserSetupObserver.onUserSetupChanged();
1335 
1336         // disable profiling bars, since they overlap and clutter the output on app windows
1337         ThreadedRenderer.overrideProperty("disableProfileBars", "true");
1338 
1339         // Private API call to make the shadows look better for Recents
1340         ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
1341     }
1342 
1343 
1344     /**
1345      * When swiping up to dismiss the lock screen, the panel expansion fraction goes from 1f to 0f.
1346      * This results in the clock/notifications/other content disappearing off the top of the screen.
1347      *
1348      * We also use the expansion fraction to animate in the app/launcher surface from the bottom of
1349      * the screen, 'pushing' off the notifications and other content. To do this, we dispatch the
1350      * expansion fraction to the KeyguardViewMediator if we're in the process of dismissing the
1351      * keyguard.
1352      */
dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch)1353     private void dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch) {
1354         // Things that mean we're not dismissing the keyguard, and should ignore this expansion:
1355         // - Keyguard isn't even visible.
1356         // - Keyguard is visible, but can't be dismissed (swiping up will show PIN/password prompt).
1357         // - The SIM is locked, you can't swipe to unlock. If the SIM is locked but there is no
1358         //   device lock set, canDismissLockScreen returns true even though you should not be able
1359         //   to dismiss the lock screen until entering the SIM PIN.
1360         // - QS is expanded and we're swiping - swiping up now will hide QS, not dismiss the
1361         //   keyguard.
1362         if (!isKeyguardShowing()
1363                 || !mKeyguardStateController.canDismissLockScreen()
1364                 || mKeyguardViewMediator.isAnySimPinSecure()
1365                 || (mNotificationPanelViewController.isQsExpanded() && trackingTouch)) {
1366             return;
1367         }
1368 
1369         // Otherwise, we should let the keyguard know about this if we're tracking touch, or if we
1370         // are already animating the keyguard dismiss (since we will need to either finish or cancel
1371         // the animation).
1372         if (trackingTouch
1373                 || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()
1374                 || mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
1375             mKeyguardStateController.notifyKeyguardDismissAmountChanged(
1376                     1f - fraction, trackingTouch);
1377         }
1378     }
1379 
onPanelExpansionChanged(float fraction, boolean expanded, boolean tracking)1380     private void onPanelExpansionChanged(float fraction, boolean expanded, boolean tracking) {
1381         dispatchPanelExpansionForKeyguardDismiss(fraction, tracking);
1382 
1383         if (fraction == 0 || fraction == 1) {
1384             if (getNavigationBarView() != null) {
1385                 getNavigationBarView().onStatusBarPanelStateChanged();
1386             }
1387             if (getNotificationPanelViewController() != null) {
1388                 getNotificationPanelViewController().updateSystemUiStateFlags();
1389             }
1390         }
1391     }
1392 
1393     @NonNull
1394     @Override
getLifecycle()1395     public Lifecycle getLifecycle() {
1396         return mLifecycle;
1397     }
1398 
1399     @VisibleForTesting
registerBroadcastReceiver()1400     protected void registerBroadcastReceiver() {
1401         IntentFilter filter = new IntentFilter();
1402         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
1403         filter.addAction(Intent.ACTION_SCREEN_OFF);
1404         filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
1405         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
1406     }
1407 
createDefaultQSFragment()1408     protected QS createDefaultQSFragment() {
1409         return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class);
1410     }
1411 
setUpPresenter()1412     private void setUpPresenter() {
1413         // Set up the initial notification state.
1414         mActivityLaunchAnimator.setCallback(mKeyguardHandler);
1415         mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
1416                 mNotificationShadeWindowViewController,
1417                 mStackScrollerController.getNotificationListContainer(),
1418                 mHeadsUpManager
1419         );
1420 
1421         // TODO: inject this.
1422         mPresenter = new StatusBarNotificationPresenter(
1423                 mContext,
1424                 mNotificationPanelViewController,
1425                 mHeadsUpManager,
1426                 mNotificationShadeWindowView,
1427                 mStackScrollerController,
1428                 mDozeScrimController,
1429                 mScrimController,
1430                 mNotificationShadeWindowController,
1431                 mDynamicPrivacyController,
1432                 mKeyguardStateController,
1433                 mKeyguardIndicationController,
1434                 mFeatureFlags,
1435                 this /* statusBar */,
1436                 mShadeController,
1437                 mLockscreenShadeTransitionController,
1438                 mCommandQueue,
1439                 mViewHierarchyManager,
1440                 mLockscreenUserManager,
1441                 mStatusBarStateController,
1442                 mNotifShadeEventSource,
1443                 mEntryManager,
1444                 mMediaManager,
1445                 mGutsManager,
1446                 mKeyguardUpdateMonitor,
1447                 mLockscreenGestureLogger,
1448                 mInitController,
1449                 mNotificationInterruptStateProvider,
1450                 mRemoteInputManager,
1451                 mConfigurationController);
1452 
1453         mNotificationShelfController.setOnActivatedListener(mPresenter);
1454         mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
1455 
1456         mNotificationActivityStarter =
1457                 mStatusBarNotificationActivityStarterBuilder
1458                         .setStatusBar(this)
1459                         .setActivityLaunchAnimator(mActivityLaunchAnimator)
1460                         .setNotificationAnimatorControllerProvider(mNotificationAnimationProvider)
1461                         .setNotificationPresenter(mPresenter)
1462                         .setNotificationPanelViewController(mNotificationPanelViewController)
1463                         .build();
1464         mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
1465         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
1466 
1467         mNotificationsController.initialize(
1468                 this,
1469                 mBubblesOptional,
1470                 mPresenter,
1471                 mStackScrollerController.getNotificationListContainer(),
1472                 mNotificationActivityStarter,
1473                 mPresenter);
1474     }
1475 
1476     /**
1477      * Post-init task of {@link #start()}
1478      * @param state1 disable1 flags
1479      * @param state2 disable2 flags
1480      */
setUpDisableFlags(int state1, int state2)1481     protected void setUpDisableFlags(int state1, int state2) {
1482         mCommandQueue.disable(mDisplayId, state1, state2, false /* animate */);
1483     }
1484 
1485     /**
1486      * Ask the display to wake up if currently dozing, else do nothing
1487      *
1488      * @param time when to wake up
1489      * @param where the view requesting the wakeup
1490      * @param why the reason for the wake up
1491      */
wakeUpIfDozing(long time, View where, String why)1492     public void wakeUpIfDozing(long time, View where, String why) {
1493         if (mDozing && !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
1494             mPowerManager.wakeUp(
1495                     time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
1496             mWakeUpComingFromTouch = true;
1497             where.getLocationInWindow(mTmpInt2);
1498 
1499             // NOTE, the incoming view can sometimes be the entire container... unsure if
1500             // this location is valuable enough
1501             mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
1502                     mTmpInt2[1] + where.getHeight() / 2);
1503             mFalsingCollector.onScreenOnFromTouch();
1504         }
1505     }
1506 
1507     // TODO(b/117478341): This was left such that CarStatusBar can override this method.
1508     // Try to remove this.
createNavigationBar(@ullable RegisterStatusBarResult result)1509     protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
1510         mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
1511     }
1512 
1513     /**
1514      * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
1515      * background window of the status bar is clicked.
1516      */
getStatusBarWindowTouchListener()1517     protected View.OnTouchListener getStatusBarWindowTouchListener() {
1518         return (v, event) -> {
1519             mAutoHideController.checkUserAutoHide(event);
1520             mRemoteInputManager.checkRemoteInputOutside(event);
1521             if (event.getAction() == MotionEvent.ACTION_DOWN) {
1522                 if (mExpandedVisible) {
1523                     mShadeController.animateCollapsePanels();
1524                 }
1525             }
1526             return mNotificationShadeWindowView.onTouchEvent(event);
1527         };
1528     }
1529 
inflateStatusBarWindow()1530     private void inflateStatusBarWindow() {
1531         mStatusBarComponent = mStatusBarComponentFactory.create();
1532         mFragmentService.addFragmentInstantiationProvider(mStatusBarComponent);
1533 
1534         mNotificationShadeWindowView = mStatusBarComponent.getNotificationShadeWindowView();
1535         mNotificationShadeWindowViewController = mStatusBarComponent
1536                 .getNotificationShadeWindowViewController();
1537         mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
1538         mNotificationShadeWindowViewController.setupExpandedStatusBar();
1539         mNotificationPanelViewController = mStatusBarComponent.getNotificationPanelViewController();
1540         mStatusBarComponent.getLockIconViewController().init();
1541         mStackScrollerController = mStatusBarComponent.getNotificationStackScrollLayoutController();
1542         mStackScroller = mStackScrollerController.getView();
1543 
1544         mNotificationShelfController = mStatusBarComponent.getNotificationShelfController();
1545         mAuthRippleController = mStatusBarComponent.getAuthRippleController();
1546         mAuthRippleController.init();
1547 
1548         mHeadsUpManager.addListener(mStatusBarComponent.getStatusBarHeadsUpChangeListener());
1549 
1550         mHeadsUpManager.addListener(mStatusBarComponent.getStatusBarHeadsUpChangeListener());
1551 
1552         // Listen for demo mode changes
1553         mDemoModeController.addCallback(mStatusBarComponent.getStatusBarDemoMode());
1554 
1555         if (mCommandQueueCallbacks != null) {
1556             mCommandQueue.removeCallback(mCommandQueueCallbacks);
1557         }
1558         mCommandQueueCallbacks = mStatusBarComponent.getStatusBarCommandQueueCallbacks();
1559         // Connect in to the status bar manager service
1560         mCommandQueue.addCallback(mCommandQueueCallbacks);
1561     }
1562 
startKeyguard()1563     protected void startKeyguard() {
1564         Trace.beginSection("StatusBar#startKeyguard");
1565         mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
1566         mBiometricUnlockController.setBiometricModeListener(
1567                 new BiometricUnlockController.BiometricModeListener() {
1568                     @Override
1569                     public void onResetMode() {
1570                         setWakeAndUnlocking(false);
1571                     }
1572 
1573                     @Override
1574                     public void onModeChanged(int mode) {
1575                         switch (mode) {
1576                             case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM:
1577                             case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING:
1578                             case BiometricUnlockController.MODE_WAKE_AND_UNLOCK:
1579                                 setWakeAndUnlocking(true);
1580                         }
1581                     }
1582 
1583                     @Override
1584                     public void notifyBiometricAuthModeChanged() {
1585                         StatusBar.this.notifyBiometricAuthModeChanged();
1586                     }
1587 
1588                     private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
1589                         if (getNavigationBarView() != null) {
1590                             getNavigationBarView().setWakeAndUnlocking(wakeAndUnlocking);
1591                         }
1592                     }
1593                 });
1594         mStatusBarKeyguardViewManager.registerStatusBar(
1595                 /* statusBar= */ this,
1596                 mNotificationPanelViewController,
1597                 mPanelExpansionStateManager,
1598                 mBiometricUnlockController,
1599                 mStackScroller,
1600                 mKeyguardBypassController);
1601         mKeyguardIndicationController
1602                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
1603         mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
1604         mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager);
1605         mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
1606 
1607         mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
1608         mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
1609         mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
1610         Trace.endSection();
1611     }
1612 
getStatusBarView()1613     protected PhoneStatusBarView getStatusBarView() {
1614         return mStatusBarView;
1615     }
1616 
getNotificationShadeWindowView()1617     public NotificationShadeWindowView getNotificationShadeWindowView() {
1618         return mNotificationShadeWindowView;
1619     }
1620 
getNotificationShadeWindowViewController()1621     public NotificationShadeWindowViewController getNotificationShadeWindowViewController() {
1622         return mNotificationShadeWindowViewController;
1623     }
1624 
getNotificationPanelViewController()1625     public NotificationPanelViewController getNotificationPanelViewController() {
1626         return mNotificationPanelViewController;
1627     }
1628 
getBouncerContainer()1629     public ViewGroup getBouncerContainer() {
1630         return mNotificationShadeWindowViewController.getBouncerContainer();
1631     }
1632 
getStatusBarHeight()1633     public int getStatusBarHeight() {
1634         return mStatusBarWindowController.getStatusBarHeight();
1635     }
1636 
toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction)1637     public boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
1638         if (!mSplitScreenOptional.isPresent()) {
1639             return false;
1640         }
1641 
1642         final LegacySplitScreen legacySplitScreen = mSplitScreenOptional.get();
1643         if (legacySplitScreen.isDividerVisible()) {
1644             if (legacySplitScreen.isMinimized() && !legacySplitScreen.isHomeStackResizable()) {
1645                 // Undocking from the minimized state is not supported
1646                 return false;
1647             }
1648 
1649             legacySplitScreen.onUndockingTask();
1650             if (metricsUndockAction != -1) {
1651                 mMetricsLogger.action(metricsUndockAction);
1652             }
1653             return true;
1654         }
1655 
1656         if (legacySplitScreen.splitPrimaryTask()) {
1657             if (metricsDockAction != -1) {
1658                 mMetricsLogger.action(metricsDockAction);
1659             }
1660             return true;
1661         }
1662 
1663         return false;
1664     }
1665 
1666     /**
1667      * Disable QS if device not provisioned.
1668      * If the user switcher is simple then disable QS during setup because
1669      * the user intends to use the lock screen user switcher, QS in not needed.
1670      */
updateQsExpansionEnabled()1671     void updateQsExpansionEnabled() {
1672         final boolean expandEnabled = mDeviceProvisionedController.isDeviceProvisioned()
1673                 && (mUserSetup || mUserSwitcherController == null
1674                         || !mUserSwitcherController.isSimpleUserSwitcher())
1675                 && !isShadeDisabled()
1676                 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1677                 && !mDozing
1678                 && !ONLY_CORE_APPS;
1679         mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled);
1680         Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
1681     }
1682 
isShadeDisabled()1683     public boolean isShadeDisabled() {
1684         return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0;
1685     }
1686 
1687     /**
1688      * Request a notification update
1689      * @param reason why we're requesting a notification update
1690      */
requestNotificationUpdate(String reason)1691     public void requestNotificationUpdate(String reason) {
1692         mNotificationsController.requestNotificationUpdate(reason);
1693     }
1694 
1695     /**
1696      * Asks {@link KeyguardUpdateMonitor} to run face auth.
1697      */
requestFaceAuth(boolean userInitiatedRequest)1698     public void requestFaceAuth(boolean userInitiatedRequest) {
1699         if (!mKeyguardStateController.canDismissLockScreen()) {
1700             mKeyguardUpdateMonitor.requestFaceAuth(userInitiatedRequest);
1701         }
1702     }
1703 
updateReportRejectedTouchVisibility()1704     private void updateReportRejectedTouchVisibility() {
1705         if (mReportRejectedTouch == null) {
1706             return;
1707         }
1708         mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD && !mDozing
1709                 && mFalsingCollector.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
1710     }
1711 
areNotificationAlertsDisabled()1712     boolean areNotificationAlertsDisabled() {
1713         return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
1714     }
1715 
1716     @Override
startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags)1717     public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
1718             int flags) {
1719         startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, flags);
1720     }
1721 
1722     @Override
startActivity(Intent intent, boolean dismissShade)1723     public void startActivity(Intent intent, boolean dismissShade) {
1724         startActivityDismissingKeyguard(intent, false /* onlyProvisioned */, dismissShade);
1725     }
1726 
1727     @Override
startActivity(Intent intent, boolean dismissShade, @Nullable ActivityLaunchAnimator.Controller animationController, boolean showOverLockscreenWhenLocked)1728     public void startActivity(Intent intent, boolean dismissShade,
1729             @Nullable ActivityLaunchAnimator.Controller animationController,
1730             boolean showOverLockscreenWhenLocked) {
1731         // Make sure that we dismiss the keyguard if it is directly dismissable or when we don't
1732         // want to show the activity above it.
1733         if (mKeyguardStateController.isUnlocked() || !showOverLockscreenWhenLocked) {
1734             startActivityDismissingKeyguard(intent, false, dismissShade,
1735                 false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
1736                 0 /* flags */, animationController);
1737             return;
1738         }
1739 
1740         boolean animate =
1741                 animationController != null && shouldAnimateLaunch(true /* isActivityIntent */,
1742                         showOverLockscreenWhenLocked);
1743 
1744         ActivityLaunchAnimator.Controller controller = null;
1745         if (animate) {
1746             // Wrap the animation controller to dismiss the shade and set
1747             // mIsLaunchingActivityOverLockscreen during the animation.
1748             ActivityLaunchAnimator.Controller delegate = wrapAnimationController(
1749                     animationController, dismissShade);
1750             controller = new DelegateLaunchAnimatorController(delegate) {
1751                 @Override
1752                 public void onIntentStarted(boolean willAnimate) {
1753                     getDelegate().onIntentStarted(willAnimate);
1754 
1755                     if (willAnimate) {
1756                         StatusBar.this.mIsLaunchingActivityOverLockscreen = true;
1757                     }
1758                 }
1759 
1760                 @Override
1761                 public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
1762                     // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
1763                     // animation so that we can assume that mIsLaunchingActivityOverLockscreen
1764                     // being true means that we will collapse the shade (or at least run the
1765                     // post collapse runnables) later on.
1766                     StatusBar.this.mIsLaunchingActivityOverLockscreen = false;
1767                     getDelegate().onLaunchAnimationEnd(isExpandingFullyAbove);
1768                 }
1769 
1770                 @Override
1771                 public void onLaunchAnimationCancelled() {
1772                     // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
1773                     // animation so that we can assume that mIsLaunchingActivityOverLockscreen
1774                     // being true means that we will collapse the shade (or at least run the
1775                     // post collapse runnables) later on.
1776                     StatusBar.this.mIsLaunchingActivityOverLockscreen = false;
1777                     getDelegate().onLaunchAnimationCancelled();
1778                 }
1779             };
1780         } else if (dismissShade) {
1781             // The animation will take care of dismissing the shade at the end of the animation. If
1782             // we don't animate, collapse it directly.
1783             collapseShade();
1784         }
1785 
1786         mActivityLaunchAnimator.startIntentWithAnimation(controller, animate,
1787                 intent.getPackage(), showOverLockscreenWhenLocked, (adapter) -> TaskStackBuilder
1788                         .create(mContext)
1789                         .addNextIntent(intent)
1790                         .startActivities(getActivityOptions(getDisplayId(), adapter),
1791                                 UserHandle.CURRENT));
1792     }
1793 
1794     /**
1795      * Whether we are currently animating an activity launch above the lockscreen (occluding
1796      * activity).
1797      */
isLaunchingActivityOverLockscreen()1798     public boolean isLaunchingActivityOverLockscreen() {
1799         return mIsLaunchingActivityOverLockscreen;
1800     }
1801 
1802     @Override
startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade)1803     public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
1804         startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade);
1805     }
1806 
1807     @Override
startActivity(Intent intent, boolean dismissShade, Callback callback)1808     public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
1809         startActivityDismissingKeyguard(intent, false, dismissShade,
1810                 false /* disallowEnterPictureInPictureWhileLaunching */, callback, 0,
1811                 null /* animationController */);
1812     }
1813 
setQsExpanded(boolean expanded)1814     public void setQsExpanded(boolean expanded) {
1815         mNotificationShadeWindowController.setQsExpanded(expanded);
1816         mNotificationPanelViewController.setStatusAccessibilityImportance(expanded
1817                 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
1818                 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
1819         mNotificationPanelViewController.updateSystemUiStateFlags();
1820         if (getNavigationBarView() != null) {
1821             getNavigationBarView().onStatusBarPanelStateChanged();
1822         }
1823     }
1824 
isWakeUpComingFromTouch()1825     public boolean isWakeUpComingFromTouch() {
1826         return mWakeUpComingFromTouch;
1827     }
1828 
isFalsingThresholdNeeded()1829     public boolean isFalsingThresholdNeeded() {
1830         return true;
1831     }
1832 
1833     /**
1834      * To be called when there's a state change in StatusBarKeyguardViewManager.
1835      */
onKeyguardViewManagerStatesUpdated()1836     public void onKeyguardViewManagerStatesUpdated() {
1837         logStateToEventlog();
1838     }
1839 
setPanelExpanded(boolean isExpanded)1840     public void setPanelExpanded(boolean isExpanded) {
1841         if (mPanelExpanded != isExpanded) {
1842             mNotificationLogger.onPanelExpandedChanged(isExpanded);
1843         }
1844         mPanelExpanded = isExpanded;
1845         mStatusBarHideIconsForBouncerManager.setPanelExpandedAndTriggerUpdate(isExpanded);
1846         mNotificationShadeWindowController.setPanelExpanded(isExpanded);
1847         mStatusBarStateController.setPanelExpanded(isExpanded);
1848         if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
1849             if (DEBUG) {
1850                 Log.v(TAG, "clearing notification effects from Height");
1851             }
1852             clearNotificationEffects();
1853         }
1854 
1855         if (!isExpanded) {
1856             mRemoteInputManager.onPanelCollapsed();
1857         }
1858     }
1859 
getNotificationScrollLayout()1860     public ViewGroup getNotificationScrollLayout() {
1861         return mStackScroller;
1862     }
1863 
isPulsing()1864     public boolean isPulsing() {
1865         return mDozeServiceHost.isPulsing();
1866     }
1867 
1868     @Nullable
getAmbientIndicationContainer()1869     public View getAmbientIndicationContainer() {
1870         return mAmbientIndicationContainer;
1871     }
1872 
1873     /**
1874      * When the keyguard is showing and covered by a "showWhenLocked" activity it
1875      * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
1876      *
1877      * @return whether the keyguard is currently occluded
1878      */
isOccluded()1879     public boolean isOccluded() {
1880         return mIsOccluded;
1881     }
1882 
setOccluded(boolean occluded)1883     public void setOccluded(boolean occluded) {
1884         mIsOccluded = occluded;
1885         mStatusBarHideIconsForBouncerManager.setIsOccludedAndTriggerUpdate(occluded);
1886         mScrimController.setKeyguardOccluded(occluded);
1887     }
1888 
1889     /** A launch animation was cancelled. */
1890     //TODO: These can / should probably be moved to NotificationPresenter or ShadeController
onLaunchAnimationCancelled(boolean isLaunchForActivity)1891     public void onLaunchAnimationCancelled(boolean isLaunchForActivity) {
1892         if (mPresenter.isPresenterFullyCollapsed() && !mPresenter.isCollapsing()
1893                 && isLaunchForActivity) {
1894             onClosingFinished();
1895         } else {
1896             mShadeController.collapsePanel(true /* animate */);
1897         }
1898     }
1899 
1900     /** A launch animation ended. */
onLaunchAnimationEnd(boolean launchIsFullScreen)1901     public void onLaunchAnimationEnd(boolean launchIsFullScreen) {
1902         if (!mPresenter.isCollapsing()) {
1903             onClosingFinished();
1904         }
1905         if (launchIsFullScreen) {
1906             instantCollapseNotificationPanel();
1907         }
1908     }
1909 
1910     /**
1911      * Whether we should animate an activity launch.
1912      *
1913      * Note: This method must be called *before* dismissing the keyguard.
1914      */
shouldAnimateLaunch(boolean isActivityIntent, boolean showOverLockscreen)1915     public boolean shouldAnimateLaunch(boolean isActivityIntent, boolean showOverLockscreen) {
1916         // TODO(b/184121838): Support launch animations when occluded.
1917         if (isOccluded()) {
1918             return false;
1919         }
1920 
1921         // Always animate if we are not showing the keyguard or if we animate over the lockscreen
1922         // (without unlocking it).
1923         if (showOverLockscreen || !mKeyguardStateController.isShowing()) {
1924             return true;
1925         }
1926 
1927         // If we are locked and have to dismiss the keyguard, only animate if remote unlock
1928         // animations are enabled. We also don't animate non-activity launches as they can break the
1929         // animation.
1930         // TODO(b/184121838): Support non activity launches on the lockscreen.
1931         return isActivityIntent && KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation;
1932     }
1933 
1934     /** Whether we should animate an activity launch. */
shouldAnimateLaunch(boolean isActivityIntent)1935     public boolean shouldAnimateLaunch(boolean isActivityIntent) {
1936         return shouldAnimateLaunch(isActivityIntent, false /* showOverLockscreen */);
1937     }
1938 
isDeviceInVrMode()1939     public boolean isDeviceInVrMode() {
1940         return mPresenter.isDeviceInVrMode();
1941     }
1942 
getPresenter()1943     public NotificationPresenter getPresenter() {
1944         return mPresenter;
1945     }
1946 
1947     @VisibleForTesting
setBarStateForTest(int state)1948     void setBarStateForTest(int state) {
1949         mState = state;
1950     }
1951 
1952     static class KeyboardShortcutsMessage {
1953         final int mDeviceId;
1954 
KeyboardShortcutsMessage(int deviceId)1955         KeyboardShortcutsMessage(int deviceId) {
1956             mDeviceId = deviceId;
1957         }
1958     }
1959 
1960     static class AnimateExpandSettingsPanelMessage {
1961         final String mSubpanel;
1962 
AnimateExpandSettingsPanelMessage(String subpanel)1963         AnimateExpandSettingsPanelMessage(String subpanel) {
1964             mSubpanel = subpanel;
1965         }
1966     }
1967 
maybeEscalateHeadsUp()1968     private void maybeEscalateHeadsUp() {
1969         mHeadsUpManager.getAllEntries().forEach(entry -> {
1970             final StatusBarNotification sbn = entry.getSbn();
1971             final Notification notification = sbn.getNotification();
1972             if (notification.fullScreenIntent != null) {
1973                 if (DEBUG) {
1974                     Log.d(TAG, "converting a heads up to fullScreen");
1975                 }
1976                 try {
1977                     EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
1978                             sbn.getKey());
1979                     wakeUpForFullScreenIntent();
1980                     notification.fullScreenIntent.send();
1981                     entry.notifyFullScreenIntentLaunched();
1982                 } catch (PendingIntent.CanceledException e) {
1983                 }
1984             }
1985         });
1986         mHeadsUpManager.releaseAllImmediately();
1987     }
1988 
wakeUpForFullScreenIntent()1989     void wakeUpForFullScreenIntent() {
1990         if (isGoingToSleep() || mDozing) {
1991             mPowerManager.wakeUp(
1992                     SystemClock.uptimeMillis(),
1993                     PowerManager.WAKE_REASON_APPLICATION,
1994                     "com.android.systemui:full_screen_intent");
1995             mWakeUpComingFromTouch = false;
1996             mWakeUpTouchLocation = null;
1997         }
1998     }
1999 
makeExpandedVisible(boolean force)2000     void makeExpandedVisible(boolean force) {
2001         if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
2002         if (!force && (mExpandedVisible || !mCommandQueue.panelsEnabled())) {
2003             return;
2004         }
2005 
2006         mExpandedVisible = true;
2007 
2008         // Expand the window to encompass the full screen in anticipation of the drag.
2009         // This is only possible to do atomically because the status bar is at the top of the screen!
2010         mNotificationShadeWindowController.setPanelVisible(true);
2011 
2012         visibilityChanged(true);
2013         mCommandQueue.recomputeDisableFlags(mDisplayId, !force /* animate */);
2014         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2015     }
2016 
postAnimateCollapsePanels()2017     public void postAnimateCollapsePanels() {
2018         mMainExecutor.execute(mShadeController::animateCollapsePanels);
2019     }
2020 
postAnimateForceCollapsePanels()2021     public void postAnimateForceCollapsePanels() {
2022         mMainExecutor.execute(
2023                 () -> mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE,
2024                 true /* force */));
2025     }
2026 
postAnimateOpenPanels()2027     public void postAnimateOpenPanels() {
2028         mMessageRouter.sendMessage(MSG_OPEN_SETTINGS_PANEL);
2029     }
2030 
isExpandedVisible()2031     public boolean isExpandedVisible() {
2032         return mExpandedVisible;
2033     }
2034 
isPanelExpanded()2035     public boolean isPanelExpanded() {
2036         return mPanelExpanded;
2037     }
2038 
2039     /**
2040      * Called when another window is about to transfer it's input focus.
2041      */
onInputFocusTransfer(boolean start, boolean cancel, float velocity)2042     public void onInputFocusTransfer(boolean start, boolean cancel, float velocity) {
2043         if (!mCommandQueue.panelsEnabled()) {
2044             return;
2045         }
2046 
2047         if (start) {
2048             mNotificationPanelViewController.startWaitingForOpenPanelGesture();
2049         } else {
2050             mNotificationPanelViewController.stopWaitingForOpenPanelGesture(cancel, velocity);
2051         }
2052     }
2053 
animateCollapseQuickSettings()2054     public void animateCollapseQuickSettings() {
2055         if (mState == StatusBarState.SHADE) {
2056             mNotificationPanelViewController.collapsePanel(
2057                     true, false /* delayed */, 1.0f /* speedUpFactor */);
2058         }
2059     }
2060 
makeExpandedInvisible()2061     void makeExpandedInvisible() {
2062         if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
2063                 + " mExpandedVisible=" + mExpandedVisible);
2064 
2065         if (!mExpandedVisible || mNotificationShadeWindowView == null) {
2066             return;
2067         }
2068 
2069         // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
2070         mNotificationPanelViewController.collapsePanel(/*animate=*/ false, false /* delayed*/,
2071                 1.0f /* speedUpFactor */);
2072 
2073         mNotificationPanelViewController.closeQs();
2074 
2075         mExpandedVisible = false;
2076         visibilityChanged(false);
2077 
2078         // Update the visibility of notification shade and status bar window.
2079         mNotificationShadeWindowController.setPanelVisible(false);
2080         mStatusBarWindowController.setForceStatusBarVisible(false);
2081 
2082         // Close any guts that might be visible
2083         mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
2084                 true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
2085 
2086         mShadeController.runPostCollapseRunnables();
2087         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2088         if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) {
2089             showBouncerOrLockScreenIfKeyguard();
2090         } else if (DEBUG) {
2091             Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");
2092         }
2093         mCommandQueue.recomputeDisableFlags(
2094                 mDisplayId,
2095                 mNotificationPanelViewController.hideStatusBarIconsWhenExpanded() /* animate */);
2096 
2097         // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2098         // the bouncer appear animation.
2099         if (!mStatusBarKeyguardViewManager.isShowing()) {
2100             WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2101         }
2102     }
2103 
2104     /** Called when a touch event occurred on {@link PhoneStatusBarView}. */
onTouchEvent(MotionEvent event)2105     public void onTouchEvent(MotionEvent event) {
2106         // TODO(b/202981994): Move this touch debugging to a central location. (Right now, it's
2107         //   split between NotificationPanelViewController and here.)
2108         if (DEBUG_GESTURES) {
2109             if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2110                 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
2111                         event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2112                         mDisabled1, mDisabled2);
2113             }
2114 
2115         }
2116 
2117         if (SPEW) {
2118             Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2119                     + mDisabled1 + " mDisabled2=" + mDisabled2);
2120         } else if (CHATTY) {
2121             if (event.getAction() != MotionEvent.ACTION_MOVE) {
2122                 Log.d(TAG, String.format(
2123                             "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
2124                             MotionEvent.actionToString(event.getAction()),
2125                             event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
2126             }
2127         }
2128 
2129         if (DEBUG_GESTURES) {
2130             mGestureRec.add(event);
2131         }
2132 
2133         if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
2134             final boolean upOrCancel =
2135                     event.getAction() == MotionEvent.ACTION_UP ||
2136                     event.getAction() == MotionEvent.ACTION_CANCEL;
2137             setInteracting(StatusBarManager.WINDOW_STATUS_BAR, !upOrCancel || mExpandedVisible);
2138         }
2139     }
2140 
isSameStatusBarState(int state)2141     boolean isSameStatusBarState(int state) {
2142         return mStatusBarWindowState == state;
2143     }
2144 
getGestureRecorder()2145     public GestureRecorder getGestureRecorder() {
2146         return mGestureRec;
2147     }
2148 
getBiometricUnlockController()2149     public BiometricUnlockController getBiometricUnlockController() {
2150         return mBiometricUnlockController;
2151     }
2152 
showTransientUnchecked()2153     void showTransientUnchecked() {
2154         if (!mTransientShown) {
2155             mTransientShown = true;
2156             mNoAnimationOnNextBarModeChange = true;
2157             maybeUpdateBarMode();
2158         }
2159     }
2160 
2161 
clearTransient()2162     void clearTransient() {
2163         if (mTransientShown) {
2164             mTransientShown = false;
2165             maybeUpdateBarMode();
2166         }
2167     }
2168 
maybeUpdateBarMode()2169     private void maybeUpdateBarMode() {
2170         final int barMode = barMode(mTransientShown, mAppearance);
2171         if (updateBarMode(barMode)) {
2172             mLightBarController.onStatusBarModeChanged(barMode);
2173             updateBubblesVisibility();
2174         }
2175     }
2176 
updateBarMode(int barMode)2177     private boolean updateBarMode(int barMode) {
2178         if (mStatusBarMode != barMode) {
2179             mStatusBarMode = barMode;
2180             checkBarModes();
2181             mAutoHideController.touchAutoHide();
2182             return true;
2183         }
2184         return false;
2185     }
2186 
barMode(boolean isTransient, int appearance)2187     private @TransitionMode int barMode(boolean isTransient, int appearance) {
2188         final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
2189         if (mOngoingCallController.hasOngoingCall() && mIsFullscreen) {
2190             return MODE_SEMI_TRANSPARENT;
2191         } else if (isTransient) {
2192             return MODE_SEMI_TRANSPARENT;
2193         } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
2194             return MODE_LIGHTS_OUT;
2195         } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
2196             return MODE_LIGHTS_OUT_TRANSPARENT;
2197         } else if ((appearance & APPEARANCE_OPAQUE_STATUS_BARS) != 0) {
2198             return MODE_OPAQUE;
2199         } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS) != 0) {
2200             return MODE_SEMI_TRANSPARENT;
2201         } else {
2202             return MODE_TRANSPARENT;
2203         }
2204     }
2205 
showWirelessChargingAnimation(int batteryLevel)2206     protected void showWirelessChargingAnimation(int batteryLevel) {
2207         showChargingAnimation(batteryLevel, UNKNOWN_BATTERY_LEVEL, 0);
2208     }
2209 
showChargingAnimation(int batteryLevel, int transmittingBatteryLevel, long animationDelay)2210     protected void showChargingAnimation(int batteryLevel, int transmittingBatteryLevel,
2211             long animationDelay) {
2212         WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
2213                 transmittingBatteryLevel, batteryLevel,
2214                 new WirelessChargingAnimation.Callback() {
2215                     @Override
2216                     public void onAnimationStarting() {
2217                         mNotificationShadeWindowController.setRequestTopUi(true, TAG);
2218                     }
2219 
2220                     @Override
2221                     public void onAnimationEnded() {
2222                         mNotificationShadeWindowController.setRequestTopUi(false, TAG);
2223                     }
2224                 }, false, sUiEventLogger).show(animationDelay);
2225     }
2226 
getStatusBarTransitions()2227     protected BarTransitions getStatusBarTransitions() {
2228         return mNotificationShadeWindowViewController.getBarTransitions();
2229     }
2230 
checkBarModes()2231     public void checkBarModes() {
2232         if (mDemoModeController.isInDemoMode()) return;
2233         if (mNotificationShadeWindowViewController != null && getStatusBarTransitions() != null) {
2234             checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions());
2235         }
2236         mNavigationBarController.checkNavBarModes(mDisplayId);
2237         mNoAnimationOnNextBarModeChange = false;
2238     }
2239 
2240     // Called by NavigationBarFragment
setQsScrimEnabled(boolean scrimEnabled)2241     public void setQsScrimEnabled(boolean scrimEnabled) {
2242         mNotificationPanelViewController.setQsScrimEnabled(scrimEnabled);
2243     }
2244 
2245     /** Temporarily hides Bubbles if the status bar is hidden. */
updateBubblesVisibility()2246     void updateBubblesVisibility() {
2247         mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
2248                 mStatusBarMode != MODE_LIGHTS_OUT
2249                         && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT
2250                         && !mStatusBarWindowHidden));
2251     }
2252 
checkBarMode(@ransitionMode int mode, @WindowVisibleState int windowState, BarTransitions transitions)2253     void checkBarMode(@TransitionMode int mode, @WindowVisibleState int windowState,
2254             BarTransitions transitions) {
2255         final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive
2256                 && windowState != WINDOW_STATE_HIDDEN;
2257         transitions.transitionTo(mode, anim);
2258     }
2259 
finishBarAnimations()2260     private void finishBarAnimations() {
2261         if (mNotificationShadeWindowController != null
2262                 && mNotificationShadeWindowViewController.getBarTransitions() != null) {
2263             mNotificationShadeWindowViewController.getBarTransitions().finishAnimations();
2264         }
2265         mNavigationBarController.finishBarAnimations(mDisplayId);
2266     }
2267 
2268     private final Runnable mCheckBarModes = this::checkBarModes;
2269 
setInteracting(int barWindow, boolean interacting)2270     public void setInteracting(int barWindow, boolean interacting) {
2271         mInteractingWindows = interacting
2272                 ? (mInteractingWindows | barWindow)
2273                 : (mInteractingWindows & ~barWindow);
2274         if (mInteractingWindows != 0) {
2275             mAutoHideController.suspendAutoHide();
2276         } else {
2277             mAutoHideController.resumeSuspendedAutoHide();
2278         }
2279         checkBarModes();
2280     }
2281 
dismissVolumeDialog()2282     private void dismissVolumeDialog() {
2283         if (mVolumeComponent != null) {
2284             mVolumeComponent.dismissNow();
2285         }
2286     }
2287 
viewInfo(View v)2288     public static String viewInfo(View v) {
2289         return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2290                 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
2291     }
2292 
2293     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2294     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2295         synchronized (mQueueLock) {
2296             pw.println("Current Status Bar state:");
2297             pw.println("  mExpandedVisible=" + mExpandedVisible);
2298             pw.println("  mDisplayMetrics=" + mDisplayMetrics);
2299             pw.println("  mStackScroller: " + viewInfo(mStackScroller));
2300             pw.println("  mStackScroller: " + viewInfo(mStackScroller)
2301                     + " scroll " + mStackScroller.getScrollX()
2302                     + "," + mStackScroller.getScrollY());
2303         }
2304 
2305         pw.print("  mInteractingWindows="); pw.println(mInteractingWindows);
2306         pw.print("  mStatusBarWindowState=");
2307         pw.println(windowStateToString(mStatusBarWindowState));
2308         pw.print("  mStatusBarMode=");
2309         pw.println(BarTransitions.modeToString(mStatusBarMode));
2310         pw.print("  mDozing="); pw.println(mDozing);
2311         pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
2312 
2313         pw.println("  ShadeWindowView: ");
2314         if (mNotificationShadeWindowViewController != null) {
2315             mNotificationShadeWindowViewController.dump(fd, pw, args);
2316             dumpBarTransitions(pw, "PhoneStatusBarTransitions",
2317                     mNotificationShadeWindowViewController.getBarTransitions());
2318         }
2319 
2320         pw.println("  mMediaManager: ");
2321         if (mMediaManager != null) {
2322             mMediaManager.dump(fd, pw, args);
2323         }
2324 
2325         pw.println("  Panels: ");
2326         if (mNotificationPanelViewController != null) {
2327             pw.println("    mNotificationPanel="
2328                     + mNotificationPanelViewController.getView() + " params="
2329                     + mNotificationPanelViewController.getView().getLayoutParams().debug(""));
2330             pw.print  ("      ");
2331             mNotificationPanelViewController.dump(fd, pw, args);
2332         }
2333         pw.println("  mStackScroller: ");
2334         if (mStackScroller != null) {
2335             DumpUtilsKt.withIndenting(pw, ipw -> {
2336                 // Triple indent until we rewrite the rest of this dump()
2337                 ipw.increaseIndent();
2338                 ipw.increaseIndent();
2339                 mStackScroller.dump(fd, ipw, args);
2340                 ipw.decreaseIndent();
2341                 ipw.decreaseIndent();
2342             });
2343         }
2344         pw.println("  Theme:");
2345         String nightMode = mUiModeManager == null ? "null" : mUiModeManager.getNightMode() + "";
2346         pw.println("    dark theme: " + nightMode +
2347                 " (auto: " + UiModeManager.MODE_NIGHT_AUTO +
2348                 ", yes: " + UiModeManager.MODE_NIGHT_YES +
2349                 ", no: " + UiModeManager.MODE_NIGHT_NO + ")");
2350         final boolean lightWpTheme = mContext.getThemeResId()
2351                 == R.style.Theme_SystemUI_LightWallpaper;
2352         pw.println("    light wallpaper theme: " + lightWpTheme);
2353 
2354         if (mKeyguardIndicationController != null) {
2355             mKeyguardIndicationController.dump(fd, pw, args);
2356         }
2357 
2358         if (mScrimController != null) {
2359             mScrimController.dump(fd, pw, args);
2360         }
2361 
2362         if (mLightRevealScrim != null) {
2363             pw.println(
2364                     "mLightRevealScrim.getRevealEffect(): " + mLightRevealScrim.getRevealEffect());
2365             pw.println(
2366                     "mLightRevealScrim.getRevealAmount(): " + mLightRevealScrim.getRevealAmount());
2367         }
2368 
2369         if (mStatusBarKeyguardViewManager != null) {
2370             mStatusBarKeyguardViewManager.dump(pw);
2371         }
2372 
2373         mNotificationsController.dump(fd, pw, args, DUMPTRUCK);
2374 
2375         if (DEBUG_GESTURES) {
2376             pw.print("  status bar gestures: ");
2377             mGestureRec.dump(fd, pw, args);
2378         }
2379 
2380         if (mHeadsUpManager != null) {
2381             mHeadsUpManager.dump(fd, pw, args);
2382         } else {
2383             pw.println("  mHeadsUpManager: null");
2384         }
2385 
2386         if (mStatusBarTouchableRegionManager != null) {
2387             mStatusBarTouchableRegionManager.dump(fd, pw, args);
2388         } else {
2389             pw.println("  mStatusBarTouchableRegionManager: null");
2390         }
2391 
2392         if (mLightBarController != null) {
2393             mLightBarController.dump(fd, pw, args);
2394         }
2395 
2396         pw.println("SharedPreferences:");
2397         for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
2398             pw.print("  "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
2399         }
2400 
2401         pw.println("Camera gesture intents:");
2402         pw.println("   Insecure camera: " + CameraIntents.getInsecureCameraIntent(mContext));
2403         pw.println("   Secure camera: " + CameraIntents.getSecureCameraIntent(mContext));
2404         pw.println("   Override package: "
2405                 + CameraIntents.getOverrideCameraPackage(mContext));
2406     }
2407 
dumpBarTransitions( PrintWriter pw, String var, @Nullable BarTransitions transitions)2408     public static void dumpBarTransitions(
2409             PrintWriter pw, String var, @Nullable BarTransitions transitions) {
2410         pw.print("  "); pw.print(var); pw.print(".BarTransitions.mMode=");
2411         if (transitions != null) {
2412             pw.println(BarTransitions.modeToString(transitions.getMode()));
2413         } else {
2414             pw.println("Unknown");
2415         }
2416     }
2417 
createAndAddWindows(@ullable RegisterStatusBarResult result)2418     public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
2419         makeStatusBarView(result);
2420         mNotificationShadeWindowController.attach();
2421         mStatusBarWindowController.attach();
2422     }
2423 
2424     // called by makeStatusbar and also by PhoneStatusBarView
updateDisplaySize()2425     void updateDisplaySize() {
2426         mDisplay.getMetrics(mDisplayMetrics);
2427         mDisplay.getSize(mCurrentDisplaySize);
2428         if (DEBUG_GESTURES) {
2429             mGestureRec.tag("display",
2430                     String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2431         }
2432     }
2433 
getDisplayDensity()2434     float getDisplayDensity() {
2435         return mDisplayMetrics.density;
2436     }
2437 
getDisplayWidth()2438     public float getDisplayWidth() {
2439         return mDisplayMetrics.widthPixels;
2440     }
2441 
getDisplayHeight()2442     public float getDisplayHeight() {
2443         return mDisplayMetrics.heightPixels;
2444     }
2445 
getRotation()2446     int getRotation() {
2447         return mDisplay.getRotation();
2448     }
2449 
getDisplayId()2450     int getDisplayId() {
2451         return mDisplayId;
2452     }
2453 
startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags)2454     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
2455             boolean dismissShade, int flags) {
2456         startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade,
2457                 false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
2458                 flags, null /* animationController */);
2459     }
2460 
startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned, boolean dismissShade)2461     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
2462             boolean dismissShade) {
2463         startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, 0);
2464     }
2465 
startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned, final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching, final Callback callback, int flags, @Nullable ActivityLaunchAnimator.Controller animationController)2466     void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
2467             final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
2468             final Callback callback, int flags,
2469             @Nullable ActivityLaunchAnimator.Controller animationController) {
2470         if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;
2471 
2472         final boolean willLaunchResolverActivity =
2473                 mActivityIntentHelper.wouldLaunchResolverActivity(intent,
2474                         mLockscreenUserManager.getCurrentUserId());
2475 
2476         boolean animate =
2477                 animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
2478                         true /* isActivityIntent */);
2479         ActivityLaunchAnimator.Controller animController =
2480                 animationController != null ? wrapAnimationController(animationController,
2481                         dismissShade) : null;
2482 
2483         // If we animate, we will dismiss the shade only once the animation is done. This is taken
2484         // care of by the StatusBarLaunchAnimationController.
2485         boolean dismissShadeDirectly = dismissShade && animController == null;
2486 
2487         Runnable runnable = () -> {
2488             mAssistManagerLazy.get().hideAssist();
2489             intent.setFlags(
2490                     Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2491             intent.addFlags(flags);
2492             int[] result = new int[]{ActivityManager.START_CANCELED};
2493 
2494             mActivityLaunchAnimator.startIntentWithAnimation(animController,
2495                     animate, intent.getPackage(), (adapter) -> {
2496                         ActivityOptions options = new ActivityOptions(
2497                                 getActivityOptions(mDisplayId, adapter));
2498                         options.setDisallowEnterPictureInPictureWhileLaunching(
2499                                 disallowEnterPictureInPictureWhileLaunching);
2500                         if (CameraIntents.isInsecureCameraIntent(intent)) {
2501                             // Normally an activity will set it's requested rotation
2502                             // animation on its window. However when launching an activity
2503                             // causes the orientation to change this is too late. In these cases
2504                             // the default animation is used. This doesn't look good for
2505                             // the camera (as it rotates the camera contents out of sync
2506                             // with physical reality). So, we ask the WindowManager to
2507                             // force the crossfade animation if an orientation change
2508                             // happens to occur during the launch.
2509                             options.setRotationAnimationHint(
2510                                     WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
2511                         }
2512                         if (Settings.Panel.ACTION_VOLUME.equals(intent.getAction())) {
2513                             // Settings Panel is implemented as activity(not a dialog), so
2514                             // underlying app is paused and may enter picture-in-picture mode
2515                             // as a result.
2516                             // So we need to disable picture-in-picture mode here
2517                             // if it is volume panel.
2518                             options.setDisallowEnterPictureInPictureWhileLaunching(true);
2519                         }
2520 
2521                         try {
2522                             result[0] = ActivityTaskManager.getService().startActivityAsUser(
2523                                     null, mContext.getBasePackageName(),
2524                                     mContext.getAttributionTag(),
2525                                     intent,
2526                                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2527                                     null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
2528                                     options.toBundle(), UserHandle.CURRENT.getIdentifier());
2529                         } catch (RemoteException e) {
2530                             Log.w(TAG, "Unable to start activity", e);
2531                         }
2532                         return result[0];
2533                     });
2534 
2535             if (callback != null) {
2536                 callback.onActivityStarted(result[0]);
2537             }
2538         };
2539         Runnable cancelRunnable = () -> {
2540             if (callback != null) {
2541                 callback.onActivityStarted(ActivityManager.START_CANCELED);
2542             }
2543         };
2544         executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
2545                 willLaunchResolverActivity, true /* deferred */, animate);
2546     }
2547 
2548     @Nullable
wrapAnimationController( ActivityLaunchAnimator.Controller animationController, boolean dismissShade)2549     private ActivityLaunchAnimator.Controller wrapAnimationController(
2550             ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
2551         View rootView = animationController.getLaunchContainer().getRootView();
2552 
2553         Optional<ActivityLaunchAnimator.Controller> controllerFromStatusBar =
2554                 mStatusBarWindowController.wrapAnimationControllerIfInStatusBar(
2555                         rootView, animationController);
2556         if (controllerFromStatusBar.isPresent()) {
2557             return controllerFromStatusBar.get();
2558         }
2559 
2560         if (dismissShade && rootView == mNotificationShadeWindowView) {
2561             // We are animating a view in the shade. We have to make sure that we collapse it when
2562             // the animation ends or is cancelled.
2563             return new StatusBarLaunchAnimatorController(animationController, this,
2564                     true /* isLaunchForActivity */);
2565         }
2566 
2567         return animationController;
2568     }
2569 
readyForKeyguardDone()2570     public void readyForKeyguardDone() {
2571         mStatusBarKeyguardViewManager.readyForKeyguardDone();
2572     }
2573 
executeRunnableDismissingKeyguard(final Runnable runnable, final Runnable cancelAction, final boolean dismissShade, final boolean afterKeyguardGone, final boolean deferred)2574     public void executeRunnableDismissingKeyguard(final Runnable runnable,
2575             final Runnable cancelAction,
2576             final boolean dismissShade,
2577             final boolean afterKeyguardGone,
2578             final boolean deferred) {
2579         executeRunnableDismissingKeyguard(runnable, cancelAction, dismissShade, afterKeyguardGone,
2580                 deferred, false /* willAnimateOnKeyguard */);
2581     }
2582 
executeRunnableDismissingKeyguard(final Runnable runnable, final Runnable cancelAction, final boolean dismissShade, final boolean afterKeyguardGone, final boolean deferred, final boolean willAnimateOnKeyguard)2583     public void executeRunnableDismissingKeyguard(final Runnable runnable,
2584             final Runnable cancelAction,
2585             final boolean dismissShade,
2586             final boolean afterKeyguardGone,
2587             final boolean deferred,
2588             final boolean willAnimateOnKeyguard) {
2589         OnDismissAction onDismissAction = new OnDismissAction() {
2590             @Override
2591             public boolean onDismiss() {
2592                 if (runnable != null) {
2593                     if (mStatusBarKeyguardViewManager.isShowing()
2594                             && mStatusBarKeyguardViewManager.isOccluded()) {
2595                         mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
2596                     } else {
2597                         mMainExecutor.execute(runnable);
2598                     }
2599                 }
2600                 if (dismissShade) {
2601                     if (mExpandedVisible && !mBouncerShowing) {
2602                         mShadeController.animateCollapsePanels(
2603                                 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
2604                                 true /* force */, true /* delayed*/);
2605                     } else {
2606 
2607                         // Do it after DismissAction has been processed to conserve the needed
2608                         // ordering.
2609                         mMainExecutor.execute(mShadeController::runPostCollapseRunnables);
2610                     }
2611                 } else if (StatusBar.this.isInLaunchTransition()
2612                         && mNotificationPanelViewController.isLaunchTransitionFinished()) {
2613 
2614                     // We are not dismissing the shade, but the launch transition is already
2615                     // finished,
2616                     // so nobody will call readyForKeyguardDone anymore. Post it such that
2617                     // keyguardDonePending gets called first.
2618                     mMainExecutor.execute(mStatusBarKeyguardViewManager::readyForKeyguardDone);
2619                 }
2620                 return deferred;
2621             }
2622 
2623             @Override
2624             public boolean willRunAnimationOnKeyguard() {
2625                 return willAnimateOnKeyguard;
2626             }
2627         };
2628         dismissKeyguardThenExecute(onDismissAction, cancelAction, afterKeyguardGone);
2629     }
2630 
2631     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2632         @Override
2633         public void onReceive(Context context, Intent intent) {
2634             Trace.beginSection("StatusBar#onReceive");
2635             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
2636             String action = intent.getAction();
2637             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
2638                 KeyboardShortcuts.dismiss();
2639                 mRemoteInputManager.closeRemoteInputs();
2640                 if (mBubblesOptional.isPresent() && mBubblesOptional.get().isStackExpanded()) {
2641                     mBubblesOptional.get().collapseStack();
2642                 }
2643                 if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
2644                     int flags = CommandQueue.FLAG_EXCLUDE_NONE;
2645                     String reason = intent.getStringExtra("reason");
2646                     if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2647                         flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
2648                     }
2649                     mShadeController.animateCollapsePanels(flags);
2650                 }
2651             }
2652             else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
2653                 if (mNotificationShadeWindowController != null) {
2654                     mNotificationShadeWindowController.setNotTouchable(false);
2655                 }
2656                 if (mBubblesOptional.isPresent() && mBubblesOptional.get().isStackExpanded()) {
2657                     // Post to main thread, since updating the UI.
2658                     mMainExecutor.execute(() -> mBubblesOptional.get().collapseStack());
2659                 }
2660                 finishBarAnimations();
2661                 resetUserExpandedStates();
2662             }
2663             else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
2664                 mQSPanelController.showDeviceMonitoringDialog();
2665             }
2666             Trace.endSection();
2667         }
2668     };
2669 
2670     private final BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
2671         @Override
2672         public void onReceive(Context context, Intent intent) {
2673             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
2674             String action = intent.getAction();
2675             if (ACTION_FAKE_ARTWORK.equals(action)) {
2676                 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2677                     mPresenter.updateMediaMetaData(true, true);
2678                 }
2679             }
2680         }
2681     };
2682 
resetUserExpandedStates()2683     public void resetUserExpandedStates() {
2684         mNotificationsController.resetUserExpandedStates();
2685     }
2686 
executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen, boolean afterKeyguardGone)2687     private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
2688             boolean afterKeyguardGone) {
2689         if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
2690             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
2691         }
2692         dismissKeyguardThenExecute(action, null /* cancelAction */,
2693                 afterKeyguardGone /* afterKeyguardGone */);
2694     }
2695 
dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone)2696     protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
2697         dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
2698     }
2699 
2700     @Override
dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction, boolean afterKeyguardGone)2701     public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
2702             boolean afterKeyguardGone) {
2703         if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
2704                 && mKeyguardStateController.canDismissLockScreen()
2705                 && !mStatusBarStateController.leaveOpenOnKeyguardHide()
2706                 && mDozeServiceHost.isPulsing()) {
2707             // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a pulse.
2708             // TODO: Factor this transition out of BiometricUnlockController.
2709             mBiometricUnlockController.startWakeAndUnlock(
2710                     BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
2711         }
2712         if (mStatusBarKeyguardViewManager.isShowing()) {
2713             mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
2714                     afterKeyguardGone);
2715         } else {
2716             action.onDismiss();
2717         }
2718     }
2719     /**
2720      * Notify the shade controller that the current user changed
2721      *
2722      * @param newUserId userId of the new user
2723      */
setLockscreenUser(int newUserId)2724     public void setLockscreenUser(int newUserId) {
2725         if (mLockscreenWallpaper != null) {
2726             mLockscreenWallpaper.setCurrentUser(newUserId);
2727         }
2728         mScrimController.setCurrentUser(newUserId);
2729         if (mWallpaperSupported) {
2730             mWallpaperChangedReceiver.onReceive(mContext, null);
2731         }
2732     }
2733 
2734     /**
2735      * Reload some of our resources when the configuration changes.
2736      *
2737      * We don't reload everything when the configuration changes -- we probably
2738      * should, but getting that smooth is tough.  Someday we'll fix that.  In the
2739      * meantime, just update the things that we know change.
2740      */
updateResources()2741     void updateResources() {
2742         // Update the quick setting tiles
2743         if (mQSPanelController != null) {
2744             mQSPanelController.updateResources();
2745         }
2746 
2747         if (mStatusBarWindowController != null) {
2748             mStatusBarWindowController.refreshStatusBarHeight();
2749         }
2750 
2751         if (mStatusBarView != null) {
2752             mStatusBarView.updateResources();
2753         }
2754         if (mNotificationPanelViewController != null) {
2755             mNotificationPanelViewController.updateResources();
2756         }
2757         if (mBrightnessMirrorController != null) {
2758             mBrightnessMirrorController.updateResources();
2759         }
2760         if (mStatusBarKeyguardViewManager != null) {
2761             mStatusBarKeyguardViewManager.updateResources();
2762         }
2763 
2764         mPowerButtonReveal = new PowerButtonReveal(mContext.getResources().getDimensionPixelSize(
2765                 com.android.systemui.R.dimen.physical_power_button_center_screen_location_y));
2766     }
2767 
2768     // Visibility reporting
handleVisibleToUserChanged(boolean visibleToUser)2769     protected void handleVisibleToUserChanged(boolean visibleToUser) {
2770         if (visibleToUser) {
2771             handleVisibleToUserChangedImpl(visibleToUser);
2772             mNotificationLogger.startNotificationLogging();
2773         } else {
2774             mNotificationLogger.stopNotificationLogging();
2775             handleVisibleToUserChangedImpl(visibleToUser);
2776         }
2777     }
2778 
2779     // Visibility reporting
handleVisibleToUserChangedImpl(boolean visibleToUser)2780     void handleVisibleToUserChangedImpl(boolean visibleToUser) {
2781         if (visibleToUser) {
2782             /* The LEDs are turned off when the notification panel is shown, even just a little bit.
2783              * See also StatusBar.setPanelExpanded for another place where we attempt to do this. */
2784             boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
2785             boolean clearNotificationEffects =
2786                     !mPresenter.isPresenterFullyCollapsed() &&
2787                             (mState == StatusBarState.SHADE
2788                                     || mState == StatusBarState.SHADE_LOCKED);
2789             int notificationLoad = mNotificationsController.getActiveNotificationsCount();
2790             if (pinnedHeadsUp && mPresenter.isPresenterFullyCollapsed()) {
2791                 notificationLoad = 1;
2792             }
2793             final int finalNotificationLoad = notificationLoad;
2794             mUiBgExecutor.execute(() -> {
2795                 try {
2796                     mBarService.onPanelRevealed(clearNotificationEffects,
2797                             finalNotificationLoad);
2798                 } catch (RemoteException ex) {
2799                     // Won't fail unless the world has ended.
2800                 }
2801             });
2802         } else {
2803             mUiBgExecutor.execute(() -> {
2804                 try {
2805                     mBarService.onPanelHidden();
2806                 } catch (RemoteException ex) {
2807                     // Won't fail unless the world has ended.
2808                 }
2809             });
2810         }
2811 
2812     }
2813 
logStateToEventlog()2814     private void logStateToEventlog() {
2815         boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
2816         boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
2817         boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
2818         boolean isSecure = mKeyguardStateController.isMethodSecure();
2819         boolean unlocked = mKeyguardStateController.canDismissLockScreen();
2820         int stateFingerprint = getLoggingFingerprint(mState,
2821                 isShowing,
2822                 isOccluded,
2823                 isBouncerShowing,
2824                 isSecure,
2825                 unlocked);
2826         if (stateFingerprint != mLastLoggedStateFingerprint) {
2827             if (mStatusBarStateLog == null) {
2828                 mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
2829             }
2830             mMetricsLogger.write(mStatusBarStateLog
2831                     .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
2832                     .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
2833                     .setSubtype(isSecure ? 1 : 0));
2834             EventLogTags.writeSysuiStatusBarState(mState,
2835                     isShowing ? 1 : 0,
2836                     isOccluded ? 1 : 0,
2837                     isBouncerShowing ? 1 : 0,
2838                     isSecure ? 1 : 0,
2839                     unlocked ? 1 : 0);
2840             mLastLoggedStateFingerprint = stateFingerprint;
2841 
2842             StringBuilder uiEventValueBuilder = new StringBuilder();
2843             uiEventValueBuilder.append(isBouncerShowing ? "BOUNCER" : "LOCKSCREEN");
2844             uiEventValueBuilder.append(isShowing ? "_OPEN" : "_CLOSE");
2845             uiEventValueBuilder.append(isSecure ? "_SECURE" : "_INSECURE");
2846             sUiEventLogger.log(StatusBarUiEvent.valueOf(uiEventValueBuilder.toString()));
2847         }
2848     }
2849 
2850     /**
2851      * Returns a fingerprint of fields logged to eventlog
2852      */
getLoggingFingerprint(int statusBarState, boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing, boolean secure, boolean currentlyInsecure)2853     private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
2854             boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
2855             boolean currentlyInsecure) {
2856         // Reserve 8 bits for statusBarState. We'll never go higher than
2857         // that, right? Riiiight.
2858         return (statusBarState & 0xFF)
2859                 | ((keyguardShowing   ? 1 : 0) <<  8)
2860                 | ((keyguardOccluded  ? 1 : 0) <<  9)
2861                 | ((bouncerShowing    ? 1 : 0) << 10)
2862                 | ((secure            ? 1 : 0) << 11)
2863                 | ((currentlyInsecure ? 1 : 0) << 12);
2864     }
2865 
2866     @Override
postQSRunnableDismissingKeyguard(final Runnable runnable)2867     public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
2868         mMainExecutor.execute(() -> {
2869             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
2870             executeRunnableDismissingKeyguard(
2871                     () -> mMainExecutor.execute(runnable), null, false, false, false);
2872         });
2873     }
2874 
2875     @Override
postStartActivityDismissingKeyguard(PendingIntent intent)2876     public void postStartActivityDismissingKeyguard(PendingIntent intent) {
2877         postStartActivityDismissingKeyguard(intent, null /* animationController */);
2878     }
2879 
2880     @Override
postStartActivityDismissingKeyguard(final PendingIntent intent, @Nullable ActivityLaunchAnimator.Controller animationController)2881     public void postStartActivityDismissingKeyguard(final PendingIntent intent,
2882             @Nullable ActivityLaunchAnimator.Controller animationController) {
2883         mMainExecutor.execute(() -> startPendingIntentDismissingKeyguard(intent,
2884                 null /* intentSentUiThreadCallback */, animationController));
2885     }
2886 
2887     @Override
postStartActivityDismissingKeyguard(final Intent intent, int delay)2888     public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
2889         postStartActivityDismissingKeyguard(intent, delay, null /* animationController */);
2890     }
2891 
2892     @Override
postStartActivityDismissingKeyguard(Intent intent, int delay, @Nullable ActivityLaunchAnimator.Controller animationController)2893     public void postStartActivityDismissingKeyguard(Intent intent, int delay,
2894             @Nullable ActivityLaunchAnimator.Controller animationController) {
2895         mMainExecutor.executeDelayed(
2896                 () ->
2897                         startActivityDismissingKeyguard(intent, true /* onlyProvisioned */,
2898                                 true /* dismissShade */,
2899                                 false /* disallowEnterPictureInPictureWhileLaunching */,
2900                                 null /* callback */,
2901                                 0 /* flags */,
2902                                 animationController),
2903                 delay);
2904     }
2905 
showKeyguard()2906     public void showKeyguard() {
2907         mStatusBarStateController.setKeyguardRequested(true);
2908         mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
2909         updateIsKeyguard();
2910         mAssistManagerLazy.get().onLockscreenShown();
2911     }
2912 
hideKeyguard()2913     public boolean hideKeyguard() {
2914         mStatusBarStateController.setKeyguardRequested(false);
2915         return updateIsKeyguard();
2916     }
2917 
2918     /**
2919      * stop(tag)
2920      * @return True if StatusBar state is FULLSCREEN_USER_SWITCHER.
2921      */
isFullScreenUserSwitcherState()2922     public boolean isFullScreenUserSwitcherState() {
2923         return mState == StatusBarState.FULLSCREEN_USER_SWITCHER;
2924     }
2925 
updateIsKeyguard()2926     boolean updateIsKeyguard() {
2927         return updateIsKeyguard(false /* force */);
2928     }
2929 
updateIsKeyguard(boolean force)2930     boolean updateIsKeyguard(boolean force) {
2931         boolean wakeAndUnlocking = mBiometricUnlockController.getMode()
2932                 == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
2933 
2934         // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
2935         // there's no surface we can show to the user. Note that the device goes fully interactive
2936         // late in the transition, so we also allow the device to start dozing once the screen has
2937         // turned off fully.
2938         boolean keyguardForDozing = mDozeServiceHost.getDozingRequested()
2939                 && (!mDeviceInteractive || isGoingToSleep() && (isScreenFullyOff() || mIsKeyguard));
2940         boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
2941                 || keyguardForDozing) && !wakeAndUnlocking;
2942         if (keyguardForDozing) {
2943             updatePanelExpansionForKeyguard();
2944         }
2945         if (shouldBeKeyguard) {
2946             if (mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()
2947                     || (isGoingToSleep()
2948                     && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF)) {
2949                 // Delay showing the keyguard until screen turned off.
2950             } else {
2951                 showKeyguardImpl();
2952             }
2953         } else {
2954             return hideKeyguardImpl(force);
2955         }
2956         return false;
2957     }
2958 
showKeyguardImpl()2959     public void showKeyguardImpl() {
2960         mIsKeyguard = true;
2961         if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
2962             mNotificationPanelViewController.cancelAnimation();
2963             onLaunchTransitionFadingEnded();
2964         }
2965         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
2966         if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
2967             mStatusBarStateController.setState(StatusBarState.FULLSCREEN_USER_SWITCHER);
2968         } else if (!mLockscreenShadeTransitionController.isWakingToShadeLocked()) {
2969             mStatusBarStateController.setState(StatusBarState.KEYGUARD);
2970         }
2971         updatePanelExpansionForKeyguard();
2972     }
2973 
updatePanelExpansionForKeyguard()2974     private void updatePanelExpansionForKeyguard() {
2975         if (mState == StatusBarState.KEYGUARD && mBiometricUnlockController.getMode()
2976                 != BiometricUnlockController.MODE_WAKE_AND_UNLOCK && !mBouncerShowing) {
2977             mShadeController.instantExpandNotificationsPanel();
2978         } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
2979             instantCollapseNotificationPanel();
2980         }
2981     }
2982 
onLaunchTransitionFadingEnded()2983     private void onLaunchTransitionFadingEnded() {
2984         mNotificationPanelViewController.setAlpha(1.0f);
2985         mNotificationPanelViewController.onAffordanceLaunchEnded();
2986         releaseGestureWakeLock();
2987         runLaunchTransitionEndRunnable();
2988         mKeyguardStateController.setLaunchTransitionFadingAway(false);
2989         mPresenter.updateMediaMetaData(true /* metaDataChanged */, true);
2990     }
2991 
isInLaunchTransition()2992     public boolean isInLaunchTransition() {
2993         return mNotificationPanelViewController.isLaunchTransitionRunning()
2994                 || mNotificationPanelViewController.isLaunchTransitionFinished();
2995     }
2996 
2997     /**
2998      * Fades the content of the keyguard away after the launch transition is done.
2999      *
3000      * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3001      *                     starts
3002      * @param endRunnable the runnable to be run when the transition is done
3003      */
fadeKeyguardAfterLaunchTransition(final Runnable beforeFading, Runnable endRunnable)3004     public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
3005             Runnable endRunnable) {
3006         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
3007         mLaunchTransitionEndRunnable = endRunnable;
3008         Runnable hideRunnable = () -> {
3009             mKeyguardStateController.setLaunchTransitionFadingAway(true);
3010             if (beforeFading != null) {
3011                 beforeFading.run();
3012             }
3013             updateScrimController();
3014             mPresenter.updateMediaMetaData(false, true);
3015             mNotificationPanelViewController.setAlpha(1);
3016             mNotificationPanelViewController.fadeOut(
3017                     FADE_KEYGUARD_START_DELAY, FADE_KEYGUARD_DURATION,
3018                     this::onLaunchTransitionFadingEnded);
3019             mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(),
3020                     LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
3021         };
3022         if (mNotificationPanelViewController.isLaunchTransitionRunning()) {
3023             mNotificationPanelViewController.setLaunchTransitionEndRunnable(hideRunnable);
3024         } else {
3025             hideRunnable.run();
3026         }
3027     }
3028 
3029     /**
3030      * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
3031      * fading.
3032      */
fadeKeyguardWhilePulsing()3033     public void fadeKeyguardWhilePulsing() {
3034         mNotificationPanelViewController.fadeOut(0, FADE_KEYGUARD_DURATION_PULSING,
3035                 ()-> {
3036                 hideKeyguard();
3037                 mStatusBarKeyguardViewManager.onKeyguardFadedAway();
3038             }).start();
3039     }
3040 
3041     /**
3042      * Plays the animation when an activity that was occluding Keyguard goes away.
3043      */
animateKeyguardUnoccluding()3044     public void animateKeyguardUnoccluding() {
3045         mNotificationPanelViewController.setExpandedFraction(0f);
3046         mCommandQueueCallbacks.animateExpandNotificationsPanel();
3047         mScrimController.setUnocclusionAnimationRunning(true);
3048     }
3049 
3050     /**
3051      * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3052      * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3053      * because the launched app crashed or something else went wrong.
3054      */
startLaunchTransitionTimeout()3055     public void startLaunchTransitionTimeout() {
3056         mMessageRouter.sendMessageDelayed(
3057                 MSG_LAUNCH_TRANSITION_TIMEOUT, LAUNCH_TRANSITION_TIMEOUT_MS);
3058     }
3059 
onLaunchTransitionTimeout()3060     private void onLaunchTransitionTimeout() {
3061         Log.w(TAG, "Launch transition: Timeout!");
3062         mNotificationPanelViewController.onAffordanceLaunchEnded();
3063         releaseGestureWakeLock();
3064         mNotificationPanelViewController.resetViews(false /* animate */);
3065     }
3066 
runLaunchTransitionEndRunnable()3067     private void runLaunchTransitionEndRunnable() {
3068         if (mLaunchTransitionEndRunnable != null) {
3069             Runnable r = mLaunchTransitionEndRunnable;
3070 
3071             // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3072             // which would lead to infinite recursion. Protect against it.
3073             mLaunchTransitionEndRunnable = null;
3074             r.run();
3075         }
3076     }
3077 
3078     /**
3079      * @return true if we would like to stay in the shade, false if it should go away entirely
3080      */
hideKeyguardImpl(boolean force)3081     public boolean hideKeyguardImpl(boolean force) {
3082         mIsKeyguard = false;
3083         Trace.beginSection("StatusBar#hideKeyguard");
3084         boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
3085         int previousState = mStatusBarStateController.getState();
3086         if (!(mStatusBarStateController.setState(StatusBarState.SHADE, force))) {
3087             //TODO: StatusBarStateController should probably know about hiding the keyguard and
3088             // notify listeners.
3089 
3090             // If the state didn't change, we may still need to update public mode
3091             mLockscreenUserManager.updatePublicMode();
3092         }
3093         if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
3094             if (!mStatusBarStateController.isKeyguardRequested()) {
3095                 mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
3096             }
3097             long delay = mKeyguardStateController.calculateGoingToFullShadeDelay();
3098             mLockscreenShadeTransitionController.onHideKeyguard(delay, previousState);
3099 
3100             // Disable layout transitions in navbar for this transition because the load is just
3101             // too heavy for the CPU and GPU on any device.
3102             mNavigationBarController.disableAnimationsDuringHide(mDisplayId, delay);
3103         } else if (!mNotificationPanelViewController.isCollapsing()) {
3104             instantCollapseNotificationPanel();
3105         }
3106 
3107         // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3108         // visibilities so next time we open the panel we know the correct height already.
3109         if (mQSPanelController != null) {
3110             mQSPanelController.refreshAllTiles();
3111         }
3112         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
3113         releaseGestureWakeLock();
3114         mNotificationPanelViewController.onAffordanceLaunchEnded();
3115         mNotificationPanelViewController.cancelAnimation();
3116         mNotificationPanelViewController.setAlpha(1f);
3117         mNotificationPanelViewController.resetViewGroupFade();
3118         updateDozingState();
3119         updateScrimController();
3120         Trace.endSection();
3121         return staying;
3122     }
3123 
releaseGestureWakeLock()3124     private void releaseGestureWakeLock() {
3125         if (mGestureWakeLock.isHeld()) {
3126             mGestureWakeLock.release();
3127         }
3128     }
3129 
3130     /**
3131      * Notifies the status bar that Keyguard is going away very soon.
3132      */
keyguardGoingAway()3133     public void keyguardGoingAway() {
3134         // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3135         // bar.
3136         mKeyguardStateController.notifyKeyguardGoingAway(true);
3137         mCommandQueue.appTransitionPending(mDisplayId, true /* forced */);
3138     }
3139 
3140     /**
3141      * Notifies the status bar the Keyguard is fading away with the specified timings.
3142      *  @param startTime the start time of the animations in uptime millis
3143      * @param delay the precalculated animation delay in milliseconds
3144      * @param fadeoutDuration the duration of the exit animation, in milliseconds
3145      * @param isBypassFading is this a fading away animation while bypassing
3146      */
setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration, boolean isBypassFading)3147     public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration,
3148             boolean isBypassFading) {
3149         mCommandQueue.appTransitionStarting(mDisplayId, startTime + fadeoutDuration
3150                         - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
3151                 LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
3152         mCommandQueue.recomputeDisableFlags(mDisplayId, fadeoutDuration > 0 /* animate */);
3153         mCommandQueue.appTransitionStarting(mDisplayId,
3154                     startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
3155                     LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
3156         mKeyguardStateController.notifyKeyguardFadingAway(delay, fadeoutDuration, isBypassFading);
3157     }
3158 
3159     /**
3160      * Notifies that the Keyguard fading away animation is done.
3161      */
finishKeyguardFadingAway()3162     public void finishKeyguardFadingAway() {
3163         mKeyguardStateController.notifyKeyguardDoneFading();
3164         mScrimController.setExpansionAffectsAlpha(true);
3165     }
3166 
3167     /**
3168      * Switches theme from light to dark and vice-versa.
3169      */
updateTheme()3170     protected void updateTheme() {
3171         // Lock wallpaper defines the color of the majority of the views, hence we'll use it
3172         // to set our default theme.
3173         final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
3174         final int themeResId = lockDarkText ? R.style.Theme_SystemUI_LightWallpaper
3175                 : R.style.Theme_SystemUI;
3176         if (mContext.getThemeResId() == themeResId) {
3177             return;
3178         }
3179         mContext.setTheme(themeResId);
3180         mConfigurationController.notifyThemeChanged();
3181     }
3182 
updateDozingState()3183     private void updateDozingState() {
3184         Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
3185         Trace.beginSection("StatusBar#updateDozingState");
3186 
3187         boolean visibleNotOccluded = mStatusBarKeyguardViewManager.isShowing()
3188                 && !mStatusBarKeyguardViewManager.isOccluded();
3189         // If we're dozing and we'll be animating the screen off, the keyguard isn't currently
3190         // visible but will be shortly for the animation, so we should proceed as if it's visible.
3191         boolean visibleNotOccludedOrWillBe =
3192                 visibleNotOccluded || (mDozing && mDozeParameters.shouldControlUnlockedScreenOff());
3193 
3194         boolean wakeAndUnlock = mBiometricUnlockController.getMode()
3195                 == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
3196         boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup() && !wakeAndUnlock)
3197                 || (mDozing && mDozeParameters.shouldControlScreenOff()
3198                 && visibleNotOccludedOrWillBe);
3199 
3200         mNotificationPanelViewController.setDozing(mDozing, animate, mWakeUpTouchLocation);
3201         updateQsExpansionEnabled();
3202         Trace.endSection();
3203     }
3204 
userActivity()3205     public void userActivity() {
3206         if (mState == StatusBarState.KEYGUARD) {
3207             mKeyguardViewMediatorCallback.userActivity();
3208         }
3209     }
3210 
interceptMediaKey(KeyEvent event)3211     public boolean interceptMediaKey(KeyEvent event) {
3212         return mState == StatusBarState.KEYGUARD
3213                 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
3214     }
3215 
3216     /**
3217      * While IME is active and a BACK event is detected, check with
3218      * {@link StatusBarKeyguardViewManager#dispatchBackKeyEventPreIme()} to see if the event
3219      * should be handled before routing to IME, in order to prevent the user having to hit back
3220      * twice to exit bouncer.
3221      */
dispatchKeyEventPreIme(KeyEvent event)3222     public boolean dispatchKeyEventPreIme(KeyEvent event) {
3223         switch (event.getKeyCode()) {
3224             case KeyEvent.KEYCODE_BACK:
3225                 if (mState == StatusBarState.KEYGUARD
3226                         && mStatusBarKeyguardViewManager.dispatchBackKeyEventPreIme()) {
3227                     return onBackPressed();
3228                 }
3229         }
3230         return false;
3231     }
3232 
shouldUnlockOnMenuPressed()3233     protected boolean shouldUnlockOnMenuPressed() {
3234         return mDeviceInteractive && mState != StatusBarState.SHADE
3235             && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed();
3236     }
3237 
onMenuPressed()3238     public boolean onMenuPressed() {
3239         if (shouldUnlockOnMenuPressed()) {
3240             mShadeController.animateCollapsePanels(
3241                     CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
3242             return true;
3243         }
3244         return false;
3245     }
3246 
endAffordanceLaunch()3247     public void endAffordanceLaunch() {
3248         releaseGestureWakeLock();
3249         mNotificationPanelViewController.onAffordanceLaunchEnded();
3250     }
3251 
onBackPressed()3252     public boolean onBackPressed() {
3253         boolean isScrimmedBouncer = mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
3254         if (mStatusBarKeyguardViewManager.onBackPressed(isScrimmedBouncer /* hideImmediately */)) {
3255             if (isScrimmedBouncer) {
3256                 mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
3257             } else {
3258                 mNotificationPanelViewController.expandWithoutQs();
3259             }
3260             return true;
3261         }
3262         if (mNotificationPanelViewController.isQsCustomizing()) {
3263             mNotificationPanelViewController.closeQsCustomizer();
3264             return true;
3265         }
3266         if (mNotificationPanelViewController.isQsExpanded()) {
3267             if (mNotificationPanelViewController.isQsDetailShowing()) {
3268                 mNotificationPanelViewController.closeQsDetail();
3269             } else {
3270                 mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
3271             }
3272             return true;
3273         }
3274         if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
3275             return true;
3276         }
3277         if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
3278             if (mNotificationPanelViewController.canPanelBeCollapsed()) {
3279                 mShadeController.animateCollapsePanels();
3280             }
3281             return true;
3282         }
3283         return false;
3284     }
3285 
onSpacePressed()3286     public boolean onSpacePressed() {
3287         if (mDeviceInteractive && mState != StatusBarState.SHADE) {
3288             mShadeController.animateCollapsePanels(
3289                     CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
3290             return true;
3291         }
3292         return false;
3293     }
3294 
showBouncerOrLockScreenIfKeyguard()3295     private void showBouncerOrLockScreenIfKeyguard() {
3296         if (!mKeyguardViewMediator.isHiding()) {
3297             if (mState == StatusBarState.SHADE_LOCKED
3298                     && mKeyguardUpdateMonitor.isUdfpsEnrolled()) {
3299                 // shade is showing while locked on the keyguard, so go back to showing the
3300                 // lock screen where users can use the UDFPS affordance to enter the device
3301                 mStatusBarKeyguardViewManager.reset(true);
3302             } else if ((mState == StatusBarState.KEYGUARD
3303                     && !mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing())
3304                     || mState == StatusBarState.SHADE_LOCKED) {
3305                 mStatusBarKeyguardViewManager.showGenericBouncer(true /* scrimmed */);
3306             }
3307         }
3308     }
3309 
3310     /**
3311      * Show the bouncer if we're currently on the keyguard or shade locked and aren't hiding.
3312      * @param performAction the action to perform when the bouncer is dismissed.
3313      * @param cancelAction the action to perform when unlock is aborted.
3314      */
showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction, Runnable cancelAction)3315     public void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
3316             Runnable cancelAction) {
3317         if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
3318                 && !mKeyguardViewMediator.isHiding()) {
3319             mStatusBarKeyguardViewManager.dismissWithAction(performAction, cancelAction,
3320                     false /* afterKeyguardGone */);
3321         } else if (cancelAction != null) {
3322             cancelAction.run();
3323         }
3324     }
3325 
instantCollapseNotificationPanel()3326     void instantCollapseNotificationPanel() {
3327         mNotificationPanelViewController.instantCollapse();
3328         mShadeController.runPostCollapseRunnables();
3329     }
3330 
3331     /**
3332      * Collapse the panel directly if we are on the main thread, post the collapsing on the main
3333      * thread if we are not.
3334      */
collapsePanelOnMainThread()3335     void collapsePanelOnMainThread() {
3336         if (Looper.getMainLooper().isCurrentThread()) {
3337             mShadeController.collapsePanel();
3338         } else {
3339             mContext.getMainExecutor().execute(mShadeController::collapsePanel);
3340         }
3341     }
3342 
3343     /** Collapse the panel. The collapsing will be animated for the given {@code duration}. */
collapsePanelWithDuration(int duration)3344     void collapsePanelWithDuration(int duration) {
3345         mNotificationPanelViewController.collapseWithDuration(duration);
3346     }
3347 
3348     /**
3349      * Updates the light reveal effect to reflect the reason we're waking or sleeping (for example,
3350      * from the power button).
3351      * @param wakingUp Whether we're updating because we're waking up (true) or going to sleep
3352      *                 (false).
3353      */
updateRevealEffect(boolean wakingUp)3354     private void updateRevealEffect(boolean wakingUp) {
3355         if (mLightRevealScrim == null) {
3356             return;
3357         }
3358 
3359         final boolean wakingUpFromPowerButton = wakingUp
3360                 && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)
3361                 && mWakefulnessLifecycle.getLastWakeReason()
3362                 == PowerManager.WAKE_REASON_POWER_BUTTON;
3363         final boolean sleepingFromPowerButton = !wakingUp
3364                 && mWakefulnessLifecycle.getLastSleepReason()
3365                 == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON;
3366 
3367         if (wakingUpFromPowerButton || sleepingFromPowerButton) {
3368             mLightRevealScrim.setRevealEffect(mPowerButtonReveal);
3369             mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
3370         } else if (!wakingUp || !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
3371             // If we're going to sleep, but it's not from the power button, use the default reveal.
3372             // If we're waking up, only use the default reveal if the biometric controller didn't
3373             // already set it to the circular reveal because we're waking up from a fingerprint/face
3374             // auth.
3375             mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
3376             mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
3377         }
3378     }
3379 
getLightRevealScrim()3380     public LightRevealScrim getLightRevealScrim() {
3381         return mLightRevealScrim;
3382     }
3383 
updateKeyguardState()3384     private void updateKeyguardState() {
3385         mKeyguardStateController.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
3386                 mStatusBarKeyguardViewManager.isOccluded());
3387     }
3388 
onTrackingStarted()3389     public void onTrackingStarted() {
3390         mShadeController.runPostCollapseRunnables();
3391     }
3392 
onClosingFinished()3393     public void onClosingFinished() {
3394         mShadeController.runPostCollapseRunnables();
3395         if (!mPresenter.isPresenterFullyCollapsed()) {
3396             // if we set it not to be focusable when collapsing, we have to undo it when we aborted
3397             // the closing
3398             mNotificationShadeWindowController.setNotificationShadeFocusable(true);
3399         }
3400     }
3401 
onUnlockHintStarted()3402     public void onUnlockHintStarted() {
3403         mFalsingCollector.onUnlockHintStarted();
3404         mKeyguardIndicationController.showActionToUnlock();
3405     }
3406 
onHintFinished()3407     public void onHintFinished() {
3408         // Delay the reset a bit so the user can read the text.
3409         mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
3410     }
3411 
onCameraHintStarted()3412     public void onCameraHintStarted() {
3413         mFalsingCollector.onCameraHintStarted();
3414         mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
3415     }
3416 
onVoiceAssistHintStarted()3417     public void onVoiceAssistHintStarted() {
3418         mFalsingCollector.onLeftAffordanceHintStarted();
3419         mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
3420     }
3421 
onPhoneHintStarted()3422     public void onPhoneHintStarted() {
3423         mFalsingCollector.onLeftAffordanceHintStarted();
3424         mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
3425     }
3426 
onTrackingStopped(boolean expand)3427     public void onTrackingStopped(boolean expand) {
3428         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
3429             if (!expand && !mKeyguardStateController.canDismissLockScreen()) {
3430                 mStatusBarKeyguardViewManager.showBouncer(false /* scrimmed */);
3431             }
3432         }
3433     }
3434 
3435     // TODO: Figure out way to remove these.
getNavigationBarView()3436     public NavigationBarView getNavigationBarView() {
3437         return mNavigationBarController.getNavigationBarView(mDisplayId);
3438     }
3439 
showPinningEnterExitToast(boolean entering)3440     public void showPinningEnterExitToast(boolean entering) {
3441         mNavigationBarController.showPinningEnterExitToast(mDisplayId, entering);
3442     }
3443 
showPinningEscapeToast()3444     public void showPinningEscapeToast() {
3445         mNavigationBarController.showPinningEscapeToast(mDisplayId);
3446     }
3447 
3448     /**
3449      * TODO: Remove this method. Views should not be passed forward. Will cause theme issues.
3450      * @return bottom area view
3451      */
getKeyguardBottomAreaView()3452     public KeyguardBottomAreaView getKeyguardBottomAreaView() {
3453         return mNotificationPanelViewController.getKeyguardBottomAreaView();
3454     }
3455 
3456     /**
3457      * Propagation of the bouncer state, indicating that it's fully visible.
3458      */
setBouncerShowing(boolean bouncerShowing)3459     public void setBouncerShowing(boolean bouncerShowing) {
3460         mBouncerShowing = bouncerShowing;
3461         mKeyguardBypassController.setBouncerShowing(bouncerShowing);
3462         mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
3463         setBouncerShowingForStatusBarComponents(bouncerShowing);
3464         mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
3465         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
3466         updateScrimController();
3467         if (!mBouncerShowing) {
3468             updatePanelExpansionForKeyguard();
3469         }
3470     }
3471 
3472     /**
3473      * Propagate the bouncer state to status bar components.
3474      *
3475      * Separate from {@link #setBouncerShowing} because we sometimes re-create the status bar and
3476      * should update only the status bar components.
3477      */
setBouncerShowingForStatusBarComponents(boolean bouncerShowing)3478     private void setBouncerShowingForStatusBarComponents(boolean bouncerShowing) {
3479         int importance = bouncerShowing
3480                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
3481                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO;
3482         if (mPhoneStatusBarViewController != null) {
3483             mPhoneStatusBarViewController.setImportantForAccessibility(importance);
3484         }
3485         mNotificationPanelViewController.setImportantForAccessibility(importance);
3486         mNotificationPanelViewController.setBouncerShowing(bouncerShowing);
3487     }
3488 
3489     /**
3490      * Collapses the notification shade if it is tracking or expanded.
3491      */
collapseShade()3492     public void collapseShade() {
3493         if (mNotificationPanelViewController.isTracking()) {
3494             mNotificationShadeWindowViewController.cancelCurrentTouch();
3495         }
3496         if (mPanelExpanded && mState == StatusBarState.SHADE) {
3497             mShadeController.animateCollapsePanels();
3498         }
3499     }
3500 
3501     @VisibleForTesting
3502     final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
3503         @Override
3504         public void onFinishedGoingToSleep() {
3505             mNotificationPanelViewController.onAffordanceLaunchEnded();
3506             releaseGestureWakeLock();
3507             mLaunchCameraWhenFinishedWaking = false;
3508             mDeviceInteractive = false;
3509             mWakeUpComingFromTouch = false;
3510             mWakeUpTouchLocation = null;
3511             updateVisibleToUser();
3512 
3513             updateNotificationPanelTouchState();
3514             mNotificationShadeWindowViewController.cancelCurrentTouch();
3515             if (mLaunchCameraOnFinishedGoingToSleep) {
3516                 mLaunchCameraOnFinishedGoingToSleep = false;
3517 
3518                 // This gets executed before we will show Keyguard, so post it in order that the state
3519                 // is correct.
3520                 mMainExecutor.execute(() -> mCommandQueueCallbacks.onCameraLaunchGestureDetected(
3521                         mLastCameraLaunchSource));
3522             }
3523 
3524             if (mLaunchEmergencyActionOnFinishedGoingToSleep) {
3525                 mLaunchEmergencyActionOnFinishedGoingToSleep = false;
3526 
3527                 // This gets executed before we will show Keyguard, so post it in order that the
3528                 // state is correct.
3529                 mMainExecutor.execute(
3530                         () -> mCommandQueueCallbacks.onEmergencyActionLaunchGestureDetected());
3531             }
3532             updateIsKeyguard();
3533         }
3534 
3535         @Override
3536         public void onStartedGoingToSleep() {
3537             String tag = "StatusBar#onStartedGoingToSleep";
3538             DejankUtils.startDetectingBlockingIpcs(tag);
3539             updateRevealEffect(false /* wakingUp */);
3540             updateNotificationPanelTouchState();
3541             maybeEscalateHeadsUp();
3542             dismissVolumeDialog();
3543             mWakeUpCoordinator.setFullyAwake(false);
3544             mBypassHeadsUpNotifier.setFullyAwake(false);
3545             mKeyguardBypassController.onStartedGoingToSleep();
3546 
3547             // The screen off animation uses our LightRevealScrim - we need to be expanded for it to
3548             // be visible.
3549             if (mDozeParameters.shouldControlUnlockedScreenOff()) {
3550                 makeExpandedVisible(true);
3551             }
3552 
3553             DejankUtils.stopDetectingBlockingIpcs(tag);
3554         }
3555 
3556         @Override
3557         public void onStartedWakingUp() {
3558             String tag = "StatusBar#onStartedWakingUp";
3559             DejankUtils.startDetectingBlockingIpcs(tag);
3560             mDeviceInteractive = true;
3561             mWakeUpCoordinator.setWakingUp(true);
3562             if (!mKeyguardBypassController.getBypassEnabled()) {
3563                 mHeadsUpManager.releaseAllImmediately();
3564             }
3565             updateVisibleToUser();
3566             updateIsKeyguard();
3567             mDozeServiceHost.stopDozing();
3568             // This is intentionally below the stopDozing call above, since it avoids that we're
3569             // unnecessarily animating the wakeUp transition. Animations should only be enabled
3570             // once we fully woke up.
3571             updateRevealEffect(true /* wakingUp */);
3572             updateNotificationPanelTouchState();
3573 
3574             // If we are waking up during the screen off animation, we should undo making the
3575             // expanded visible (we did that so the LightRevealScrim would be visible).
3576             if (mUnlockedScreenOffAnimationController.isScreenOffLightRevealAnimationPlaying()) {
3577                 makeExpandedInvisible();
3578             }
3579 
3580             DejankUtils.stopDetectingBlockingIpcs(tag);
3581         }
3582 
3583         @Override
3584         public void onFinishedWakingUp() {
3585             mWakeUpCoordinator.setFullyAwake(true);
3586             mBypassHeadsUpNotifier.setFullyAwake(true);
3587             mWakeUpCoordinator.setWakingUp(false);
3588             if (mLaunchCameraWhenFinishedWaking) {
3589                 mNotificationPanelViewController.launchCamera(
3590                         false /* animate */, mLastCameraLaunchSource);
3591                 mLaunchCameraWhenFinishedWaking = false;
3592             }
3593             if (mLaunchEmergencyActionWhenFinishedWaking) {
3594                 mLaunchEmergencyActionWhenFinishedWaking = false;
3595                 Intent emergencyIntent = getEmergencyActionIntent();
3596                 if (emergencyIntent != null) {
3597                     mContext.startActivityAsUser(emergencyIntent, UserHandle.CURRENT);
3598                 }
3599             }
3600             updateScrimController();
3601         }
3602     };
3603 
3604     /**
3605      * We need to disable touch events because these might
3606      * collapse the panel after we expanded it, and thus we would end up with a blank
3607      * Keyguard.
3608      */
updateNotificationPanelTouchState()3609     void updateNotificationPanelTouchState() {
3610         boolean goingToSleepWithoutAnimation = isGoingToSleep()
3611                 && !mDozeParameters.shouldControlScreenOff();
3612         boolean disabled = (!mDeviceInteractive && !mDozeServiceHost.isPulsing())
3613                 || goingToSleepWithoutAnimation;
3614         mNotificationPanelViewController.setTouchAndAnimationDisabled(disabled);
3615         mNotificationIconAreaController.setAnimationsEnabled(!disabled);
3616     }
3617 
3618     final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
3619         @Override
3620         public void onScreenTurningOn() {
3621             mFalsingCollector.onScreenTurningOn();
3622             mNotificationPanelViewController.onScreenTurningOn();
3623         }
3624 
3625         @Override
3626         public void onScreenTurnedOn() {
3627             mScrimController.onScreenTurnedOn();
3628         }
3629 
3630         @Override
3631         public void onScreenTurnedOff() {
3632             mFalsingCollector.onScreenOff();
3633             mScrimController.onScreenTurnedOff();
3634             updateIsKeyguard();
3635         }
3636     };
3637 
getWakefulnessState()3638     public int getWakefulnessState() {
3639         return mWakefulnessLifecycle.getWakefulness();
3640     }
3641 
3642     /**
3643      * @return true if the screen is currently fully off, i.e. has finished turning off and has
3644      * since not started turning on.
3645      */
isScreenFullyOff()3646     public boolean isScreenFullyOff() {
3647         return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF;
3648     }
3649 
showScreenPinningRequest(int taskId, boolean allowCancel)3650     public void showScreenPinningRequest(int taskId, boolean allowCancel) {
3651         mScreenPinningRequest.showPrompt(taskId, allowCancel);
3652     }
3653 
getEmergencyActionIntent()3654     @Nullable Intent getEmergencyActionIntent() {
3655         Intent emergencyIntent = new Intent(EmergencyGesture.ACTION_LAUNCH_EMERGENCY);
3656         PackageManager pm = mContext.getPackageManager();
3657         List<ResolveInfo> emergencyActivities = pm.queryIntentActivities(emergencyIntent,
3658                 PackageManager.MATCH_SYSTEM_ONLY);
3659         ResolveInfo resolveInfo = getTopEmergencySosInfo(emergencyActivities);
3660         if (resolveInfo == null) {
3661             Log.wtf(TAG, "Couldn't find an app to process the emergency intent.");
3662             return null;
3663         }
3664         emergencyIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,
3665                 resolveInfo.activityInfo.name));
3666         emergencyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3667         return emergencyIntent;
3668     }
3669 
3670     /**
3671      * Select and return the "best" ResolveInfo for Emergency SOS Activity.
3672      */
getTopEmergencySosInfo(List<ResolveInfo> emergencyActivities)3673     private @Nullable ResolveInfo getTopEmergencySosInfo(List<ResolveInfo> emergencyActivities) {
3674         // No matched activity.
3675         if (emergencyActivities == null || emergencyActivities.isEmpty()) {
3676             return null;
3677         }
3678 
3679         // Of multiple matched Activities, give preference to the pre-set package name.
3680         String preferredAppPackageName =
3681                 mContext.getString(R.string.config_preferredEmergencySosPackage);
3682 
3683         // If there is no preferred app, then return first match.
3684         if (TextUtils.isEmpty(preferredAppPackageName)) {
3685             return emergencyActivities.get(0);
3686         }
3687 
3688         for (ResolveInfo emergencyInfo: emergencyActivities) {
3689             // If activity is from the preferred app, use it.
3690             if (TextUtils.equals(emergencyInfo.activityInfo.packageName, preferredAppPackageName)) {
3691                 return emergencyInfo;
3692             }
3693         }
3694         // No matching activity: return first match
3695         return emergencyActivities.get(0);
3696     }
3697 
isCameraAllowedByAdmin()3698     boolean isCameraAllowedByAdmin() {
3699         if (mDevicePolicyManager.getCameraDisabled(null,
3700                 mLockscreenUserManager.getCurrentUserId())) {
3701             return false;
3702         } else if (mStatusBarKeyguardViewManager == null
3703                 || (isKeyguardShowing() && isKeyguardSecure())) {
3704             // Check if the admin has disabled the camera specifically for the keyguard
3705             return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
3706                     mLockscreenUserManager.getCurrentUserId())
3707                     & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
3708         }
3709         return true;
3710     }
3711 
isGoingToSleep()3712     boolean isGoingToSleep() {
3713         return mWakefulnessLifecycle.getWakefulness()
3714                 == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
3715     }
3716 
notifyBiometricAuthModeChanged()3717     public void notifyBiometricAuthModeChanged() {
3718         mDozeServiceHost.updateDozing();
3719         updateScrimController();
3720     }
3721 
3722     @VisibleForTesting
updateScrimController()3723     public void updateScrimController() {
3724         Trace.beginSection("StatusBar#updateScrimController");
3725 
3726         // We don't want to end up in KEYGUARD state when we're unlocking with
3727         // fingerprint from doze. We should cross fade directly from black.
3728         boolean unlocking = mBiometricUnlockController.isWakeAndUnlock()
3729                 || mKeyguardStateController.isKeyguardFadingAway();
3730 
3731         // Do not animate the scrim expansion when triggered by the fingerprint sensor.
3732         boolean onKeyguardOrHidingIt = mKeyguardStateController.isShowing()
3733                 || mKeyguardStateController.isKeyguardFadingAway()
3734                 || mKeyguardStateController.isKeyguardGoingAway();
3735         mScrimController.setExpansionAffectsAlpha(!(mBiometricUnlockController.isBiometricUnlock()
3736                         && onKeyguardOrHidingIt));
3737 
3738         boolean launchingAffordanceWithPreview =
3739                 mNotificationPanelViewController.isLaunchingAffordanceWithPreview();
3740         mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
3741 
3742         if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
3743             if (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED) {
3744                 mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
3745             } else {
3746                 mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
3747             }
3748         } else if (mBouncerShowing) {
3749             // Bouncer needs the front scrim when it's on top of an activity,
3750             // tapping on a notification, editing QS or being dismissed by
3751             // FLAG_DISMISS_KEYGUARD_ACTIVITY.
3752             ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
3753                     ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
3754             mScrimController.transitionTo(state);
3755         } else if (launchingAffordanceWithPreview) {
3756             // We want to avoid animating when launching with a preview.
3757             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
3758         } else if (mBrightnessMirrorVisible) {
3759             mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
3760         } else if (mState == StatusBarState.SHADE_LOCKED) {
3761             mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
3762         } else if (mDozeServiceHost.isPulsing()) {
3763             mScrimController.transitionTo(ScrimState.PULSING,
3764                     mDozeScrimController.getScrimCallback());
3765         } else if (mDozeServiceHost.hasPendingScreenOffCallback()) {
3766             mScrimController.transitionTo(ScrimState.OFF, new ScrimController.Callback() {
3767                 @Override
3768                 public void onFinished() {
3769                     mDozeServiceHost.executePendingScreenOffCallback();
3770                 }
3771             });
3772         } else if (mDozing && !unlocking) {
3773             mScrimController.transitionTo(ScrimState.AOD);
3774         } else if (mIsKeyguard && !unlocking) {
3775             mScrimController.transitionTo(ScrimState.KEYGUARD);
3776         } else {
3777             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
3778         }
3779         updateLightRevealScrimVisibility();
3780 
3781         Trace.endSection();
3782     }
3783 
isKeyguardShowing()3784     public boolean isKeyguardShowing() {
3785         if (mStatusBarKeyguardViewManager == null) {
3786             Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
3787             return true;
3788         }
3789         return mStatusBarKeyguardViewManager.isShowing();
3790     }
3791 
shouldIgnoreTouch()3792     public boolean shouldIgnoreTouch() {
3793         return (mStatusBarStateController.isDozing()
3794                 && mDozeServiceHost.getIgnoreTouchWhilePulsing())
3795                 || mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying();
3796     }
3797 
3798     // Begin Extra BaseStatusBar methods.
3799 
3800     protected final CommandQueue mCommandQueue;
3801     protected IStatusBarService mBarService;
3802 
3803     // all notifications
3804     protected NotificationStackScrollLayout mStackScroller;
3805 
3806     // handling reordering
3807     private final VisualStabilityManager mVisualStabilityManager;
3808 
3809     protected AccessibilityManager mAccessibilityManager;
3810 
3811     protected boolean mDeviceInteractive;
3812 
3813     protected boolean mVisible;
3814 
3815     // mScreenOnFromKeyguard && mVisible.
3816     private boolean mVisibleToUser;
3817 
3818     protected DevicePolicyManager mDevicePolicyManager;
3819     private final PowerManager mPowerManager;
3820     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
3821 
3822     protected KeyguardManager mKeyguardManager;
3823     private final DeviceProvisionedController mDeviceProvisionedController;
3824 
3825     private final NavigationBarController mNavigationBarController;
3826     private final AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
3827 
3828     // UI-specific methods
3829 
3830     protected WindowManager mWindowManager;
3831     protected IWindowManager mWindowManagerService;
3832     private IDreamManager mDreamManager;
3833 
3834     protected Display mDisplay;
3835     private int mDisplayId;
3836 
3837     protected NotificationShelfController mNotificationShelfController;
3838 
3839     private final Lazy<AssistManager> mAssistManagerLazy;
3840 
isDeviceInteractive()3841     public boolean isDeviceInteractive() {
3842         return mDeviceInteractive;
3843     }
3844 
3845     private final BroadcastReceiver mBannerActionBroadcastReceiver = new BroadcastReceiver() {
3846         @Override
3847         public void onReceive(Context context, Intent intent) {
3848             String action = intent.getAction();
3849             if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
3850                 NotificationManager noMan = (NotificationManager)
3851                         mContext.getSystemService(Context.NOTIFICATION_SERVICE);
3852                 noMan.cancel(com.android.internal.messages.nano.SystemMessageProto.SystemMessage.
3853                         NOTE_HIDDEN_NOTIFICATIONS);
3854 
3855                 Settings.Secure.putInt(mContext.getContentResolver(),
3856                         Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
3857                 if (BANNER_ACTION_SETUP.equals(action)) {
3858                     mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
3859                             true /* force */);
3860                     mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
3861                             .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
3862 
3863                     );
3864                 }
3865             }
3866         }
3867     };
3868 
setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption)3869     public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
3870         mNotificationsController.setNotificationSnoozed(sbn, snoozeOption);
3871     }
3872 
3873 
awakenDreams()3874     public void awakenDreams() {
3875         mUiBgExecutor.execute(() -> {
3876             try {
3877                 mDreamManager.awaken();
3878             } catch (RemoteException e) {
3879                 e.printStackTrace();
3880             }
3881         });
3882     }
3883 
toggleKeyboardShortcuts(int deviceId)3884     protected void toggleKeyboardShortcuts(int deviceId) {
3885         KeyboardShortcuts.toggle(mContext, deviceId);
3886     }
3887 
dismissKeyboardShortcuts()3888     protected void dismissKeyboardShortcuts() {
3889         KeyboardShortcuts.dismiss();
3890     }
3891 
3892     /**
3893      * Dismiss the keyguard then execute an action.
3894      *
3895      * @param action The action to execute after dismissing the keyguard.
3896      * @param collapsePanel Whether we should collapse the panel after dismissing the keyguard.
3897      * @param willAnimateOnKeyguard Whether {@param action} will run an animation on the keyguard if
3898      *                              we are locked.
3899      */
executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone, boolean collapsePanel, boolean willAnimateOnKeyguard)3900     private void executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone,
3901             boolean collapsePanel, boolean willAnimateOnKeyguard) {
3902         if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
3903 
3904         OnDismissAction onDismissAction = new OnDismissAction() {
3905             @Override
3906             public boolean onDismiss() {
3907                 new Thread(() -> {
3908                     try {
3909                         // The intent we are sending is for the application, which
3910                         // won't have permission to immediately start an activity after
3911                         // the user switches to home.  We know it is safe to do at this
3912                         // point, so make sure new activity switches are now allowed.
3913                         ActivityManager.getService().resumeAppSwitches();
3914                     } catch (RemoteException e) {
3915                     }
3916                     action.run();
3917                 }).start();
3918 
3919                 return collapsePanel ? mShadeController.collapsePanel() : willAnimateOnKeyguard;
3920             }
3921 
3922             @Override
3923             public boolean willRunAnimationOnKeyguard() {
3924                 return willAnimateOnKeyguard;
3925             }
3926         };
3927         dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
3928     }
3929 
3930     @Override
startPendingIntentDismissingKeyguard(final PendingIntent intent)3931     public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
3932         startPendingIntentDismissingKeyguard(intent, null);
3933     }
3934 
3935     @Override
startPendingIntentDismissingKeyguard( final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback)3936     public void startPendingIntentDismissingKeyguard(
3937             final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
3938         startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
3939                 (ActivityLaunchAnimator.Controller) null);
3940     }
3941 
3942     @Override
startPendingIntentDismissingKeyguard(PendingIntent intent, Runnable intentSentUiThreadCallback, View associatedView)3943     public void startPendingIntentDismissingKeyguard(PendingIntent intent,
3944             Runnable intentSentUiThreadCallback, View associatedView) {
3945         ActivityLaunchAnimator.Controller animationController = null;
3946         if (associatedView instanceof ExpandableNotificationRow) {
3947             animationController = mNotificationAnimationProvider.getAnimatorController(
3948                     ((ExpandableNotificationRow) associatedView));
3949         }
3950 
3951         startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
3952                 animationController);
3953     }
3954 
3955     @Override
startPendingIntentDismissingKeyguard( final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback, @Nullable ActivityLaunchAnimator.Controller animationController)3956     public void startPendingIntentDismissingKeyguard(
3957             final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
3958             @Nullable ActivityLaunchAnimator.Controller animationController) {
3959         final boolean willLaunchResolverActivity = intent.isActivity()
3960                 && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
3961                 mLockscreenUserManager.getCurrentUserId());
3962 
3963         boolean animate = !willLaunchResolverActivity
3964                 && animationController != null
3965                 && shouldAnimateLaunch(intent.isActivity());
3966 
3967         // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we run
3968         // the animation on the keyguard). The animation will take care of (instantly) collapsing
3969         // the shade and hiding the keyguard once it is done.
3970         boolean collapse = !animate;
3971         executeActionDismissingKeyguard(() -> {
3972             try {
3973                 // We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
3974                 // shade is collapsed after the animation (or when it is cancelled, aborted, etc).
3975                 ActivityLaunchAnimator.Controller controller =
3976                         animationController != null ? new StatusBarLaunchAnimatorController(
3977                                 animationController, this, intent.isActivity()) : null;
3978 
3979                 mActivityLaunchAnimator.startPendingIntentWithAnimation(
3980                         controller, animate, intent.getCreatorPackage(),
3981                         (animationAdapter) -> intent.sendAndReturnResult(null, 0, null, null, null,
3982                                 null, getActivityOptions(mDisplayId, animationAdapter)));
3983             } catch (PendingIntent.CanceledException e) {
3984                 // the stack trace isn't very helpful here.
3985                 // Just log the exception message.
3986                 Log.w(TAG, "Sending intent failed: " + e);
3987                 if (!collapse) {
3988                     // executeActionDismissingKeyguard did not collapse for us already.
3989                     collapsePanelOnMainThread();
3990                 }
3991                 // TODO: Dismiss Keyguard.
3992             }
3993             if (intent.isActivity()) {
3994                 mAssistManagerLazy.get().hideAssist();
3995             }
3996             if (intentSentUiThreadCallback != null) {
3997                 postOnUiThread(intentSentUiThreadCallback);
3998             }
3999         }, willLaunchResolverActivity, collapse, animate);
4000     }
4001 
postOnUiThread(Runnable runnable)4002     private void postOnUiThread(Runnable runnable) {
4003         mMainExecutor.execute(runnable);
4004     }
4005 
4006     /**
4007      * Returns an ActivityOptions bundle created using the given parameters.
4008      *
4009      * @param displayId The ID of the display to launch the activity in. Typically this would be the
4010      *                  display the status bar is on.
4011      * @param animationAdapter The animation adapter used to start this activity, or {@code null}
4012      *                         for the default animation.
4013      */
getActivityOptions(int displayId, @Nullable RemoteAnimationAdapter animationAdapter)4014     public static Bundle getActivityOptions(int displayId,
4015             @Nullable RemoteAnimationAdapter animationAdapter) {
4016         ActivityOptions options = getDefaultActivityOptions(animationAdapter);
4017         options.setLaunchDisplayId(displayId);
4018         options.setCallerDisplayId(displayId);
4019         return options.toBundle();
4020     }
4021 
4022     /**
4023      * Returns an ActivityOptions bundle created using the given parameters.
4024      *
4025      * @param displayId The ID of the display to launch the activity in. Typically this would be the
4026      *                  display the status bar is on.
4027      * @param animationAdapter The animation adapter used to start this activity, or {@code null}
4028      *                         for the default animation.
4029      * @param isKeyguardShowing Whether keyguard is currently showing.
4030      * @param eventTime The event time in milliseconds since boot, not including sleep. See
4031      *                  {@link ActivityOptions#setSourceInfo}.
4032      */
getActivityOptions(int displayId, @Nullable RemoteAnimationAdapter animationAdapter, boolean isKeyguardShowing, long eventTime)4033     public static Bundle getActivityOptions(int displayId,
4034             @Nullable RemoteAnimationAdapter animationAdapter, boolean isKeyguardShowing,
4035             long eventTime) {
4036         ActivityOptions options = getDefaultActivityOptions(animationAdapter);
4037         options.setSourceInfo(isKeyguardShowing ? ActivityOptions.SourceInfo.TYPE_LOCKSCREEN
4038                 : ActivityOptions.SourceInfo.TYPE_NOTIFICATION, eventTime);
4039         options.setLaunchDisplayId(displayId);
4040         options.setCallerDisplayId(displayId);
4041         return options.toBundle();
4042     }
4043 
getDefaultActivityOptions( @ullable RemoteAnimationAdapter animationAdapter)4044     public static ActivityOptions getDefaultActivityOptions(
4045             @Nullable RemoteAnimationAdapter animationAdapter) {
4046         ActivityOptions options;
4047         if (animationAdapter != null) {
4048             options = ActivityOptions.makeRemoteAnimation(animationAdapter);
4049         } else {
4050             options = ActivityOptions.makeBasic();
4051         }
4052         return options;
4053     }
4054 
visibilityChanged(boolean visible)4055     void visibilityChanged(boolean visible) {
4056         if (mVisible != visible) {
4057             mVisible = visible;
4058             if (!visible) {
4059                 mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
4060                         true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
4061             }
4062         }
4063         updateVisibleToUser();
4064     }
4065 
updateVisibleToUser()4066     protected void updateVisibleToUser() {
4067         boolean oldVisibleToUser = mVisibleToUser;
4068         mVisibleToUser = mVisible && mDeviceInteractive;
4069 
4070         if (oldVisibleToUser != mVisibleToUser) {
4071             handleVisibleToUserChanged(mVisibleToUser);
4072         }
4073     }
4074 
4075     /**
4076      * Clear Buzz/Beep/Blink.
4077      */
clearNotificationEffects()4078     public void clearNotificationEffects() {
4079         try {
4080             mBarService.clearNotificationEffects();
4081         } catch (RemoteException e) {
4082             // Won't fail unless the world has ended.
4083         }
4084     }
4085 
4086     /**
4087      * @return Whether the security bouncer from Keyguard is showing.
4088      */
isBouncerShowing()4089     public boolean isBouncerShowing() {
4090         return mBouncerShowing;
4091     }
4092 
4093     /**
4094      * @return Whether the security bouncer from Keyguard is showing.
4095      */
isBouncerShowingScrimmed()4096     public boolean isBouncerShowingScrimmed() {
4097         return isBouncerShowing() && mStatusBarKeyguardViewManager.bouncerNeedsScrimming();
4098     }
4099 
4100     /**
4101      * When {@link KeyguardBouncer} starts to be dismissed, playing its animation.
4102      */
onBouncerPreHideAnimation()4103     public void onBouncerPreHideAnimation() {
4104         mNotificationPanelViewController.onBouncerPreHideAnimation();
4105 
4106     }
4107 
4108     /**
4109      * @return a PackageManger for userId or if userId is < 0 (USER_ALL etc) then
4110      *         return PackageManager for mContext
4111      */
getPackageManagerForUser(Context context, int userId)4112     public static PackageManager getPackageManagerForUser(Context context, int userId) {
4113         Context contextForUser = context;
4114         // UserHandle defines special userId as negative values, e.g. USER_ALL
4115         if (userId >= 0) {
4116             try {
4117                 // Create a context for the correct user so if a package isn't installed
4118                 // for user 0 we can still load information about the package.
4119                 contextForUser =
4120                         context.createPackageContextAsUser(context.getPackageName(),
4121                         Context.CONTEXT_RESTRICTED,
4122                         new UserHandle(userId));
4123             } catch (NameNotFoundException e) {
4124                 // Shouldn't fail to find the package name for system ui.
4125             }
4126         }
4127         return contextForUser.getPackageManager();
4128     }
4129 
isKeyguardSecure()4130     public boolean isKeyguardSecure() {
4131         if (mStatusBarKeyguardViewManager == null) {
4132             // startKeyguard() hasn't been called yet, so we don't know.
4133             // Make sure anything that needs to know isKeyguardSecure() checks and re-checks this
4134             // value onVisibilityChanged().
4135             Slog.w(TAG, "isKeyguardSecure() called before startKeyguard(), returning false",
4136                     new Throwable());
4137             return false;
4138         }
4139         return mStatusBarKeyguardViewManager.isSecure();
4140     }
getPanelController()4141     public NotificationPanelViewController getPanelController() {
4142         return mNotificationPanelViewController;
4143     }
4144     // End Extra BaseStatusBarMethods.
4145 
getGutsManager()4146     public NotificationGutsManager getGutsManager() {
4147         return mGutsManager;
4148     }
4149 
isTransientShown()4150     boolean isTransientShown() {
4151         return mTransientShown;
4152     }
4153 
updateLightRevealScrimVisibility()4154     private void updateLightRevealScrimVisibility() {
4155         if (mLightRevealScrim == null) {
4156             // status bar may not be inflated yet
4157             return;
4158         }
4159 
4160         mLightRevealScrim.setAlpha(mScrimController.getState().getMaxLightRevealScrimAlpha());
4161     }
4162 
4163     private final KeyguardUpdateMonitorCallback mUpdateCallback =
4164             new KeyguardUpdateMonitorCallback() {
4165                 @Override
4166                 public void onDreamingStateChanged(boolean dreaming) {
4167                     if (dreaming) {
4168                         maybeEscalateHeadsUp();
4169                     }
4170                 }
4171 
4172                 // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
4173                 //  KeyguardCoordinator
4174                 @Override
4175                 public void onStrongAuthStateChanged(int userId) {
4176                     super.onStrongAuthStateChanged(userId);
4177                     mNotificationsController.requestNotificationUpdate("onStrongAuthStateChanged");
4178                 }
4179             };
4180 
4181 
4182     private final FalsingManager.FalsingBeliefListener mFalsingBeliefListener =
4183             new FalsingManager.FalsingBeliefListener() {
4184                 @Override
4185                 public void onFalse() {
4186                     // Hides quick settings, bouncer, and quick-quick settings.
4187                     mStatusBarKeyguardViewManager.reset(true);
4188                 }
4189             };
4190 
4191     // Notifies StatusBarKeyguardViewManager every time the keyguard transition is over,
4192     // this animation is tied to the scrim for historic reasons.
4193     // TODO: notify when keyguard has faded away instead of the scrim.
4194     private final ScrimController.Callback mUnlockScrimCallback = new ScrimController
4195             .Callback() {
4196         @Override
4197         public void onFinished() {
4198             if (mStatusBarKeyguardViewManager == null) {
4199                 Log.w(TAG, "Tried to notify keyguard visibility when "
4200                         + "mStatusBarKeyguardViewManager was null");
4201                 return;
4202             }
4203             if (mKeyguardStateController.isKeyguardFadingAway()) {
4204                 mStatusBarKeyguardViewManager.onKeyguardFadedAway();
4205             }
4206         }
4207 
4208         @Override
4209         public void onCancelled() {
4210             onFinished();
4211         }
4212     };
4213 
4214     private final DeviceProvisionedListener mUserSetupObserver = new DeviceProvisionedListener() {
4215         @Override
4216         public void onUserSetupChanged() {
4217             final boolean userSetup = mDeviceProvisionedController.isCurrentUserSetup();
4218             Log.d(TAG, "mUserSetupObserver - DeviceProvisionedListener called for "
4219                     + "current user");
4220             if (MULTIUSER_DEBUG) {
4221                 Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s",
4222                         userSetup, mUserSetup));
4223             }
4224 
4225             if (userSetup != mUserSetup) {
4226                 mUserSetup = userSetup;
4227                 if (!mUserSetup && mStatusBarView != null) {
4228                     animateCollapseQuickSettings();
4229                 }
4230                 if (mNotificationPanelViewController != null) {
4231                     mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
4232                 }
4233                 updateQsExpansionEnabled();
4234             }
4235         }
4236     };
4237 
4238     private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
4239         @Override
4240         public void onReceive(Context context, Intent intent) {
4241             if (!mWallpaperSupported) {
4242                 // Receiver should not have been registered at all...
4243                 Log.wtf(TAG, "WallpaperManager not supported");
4244                 return;
4245             }
4246             WallpaperInfo info = mWallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
4247             mWallpaperController.onWallpaperInfoUpdated(info);
4248 
4249             final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
4250                     com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
4251             // If WallpaperInfo is null, it must be ImageWallpaper.
4252             final boolean supportsAmbientMode = deviceSupportsAodWallpaper
4253                     && (info != null && info.supportsAmbientMode());
4254 
4255             mNotificationShadeWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
4256             mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
4257             mKeyguardViewMediator.setWallpaperSupportsAmbientMode(supportsAmbientMode);
4258         }
4259     };
4260 
4261     private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
4262         @Override
4263         public void onConfigChanged(Configuration newConfig) {
4264             updateResources();
4265             updateDisplaySize(); // populates mDisplayMetrics
4266 
4267             if (DEBUG) {
4268                 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
4269             }
4270 
4271             mViewHierarchyManager.updateRowStates();
4272             mScreenPinningRequest.onConfigurationChanged();
4273         }
4274 
4275         @Override
4276         public void onDensityOrFontScaleChanged() {
4277             // TODO: Remove this.
4278             if (mBrightnessMirrorController != null) {
4279                 mBrightnessMirrorController.onDensityOrFontScaleChanged();
4280             }
4281             // TODO: Bring these out of StatusBar.
4282             mUserInfoControllerImpl.onDensityOrFontScaleChanged();
4283             mUserSwitcherController.onDensityOrFontScaleChanged();
4284             mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
4285             mHeadsUpManager.onDensityOrFontScaleChanged();
4286         }
4287 
4288         @Override
4289         public void onThemeChanged() {
4290             if (mBrightnessMirrorController != null) {
4291                 mBrightnessMirrorController.onOverlayChanged();
4292             }
4293             // We need the new R.id.keyguard_indication_area before recreating
4294             // mKeyguardIndicationController
4295             mNotificationPanelViewController.onThemeChanged();
4296 
4297             if (mStatusBarKeyguardViewManager != null) {
4298                 mStatusBarKeyguardViewManager.onThemeChanged();
4299             }
4300             if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
4301                 ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
4302             }
4303             mNotificationIconAreaController.onThemeChanged();
4304         }
4305 
4306         @Override
4307         public void onUiModeChanged() {
4308             if (mBrightnessMirrorController != null) {
4309                 mBrightnessMirrorController.onUiModeChanged();
4310             }
4311         }
4312     };
4313 
4314     private StatusBarStateController.StateListener mStateListener =
4315             new StatusBarStateController.StateListener() {
4316                 @Override
4317                 public void onStatePreChange(int oldState, int newState) {
4318                     // If we're visible and switched to SHADE_LOCKED (the user dragged
4319                     // down on the lockscreen), clear notification LED, vibration,
4320                     // ringing.
4321                     // Other transitions are covered in handleVisibleToUserChanged().
4322                     if (mVisible && (newState == StatusBarState.SHADE_LOCKED
4323                             || mStatusBarStateController.goingToFullShade())) {
4324                         clearNotificationEffects();
4325                     }
4326                     if (newState == StatusBarState.KEYGUARD) {
4327                         mRemoteInputManager.onPanelCollapsed();
4328                         maybeEscalateHeadsUp();
4329                     }
4330                 }
4331 
4332                 @Override
4333                 public void onStateChanged(int newState) {
4334                     mState = newState;
4335                     updateReportRejectedTouchVisibility();
4336                     mDozeServiceHost.updateDozing();
4337                     updateTheme();
4338                     mNavigationBarController.touchAutoDim(mDisplayId);
4339                     Trace.beginSection("StatusBar#updateKeyguardState");
4340                     if (mState == StatusBarState.KEYGUARD && mStatusBarView != null) {
4341                         mNotificationPanelViewController.cancelPendingPanelCollapse();
4342                     }
4343                     updateDozingState();
4344                     checkBarModes();
4345                     updateScrimController();
4346                     mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
4347                     updateKeyguardState();
4348                     Trace.endSection();
4349                 }
4350 
4351                 @Override
4352                 public void onDozeAmountChanged(float linear, float eased) {
4353                     if (mFeatureFlags.useNewLockscreenAnimations()
4354                             && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)
4355                             && !mBiometricUnlockController.isWakeAndUnlock()) {
4356                         mLightRevealScrim.setRevealAmount(1f - linear);
4357                     }
4358                 }
4359 
4360                 @Override
4361                 public void onDozingChanged(boolean isDozing) {
4362                     Trace.beginSection("StatusBar#updateDozing");
4363                     mDozing = isDozing;
4364 
4365                     // Collapse the notification panel if open
4366                     boolean dozingAnimated = mDozeServiceHost.getDozingRequested()
4367                             && mDozeParameters.shouldControlScreenOff();
4368                     mNotificationPanelViewController.resetViews(dozingAnimated);
4369 
4370                     updateQsExpansionEnabled();
4371                     mKeyguardViewMediator.setDozing(mDozing);
4372 
4373                     mNotificationsController.requestNotificationUpdate("onDozingChanged");
4374                     updateDozingState();
4375                     mDozeServiceHost.updateDozing();
4376                     updateScrimController();
4377                     updateReportRejectedTouchVisibility();
4378                     Trace.endSection();
4379                 }
4380 
4381                 @Override
4382                 public void onFullscreenStateChanged(boolean isFullscreen) {
4383                     mIsFullscreen = isFullscreen;
4384                     maybeUpdateBarMode();
4385                 }
4386             };
4387 
4388     private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback =
4389             new BatteryController.BatteryStateChangeCallback() {
4390                 @Override
4391                 public void onPowerSaveChanged(boolean isPowerSave) {
4392                     mMainExecutor.execute(mCheckBarModes);
4393                     if (mDozeServiceHost != null) {
4394                         mDozeServiceHost.firePowerSaveChanged(isPowerSave);
4395                     }
4396                 }
4397             };
4398 
4399     private final ActivityLaunchAnimator.Callback mKeyguardHandler =
4400             new ActivityLaunchAnimator.Callback() {
4401                 @Override
4402                 public boolean isOnKeyguard() {
4403                     return mKeyguardStateController.isShowing();
4404                 }
4405 
4406                 @Override
4407                 public void hideKeyguardWithAnimation(IRemoteAnimationRunner runner) {
4408                     // We post to the main thread for 2 reasons:
4409                     //   1. KeyguardViewMediator is not thread-safe.
4410                     //   2. To ensure that ViewMediatorCallback#keyguardDonePending is called before
4411                     //      ViewMediatorCallback#readyForKeyguardDone. The wrong order could occur
4412                     //      when doing
4413                     //      dismissKeyguardThenExecute { hideKeyguardWithAnimation(runner) }.
4414                     mMainExecutor.execute(() -> mKeyguardViewMediator.hideWithAnimation(runner));
4415                 }
4416 
4417                 @Override
4418                 public void setBlursDisabledForAppLaunch(boolean disabled) {
4419                     mKeyguardViewMediator.setBlursDisabledForAppLaunch(disabled);
4420                 }
4421 
4422                 @Override
4423                 public int getBackgroundColor(TaskInfo task) {
4424                     if (!mStartingSurfaceOptional.isPresent()) {
4425                         Log.w(TAG, "No starting surface, defaulting to SystemBGColor");
4426                         return SplashscreenContentDrawer.getSystemBGColor();
4427                     }
4428 
4429                     return mStartingSurfaceOptional.get().getBackgroundColor(task);
4430                 }
4431             };
4432 }
4433