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 android.content.ComponentName; 20 import android.graphics.Rect; 21 import android.hardware.biometrics.IBiometricPromptReceiver; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.os.IBinder; 25 import android.os.Looper; 26 import android.os.Message; 27 import android.os.RemoteException; 28 import android.support.annotation.VisibleForTesting; 29 import android.util.Pair; 30 31 import com.android.internal.os.SomeArgs; 32 import com.android.internal.statusbar.IStatusBar; 33 import com.android.internal.statusbar.StatusBarIcon; 34 import com.android.systemui.SystemUI; 35 36 import java.util.ArrayList; 37 38 /** 39 * This class takes the functions from IStatusBar that come in on 40 * binder pool threads and posts messages to get them onto the main 41 * thread, and calls onto Callbacks. It also takes care of 42 * coalescing these calls so they don't stack up. For the calls 43 * are coalesced, note that they are all idempotent. 44 */ 45 public class CommandQueue extends IStatusBar.Stub { 46 private static final int INDEX_MASK = 0xffff; 47 private static final int MSG_SHIFT = 16; 48 private static final int MSG_MASK = 0xffff << MSG_SHIFT; 49 50 private static final int OP_SET_ICON = 1; 51 private static final int OP_REMOVE_ICON = 2; 52 53 private static final int MSG_ICON = 1 << MSG_SHIFT; 54 private static final int MSG_DISABLE = 2 << MSG_SHIFT; 55 private static final int MSG_EXPAND_NOTIFICATIONS = 3 << MSG_SHIFT; 56 private static final int MSG_COLLAPSE_PANELS = 4 << MSG_SHIFT; 57 private static final int MSG_EXPAND_SETTINGS = 5 << MSG_SHIFT; 58 private static final int MSG_SET_SYSTEMUI_VISIBILITY = 6 << MSG_SHIFT; 59 private static final int MSG_TOP_APP_WINDOW_CHANGED = 7 << MSG_SHIFT; 60 private static final int MSG_SHOW_IME_BUTTON = 8 << MSG_SHIFT; 61 private static final int MSG_TOGGLE_RECENT_APPS = 9 << MSG_SHIFT; 62 private static final int MSG_PRELOAD_RECENT_APPS = 10 << MSG_SHIFT; 63 private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 11 << MSG_SHIFT; 64 private static final int MSG_SET_WINDOW_STATE = 12 << MSG_SHIFT; 65 private static final int MSG_SHOW_RECENT_APPS = 13 << MSG_SHIFT; 66 private static final int MSG_HIDE_RECENT_APPS = 14 << MSG_SHIFT; 67 private static final int MSG_SHOW_SCREEN_PIN_REQUEST = 18 << MSG_SHIFT; 68 private static final int MSG_APP_TRANSITION_PENDING = 19 << MSG_SHIFT; 69 private static final int MSG_APP_TRANSITION_CANCELLED = 20 << MSG_SHIFT; 70 private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT; 71 private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT; 72 private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; 73 private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; 74 private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS = 25 << MSG_SHIFT; 75 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 26 << MSG_SHIFT; 76 private static final int MSG_ADD_QS_TILE = 27 << MSG_SHIFT; 77 private static final int MSG_REMOVE_QS_TILE = 28 << MSG_SHIFT; 78 private static final int MSG_CLICK_QS_TILE = 29 << MSG_SHIFT; 79 private static final int MSG_TOGGLE_APP_SPLIT_SCREEN = 30 << MSG_SHIFT; 80 private static final int MSG_APP_TRANSITION_FINISHED = 31 << MSG_SHIFT; 81 private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS = 32 << MSG_SHIFT; 82 private static final int MSG_HANDLE_SYSTEM_KEY = 33 << MSG_SHIFT; 83 private static final int MSG_SHOW_GLOBAL_ACTIONS = 34 << MSG_SHIFT; 84 private static final int MSG_TOGGLE_PANEL = 35 << MSG_SHIFT; 85 private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT; 86 private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR = 37 << MSG_SHIFT; 87 private static final int MSG_ROTATION_PROPOSAL = 38 << MSG_SHIFT; 88 private static final int MSG_FINGERPRINT_SHOW = 39 << MSG_SHIFT; 89 private static final int MSG_FINGERPRINT_AUTHENTICATED = 40 << MSG_SHIFT; 90 private static final int MSG_FINGERPRINT_HELP = 41 << MSG_SHIFT; 91 private static final int MSG_FINGERPRINT_ERROR = 42 << MSG_SHIFT; 92 private static final int MSG_FINGERPRINT_HIDE = 43 << MSG_SHIFT; 93 private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT; 94 private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT; 95 private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT; 96 97 public static final int FLAG_EXCLUDE_NONE = 0; 98 public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; 99 public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1; 100 public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2; 101 public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3; 102 public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4; 103 104 private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey"; 105 106 private final Object mLock = new Object(); 107 private ArrayList<Callbacks> mCallbacks = new ArrayList<>(); 108 private Handler mHandler = new H(Looper.getMainLooper()); 109 private int mDisable1; 110 private int mDisable2; 111 112 /** 113 * These methods are called back on the main thread. 114 */ 115 public interface Callbacks { 116 default void setIcon(String slot, StatusBarIcon icon) { } 117 default void removeIcon(String slot) { } 118 default void disable(int state1, int state2, boolean animate) { } 119 default void animateExpandNotificationsPanel() { } 120 default void animateCollapsePanels(int flags) { } 121 default void togglePanel() { } 122 default void animateExpandSettingsPanel(String obj) { } 123 default void setSystemUiVisibility(int vis, int fullscreenStackVis, 124 int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) { 125 } 126 default void topAppWindowChanged(boolean visible) { } 127 default void setImeWindowStatus(IBinder token, int vis, int backDisposition, 128 boolean showImeSwitcher) { } 129 default void showRecentApps(boolean triggeredFromAltTab) { } 130 default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } 131 default void toggleRecentApps() { } 132 default void toggleSplitScreen() { } 133 default void preloadRecentApps() { } 134 default void dismissKeyboardShortcutsMenu() { } 135 default void toggleKeyboardShortcutsMenu(int deviceId) { } 136 default void cancelPreloadRecentApps() { } 137 default void setWindowState(int window, int state) { } 138 default void showScreenPinningRequest(int taskId) { } 139 default void appTransitionPending(boolean forced) { } 140 default void appTransitionCancelled() { } 141 default void appTransitionStarting(long startTime, long duration, boolean forced) { } 142 default void appTransitionFinished() { } 143 default void showAssistDisclosure() { } 144 default void startAssist(Bundle args) { } 145 default void onCameraLaunchGestureDetected(int source) { } 146 default void showPictureInPictureMenu() { } 147 default void setTopAppHidesStatusBar(boolean topAppHidesStatusBar) { } 148 149 default void addQsTile(ComponentName tile) { } 150 default void remQsTile(ComponentName tile) { } 151 default void clickTile(ComponentName tile) { } 152 153 default void handleSystemKey(int arg1) { } 154 default void showPinningEnterExitToast(boolean entering) { } 155 default void showPinningEscapeToast() { } 156 default void handleShowGlobalActionsMenu() { } 157 default void handleShowShutdownUi(boolean isReboot, String reason) { } 158 159 default void showWirelessChargingAnimation(int batteryLevel) { } 160 161 default void onRotationProposal(int rotation, boolean isValid) { } 162 163 default void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) { } 164 default void onFingerprintAuthenticated() { } 165 default void onFingerprintHelp(String message) { } 166 default void onFingerprintError(String error) { } 167 default void hideFingerprintDialog() { } 168 } 169 170 @VisibleForTesting 171 protected CommandQueue() { 172 } 173 174 public void addCallbacks(Callbacks callbacks) { 175 mCallbacks.add(callbacks); 176 callbacks.disable(mDisable1, mDisable2, false /* animate */); 177 } 178 179 public void removeCallbacks(Callbacks callbacks) { 180 mCallbacks.remove(callbacks); 181 } 182 183 public void setIcon(String slot, StatusBarIcon icon) { 184 synchronized (mLock) { 185 // don't coalesce these 186 mHandler.obtainMessage(MSG_ICON, OP_SET_ICON, 0, 187 new Pair<String, StatusBarIcon>(slot, icon)).sendToTarget(); 188 } 189 } 190 191 public void removeIcon(String slot) { 192 synchronized (mLock) { 193 // don't coalesce these 194 mHandler.obtainMessage(MSG_ICON, OP_REMOVE_ICON, 0, slot).sendToTarget(); 195 } 196 } 197 198 public void disable(int state1, int state2, boolean animate) { 199 synchronized (mLock) { 200 mDisable1 = state1; 201 mDisable2 = state2; 202 mHandler.removeMessages(MSG_DISABLE); 203 Message msg = mHandler.obtainMessage(MSG_DISABLE, state1, state2, animate); 204 if (Looper.myLooper() == mHandler.getLooper()) { 205 // If its the right looper execute immediately so hides can be handled quickly. 206 mHandler.handleMessage(msg); 207 msg.recycle(); 208 } else { 209 msg.sendToTarget(); 210 } 211 } 212 } 213 214 public void disable(int state1, int state2) { 215 disable(state1, state2, true); 216 } 217 218 public void recomputeDisableFlags(boolean animate) { 219 disable(mDisable1, mDisable2, animate); 220 } 221 222 public void animateExpandNotificationsPanel() { 223 synchronized (mLock) { 224 mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS); 225 mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS); 226 } 227 } 228 229 public void animateCollapsePanels() { 230 synchronized (mLock) { 231 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 232 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, 0, 0).sendToTarget(); 233 } 234 } 235 236 public void animateCollapsePanels(int flags) { 237 synchronized (mLock) { 238 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 239 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, 0).sendToTarget(); 240 } 241 } 242 243 public void togglePanel() { 244 synchronized (mLock) { 245 mHandler.removeMessages(MSG_TOGGLE_PANEL); 246 mHandler.obtainMessage(MSG_TOGGLE_PANEL, 0, 0).sendToTarget(); 247 } 248 } 249 250 public void animateExpandSettingsPanel(String subPanel) { 251 synchronized (mLock) { 252 mHandler.removeMessages(MSG_EXPAND_SETTINGS); 253 mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget(); 254 } 255 } 256 257 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, 258 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) { 259 synchronized (mLock) { 260 // Don't coalesce these, since it might have one time flags set such as 261 // STATUS_BAR_UNHIDE which might get lost. 262 SomeArgs args = SomeArgs.obtain(); 263 args.argi1 = vis; 264 args.argi2 = fullscreenStackVis; 265 args.argi3 = dockedStackVis; 266 args.argi4 = mask; 267 args.arg1 = fullscreenStackBounds; 268 args.arg2 = dockedStackBounds; 269 mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, args).sendToTarget(); 270 } 271 } 272 273 public void topAppWindowChanged(boolean menuVisible) { 274 synchronized (mLock) { 275 mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED); 276 mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0, 277 null).sendToTarget(); 278 } 279 } 280 281 public void setImeWindowStatus(IBinder token, int vis, int backDisposition, 282 boolean showImeSwitcher) { 283 synchronized (mLock) { 284 mHandler.removeMessages(MSG_SHOW_IME_BUTTON); 285 Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, vis, backDisposition, token); 286 m.getData().putBoolean(SHOW_IME_SWITCHER_KEY, showImeSwitcher); 287 m.sendToTarget(); 288 } 289 } 290 291 public void showRecentApps(boolean triggeredFromAltTab) { 292 synchronized (mLock) { 293 mHandler.removeMessages(MSG_SHOW_RECENT_APPS); 294 mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, triggeredFromAltTab ? 1 : 0, 0, 295 null).sendToTarget(); 296 } 297 } 298 299 public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { 300 synchronized (mLock) { 301 mHandler.removeMessages(MSG_HIDE_RECENT_APPS); 302 mHandler.obtainMessage(MSG_HIDE_RECENT_APPS, 303 triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0, 304 null).sendToTarget(); 305 } 306 } 307 308 public void toggleSplitScreen() { 309 synchronized (mLock) { 310 mHandler.removeMessages(MSG_TOGGLE_APP_SPLIT_SCREEN); 311 mHandler.obtainMessage(MSG_TOGGLE_APP_SPLIT_SCREEN, 0, 0, null).sendToTarget(); 312 } 313 } 314 315 public void toggleRecentApps() { 316 synchronized (mLock) { 317 mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); 318 Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null); 319 msg.setAsynchronous(true); 320 msg.sendToTarget(); 321 } 322 } 323 324 public void preloadRecentApps() { 325 synchronized (mLock) { 326 mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS); 327 mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 328 } 329 } 330 331 public void cancelPreloadRecentApps() { 332 synchronized (mLock) { 333 mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS); 334 mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 335 } 336 } 337 338 @Override 339 public void dismissKeyboardShortcutsMenu() { 340 synchronized (mLock) { 341 mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS); 342 mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget(); 343 } 344 } 345 346 @Override 347 public void toggleKeyboardShortcutsMenu(int deviceId) { 348 synchronized (mLock) { 349 mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS); 350 mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget(); 351 } 352 } 353 354 @Override 355 public void showPictureInPictureMenu() { 356 synchronized (mLock) { 357 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 358 mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU).sendToTarget(); 359 } 360 } 361 362 public void setWindowState(int window, int state) { 363 synchronized (mLock) { 364 // don't coalesce these 365 mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget(); 366 } 367 } 368 369 public void showScreenPinningRequest(int taskId) { 370 synchronized (mLock) { 371 mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null) 372 .sendToTarget(); 373 } 374 } 375 376 public void appTransitionPending() { 377 appTransitionPending(false /* forced */); 378 } 379 380 public void appTransitionPending(boolean forced) { 381 synchronized (mLock) { 382 mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, forced ? 1 : 0, 0).sendToTarget(); 383 } 384 } 385 386 public void appTransitionCancelled() { 387 synchronized (mLock) { 388 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_CANCELLED); 389 } 390 } 391 392 public void appTransitionStarting(long startTime, long duration) { 393 appTransitionStarting(startTime, duration, false /* forced */); 394 } 395 396 public void appTransitionStarting(long startTime, long duration, boolean forced) { 397 synchronized (mLock) { 398 mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, forced ? 1 : 0, 0, 399 Pair.create(startTime, duration)).sendToTarget(); 400 } 401 } 402 403 @Override 404 public void appTransitionFinished() { 405 synchronized (mLock) { 406 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_FINISHED); 407 } 408 } 409 410 public void showAssistDisclosure() { 411 synchronized (mLock) { 412 mHandler.removeMessages(MSG_ASSIST_DISCLOSURE); 413 mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget(); 414 } 415 } 416 417 public void startAssist(Bundle args) { 418 synchronized (mLock) { 419 mHandler.removeMessages(MSG_START_ASSIST); 420 mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget(); 421 } 422 } 423 424 @Override 425 public void onCameraLaunchGestureDetected(int source) { 426 synchronized (mLock) { 427 mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE); 428 mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget(); 429 } 430 } 431 432 @Override 433 public void addQsTile(ComponentName tile) { 434 synchronized (mLock) { 435 mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget(); 436 } 437 } 438 439 @Override 440 public void remQsTile(ComponentName tile) { 441 synchronized (mLock) { 442 mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget(); 443 } 444 } 445 446 @Override 447 public void clickQsTile(ComponentName tile) { 448 synchronized (mLock) { 449 mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget(); 450 } 451 } 452 453 @Override 454 public void handleSystemKey(int key) { 455 synchronized (mLock) { 456 mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key, 0).sendToTarget(); 457 } 458 } 459 460 @Override 461 public void showPinningEnterExitToast(boolean entering) { 462 synchronized (mLock) { 463 mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget(); 464 } 465 } 466 467 @Override 468 public void showPinningEscapeToast() { 469 synchronized (mLock) { 470 mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget(); 471 } 472 } 473 474 475 @Override 476 public void showGlobalActionsMenu() { 477 synchronized (mLock) { 478 mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS); 479 mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget(); 480 } 481 } 482 483 @Override 484 public void setTopAppHidesStatusBar(boolean hidesStatusBar) { 485 mHandler.removeMessages(MSG_SET_TOP_APP_HIDES_STATUS_BAR); 486 mHandler.obtainMessage(MSG_SET_TOP_APP_HIDES_STATUS_BAR, hidesStatusBar ? 1 : 0, 0) 487 .sendToTarget(); 488 } 489 490 @Override 491 public void showShutdownUi(boolean isReboot, String reason) { 492 synchronized (mLock) { 493 mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI); 494 mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason) 495 .sendToTarget(); 496 } 497 } 498 499 @Override 500 public void showWirelessChargingAnimation(int batteryLevel) { 501 mHandler.removeMessages(MSG_SHOW_CHARGING_ANIMATION); 502 mHandler.obtainMessage(MSG_SHOW_CHARGING_ANIMATION, batteryLevel, 0) 503 .sendToTarget(); 504 } 505 506 @Override 507 public void onProposedRotationChanged(int rotation, boolean isValid) { 508 synchronized (mLock) { 509 mHandler.removeMessages(MSG_ROTATION_PROPOSAL); 510 mHandler.obtainMessage(MSG_ROTATION_PROPOSAL, rotation, isValid ? 1 : 0, 511 null).sendToTarget(); 512 } 513 } 514 515 @Override 516 public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) { 517 synchronized (mLock) { 518 SomeArgs args = SomeArgs.obtain(); 519 args.arg1 = bundle; 520 args.arg2 = receiver; 521 mHandler.obtainMessage(MSG_FINGERPRINT_SHOW, args) 522 .sendToTarget(); 523 } 524 } 525 526 @Override 527 public void onFingerprintAuthenticated() { 528 synchronized (mLock) { 529 mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget(); 530 } 531 } 532 533 @Override 534 public void onFingerprintHelp(String message) { 535 synchronized (mLock) { 536 mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget(); 537 } 538 } 539 540 @Override 541 public void onFingerprintError(String error) { 542 synchronized (mLock) { 543 mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget(); 544 } 545 } 546 547 @Override 548 public void hideFingerprintDialog() { 549 synchronized (mLock) { 550 mHandler.obtainMessage(MSG_FINGERPRINT_HIDE).sendToTarget(); 551 } 552 } 553 554 private final class H extends Handler { 555 private H(Looper l) { 556 super(l); 557 } 558 559 public void handleMessage(Message msg) { 560 final int what = msg.what & MSG_MASK; 561 switch (what) { 562 case MSG_ICON: { 563 switch (msg.arg1) { 564 case OP_SET_ICON: { 565 Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj; 566 for (int i = 0; i < mCallbacks.size(); i++) { 567 mCallbacks.get(i).setIcon(p.first, p.second); 568 } 569 break; 570 } 571 case OP_REMOVE_ICON: 572 for (int i = 0; i < mCallbacks.size(); i++) { 573 mCallbacks.get(i).removeIcon((String) msg.obj); 574 } 575 break; 576 } 577 break; 578 } 579 case MSG_DISABLE: 580 for (int i = 0; i < mCallbacks.size(); i++) { 581 mCallbacks.get(i).disable(msg.arg1, msg.arg2, (Boolean) msg.obj); 582 } 583 break; 584 case MSG_EXPAND_NOTIFICATIONS: 585 for (int i = 0; i < mCallbacks.size(); i++) { 586 mCallbacks.get(i).animateExpandNotificationsPanel(); 587 } 588 break; 589 case MSG_COLLAPSE_PANELS: 590 for (int i = 0; i < mCallbacks.size(); i++) { 591 mCallbacks.get(i).animateCollapsePanels(msg.arg1); 592 } 593 break; 594 case MSG_TOGGLE_PANEL: 595 for (int i = 0; i < mCallbacks.size(); i++) { 596 mCallbacks.get(i).togglePanel(); 597 } 598 break; 599 case MSG_EXPAND_SETTINGS: 600 for (int i = 0; i < mCallbacks.size(); i++) { 601 mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj); 602 } 603 break; 604 case MSG_SET_SYSTEMUI_VISIBILITY: 605 SomeArgs args = (SomeArgs) msg.obj; 606 for (int i = 0; i < mCallbacks.size(); i++) { 607 mCallbacks.get(i).setSystemUiVisibility(args.argi1, args.argi2, args.argi3, 608 args.argi4, (Rect) args.arg1, (Rect) args.arg2); 609 } 610 args.recycle(); 611 break; 612 case MSG_TOP_APP_WINDOW_CHANGED: 613 for (int i = 0; i < mCallbacks.size(); i++) { 614 mCallbacks.get(i).topAppWindowChanged(msg.arg1 != 0); 615 } 616 break; 617 case MSG_SHOW_IME_BUTTON: 618 for (int i = 0; i < mCallbacks.size(); i++) { 619 mCallbacks.get(i).setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2, 620 msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false)); 621 } 622 break; 623 case MSG_SHOW_RECENT_APPS: 624 for (int i = 0; i < mCallbacks.size(); i++) { 625 mCallbacks.get(i).showRecentApps(msg.arg1 != 0); 626 } 627 break; 628 case MSG_HIDE_RECENT_APPS: 629 for (int i = 0; i < mCallbacks.size(); i++) { 630 mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0); 631 } 632 break; 633 case MSG_TOGGLE_RECENT_APPS: 634 for (int i = 0; i < mCallbacks.size(); i++) { 635 mCallbacks.get(i).toggleRecentApps(); 636 } 637 break; 638 case MSG_PRELOAD_RECENT_APPS: 639 for (int i = 0; i < mCallbacks.size(); i++) { 640 mCallbacks.get(i).preloadRecentApps(); 641 } 642 break; 643 case MSG_CANCEL_PRELOAD_RECENT_APPS: 644 for (int i = 0; i < mCallbacks.size(); i++) { 645 mCallbacks.get(i).cancelPreloadRecentApps(); 646 } 647 break; 648 case MSG_DISMISS_KEYBOARD_SHORTCUTS: 649 for (int i = 0; i < mCallbacks.size(); i++) { 650 mCallbacks.get(i).dismissKeyboardShortcutsMenu(); 651 } 652 break; 653 case MSG_TOGGLE_KEYBOARD_SHORTCUTS: 654 for (int i = 0; i < mCallbacks.size(); i++) { 655 mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1); 656 } 657 break; 658 case MSG_SET_WINDOW_STATE: 659 for (int i = 0; i < mCallbacks.size(); i++) { 660 mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2); 661 } 662 break; 663 case MSG_SHOW_SCREEN_PIN_REQUEST: 664 for (int i = 0; i < mCallbacks.size(); i++) { 665 mCallbacks.get(i).showScreenPinningRequest(msg.arg1); 666 } 667 break; 668 case MSG_APP_TRANSITION_PENDING: 669 for (int i = 0; i < mCallbacks.size(); i++) { 670 mCallbacks.get(i).appTransitionPending(msg.arg1 != 0); 671 } 672 break; 673 case MSG_APP_TRANSITION_CANCELLED: 674 for (int i = 0; i < mCallbacks.size(); i++) { 675 mCallbacks.get(i).appTransitionCancelled(); 676 } 677 break; 678 case MSG_APP_TRANSITION_STARTING: 679 for (int i = 0; i < mCallbacks.size(); i++) { 680 Pair<Long, Long> data = (Pair<Long, Long>) msg.obj; 681 mCallbacks.get(i).appTransitionStarting(data.first, data.second, 682 msg.arg1 != 0); 683 } 684 break; 685 case MSG_APP_TRANSITION_FINISHED: 686 for (int i = 0; i < mCallbacks.size(); i++) { 687 mCallbacks.get(i).appTransitionFinished(); 688 } 689 break; 690 case MSG_ASSIST_DISCLOSURE: 691 for (int i = 0; i < mCallbacks.size(); i++) { 692 mCallbacks.get(i).showAssistDisclosure(); 693 } 694 break; 695 case MSG_START_ASSIST: 696 for (int i = 0; i < mCallbacks.size(); i++) { 697 mCallbacks.get(i).startAssist((Bundle) msg.obj); 698 } 699 break; 700 case MSG_CAMERA_LAUNCH_GESTURE: 701 for (int i = 0; i < mCallbacks.size(); i++) { 702 mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1); 703 } 704 break; 705 case MSG_SHOW_PICTURE_IN_PICTURE_MENU: 706 for (int i = 0; i < mCallbacks.size(); i++) { 707 mCallbacks.get(i).showPictureInPictureMenu(); 708 } 709 break; 710 case MSG_ADD_QS_TILE: 711 for (int i = 0; i < mCallbacks.size(); i++) { 712 mCallbacks.get(i).addQsTile((ComponentName) msg.obj); 713 } 714 break; 715 case MSG_REMOVE_QS_TILE: 716 for (int i = 0; i < mCallbacks.size(); i++) { 717 mCallbacks.get(i).remQsTile((ComponentName) msg.obj); 718 } 719 break; 720 case MSG_CLICK_QS_TILE: 721 for (int i = 0; i < mCallbacks.size(); i++) { 722 mCallbacks.get(i).clickTile((ComponentName) msg.obj); 723 } 724 break; 725 case MSG_TOGGLE_APP_SPLIT_SCREEN: 726 for (int i = 0; i < mCallbacks.size(); i++) { 727 mCallbacks.get(i).toggleSplitScreen(); 728 } 729 break; 730 case MSG_HANDLE_SYSTEM_KEY: 731 for (int i = 0; i < mCallbacks.size(); i++) { 732 mCallbacks.get(i).handleSystemKey(msg.arg1); 733 } 734 break; 735 case MSG_SHOW_GLOBAL_ACTIONS: 736 for (int i = 0; i < mCallbacks.size(); i++) { 737 mCallbacks.get(i).handleShowGlobalActionsMenu(); 738 } 739 break; 740 case MSG_SHOW_SHUTDOWN_UI: 741 for (int i = 0; i < mCallbacks.size(); i++) { 742 mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj); 743 } 744 break; 745 case MSG_SET_TOP_APP_HIDES_STATUS_BAR: 746 for (int i = 0; i < mCallbacks.size(); i++) { 747 mCallbacks.get(i).setTopAppHidesStatusBar(msg.arg1 != 0); 748 } 749 break; 750 case MSG_ROTATION_PROPOSAL: 751 for (int i = 0; i < mCallbacks.size(); i++) { 752 mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0); 753 } 754 break; 755 case MSG_FINGERPRINT_SHOW: 756 mHandler.removeMessages(MSG_FINGERPRINT_ERROR); 757 mHandler.removeMessages(MSG_FINGERPRINT_HELP); 758 mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED); 759 for (int i = 0; i < mCallbacks.size(); i++) { 760 mCallbacks.get(i).showFingerprintDialog( 761 (Bundle)((SomeArgs)msg.obj).arg1, 762 (IBiometricPromptReceiver)((SomeArgs)msg.obj).arg2); 763 } 764 break; 765 case MSG_FINGERPRINT_AUTHENTICATED: 766 for (int i = 0; i < mCallbacks.size(); i++) { 767 mCallbacks.get(i).onFingerprintAuthenticated(); 768 } 769 break; 770 case MSG_FINGERPRINT_HELP: 771 for (int i = 0; i < mCallbacks.size(); i++) { 772 mCallbacks.get(i).onFingerprintHelp((String) msg.obj); 773 } 774 break; 775 case MSG_FINGERPRINT_ERROR: 776 for (int i = 0; i < mCallbacks.size(); i++) { 777 mCallbacks.get(i).onFingerprintError((String) msg.obj); 778 } 779 break; 780 case MSG_FINGERPRINT_HIDE: 781 for (int i = 0; i < mCallbacks.size(); i++) { 782 mCallbacks.get(i).hideFingerprintDialog(); 783 } 784 break; 785 case MSG_SHOW_CHARGING_ANIMATION: 786 for (int i = 0; i < mCallbacks.size(); i++) { 787 mCallbacks.get(i).showWirelessChargingAnimation(msg.arg1); 788 } 789 break; 790 case MSG_SHOW_PINNING_TOAST_ENTER_EXIT: 791 for (int i = 0; i < mCallbacks.size(); i++) { 792 mCallbacks.get(i).showPinningEnterExitToast((Boolean) msg.obj); 793 } 794 break; 795 case MSG_SHOW_PINNING_TOAST_ESCAPE: 796 for (int i = 0; i < mCallbacks.size(); i++) { 797 mCallbacks.get(i).showPinningEscapeToast(); 798 } 799 break; 800 } 801 } 802 } 803 804 // Need this class since CommandQueue already extends IStatusBar.Stub, so CommandQueueStart 805 // is needed so it can extend SystemUI. 806 public static class CommandQueueStart extends SystemUI { 807 @Override 808 public void start() { 809 putComponent(CommandQueue.class, new CommandQueue()); 810 } 811 } 812 } 813