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