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