OSDN Git Service

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