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