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