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.os.Bundle; 22 import android.os.Handler; 23 import android.os.IBinder; 24 import android.os.Looper; 25 import android.os.Message; 26 import android.support.annotation.VisibleForTesting; 27 import android.util.Pair; 28 29 import com.android.internal.os.SomeArgs; 30 import com.android.internal.statusbar.IStatusBar; 31 import com.android.internal.statusbar.StatusBarIcon; 32 import com.android.systemui.SystemUI; 33 34 import java.util.ArrayList; 35 36 /** 37 * This class takes the functions from IStatusBar that come in on 38 * binder pool threads and posts messages to get them onto the main 39 * thread, and calls onto Callbacks. It also takes care of 40 * coalescing these calls so they don't stack up. For the calls 41 * are coalesced, note that they are all idempotent. 42 */ 43 public class CommandQueue extends IStatusBar.Stub { 44 private static final int INDEX_MASK = 0xffff; 45 private static final int MSG_SHIFT = 16; 46 private static final int MSG_MASK = 0xffff << MSG_SHIFT; 47 48 private static final int OP_SET_ICON = 1; 49 private static final int OP_REMOVE_ICON = 2; 50 51 private static final int MSG_ICON = 1 << MSG_SHIFT; 52 private static final int MSG_DISABLE = 2 << MSG_SHIFT; 53 private static final int MSG_EXPAND_NOTIFICATIONS = 3 << MSG_SHIFT; 54 private static final int MSG_COLLAPSE_PANELS = 4 << MSG_SHIFT; 55 private static final int MSG_EXPAND_SETTINGS = 5 << MSG_SHIFT; 56 private static final int MSG_SET_SYSTEMUI_VISIBILITY = 6 << MSG_SHIFT; 57 private static final int MSG_TOP_APP_WINDOW_CHANGED = 7 << MSG_SHIFT; 58 private static final int MSG_SHOW_IME_BUTTON = 8 << MSG_SHIFT; 59 private static final int MSG_TOGGLE_RECENT_APPS = 9 << MSG_SHIFT; 60 private static final int MSG_PRELOAD_RECENT_APPS = 10 << MSG_SHIFT; 61 private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 11 << MSG_SHIFT; 62 private static final int MSG_SET_WINDOW_STATE = 12 << MSG_SHIFT; 63 private static final int MSG_SHOW_RECENT_APPS = 13 << MSG_SHIFT; 64 private static final int MSG_HIDE_RECENT_APPS = 14 << MSG_SHIFT; 65 private static final int MSG_SHOW_SCREEN_PIN_REQUEST = 18 << MSG_SHIFT; 66 private static final int MSG_APP_TRANSITION_PENDING = 19 << MSG_SHIFT; 67 private static final int MSG_APP_TRANSITION_CANCELLED = 20 << MSG_SHIFT; 68 private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT; 69 private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT; 70 private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; 71 private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; 72 private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS = 25 << MSG_SHIFT; 73 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 26 << MSG_SHIFT; 74 private static final int MSG_ADD_QS_TILE = 27 << MSG_SHIFT; 75 private static final int MSG_REMOVE_QS_TILE = 28 << MSG_SHIFT; 76 private static final int MSG_CLICK_QS_TILE = 29 << MSG_SHIFT; 77 private static final int MSG_TOGGLE_APP_SPLIT_SCREEN = 30 << MSG_SHIFT; 78 private static final int MSG_APP_TRANSITION_FINISHED = 31 << MSG_SHIFT; 79 private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS = 32 << MSG_SHIFT; 80 private static final int MSG_HANDLE_SYSNAV_KEY = 33 << MSG_SHIFT; 81 private static final int MSG_SHOW_GLOBAL_ACTIONS = 34 << MSG_SHIFT; 82 83 public static final int FLAG_EXCLUDE_NONE = 0; 84 public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; 85 public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1; 86 public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2; 87 public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3; 88 public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4; 89 90 private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey"; 91 92 private final Object mLock = new Object(); 93 private ArrayList<Callbacks> mCallbacks = new ArrayList<>(); 94 private Handler mHandler = new H(Looper.getMainLooper()); 95 private int mDisable1; 96 private int mDisable2; 97 98 /** 99 * These methods are called back on the main thread. 100 */ 101 public interface Callbacks { setIcon(String slot, StatusBarIcon icon)102 default void setIcon(String slot, StatusBarIcon icon) { } removeIcon(String slot)103 default void removeIcon(String slot) { } disable(int state1, int state2, boolean animate)104 default void disable(int state1, int state2, boolean animate) { } animateExpandNotificationsPanel()105 default void animateExpandNotificationsPanel() { } animateCollapsePanels(int flags)106 default void animateCollapsePanels(int flags) { } animateExpandSettingsPanel(String obj)107 default void animateExpandSettingsPanel(String obj) { } setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds)108 default void setSystemUiVisibility(int vis, int fullscreenStackVis, 109 int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) { 110 } topAppWindowChanged(boolean visible)111 default void topAppWindowChanged(boolean visible) { } setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher)112 default void setImeWindowStatus(IBinder token, int vis, int backDisposition, 113 boolean showImeSwitcher) { } showRecentApps(boolean triggeredFromAltTab, boolean fromHome)114 default void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) { } hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)115 default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } toggleRecentApps()116 default void toggleRecentApps() { } toggleSplitScreen()117 default void toggleSplitScreen() { } preloadRecentApps()118 default void preloadRecentApps() { } dismissKeyboardShortcutsMenu()119 default void dismissKeyboardShortcutsMenu() { } toggleKeyboardShortcutsMenu(int deviceId)120 default void toggleKeyboardShortcutsMenu(int deviceId) { } cancelPreloadRecentApps()121 default void cancelPreloadRecentApps() { } setWindowState(int window, int state)122 default void setWindowState(int window, int state) { } showScreenPinningRequest(int taskId)123 default void showScreenPinningRequest(int taskId) { } appTransitionPending(boolean forced)124 default void appTransitionPending(boolean forced) { } appTransitionCancelled()125 default void appTransitionCancelled() { } appTransitionStarting(long startTime, long duration, boolean forced)126 default void appTransitionStarting(long startTime, long duration, boolean forced) { } appTransitionFinished()127 default void appTransitionFinished() { } showAssistDisclosure()128 default void showAssistDisclosure() { } startAssist(Bundle args)129 default void startAssist(Bundle args) { } onCameraLaunchGestureDetected(int source)130 default void onCameraLaunchGestureDetected(int source) { } showPictureInPictureMenu()131 default void showPictureInPictureMenu() { } 132 addQsTile(ComponentName tile)133 default void addQsTile(ComponentName tile) { } remQsTile(ComponentName tile)134 default void remQsTile(ComponentName tile) { } clickTile(ComponentName tile)135 default void clickTile(ComponentName tile) { } 136 handleSystemNavigationKey(int arg1)137 default void handleSystemNavigationKey(int arg1) { } handleShowGlobalActionsMenu()138 default void handleShowGlobalActionsMenu() { } 139 } 140 141 @VisibleForTesting CommandQueue()142 protected CommandQueue() { 143 } 144 addCallbacks(Callbacks callbacks)145 public void addCallbacks(Callbacks callbacks) { 146 mCallbacks.add(callbacks); 147 callbacks.disable(mDisable1, mDisable2, false /* animate */); 148 } 149 removeCallbacks(Callbacks callbacks)150 public void removeCallbacks(Callbacks callbacks) { 151 mCallbacks.remove(callbacks); 152 } 153 setIcon(String slot, StatusBarIcon icon)154 public void setIcon(String slot, StatusBarIcon icon) { 155 synchronized (mLock) { 156 // don't coalesce these 157 mHandler.obtainMessage(MSG_ICON, OP_SET_ICON, 0, 158 new Pair<String, StatusBarIcon>(slot, icon)).sendToTarget(); 159 } 160 } 161 removeIcon(String slot)162 public void removeIcon(String slot) { 163 synchronized (mLock) { 164 // don't coalesce these 165 mHandler.obtainMessage(MSG_ICON, OP_REMOVE_ICON, 0, slot).sendToTarget(); 166 } 167 } 168 disable(int state1, int state2, boolean animate)169 public void disable(int state1, int state2, boolean animate) { 170 synchronized (mLock) { 171 mDisable1 = state1; 172 mDisable2 = state2; 173 mHandler.removeMessages(MSG_DISABLE); 174 Message msg = mHandler.obtainMessage(MSG_DISABLE, state1, state2, animate); 175 if (Looper.myLooper() == mHandler.getLooper()) { 176 // If its the right looper execute immediately so hides can be handled quickly. 177 mHandler.handleMessage(msg); 178 msg.recycle(); 179 } else { 180 msg.sendToTarget(); 181 } 182 } 183 } 184 disable(int state1, int state2)185 public void disable(int state1, int state2) { 186 disable(state1, state2, true); 187 } 188 recomputeDisableFlags(boolean animate)189 public void recomputeDisableFlags(boolean animate) { 190 disable(mDisable1, mDisable2, animate); 191 } 192 animateExpandNotificationsPanel()193 public void animateExpandNotificationsPanel() { 194 synchronized (mLock) { 195 mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS); 196 mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS); 197 } 198 } 199 animateCollapsePanels()200 public void animateCollapsePanels() { 201 synchronized (mLock) { 202 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 203 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, 0, 0).sendToTarget(); 204 } 205 } 206 animateCollapsePanels(int flags)207 public void animateCollapsePanels(int flags) { 208 synchronized (mLock) { 209 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 210 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, 0).sendToTarget(); 211 } 212 } 213 animateExpandSettingsPanel(String subPanel)214 public void animateExpandSettingsPanel(String subPanel) { 215 synchronized (mLock) { 216 mHandler.removeMessages(MSG_EXPAND_SETTINGS); 217 mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget(); 218 } 219 } 220 setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds)221 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, 222 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) { 223 synchronized (mLock) { 224 // Don't coalesce these, since it might have one time flags set such as 225 // STATUS_BAR_UNHIDE which might get lost. 226 SomeArgs args = SomeArgs.obtain(); 227 args.argi1 = vis; 228 args.argi2 = fullscreenStackVis; 229 args.argi3 = dockedStackVis; 230 args.argi4 = mask; 231 args.arg1 = fullscreenStackBounds; 232 args.arg2 = dockedStackBounds; 233 mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, args).sendToTarget(); 234 } 235 } 236 topAppWindowChanged(boolean menuVisible)237 public void topAppWindowChanged(boolean menuVisible) { 238 synchronized (mLock) { 239 mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED); 240 mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0, 241 null).sendToTarget(); 242 } 243 } 244 setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher)245 public void setImeWindowStatus(IBinder token, int vis, int backDisposition, 246 boolean showImeSwitcher) { 247 synchronized (mLock) { 248 mHandler.removeMessages(MSG_SHOW_IME_BUTTON); 249 Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, vis, backDisposition, token); 250 m.getData().putBoolean(SHOW_IME_SWITCHER_KEY, showImeSwitcher); 251 m.sendToTarget(); 252 } 253 } 254 showRecentApps(boolean triggeredFromAltTab, boolean fromHome)255 public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) { 256 synchronized (mLock) { 257 mHandler.removeMessages(MSG_SHOW_RECENT_APPS); 258 mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, 259 triggeredFromAltTab ? 1 : 0, fromHome ? 1 : 0, null).sendToTarget(); 260 } 261 } 262 hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)263 public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { 264 synchronized (mLock) { 265 mHandler.removeMessages(MSG_HIDE_RECENT_APPS); 266 mHandler.obtainMessage(MSG_HIDE_RECENT_APPS, 267 triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0, 268 null).sendToTarget(); 269 } 270 } 271 toggleSplitScreen()272 public void toggleSplitScreen() { 273 synchronized (mLock) { 274 mHandler.removeMessages(MSG_TOGGLE_APP_SPLIT_SCREEN); 275 mHandler.obtainMessage(MSG_TOGGLE_APP_SPLIT_SCREEN, 0, 0, null).sendToTarget(); 276 } 277 } 278 toggleRecentApps()279 public void toggleRecentApps() { 280 synchronized (mLock) { 281 mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); 282 Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null); 283 msg.setAsynchronous(true); 284 msg.sendToTarget(); 285 } 286 } 287 preloadRecentApps()288 public void preloadRecentApps() { 289 synchronized (mLock) { 290 mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS); 291 mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 292 } 293 } 294 cancelPreloadRecentApps()295 public void cancelPreloadRecentApps() { 296 synchronized (mLock) { 297 mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS); 298 mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 299 } 300 } 301 302 @Override dismissKeyboardShortcutsMenu()303 public void dismissKeyboardShortcutsMenu() { 304 synchronized (mLock) { 305 mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS); 306 mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget(); 307 } 308 } 309 310 @Override toggleKeyboardShortcutsMenu(int deviceId)311 public void toggleKeyboardShortcutsMenu(int deviceId) { 312 synchronized (mLock) { 313 mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS); 314 mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget(); 315 } 316 } 317 318 @Override showPictureInPictureMenu()319 public void showPictureInPictureMenu() { 320 synchronized (mLock) { 321 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 322 mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU).sendToTarget(); 323 } 324 } 325 setWindowState(int window, int state)326 public void setWindowState(int window, int state) { 327 synchronized (mLock) { 328 // don't coalesce these 329 mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget(); 330 } 331 } 332 showScreenPinningRequest(int taskId)333 public void showScreenPinningRequest(int taskId) { 334 synchronized (mLock) { 335 mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null) 336 .sendToTarget(); 337 } 338 } 339 appTransitionPending()340 public void appTransitionPending() { 341 appTransitionPending(false /* forced */); 342 } 343 appTransitionPending(boolean forced)344 public void appTransitionPending(boolean forced) { 345 synchronized (mLock) { 346 mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, forced ? 1 : 0, 0).sendToTarget(); 347 } 348 } 349 appTransitionCancelled()350 public void appTransitionCancelled() { 351 synchronized (mLock) { 352 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_CANCELLED); 353 } 354 } 355 appTransitionStarting(long startTime, long duration)356 public void appTransitionStarting(long startTime, long duration) { 357 appTransitionStarting(startTime, duration, false /* forced */); 358 } 359 appTransitionStarting(long startTime, long duration, boolean forced)360 public void appTransitionStarting(long startTime, long duration, boolean forced) { 361 synchronized (mLock) { 362 mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, forced ? 1 : 0, 0, 363 Pair.create(startTime, duration)).sendToTarget(); 364 } 365 } 366 367 @Override appTransitionFinished()368 public void appTransitionFinished() { 369 synchronized (mLock) { 370 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_FINISHED); 371 } 372 } 373 showAssistDisclosure()374 public void showAssistDisclosure() { 375 synchronized (mLock) { 376 mHandler.removeMessages(MSG_ASSIST_DISCLOSURE); 377 mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget(); 378 } 379 } 380 startAssist(Bundle args)381 public void startAssist(Bundle args) { 382 synchronized (mLock) { 383 mHandler.removeMessages(MSG_START_ASSIST); 384 mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget(); 385 } 386 } 387 388 @Override onCameraLaunchGestureDetected(int source)389 public void onCameraLaunchGestureDetected(int source) { 390 synchronized (mLock) { 391 mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE); 392 mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget(); 393 } 394 } 395 396 @Override addQsTile(ComponentName tile)397 public void addQsTile(ComponentName tile) { 398 synchronized (mLock) { 399 mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget(); 400 } 401 } 402 403 @Override remQsTile(ComponentName tile)404 public void remQsTile(ComponentName tile) { 405 synchronized (mLock) { 406 mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget(); 407 } 408 } 409 410 @Override clickQsTile(ComponentName tile)411 public void clickQsTile(ComponentName tile) { 412 synchronized (mLock) { 413 mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget(); 414 } 415 } 416 417 @Override handleSystemNavigationKey(int key)418 public void handleSystemNavigationKey(int key) { 419 synchronized (mLock) { 420 mHandler.obtainMessage(MSG_HANDLE_SYSNAV_KEY, key, 0).sendToTarget(); 421 } 422 } 423 424 @Override showGlobalActionsMenu()425 public void showGlobalActionsMenu() { 426 synchronized (mLock) { 427 mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS); 428 mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget(); 429 } 430 } 431 432 private final class H extends Handler { H(Looper l)433 private H(Looper l) { 434 super(l); 435 } 436 handleMessage(Message msg)437 public void handleMessage(Message msg) { 438 final int what = msg.what & MSG_MASK; 439 switch (what) { 440 case MSG_ICON: { 441 switch (msg.arg1) { 442 case OP_SET_ICON: { 443 Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj; 444 for (int i = 0; i < mCallbacks.size(); i++) { 445 mCallbacks.get(i).setIcon(p.first, p.second); 446 } 447 break; 448 } 449 case OP_REMOVE_ICON: 450 for (int i = 0; i < mCallbacks.size(); i++) { 451 mCallbacks.get(i).removeIcon((String) msg.obj); 452 } 453 break; 454 } 455 break; 456 } 457 case MSG_DISABLE: 458 for (int i = 0; i < mCallbacks.size(); i++) { 459 mCallbacks.get(i).disable(msg.arg1, msg.arg2, (Boolean) msg.obj); 460 } 461 break; 462 case MSG_EXPAND_NOTIFICATIONS: 463 for (int i = 0; i < mCallbacks.size(); i++) { 464 mCallbacks.get(i).animateExpandNotificationsPanel(); 465 } 466 break; 467 case MSG_COLLAPSE_PANELS: 468 for (int i = 0; i < mCallbacks.size(); i++) { 469 mCallbacks.get(i).animateCollapsePanels(msg.arg1); 470 } 471 break; 472 case MSG_EXPAND_SETTINGS: 473 for (int i = 0; i < mCallbacks.size(); i++) { 474 mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj); 475 } 476 break; 477 case MSG_SET_SYSTEMUI_VISIBILITY: 478 SomeArgs args = (SomeArgs) msg.obj; 479 for (int i = 0; i < mCallbacks.size(); i++) { 480 mCallbacks.get(i).setSystemUiVisibility(args.argi1, args.argi2, args.argi3, 481 args.argi4, (Rect) args.arg1, (Rect) args.arg2); 482 } 483 args.recycle(); 484 break; 485 case MSG_TOP_APP_WINDOW_CHANGED: 486 for (int i = 0; i < mCallbacks.size(); i++) { 487 mCallbacks.get(i).topAppWindowChanged(msg.arg1 != 0); 488 } 489 break; 490 case MSG_SHOW_IME_BUTTON: 491 for (int i = 0; i < mCallbacks.size(); i++) { 492 mCallbacks.get(i).setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2, 493 msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false)); 494 } 495 break; 496 case MSG_SHOW_RECENT_APPS: 497 for (int i = 0; i < mCallbacks.size(); i++) { 498 mCallbacks.get(i).showRecentApps(msg.arg1 != 0, msg.arg2 != 0); 499 } 500 break; 501 case MSG_HIDE_RECENT_APPS: 502 for (int i = 0; i < mCallbacks.size(); i++) { 503 mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0); 504 } 505 break; 506 case MSG_TOGGLE_RECENT_APPS: 507 for (int i = 0; i < mCallbacks.size(); i++) { 508 mCallbacks.get(i).toggleRecentApps(); 509 } 510 break; 511 case MSG_PRELOAD_RECENT_APPS: 512 for (int i = 0; i < mCallbacks.size(); i++) { 513 mCallbacks.get(i).preloadRecentApps(); 514 } 515 break; 516 case MSG_CANCEL_PRELOAD_RECENT_APPS: 517 for (int i = 0; i < mCallbacks.size(); i++) { 518 mCallbacks.get(i).cancelPreloadRecentApps(); 519 } 520 break; 521 case MSG_DISMISS_KEYBOARD_SHORTCUTS: 522 for (int i = 0; i < mCallbacks.size(); i++) { 523 mCallbacks.get(i).dismissKeyboardShortcutsMenu(); 524 } 525 break; 526 case MSG_TOGGLE_KEYBOARD_SHORTCUTS: 527 for (int i = 0; i < mCallbacks.size(); i++) { 528 mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1); 529 } 530 break; 531 case MSG_SET_WINDOW_STATE: 532 for (int i = 0; i < mCallbacks.size(); i++) { 533 mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2); 534 } 535 break; 536 case MSG_SHOW_SCREEN_PIN_REQUEST: 537 for (int i = 0; i < mCallbacks.size(); i++) { 538 mCallbacks.get(i).showScreenPinningRequest(msg.arg1); 539 } 540 break; 541 case MSG_APP_TRANSITION_PENDING: 542 for (int i = 0; i < mCallbacks.size(); i++) { 543 mCallbacks.get(i).appTransitionPending(msg.arg1 != 0); 544 } 545 break; 546 case MSG_APP_TRANSITION_CANCELLED: 547 for (int i = 0; i < mCallbacks.size(); i++) { 548 mCallbacks.get(i).appTransitionCancelled(); 549 } 550 break; 551 case MSG_APP_TRANSITION_STARTING: 552 for (int i = 0; i < mCallbacks.size(); i++) { 553 Pair<Long, Long> data = (Pair<Long, Long>) msg.obj; 554 mCallbacks.get(i).appTransitionStarting(data.first, data.second, 555 msg.arg1 != 0); 556 } 557 break; 558 case MSG_APP_TRANSITION_FINISHED: 559 for (int i = 0; i < mCallbacks.size(); i++) { 560 mCallbacks.get(i).appTransitionFinished(); 561 } 562 break; 563 case MSG_ASSIST_DISCLOSURE: 564 for (int i = 0; i < mCallbacks.size(); i++) { 565 mCallbacks.get(i).showAssistDisclosure(); 566 } 567 break; 568 case MSG_START_ASSIST: 569 for (int i = 0; i < mCallbacks.size(); i++) { 570 mCallbacks.get(i).startAssist((Bundle) msg.obj); 571 } 572 break; 573 case MSG_CAMERA_LAUNCH_GESTURE: 574 for (int i = 0; i < mCallbacks.size(); i++) { 575 mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1); 576 } 577 break; 578 case MSG_SHOW_PICTURE_IN_PICTURE_MENU: 579 for (int i = 0; i < mCallbacks.size(); i++) { 580 mCallbacks.get(i).showPictureInPictureMenu(); 581 } 582 break; 583 case MSG_ADD_QS_TILE: 584 for (int i = 0; i < mCallbacks.size(); i++) { 585 mCallbacks.get(i).addQsTile((ComponentName) msg.obj); 586 } 587 break; 588 case MSG_REMOVE_QS_TILE: 589 for (int i = 0; i < mCallbacks.size(); i++) { 590 mCallbacks.get(i).remQsTile((ComponentName) msg.obj); 591 } 592 break; 593 case MSG_CLICK_QS_TILE: 594 for (int i = 0; i < mCallbacks.size(); i++) { 595 mCallbacks.get(i).clickTile((ComponentName) msg.obj); 596 } 597 break; 598 case MSG_TOGGLE_APP_SPLIT_SCREEN: 599 for (int i = 0; i < mCallbacks.size(); i++) { 600 mCallbacks.get(i).toggleSplitScreen(); 601 } 602 break; 603 case MSG_HANDLE_SYSNAV_KEY: 604 for (int i = 0; i < mCallbacks.size(); i++) { 605 mCallbacks.get(i).handleSystemNavigationKey(msg.arg1); 606 } 607 break; 608 case MSG_SHOW_GLOBAL_ACTIONS: 609 for (int i = 0; i < mCallbacks.size(); i++) { 610 mCallbacks.get(i).handleShowGlobalActionsMenu(); 611 } 612 break; 613 } 614 } 615 } 616 617 // Need this class since CommandQueue already extends IStatusBar.Stub, so CommandQueueStart 618 // is needed so it can extend SystemUI. 619 public static class CommandQueueStart extends SystemUI { 620 @Override start()621 public void start() { 622 putComponent(CommandQueue.class, new CommandQueue()); 623 } 624 } 625 } 626 627