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