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