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