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; 18 19 import static android.app.StatusBarManager.DISABLE2_NONE; 20 import static android.app.StatusBarManager.DISABLE_NONE; 21 import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; 22 import static android.inputmethodservice.InputMethodService.IME_INVISIBLE; 23 import static android.view.Display.DEFAULT_DISPLAY; 24 import static android.view.Display.INVALID_DISPLAY; 25 26 import static com.android.systemui.statusbar.phone.StatusBar.ONLY_CORE_APPS; 27 28 import android.annotation.Nullable; 29 import android.app.ITransientNotificationCallback; 30 import android.app.StatusBarManager; 31 import android.app.StatusBarManager.Disable2Flags; 32 import android.app.StatusBarManager.DisableFlags; 33 import android.app.StatusBarManager.WindowType; 34 import android.app.StatusBarManager.WindowVisibleState; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.hardware.biometrics.BiometricAuthenticator.Modality; 38 import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode; 39 import android.hardware.biometrics.IBiometricSysuiReceiver; 40 import android.hardware.biometrics.PromptInfo; 41 import android.hardware.display.DisplayManager; 42 import android.hardware.fingerprint.IUdfpsHbmListener; 43 import android.inputmethodservice.InputMethodService.BackDispositionMode; 44 import android.os.Bundle; 45 import android.os.Handler; 46 import android.os.IBinder; 47 import android.os.Looper; 48 import android.os.Message; 49 import android.os.ParcelFileDescriptor; 50 import android.util.Log; 51 import android.util.Pair; 52 import android.util.SparseArray; 53 import android.view.InsetsState.InternalInsetsType; 54 import android.view.WindowInsetsController.Appearance; 55 import android.view.WindowInsetsController.Behavior; 56 57 import androidx.annotation.NonNull; 58 59 import com.android.internal.os.SomeArgs; 60 import com.android.internal.statusbar.IStatusBar; 61 import com.android.internal.statusbar.StatusBarIcon; 62 import com.android.internal.util.GcUtils; 63 import com.android.internal.view.AppearanceRegion; 64 import com.android.systemui.statusbar.CommandQueue.Callbacks; 65 import com.android.systemui.statusbar.commandline.CommandRegistry; 66 import com.android.systemui.statusbar.policy.CallbackController; 67 import com.android.systemui.tracing.ProtoTracer; 68 69 import java.io.FileOutputStream; 70 import java.io.IOException; 71 import java.io.PrintWriter; 72 import java.util.ArrayList; 73 74 /** 75 * This class takes the functions from IStatusBar that come in on 76 * binder pool threads and posts messages to get them onto the main 77 * thread, and calls onto Callbacks. It also takes care of 78 * coalescing these calls so they don't stack up. For the calls 79 * are coalesced, note that they are all idempotent. 80 */ 81 public class CommandQueue extends IStatusBar.Stub implements CallbackController<Callbacks>, 82 DisplayManager.DisplayListener { 83 private static final String TAG = CommandQueue.class.getSimpleName(); 84 85 private static final int INDEX_MASK = 0xffff; 86 private static final int MSG_SHIFT = 16; 87 private static final int MSG_MASK = 0xffff << MSG_SHIFT; 88 89 private static final int OP_SET_ICON = 1; 90 private static final int OP_REMOVE_ICON = 2; 91 92 private static final int MSG_ICON = 1 << MSG_SHIFT; 93 private static final int MSG_DISABLE = 2 << MSG_SHIFT; 94 private static final int MSG_EXPAND_NOTIFICATIONS = 3 << MSG_SHIFT; 95 private static final int MSG_COLLAPSE_PANELS = 4 << MSG_SHIFT; 96 private static final int MSG_EXPAND_SETTINGS = 5 << MSG_SHIFT; 97 private static final int MSG_SYSTEM_BAR_CHANGED = 6 << MSG_SHIFT; 98 private static final int MSG_DISPLAY_READY = 7 << MSG_SHIFT; 99 private static final int MSG_SHOW_IME_BUTTON = 8 << MSG_SHIFT; 100 private static final int MSG_TOGGLE_RECENT_APPS = 9 << MSG_SHIFT; 101 private static final int MSG_PRELOAD_RECENT_APPS = 10 << MSG_SHIFT; 102 private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 11 << MSG_SHIFT; 103 private static final int MSG_SET_WINDOW_STATE = 12 << MSG_SHIFT; 104 private static final int MSG_SHOW_RECENT_APPS = 13 << MSG_SHIFT; 105 private static final int MSG_HIDE_RECENT_APPS = 14 << MSG_SHIFT; 106 private static final int MSG_SHOW_SCREEN_PIN_REQUEST = 18 << MSG_SHIFT; 107 private static final int MSG_APP_TRANSITION_PENDING = 19 << MSG_SHIFT; 108 private static final int MSG_APP_TRANSITION_CANCELLED = 20 << MSG_SHIFT; 109 private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT; 110 private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT; 111 private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; 112 private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; 113 private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS = 25 << MSG_SHIFT; 114 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 26 << MSG_SHIFT; 115 private static final int MSG_ADD_QS_TILE = 27 << MSG_SHIFT; 116 private static final int MSG_REMOVE_QS_TILE = 28 << MSG_SHIFT; 117 private static final int MSG_CLICK_QS_TILE = 29 << MSG_SHIFT; 118 private static final int MSG_TOGGLE_APP_SPLIT_SCREEN = 30 << MSG_SHIFT; 119 private static final int MSG_APP_TRANSITION_FINISHED = 31 << MSG_SHIFT; 120 private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS = 32 << MSG_SHIFT; 121 private static final int MSG_HANDLE_SYSTEM_KEY = 33 << MSG_SHIFT; 122 private static final int MSG_SHOW_GLOBAL_ACTIONS = 34 << MSG_SHIFT; 123 private static final int MSG_TOGGLE_PANEL = 35 << MSG_SHIFT; 124 private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT; 125 private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR = 37 << MSG_SHIFT; 126 private static final int MSG_ROTATION_PROPOSAL = 38 << MSG_SHIFT; 127 private static final int MSG_BIOMETRIC_SHOW = 39 << MSG_SHIFT; 128 private static final int MSG_BIOMETRIC_AUTHENTICATED = 40 << MSG_SHIFT; 129 private static final int MSG_BIOMETRIC_HELP = 41 << MSG_SHIFT; 130 private static final int MSG_BIOMETRIC_ERROR = 42 << MSG_SHIFT; 131 private static final int MSG_BIOMETRIC_HIDE = 43 << MSG_SHIFT; 132 private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT; 133 private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT; 134 private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT; 135 private static final int MSG_RECENTS_ANIMATION_STATE_CHANGED = 47 << MSG_SHIFT; 136 private static final int MSG_SHOW_TRANSIENT = 48 << MSG_SHIFT; 137 private static final int MSG_ABORT_TRANSIENT = 49 << MSG_SHIFT; 138 private static final int MSG_SHOW_INATTENTIVE_SLEEP_WARNING = 50 << MSG_SHIFT; 139 private static final int MSG_DISMISS_INATTENTIVE_SLEEP_WARNING = 51 << MSG_SHIFT; 140 private static final int MSG_SHOW_TOAST = 52 << MSG_SHIFT; 141 private static final int MSG_HIDE_TOAST = 53 << MSG_SHIFT; 142 private static final int MSG_TRACING_STATE_CHANGED = 54 << MSG_SHIFT; 143 private static final int MSG_SUPPRESS_AMBIENT_DISPLAY = 55 << MSG_SHIFT; 144 private static final int MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION = 56 << MSG_SHIFT; 145 private static final int MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND = 57 << MSG_SHIFT; 146 //TODO(b/169175022) Update name and when feature name is locked. 147 private static final int MSG_EMERGENCY_ACTION_LAUNCH_GESTURE = 58 << MSG_SHIFT; 148 private static final int MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED = 59 << MSG_SHIFT; 149 private static final int MSG_SET_UDFPS_HBM_LISTENER = 60 << MSG_SHIFT; 150 151 public static final int FLAG_EXCLUDE_NONE = 0; 152 public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; 153 public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1; 154 public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2; 155 public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3; 156 public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4; 157 158 private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey"; 159 160 private final Object mLock = new Object(); 161 private ArrayList<Callbacks> mCallbacks = new ArrayList<>(); 162 private Handler mHandler = new H(Looper.getMainLooper()); 163 /** A map of display id - disable flag pair */ 164 private SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>(); 165 /** 166 * The last ID of the display where IME window for which we received setImeWindowStatus 167 * event. 168 */ 169 private int mLastUpdatedImeDisplayId = INVALID_DISPLAY; 170 private ProtoTracer mProtoTracer; 171 private final @Nullable CommandRegistry mRegistry; 172 173 /** 174 * These methods are called back on the main thread. 175 */ 176 public interface Callbacks { setIcon(String slot, StatusBarIcon icon)177 default void setIcon(String slot, StatusBarIcon icon) { } removeIcon(String slot)178 default void removeIcon(String slot) { } 179 180 /** 181 * Called to notify that disable flags are updated. 182 * @see IStatusBar#disable(int, int, int). 183 * 184 * @param displayId The id of the display to notify. 185 * @param state1 The combination of following DISABLE_* flags: 186 * @param state2 The combination of following DISABLE2_* flags: 187 * @param animate {@code true} to show animations. 188 */ disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)189 default void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, 190 boolean animate) { } animateExpandNotificationsPanel()191 default void animateExpandNotificationsPanel() { } animateCollapsePanels(int flags, boolean force)192 default void animateCollapsePanels(int flags, boolean force) { } togglePanel()193 default void togglePanel() { } animateExpandSettingsPanel(String obj)194 default void animateExpandSettingsPanel(String obj) { } 195 196 /** 197 * Called to notify IME window status changes. 198 * 199 * @param displayId The id of the display to notify. 200 * @param token IME token. 201 * @param vis IME visibility. 202 * @param backDisposition Disposition mode of back button. It should be one of below flags: 203 * @param showImeSwitcher {@code true} to show IME switch button. 204 */ setImeWindowStatus(int displayId, IBinder token, int vis, @BackDispositionMode int backDisposition, boolean showImeSwitcher)205 default void setImeWindowStatus(int displayId, IBinder token, int vis, 206 @BackDispositionMode int backDisposition, boolean showImeSwitcher) { } showRecentApps(boolean triggeredFromAltTab)207 default void showRecentApps(boolean triggeredFromAltTab) { } hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)208 default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } toggleRecentApps()209 default void toggleRecentApps() { } toggleSplitScreen()210 default void toggleSplitScreen() { } preloadRecentApps()211 default void preloadRecentApps() { } dismissKeyboardShortcutsMenu()212 default void dismissKeyboardShortcutsMenu() { } toggleKeyboardShortcutsMenu(int deviceId)213 default void toggleKeyboardShortcutsMenu(int deviceId) { } cancelPreloadRecentApps()214 default void cancelPreloadRecentApps() { } 215 216 /** 217 * Called to notify window state changes. 218 * @see IStatusBar#setWindowState(int, int, int) 219 * 220 * @param displayId The id of the display to notify. 221 * @param window Window type. It should be one of {@link StatusBarManager#WINDOW_STATUS_BAR} 222 * or {@link StatusBarManager#WINDOW_NAVIGATION_BAR} 223 * @param state Window visible state. 224 */ setWindowState(int displayId, @WindowType int window, @WindowVisibleState int state)225 default void setWindowState(int displayId, @WindowType int window, 226 @WindowVisibleState int state) { } showScreenPinningRequest(int taskId)227 default void showScreenPinningRequest(int taskId) { } 228 229 /** 230 * Called to notify System UI that an application transition is pending. 231 * @see IStatusBar#appTransitionPending(int). 232 * 233 * @param displayId The id of the display to notify. 234 * @param forced {@code true} to force transition pending. 235 */ appTransitionPending(int displayId, boolean forced)236 default void appTransitionPending(int displayId, boolean forced) { } 237 238 /** 239 * Called to notify System UI that an application transition is canceled. 240 * @see IStatusBar#appTransitionCancelled(int). 241 * 242 * @param displayId The id of the display to notify. 243 */ appTransitionCancelled(int displayId)244 default void appTransitionCancelled(int displayId) { } 245 246 /** 247 * Called to notify System UI that an application transition is starting. 248 * @see IStatusBar#appTransitionStarting(int, long, long). 249 * 250 * @param displayId The id of the display to notify. 251 * @param startTime Transition start time. 252 * @param duration Transition duration. 253 * @param forced {@code true} to force transition pending. 254 */ appTransitionStarting( int displayId, long startTime, long duration, boolean forced)255 default void appTransitionStarting( 256 int displayId, long startTime, long duration, boolean forced) { } 257 258 /** 259 * Called to notify System UI that an application transition is finished. 260 * @see IStatusBar#appTransitionFinished(int) 261 * 262 * @param displayId The id of the display to notify. 263 */ appTransitionFinished(int displayId)264 default void appTransitionFinished(int displayId) { } showAssistDisclosure()265 default void showAssistDisclosure() { } startAssist(Bundle args)266 default void startAssist(Bundle args) { } onCameraLaunchGestureDetected(int source)267 default void onCameraLaunchGestureDetected(int source) { } 268 269 /** 270 * Notifies SysUI that the emergency action gesture was detected. 271 */ onEmergencyActionLaunchGestureDetected()272 default void onEmergencyActionLaunchGestureDetected() { } showPictureInPictureMenu()273 default void showPictureInPictureMenu() { } setTopAppHidesStatusBar(boolean topAppHidesStatusBar)274 default void setTopAppHidesStatusBar(boolean topAppHidesStatusBar) { } 275 addQsTile(ComponentName tile)276 default void addQsTile(ComponentName tile) { } remQsTile(ComponentName tile)277 default void remQsTile(ComponentName tile) { } clickTile(ComponentName tile)278 default void clickTile(ComponentName tile) { } 279 handleSystemKey(int arg1)280 default void handleSystemKey(int arg1) { } showPinningEnterExitToast(boolean entering)281 default void showPinningEnterExitToast(boolean entering) { } showPinningEscapeToast()282 default void showPinningEscapeToast() { } handleShowGlobalActionsMenu()283 default void handleShowGlobalActionsMenu() { } handleShowShutdownUi(boolean isReboot, String reason)284 default void handleShowShutdownUi(boolean isReboot, String reason) { } 285 showWirelessChargingAnimation(int batteryLevel)286 default void showWirelessChargingAnimation(int batteryLevel) { } 287 onRotationProposal(int rotation, boolean isValid)288 default void onRotationProposal(int rotation, boolean isValid) { } 289 showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId, @BiometricMultiSensorMode int multiSensorConfig)290 default void showAuthenticationDialog(PromptInfo promptInfo, 291 IBiometricSysuiReceiver receiver, 292 int[] sensorIds, boolean credentialAllowed, 293 boolean requireConfirmation, int userId, String opPackageName, 294 long operationId, @BiometricMultiSensorMode int multiSensorConfig) { 295 } 296 297 /** @see IStatusBar#onBiometricAuthenticated() */ onBiometricAuthenticated()298 default void onBiometricAuthenticated() { 299 } 300 301 /** @see IStatusBar#onBiometricHelp(String) */ onBiometricHelp(@odality int modality, String message)302 default void onBiometricHelp(@Modality int modality, String message) { 303 } 304 305 /** @see IStatusBar#onBiometricError(int, int, int) */ onBiometricError(@odality int modality, int error, int vendorCode)306 default void onBiometricError(@Modality int modality, int error, int vendorCode) { 307 } 308 hideAuthenticationDialog()309 default void hideAuthenticationDialog() { 310 } 311 312 /** 313 * @see IStatusBar#setUdfpsHbmListener(IUdfpsHbmListener) 314 */ setUdfpsHbmListener(IUdfpsHbmListener listener)315 default void setUdfpsHbmListener(IUdfpsHbmListener listener) { 316 } 317 318 /** 319 * @see IStatusBar#onDisplayReady(int) 320 */ onDisplayReady(int displayId)321 default void onDisplayReady(int displayId) { 322 } 323 324 /** 325 * @see DisplayManager.DisplayListener#onDisplayRemoved(int) 326 */ onDisplayRemoved(int displayId)327 default void onDisplayRemoved(int displayId) { 328 } 329 330 /** 331 * @see IStatusBar#onRecentsAnimationStateChanged(boolean) 332 */ onRecentsAnimationStateChanged(boolean running)333 default void onRecentsAnimationStateChanged(boolean running) { } 334 335 /** 336 * @see IStatusBar#onSystemBarAttributesChanged. 337 */ onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, boolean isFullscreen)338 default void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, 339 AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, 340 @Behavior int behavior, boolean isFullscreen) { } 341 342 /** 343 * @see IStatusBar#showTransient(int, int[]). 344 */ showTransient(int displayId, @InternalInsetsType int[] types)345 default void showTransient(int displayId, @InternalInsetsType int[] types) { } 346 347 /** 348 * @see IStatusBar#abortTransient(int, int[]). 349 */ abortTransient(int displayId, @InternalInsetsType int[] types)350 default void abortTransient(int displayId, @InternalInsetsType int[] types) { } 351 352 /** 353 * Called to notify System UI that a warning about the device going to sleep 354 * due to prolonged user inactivity should be shown. 355 */ showInattentiveSleepWarning()356 default void showInattentiveSleepWarning() { } 357 358 /** 359 * Called to notify System UI that the warning about the device going to sleep 360 * due to prolonged user inactivity should be dismissed. 361 */ dismissInattentiveSleepWarning(boolean animated)362 default void dismissInattentiveSleepWarning(boolean animated) { } 363 364 /** Called to suppress ambient display. */ suppressAmbientDisplay(boolean suppress)365 default void suppressAmbientDisplay(boolean suppress) { } 366 367 /** 368 * @see IStatusBar#showToast(int, String, IBinder, CharSequence, IBinder, int, 369 * ITransientNotificationCallback) 370 */ showToast(int uid, String packageName, IBinder token, CharSequence text, IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback)371 default void showToast(int uid, String packageName, IBinder token, CharSequence text, 372 IBinder windowToken, int duration, 373 @Nullable ITransientNotificationCallback callback) { } 374 375 /** 376 * @see IStatusBar#hideToast(String, IBinder) (String, IBinder) 377 */ hideToast(String packageName, IBinder token)378 default void hideToast(String packageName, IBinder token) { } 379 380 /** 381 * @param enabled 382 */ onTracingStateChanged(boolean enabled)383 default void onTracingStateChanged(boolean enabled) { } 384 385 /** 386 * Requests {@link com.android.systemui.accessibility.WindowMagnification} to invoke 387 * {@code android.view.accessibility.AccessibilityManager# 388 * setWindowMagnificationConnection(IWindowMagnificationConnection)} 389 * 390 * @param connect {@code true} if needs connection, otherwise set the connection to null. 391 */ requestWindowMagnificationConnection(boolean connect)392 default void requestWindowMagnificationConnection(boolean connect) { } 393 394 /** 395 * Handles a window manager shell logging command. 396 */ handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd)397 default void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {} 398 399 /** 400 * @see IStatusBar#setNavigationBarLumaSamplingEnabled(int, boolean) 401 */ setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)402 default void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {} 403 } 404 CommandQueue(Context context)405 public CommandQueue(Context context) { 406 this(context, null, null); 407 } 408 CommandQueue(Context context, ProtoTracer protoTracer, CommandRegistry registry)409 public CommandQueue(Context context, ProtoTracer protoTracer, CommandRegistry registry) { 410 mProtoTracer = protoTracer; 411 mRegistry = registry; 412 context.getSystemService(DisplayManager.class).registerDisplayListener(this, mHandler); 413 // We always have default display. 414 setDisabled(DEFAULT_DISPLAY, DISABLE_NONE, DISABLE2_NONE); 415 } 416 417 @Override onDisplayAdded(int displayId)418 public void onDisplayAdded(int displayId) { } 419 420 @Override onDisplayRemoved(int displayId)421 public void onDisplayRemoved(int displayId) { 422 synchronized (mLock) { 423 mDisplayDisabled.remove(displayId); 424 } 425 // This callback is registered with {@link #mHandler} that already posts to run on main 426 // thread, so it is safe to dispatch directly. 427 for (int i = mCallbacks.size() - 1; i >= 0; i--) { 428 mCallbacks.get(i).onDisplayRemoved(displayId); 429 } 430 } 431 432 @Override onDisplayChanged(int displayId)433 public void onDisplayChanged(int displayId) { } 434 435 // TODO(b/118592525): add multi-display support if needed. panelsEnabled()436 public boolean panelsEnabled() { 437 final int disabled1 = getDisabled1(DEFAULT_DISPLAY); 438 final int disabled2 = getDisabled2(DEFAULT_DISPLAY); 439 return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0 440 && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0 441 && !ONLY_CORE_APPS; 442 } 443 444 @Override addCallback(@onNull Callbacks callbacks)445 public void addCallback(@NonNull Callbacks callbacks) { 446 mCallbacks.add(callbacks); 447 // TODO(b/117478341): find a better way to pass disable flags by display. 448 for (int i = 0; i < mDisplayDisabled.size(); i++) { 449 int displayId = mDisplayDisabled.keyAt(i); 450 int disabled1 = getDisabled1(displayId); 451 int disabled2 = getDisabled2(displayId); 452 callbacks.disable(displayId, disabled1, disabled2, false /* animate */); 453 } 454 } 455 456 @Override removeCallback(@onNull Callbacks callbacks)457 public void removeCallback(@NonNull Callbacks callbacks) { 458 mCallbacks.remove(callbacks); 459 } 460 setIcon(String slot, StatusBarIcon icon)461 public void setIcon(String slot, StatusBarIcon icon) { 462 synchronized (mLock) { 463 // don't coalesce these 464 mHandler.obtainMessage(MSG_ICON, OP_SET_ICON, 0, 465 new Pair<String, StatusBarIcon>(slot, icon)).sendToTarget(); 466 } 467 } 468 removeIcon(String slot)469 public void removeIcon(String slot) { 470 synchronized (mLock) { 471 // don't coalesce these 472 mHandler.obtainMessage(MSG_ICON, OP_REMOVE_ICON, 0, slot).sendToTarget(); 473 } 474 } 475 476 /** 477 * Called to notify that disable flags are updated. 478 * @see Callbacks#disable(int, int, int, boolean). 479 */ disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)480 public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, 481 boolean animate) { 482 synchronized (mLock) { 483 setDisabled(displayId, state1, state2); 484 mHandler.removeMessages(MSG_DISABLE); 485 final SomeArgs args = SomeArgs.obtain(); 486 args.argi1 = displayId; 487 args.argi2 = state1; 488 args.argi3 = state2; 489 args.argi4 = animate ? 1 : 0; 490 Message msg = mHandler.obtainMessage(MSG_DISABLE, args); 491 if (Looper.myLooper() == mHandler.getLooper()) { 492 // If its the right looper execute immediately so hides can be handled quickly. 493 mHandler.handleMessage(msg); 494 msg.recycle(); 495 } else { 496 msg.sendToTarget(); 497 } 498 } 499 } 500 501 @Override disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2)502 public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2) { 503 disable(displayId, state1, state2, true); 504 } 505 506 /** 507 * Apply current disable flags by {@link CommandQueue#disable(int, int, int, boolean)}. 508 * 509 * @param displayId The id of the display to notify. 510 * @param animate {@code true} to show animations. 511 */ recomputeDisableFlags(int displayId, boolean animate)512 public void recomputeDisableFlags(int displayId, boolean animate) { 513 int disabled1 = getDisabled1(displayId); 514 int disabled2 = getDisabled2(displayId); 515 disable(displayId, disabled1, disabled2, animate); 516 } 517 setDisabled(int displayId, int disabled1, int disabled2)518 private void setDisabled(int displayId, int disabled1, int disabled2) { 519 mDisplayDisabled.put(displayId, new Pair<>(disabled1, disabled2)); 520 } 521 getDisabled1(int displayId)522 private int getDisabled1(int displayId) { 523 return getDisabled(displayId).first; 524 } 525 getDisabled2(int displayId)526 private int getDisabled2(int displayId) { 527 return getDisabled(displayId).second; 528 } 529 getDisabled(int displayId)530 private Pair<Integer, Integer> getDisabled(int displayId) { 531 Pair<Integer, Integer> disablePair = mDisplayDisabled.get(displayId); 532 if (disablePair == null) { 533 disablePair = new Pair<>(DISABLE_NONE, DISABLE2_NONE); 534 mDisplayDisabled.put(displayId, disablePair); 535 } 536 return disablePair; 537 } 538 animateExpandNotificationsPanel()539 public void animateExpandNotificationsPanel() { 540 synchronized (mLock) { 541 mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS); 542 mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS); 543 } 544 } 545 animateCollapsePanels()546 public void animateCollapsePanels() { 547 synchronized (mLock) { 548 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 549 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, 0, 0).sendToTarget(); 550 } 551 } 552 animateCollapsePanels(int flags, boolean force)553 public void animateCollapsePanels(int flags, boolean force) { 554 synchronized (mLock) { 555 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 556 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, force ? 1 : 0).sendToTarget(); 557 } 558 } 559 togglePanel()560 public void togglePanel() { 561 synchronized (mLock) { 562 mHandler.removeMessages(MSG_TOGGLE_PANEL); 563 mHandler.obtainMessage(MSG_TOGGLE_PANEL, 0, 0).sendToTarget(); 564 } 565 } 566 animateExpandSettingsPanel(String subPanel)567 public void animateExpandSettingsPanel(String subPanel) { 568 synchronized (mLock) { 569 mHandler.removeMessages(MSG_EXPAND_SETTINGS); 570 mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget(); 571 } 572 } 573 574 @Override setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher, boolean isMultiClientImeEnabled)575 public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, 576 boolean showImeSwitcher, boolean isMultiClientImeEnabled) { 577 synchronized (mLock) { 578 mHandler.removeMessages(MSG_SHOW_IME_BUTTON); 579 SomeArgs args = SomeArgs.obtain(); 580 args.argi1 = displayId; 581 args.argi2 = vis; 582 args.argi3 = backDisposition; 583 args.argi4 = showImeSwitcher ? 1 : 0; 584 args.argi5 = isMultiClientImeEnabled ? 1 : 0; 585 args.arg1 = token; 586 Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, args); 587 m.sendToTarget(); 588 } 589 } 590 showRecentApps(boolean triggeredFromAltTab)591 public void showRecentApps(boolean triggeredFromAltTab) { 592 synchronized (mLock) { 593 mHandler.removeMessages(MSG_SHOW_RECENT_APPS); 594 mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, triggeredFromAltTab ? 1 : 0, 0, 595 null).sendToTarget(); 596 } 597 } 598 hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)599 public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { 600 synchronized (mLock) { 601 mHandler.removeMessages(MSG_HIDE_RECENT_APPS); 602 mHandler.obtainMessage(MSG_HIDE_RECENT_APPS, 603 triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0, 604 null).sendToTarget(); 605 } 606 } 607 toggleSplitScreen()608 public void toggleSplitScreen() { 609 synchronized (mLock) { 610 mHandler.removeMessages(MSG_TOGGLE_APP_SPLIT_SCREEN); 611 mHandler.obtainMessage(MSG_TOGGLE_APP_SPLIT_SCREEN, 0, 0, null).sendToTarget(); 612 } 613 } 614 toggleRecentApps()615 public void toggleRecentApps() { 616 synchronized (mLock) { 617 mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); 618 Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null); 619 msg.setAsynchronous(true); 620 msg.sendToTarget(); 621 } 622 } 623 preloadRecentApps()624 public void preloadRecentApps() { 625 synchronized (mLock) { 626 mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS); 627 mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 628 } 629 } 630 cancelPreloadRecentApps()631 public void cancelPreloadRecentApps() { 632 synchronized (mLock) { 633 mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS); 634 mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 635 } 636 } 637 638 @Override dismissKeyboardShortcutsMenu()639 public void dismissKeyboardShortcutsMenu() { 640 synchronized (mLock) { 641 mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS); 642 mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget(); 643 } 644 } 645 646 @Override toggleKeyboardShortcutsMenu(int deviceId)647 public void toggleKeyboardShortcutsMenu(int deviceId) { 648 synchronized (mLock) { 649 mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS); 650 mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget(); 651 } 652 } 653 654 @Override showPictureInPictureMenu()655 public void showPictureInPictureMenu() { 656 synchronized (mLock) { 657 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 658 mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU).sendToTarget(); 659 } 660 } 661 662 @Override setWindowState(int displayId, int window, int state)663 public void setWindowState(int displayId, int window, int state) { 664 synchronized (mLock) { 665 // don't coalesce these 666 mHandler.obtainMessage(MSG_SET_WINDOW_STATE, displayId, window, state).sendToTarget(); 667 } 668 } 669 showScreenPinningRequest(int taskId)670 public void showScreenPinningRequest(int taskId) { 671 synchronized (mLock) { 672 mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null) 673 .sendToTarget(); 674 } 675 } 676 677 @Override appTransitionPending(int displayId)678 public void appTransitionPending(int displayId) { 679 appTransitionPending(displayId, false /* forced */); 680 } 681 682 /** 683 * Called to notify System UI that an application transition is pending. 684 * @see Callbacks#appTransitionPending(int, boolean) 685 */ appTransitionPending(int displayId, boolean forced)686 public void appTransitionPending(int displayId, boolean forced) { 687 synchronized (mLock) { 688 mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, displayId, forced ? 1 : 0) 689 .sendToTarget(); 690 } 691 } 692 693 @Override appTransitionCancelled(int displayId)694 public void appTransitionCancelled(int displayId) { 695 synchronized (mLock) { 696 mHandler.obtainMessage(MSG_APP_TRANSITION_CANCELLED, displayId, 0 /* unused */) 697 .sendToTarget(); 698 } 699 } 700 701 @Override appTransitionStarting(int displayId, long startTime, long duration)702 public void appTransitionStarting(int displayId, long startTime, long duration) { 703 appTransitionStarting(displayId, startTime, duration, false /* forced */); 704 } 705 706 /** 707 * Called to notify System UI that an application transition is starting. 708 * @see Callbacks#appTransitionStarting(int, long, long, boolean). 709 */ appTransitionStarting(int displayId, long startTime, long duration, boolean forced)710 public void appTransitionStarting(int displayId, long startTime, long duration, 711 boolean forced) { 712 synchronized (mLock) { 713 final SomeArgs args = SomeArgs.obtain(); 714 args.argi1 = displayId; 715 args.argi2 = forced ? 1 : 0; 716 args.arg1 = startTime; 717 args.arg2 = duration; 718 mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, args).sendToTarget(); 719 } 720 } 721 722 @Override appTransitionFinished(int displayId)723 public void appTransitionFinished(int displayId) { 724 synchronized (mLock) { 725 mHandler.obtainMessage(MSG_APP_TRANSITION_FINISHED, displayId, 0 /* unused */) 726 .sendToTarget(); 727 } 728 } 729 showAssistDisclosure()730 public void showAssistDisclosure() { 731 synchronized (mLock) { 732 mHandler.removeMessages(MSG_ASSIST_DISCLOSURE); 733 mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget(); 734 } 735 } 736 startAssist(Bundle args)737 public void startAssist(Bundle args) { 738 synchronized (mLock) { 739 mHandler.removeMessages(MSG_START_ASSIST); 740 mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget(); 741 } 742 } 743 744 @Override onCameraLaunchGestureDetected(int source)745 public void onCameraLaunchGestureDetected(int source) { 746 synchronized (mLock) { 747 mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE); 748 mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget(); 749 } 750 } 751 752 @Override onEmergencyActionLaunchGestureDetected()753 public void onEmergencyActionLaunchGestureDetected() { 754 synchronized (mLock) { 755 mHandler.removeMessages(MSG_EMERGENCY_ACTION_LAUNCH_GESTURE); 756 mHandler.obtainMessage(MSG_EMERGENCY_ACTION_LAUNCH_GESTURE).sendToTarget(); 757 } 758 } 759 760 @Override addQsTile(ComponentName tile)761 public void addQsTile(ComponentName tile) { 762 synchronized (mLock) { 763 mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget(); 764 } 765 } 766 767 @Override remQsTile(ComponentName tile)768 public void remQsTile(ComponentName tile) { 769 synchronized (mLock) { 770 mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget(); 771 } 772 } 773 774 @Override clickQsTile(ComponentName tile)775 public void clickQsTile(ComponentName tile) { 776 synchronized (mLock) { 777 mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget(); 778 } 779 } 780 781 @Override handleSystemKey(int key)782 public void handleSystemKey(int key) { 783 synchronized (mLock) { 784 mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key, 0).sendToTarget(); 785 } 786 } 787 788 @Override showPinningEnterExitToast(boolean entering)789 public void showPinningEnterExitToast(boolean entering) { 790 synchronized (mLock) { 791 mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget(); 792 } 793 } 794 795 @Override showPinningEscapeToast()796 public void showPinningEscapeToast() { 797 synchronized (mLock) { 798 mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget(); 799 } 800 } 801 802 803 @Override showGlobalActionsMenu()804 public void showGlobalActionsMenu() { 805 synchronized (mLock) { 806 mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS); 807 mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget(); 808 } 809 } 810 811 @Override setTopAppHidesStatusBar(boolean hidesStatusBar)812 public void setTopAppHidesStatusBar(boolean hidesStatusBar) { 813 mHandler.removeMessages(MSG_SET_TOP_APP_HIDES_STATUS_BAR); 814 mHandler.obtainMessage(MSG_SET_TOP_APP_HIDES_STATUS_BAR, hidesStatusBar ? 1 : 0, 0) 815 .sendToTarget(); 816 } 817 818 @Override showShutdownUi(boolean isReboot, String reason)819 public void showShutdownUi(boolean isReboot, String reason) { 820 synchronized (mLock) { 821 mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI); 822 mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason) 823 .sendToTarget(); 824 } 825 } 826 827 @Override showWirelessChargingAnimation(int batteryLevel)828 public void showWirelessChargingAnimation(int batteryLevel) { 829 mHandler.removeMessages(MSG_SHOW_CHARGING_ANIMATION); 830 mHandler.obtainMessage(MSG_SHOW_CHARGING_ANIMATION, batteryLevel, 0) 831 .sendToTarget(); 832 } 833 834 @Override onProposedRotationChanged(int rotation, boolean isValid)835 public void onProposedRotationChanged(int rotation, boolean isValid) { 836 synchronized (mLock) { 837 mHandler.removeMessages(MSG_ROTATION_PROPOSAL); 838 mHandler.obtainMessage(MSG_ROTATION_PROPOSAL, rotation, isValid ? 1 : 0, 839 null).sendToTarget(); 840 } 841 } 842 843 @Override showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId, @BiometricMultiSensorMode int multiSensorConfig)844 public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, 845 int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, 846 int userId, String opPackageName, long operationId, 847 @BiometricMultiSensorMode int multiSensorConfig) { 848 synchronized (mLock) { 849 SomeArgs args = SomeArgs.obtain(); 850 args.arg1 = promptInfo; 851 args.arg2 = receiver; 852 args.arg3 = sensorIds; 853 args.arg4 = credentialAllowed; 854 args.arg5 = requireConfirmation; 855 args.argi1 = userId; 856 args.arg6 = opPackageName; 857 args.arg7 = operationId; 858 args.argi2 = multiSensorConfig; 859 mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args) 860 .sendToTarget(); 861 } 862 } 863 864 @Override showToast(int uid, String packageName, IBinder token, CharSequence text, IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback)865 public void showToast(int uid, String packageName, IBinder token, CharSequence text, 866 IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback) { 867 synchronized (mLock) { 868 SomeArgs args = SomeArgs.obtain(); 869 args.arg1 = packageName; 870 args.arg2 = token; 871 args.arg3 = text; 872 args.arg4 = windowToken; 873 args.arg5 = callback; 874 args.argi1 = uid; 875 args.argi2 = duration; 876 mHandler.obtainMessage(MSG_SHOW_TOAST, args).sendToTarget(); 877 } 878 } 879 880 @Override hideToast(String packageName, IBinder token)881 public void hideToast(String packageName, IBinder token) { 882 synchronized (mLock) { 883 SomeArgs args = SomeArgs.obtain(); 884 args.arg1 = packageName; 885 args.arg2 = token; 886 mHandler.obtainMessage(MSG_HIDE_TOAST, args).sendToTarget(); 887 } 888 } 889 890 @Override onBiometricAuthenticated()891 public void onBiometricAuthenticated() { 892 synchronized (mLock) { 893 mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget(); 894 } 895 } 896 897 @Override onBiometricHelp(@odality int modality, String message)898 public void onBiometricHelp(@Modality int modality, String message) { 899 synchronized (mLock) { 900 SomeArgs args = SomeArgs.obtain(); 901 args.argi1 = modality; 902 args.arg1 = message; 903 mHandler.obtainMessage(MSG_BIOMETRIC_HELP, args).sendToTarget(); 904 } 905 } 906 907 @Override onBiometricError(int modality, int error, int vendorCode)908 public void onBiometricError(int modality, int error, int vendorCode) { 909 synchronized (mLock) { 910 SomeArgs args = SomeArgs.obtain(); 911 args.argi1 = modality; 912 args.argi2 = error; 913 args.argi3 = vendorCode; 914 mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, args).sendToTarget(); 915 } 916 } 917 918 @Override hideAuthenticationDialog()919 public void hideAuthenticationDialog() { 920 synchronized (mLock) { 921 mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget(); 922 } 923 } 924 925 @Override setUdfpsHbmListener(IUdfpsHbmListener listener)926 public void setUdfpsHbmListener(IUdfpsHbmListener listener) { 927 synchronized (mLock) { 928 mHandler.obtainMessage(MSG_SET_UDFPS_HBM_LISTENER, listener).sendToTarget(); 929 } 930 } 931 932 @Override onDisplayReady(int displayId)933 public void onDisplayReady(int displayId) { 934 synchronized (mLock) { 935 mHandler.obtainMessage(MSG_DISPLAY_READY, displayId, 0).sendToTarget(); 936 } 937 } 938 939 @Override onRecentsAnimationStateChanged(boolean running)940 public void onRecentsAnimationStateChanged(boolean running) { 941 synchronized (mLock) { 942 mHandler.obtainMessage(MSG_RECENTS_ANIMATION_STATE_CHANGED, running ? 1 : 0, 0) 943 .sendToTarget(); 944 } 945 } 946 947 @Override showInattentiveSleepWarning()948 public void showInattentiveSleepWarning() { 949 synchronized (mLock) { 950 mHandler.obtainMessage(MSG_SHOW_INATTENTIVE_SLEEP_WARNING) 951 .sendToTarget(); 952 } 953 } 954 955 @Override dismissInattentiveSleepWarning(boolean animated)956 public void dismissInattentiveSleepWarning(boolean animated) { 957 synchronized (mLock) { 958 mHandler.obtainMessage(MSG_DISMISS_INATTENTIVE_SLEEP_WARNING, animated) 959 .sendToTarget(); 960 } 961 } 962 963 @Override requestWindowMagnificationConnection(boolean connect)964 public void requestWindowMagnificationConnection(boolean connect) { 965 synchronized (mLock) { 966 mHandler.obtainMessage(MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION, connect) 967 .sendToTarget(); 968 } 969 } 970 handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher, boolean isMultiClientImeEnabled)971 private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, 972 boolean showImeSwitcher, boolean isMultiClientImeEnabled) { 973 if (displayId == INVALID_DISPLAY) return; 974 975 if (!isMultiClientImeEnabled && mLastUpdatedImeDisplayId != displayId 976 && mLastUpdatedImeDisplayId != INVALID_DISPLAY) { 977 // Set previous NavBar's IME window status as invisible when IME 978 // window switched to another display for single-session IME case. 979 sendImeInvisibleStatusForPrevNavBar(); 980 } 981 for (int i = 0; i < mCallbacks.size(); i++) { 982 mCallbacks.get(i).setImeWindowStatus(displayId, token, vis, backDisposition, 983 showImeSwitcher); 984 } 985 mLastUpdatedImeDisplayId = displayId; 986 } 987 sendImeInvisibleStatusForPrevNavBar()988 private void sendImeInvisibleStatusForPrevNavBar() { 989 for (int i = 0; i < mCallbacks.size(); i++) { 990 mCallbacks.get(i).setImeWindowStatus(mLastUpdatedImeDisplayId, 991 null /* token */, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, 992 false /* showImeSwitcher */); 993 } 994 } 995 996 @Override onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, boolean isFullscreen)997 public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, 998 AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, 999 @Behavior int behavior, boolean isFullscreen) { 1000 synchronized (mLock) { 1001 SomeArgs args = SomeArgs.obtain(); 1002 args.argi1 = displayId; 1003 args.argi2 = appearance; 1004 args.argi3 = navbarColorManagedByIme ? 1 : 0; 1005 args.arg1 = appearanceRegions; 1006 args.argi4 = behavior; 1007 args.argi5 = isFullscreen ? 1 : 0; 1008 mHandler.obtainMessage(MSG_SYSTEM_BAR_CHANGED, args).sendToTarget(); 1009 } 1010 } 1011 1012 @Override showTransient(int displayId, int[] types)1013 public void showTransient(int displayId, int[] types) { 1014 synchronized (mLock) { 1015 mHandler.obtainMessage(MSG_SHOW_TRANSIENT, displayId, 0, types).sendToTarget(); 1016 } 1017 } 1018 1019 @Override abortTransient(int displayId, int[] types)1020 public void abortTransient(int displayId, int[] types) { 1021 synchronized (mLock) { 1022 mHandler.obtainMessage(MSG_ABORT_TRANSIENT, displayId, 0, types).sendToTarget(); 1023 } 1024 } 1025 1026 @Override startTracing()1027 public void startTracing() { 1028 synchronized (mLock) { 1029 if (mProtoTracer != null) { 1030 mProtoTracer.start(); 1031 } 1032 mHandler.obtainMessage(MSG_TRACING_STATE_CHANGED, true).sendToTarget(); 1033 } 1034 } 1035 1036 @Override stopTracing()1037 public void stopTracing() { 1038 synchronized (mLock) { 1039 if (mProtoTracer != null) { 1040 mProtoTracer.stop(); 1041 } 1042 mHandler.obtainMessage(MSG_TRACING_STATE_CHANGED, false).sendToTarget(); 1043 } 1044 } 1045 1046 @Override handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd)1047 public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) { 1048 synchronized (mLock) { 1049 SomeArgs internalArgs = SomeArgs.obtain(); 1050 internalArgs.arg1 = args; 1051 internalArgs.arg2 = outFd; 1052 mHandler.obtainMessage(MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND, internalArgs) 1053 .sendToTarget(); 1054 } 1055 } 1056 1057 @Override suppressAmbientDisplay(boolean suppress)1058 public void suppressAmbientDisplay(boolean suppress) { 1059 synchronized (mLock) { 1060 mHandler.obtainMessage(MSG_SUPPRESS_AMBIENT_DISPLAY, suppress).sendToTarget(); 1061 } 1062 } 1063 1064 @Override setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)1065 public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) { 1066 synchronized (mLock) { 1067 mHandler.obtainMessage(MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED, displayId, 1068 enable ? 1 : 0).sendToTarget(); 1069 } 1070 } 1071 1072 @Override passThroughShellCommand(String[] args, ParcelFileDescriptor pfd)1073 public void passThroughShellCommand(String[] args, ParcelFileDescriptor pfd) { 1074 final FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor()); 1075 final PrintWriter pw = new PrintWriter(fos); 1076 // This is mimicking Binder#dumpAsync, but on this side of the binder. Might be possible 1077 // to just throw this work onto the handler just like the other messages 1078 Thread thr = new Thread("Sysui.passThroughShellCommand") { 1079 public void run() { 1080 try { 1081 if (mRegistry == null) { 1082 return; 1083 } 1084 1085 // Registry blocks this thread until finished 1086 mRegistry.onShellCommand(pw, args); 1087 } finally { 1088 pw.flush(); 1089 try { 1090 // Close the file descriptor so the TransferPipe finishes its thread 1091 pfd.close(); 1092 } catch (Exception e) { 1093 } 1094 } 1095 } 1096 }; 1097 thr.start(); 1098 } 1099 1100 @Override runGcForTest()1101 public void runGcForTest() { 1102 // Gc sysui 1103 GcUtils.runGcAndFinalizersSync(); 1104 } 1105 1106 private final class H extends Handler { H(Looper l)1107 private H(Looper l) { 1108 super(l); 1109 } 1110 handleMessage(Message msg)1111 public void handleMessage(Message msg) { 1112 final int what = msg.what & MSG_MASK; 1113 switch (what) { 1114 case MSG_ICON: { 1115 switch (msg.arg1) { 1116 case OP_SET_ICON: { 1117 Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj; 1118 for (int i = 0; i < mCallbacks.size(); i++) { 1119 mCallbacks.get(i).setIcon(p.first, p.second); 1120 } 1121 break; 1122 } 1123 case OP_REMOVE_ICON: 1124 for (int i = 0; i < mCallbacks.size(); i++) { 1125 mCallbacks.get(i).removeIcon((String) msg.obj); 1126 } 1127 break; 1128 } 1129 break; 1130 } 1131 case MSG_DISABLE: 1132 SomeArgs args = (SomeArgs) msg.obj; 1133 for (int i = 0; i < mCallbacks.size(); i++) { 1134 mCallbacks.get(i).disable(args.argi1, args.argi2, args.argi3, 1135 args.argi4 != 0 /* animate */); 1136 } 1137 break; 1138 case MSG_EXPAND_NOTIFICATIONS: 1139 for (int i = 0; i < mCallbacks.size(); i++) { 1140 mCallbacks.get(i).animateExpandNotificationsPanel(); 1141 } 1142 break; 1143 case MSG_COLLAPSE_PANELS: 1144 for (int i = 0; i < mCallbacks.size(); i++) { 1145 mCallbacks.get(i).animateCollapsePanels(msg.arg1, msg.arg2 != 0); 1146 } 1147 break; 1148 case MSG_TOGGLE_PANEL: 1149 for (int i = 0; i < mCallbacks.size(); i++) { 1150 mCallbacks.get(i).togglePanel(); 1151 } 1152 break; 1153 case MSG_EXPAND_SETTINGS: 1154 for (int i = 0; i < mCallbacks.size(); i++) { 1155 mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj); 1156 } 1157 break; 1158 case MSG_SHOW_IME_BUTTON: 1159 args = (SomeArgs) msg.obj; 1160 handleShowImeButton(args.argi1 /* displayId */, (IBinder) args.arg1 /* token */, 1161 args.argi2 /* vis */, args.argi3 /* backDisposition */, 1162 args.argi4 != 0 /* showImeSwitcher */, 1163 args.argi5 != 0 /* isMultiClientImeEnabled */); 1164 break; 1165 case MSG_SHOW_RECENT_APPS: 1166 for (int i = 0; i < mCallbacks.size(); i++) { 1167 mCallbacks.get(i).showRecentApps(msg.arg1 != 0); 1168 } 1169 break; 1170 case MSG_HIDE_RECENT_APPS: 1171 for (int i = 0; i < mCallbacks.size(); i++) { 1172 mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0); 1173 } 1174 break; 1175 case MSG_TOGGLE_RECENT_APPS: 1176 for (int i = 0; i < mCallbacks.size(); i++) { 1177 mCallbacks.get(i).toggleRecentApps(); 1178 } 1179 break; 1180 case MSG_PRELOAD_RECENT_APPS: 1181 for (int i = 0; i < mCallbacks.size(); i++) { 1182 mCallbacks.get(i).preloadRecentApps(); 1183 } 1184 break; 1185 case MSG_CANCEL_PRELOAD_RECENT_APPS: 1186 for (int i = 0; i < mCallbacks.size(); i++) { 1187 mCallbacks.get(i).cancelPreloadRecentApps(); 1188 } 1189 break; 1190 case MSG_DISMISS_KEYBOARD_SHORTCUTS: 1191 for (int i = 0; i < mCallbacks.size(); i++) { 1192 mCallbacks.get(i).dismissKeyboardShortcutsMenu(); 1193 } 1194 break; 1195 case MSG_TOGGLE_KEYBOARD_SHORTCUTS: 1196 for (int i = 0; i < mCallbacks.size(); i++) { 1197 mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1); 1198 } 1199 break; 1200 case MSG_SET_WINDOW_STATE: 1201 for (int i = 0; i < mCallbacks.size(); i++) { 1202 mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2, (int) msg.obj); 1203 } 1204 break; 1205 case MSG_SHOW_SCREEN_PIN_REQUEST: 1206 for (int i = 0; i < mCallbacks.size(); i++) { 1207 mCallbacks.get(i).showScreenPinningRequest(msg.arg1); 1208 } 1209 break; 1210 case MSG_APP_TRANSITION_PENDING: 1211 for (int i = 0; i < mCallbacks.size(); i++) { 1212 mCallbacks.get(i).appTransitionPending(msg.arg1, msg.arg2 != 0); 1213 } 1214 break; 1215 case MSG_APP_TRANSITION_CANCELLED: 1216 for (int i = 0; i < mCallbacks.size(); i++) { 1217 mCallbacks.get(i).appTransitionCancelled(msg.arg1); 1218 } 1219 break; 1220 case MSG_APP_TRANSITION_STARTING: 1221 args = (SomeArgs) msg.obj; 1222 for (int i = 0; i < mCallbacks.size(); i++) { 1223 mCallbacks.get(i).appTransitionStarting(args.argi1, (long) args.arg1, 1224 (long) args.arg2, args.argi2 != 0 /* forced */); 1225 } 1226 break; 1227 case MSG_APP_TRANSITION_FINISHED: 1228 for (int i = 0; i < mCallbacks.size(); i++) { 1229 mCallbacks.get(i).appTransitionFinished(msg.arg1); 1230 } 1231 break; 1232 case MSG_ASSIST_DISCLOSURE: 1233 for (int i = 0; i < mCallbacks.size(); i++) { 1234 mCallbacks.get(i).showAssistDisclosure(); 1235 } 1236 break; 1237 case MSG_START_ASSIST: 1238 for (int i = 0; i < mCallbacks.size(); i++) { 1239 mCallbacks.get(i).startAssist((Bundle) msg.obj); 1240 } 1241 break; 1242 case MSG_CAMERA_LAUNCH_GESTURE: 1243 for (int i = 0; i < mCallbacks.size(); i++) { 1244 mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1); 1245 } 1246 break; 1247 case MSG_EMERGENCY_ACTION_LAUNCH_GESTURE: 1248 for (int i = 0; i < mCallbacks.size(); i++) { 1249 mCallbacks.get(i).onEmergencyActionLaunchGestureDetected(); 1250 } 1251 break; 1252 case MSG_SHOW_PICTURE_IN_PICTURE_MENU: 1253 for (int i = 0; i < mCallbacks.size(); i++) { 1254 mCallbacks.get(i).showPictureInPictureMenu(); 1255 } 1256 break; 1257 case MSG_ADD_QS_TILE: 1258 for (int i = 0; i < mCallbacks.size(); i++) { 1259 mCallbacks.get(i).addQsTile((ComponentName) msg.obj); 1260 } 1261 break; 1262 case MSG_REMOVE_QS_TILE: 1263 for (int i = 0; i < mCallbacks.size(); i++) { 1264 mCallbacks.get(i).remQsTile((ComponentName) msg.obj); 1265 } 1266 break; 1267 case MSG_CLICK_QS_TILE: 1268 for (int i = 0; i < mCallbacks.size(); i++) { 1269 mCallbacks.get(i).clickTile((ComponentName) msg.obj); 1270 } 1271 break; 1272 case MSG_TOGGLE_APP_SPLIT_SCREEN: 1273 for (int i = 0; i < mCallbacks.size(); i++) { 1274 mCallbacks.get(i).toggleSplitScreen(); 1275 } 1276 break; 1277 case MSG_HANDLE_SYSTEM_KEY: 1278 for (int i = 0; i < mCallbacks.size(); i++) { 1279 mCallbacks.get(i).handleSystemKey(msg.arg1); 1280 } 1281 break; 1282 case MSG_SHOW_GLOBAL_ACTIONS: 1283 for (int i = 0; i < mCallbacks.size(); i++) { 1284 mCallbacks.get(i).handleShowGlobalActionsMenu(); 1285 } 1286 break; 1287 case MSG_SHOW_SHUTDOWN_UI: 1288 for (int i = 0; i < mCallbacks.size(); i++) { 1289 mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj); 1290 } 1291 break; 1292 case MSG_SET_TOP_APP_HIDES_STATUS_BAR: 1293 for (int i = 0; i < mCallbacks.size(); i++) { 1294 mCallbacks.get(i).setTopAppHidesStatusBar(msg.arg1 != 0); 1295 } 1296 break; 1297 case MSG_ROTATION_PROPOSAL: 1298 for (int i = 0; i < mCallbacks.size(); i++) { 1299 mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0); 1300 } 1301 break; 1302 case MSG_BIOMETRIC_SHOW: { 1303 mHandler.removeMessages(MSG_BIOMETRIC_ERROR); 1304 mHandler.removeMessages(MSG_BIOMETRIC_HELP); 1305 mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED); 1306 SomeArgs someArgs = (SomeArgs) msg.obj; 1307 for (int i = 0; i < mCallbacks.size(); i++) { 1308 mCallbacks.get(i).showAuthenticationDialog( 1309 (PromptInfo) someArgs.arg1, 1310 (IBiometricSysuiReceiver) someArgs.arg2, 1311 (int[]) someArgs.arg3 /* sensorIds */, 1312 (boolean) someArgs.arg4 /* credentialAllowed */, 1313 (boolean) someArgs.arg5 /* requireConfirmation */, 1314 someArgs.argi1 /* userId */, 1315 (String) someArgs.arg6 /* opPackageName */, 1316 (long) someArgs.arg7 /* operationId */, 1317 someArgs.argi2 /* multiSensorConfig */); 1318 } 1319 someArgs.recycle(); 1320 break; 1321 } 1322 case MSG_BIOMETRIC_AUTHENTICATED: { 1323 for (int i = 0; i < mCallbacks.size(); i++) { 1324 mCallbacks.get(i).onBiometricAuthenticated(); 1325 } 1326 break; 1327 } 1328 case MSG_BIOMETRIC_HELP: { 1329 SomeArgs someArgs = (SomeArgs) msg.obj; 1330 for (int i = 0; i < mCallbacks.size(); i++) { 1331 mCallbacks.get(i).onBiometricHelp( 1332 someArgs.argi1 /* modality */, 1333 (String) someArgs.arg1 /* message */); 1334 } 1335 someArgs.recycle(); 1336 break; 1337 } 1338 case MSG_BIOMETRIC_ERROR: { 1339 SomeArgs someArgs = (SomeArgs) msg.obj; 1340 for (int i = 0; i < mCallbacks.size(); i++) { 1341 mCallbacks.get(i).onBiometricError( 1342 someArgs.argi1 /* modality */, 1343 someArgs.argi2 /* error */, 1344 someArgs.argi3 /* vendorCode */ 1345 ); 1346 } 1347 someArgs.recycle(); 1348 break; 1349 } 1350 case MSG_BIOMETRIC_HIDE: 1351 for (int i = 0; i < mCallbacks.size(); i++) { 1352 mCallbacks.get(i).hideAuthenticationDialog(); 1353 } 1354 break; 1355 case MSG_SET_UDFPS_HBM_LISTENER: 1356 for (int i = 0; i < mCallbacks.size(); i++) { 1357 mCallbacks.get(i).setUdfpsHbmListener((IUdfpsHbmListener) msg.obj); 1358 } 1359 break; 1360 case MSG_SHOW_CHARGING_ANIMATION: 1361 for (int i = 0; i < mCallbacks.size(); i++) { 1362 mCallbacks.get(i).showWirelessChargingAnimation(msg.arg1); 1363 } 1364 break; 1365 case MSG_SHOW_PINNING_TOAST_ENTER_EXIT: 1366 for (int i = 0; i < mCallbacks.size(); i++) { 1367 mCallbacks.get(i).showPinningEnterExitToast((Boolean) msg.obj); 1368 } 1369 break; 1370 case MSG_SHOW_PINNING_TOAST_ESCAPE: 1371 for (int i = 0; i < mCallbacks.size(); i++) { 1372 mCallbacks.get(i).showPinningEscapeToast(); 1373 } 1374 break; 1375 case MSG_DISPLAY_READY: 1376 for (int i = 0; i < mCallbacks.size(); i++) { 1377 mCallbacks.get(i).onDisplayReady(msg.arg1); 1378 } 1379 break; 1380 case MSG_RECENTS_ANIMATION_STATE_CHANGED: 1381 for (int i = 0; i < mCallbacks.size(); i++) { 1382 mCallbacks.get(i).onRecentsAnimationStateChanged(msg.arg1 > 0); 1383 } 1384 break; 1385 case MSG_SYSTEM_BAR_CHANGED: 1386 args = (SomeArgs) msg.obj; 1387 for (int i = 0; i < mCallbacks.size(); i++) { 1388 mCallbacks.get(i).onSystemBarAttributesChanged(args.argi1, args.argi2, 1389 (AppearanceRegion[]) args.arg1, args.argi3 == 1, args.argi4, 1390 args.argi5 == 1); 1391 } 1392 args.recycle(); 1393 break; 1394 case MSG_SHOW_TRANSIENT: { 1395 final int displayId = msg.arg1; 1396 final int[] types = (int[]) msg.obj; 1397 for (int i = 0; i < mCallbacks.size(); i++) { 1398 mCallbacks.get(i).showTransient(displayId, types); 1399 } 1400 break; 1401 } 1402 case MSG_ABORT_TRANSIENT: { 1403 final int displayId = msg.arg1; 1404 final int[] types = (int[]) msg.obj; 1405 for (int i = 0; i < mCallbacks.size(); i++) { 1406 mCallbacks.get(i).abortTransient(displayId, types); 1407 } 1408 break; 1409 } 1410 case MSG_SHOW_INATTENTIVE_SLEEP_WARNING: 1411 for (int i = 0; i < mCallbacks.size(); i++) { 1412 mCallbacks.get(i).showInattentiveSleepWarning(); 1413 } 1414 break; 1415 case MSG_DISMISS_INATTENTIVE_SLEEP_WARNING: 1416 for (int i = 0; i < mCallbacks.size(); i++) { 1417 mCallbacks.get(i).dismissInattentiveSleepWarning((Boolean) msg.obj); 1418 } 1419 break; 1420 case MSG_SHOW_TOAST: { 1421 args = (SomeArgs) msg.obj; 1422 String packageName = (String) args.arg1; 1423 IBinder token = (IBinder) args.arg2; 1424 CharSequence text = (CharSequence) args.arg3; 1425 IBinder windowToken = (IBinder) args.arg4; 1426 ITransientNotificationCallback callback = 1427 (ITransientNotificationCallback) args.arg5; 1428 int uid = args.argi1; 1429 int duration = args.argi2; 1430 for (Callbacks callbacks : mCallbacks) { 1431 callbacks.showToast(uid, packageName, token, text, windowToken, duration, 1432 callback); 1433 } 1434 break; 1435 } 1436 case MSG_HIDE_TOAST: { 1437 args = (SomeArgs) msg.obj; 1438 String packageName = (String) args.arg1; 1439 IBinder token = (IBinder) args.arg2; 1440 for (Callbacks callbacks : mCallbacks) { 1441 callbacks.hideToast(packageName, token); 1442 } 1443 break; 1444 } 1445 case MSG_TRACING_STATE_CHANGED: 1446 for (int i = 0; i < mCallbacks.size(); i++) { 1447 mCallbacks.get(i).onTracingStateChanged((Boolean) msg.obj); 1448 } 1449 break; 1450 case MSG_SUPPRESS_AMBIENT_DISPLAY: 1451 for (Callbacks callbacks: mCallbacks) { 1452 callbacks.suppressAmbientDisplay((boolean) msg.obj); 1453 } 1454 break; 1455 case MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION: 1456 for (int i = 0; i < mCallbacks.size(); i++) { 1457 mCallbacks.get(i).requestWindowMagnificationConnection((Boolean) msg.obj); 1458 } 1459 break; 1460 case MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND: 1461 args = (SomeArgs) msg.obj; 1462 try (ParcelFileDescriptor pfd = (ParcelFileDescriptor) args.arg2) { 1463 for (int i = 0; i < mCallbacks.size(); i++) { 1464 mCallbacks.get(i).handleWindowManagerLoggingCommand( 1465 (String[]) args.arg1, pfd); 1466 } 1467 } catch (IOException e) { 1468 Log.e(TAG, "Failed to handle logging command", e); 1469 } 1470 args.recycle(); 1471 break; 1472 case MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED: 1473 for (int i = 0; i < mCallbacks.size(); i++) { 1474 mCallbacks.get(i).setNavigationBarLumaSamplingEnabled(msg.arg1, 1475 msg.arg2 != 0); 1476 } 1477 break; 1478 } 1479 } 1480 } 1481 } 1482