2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.systemui.statusbar;
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;
28 import com.android.internal.os.SomeArgs;
29 import com.android.internal.statusbar.IStatusBar;
30 import com.android.internal.statusbar.StatusBarIcon;
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.
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;
44 private static final int OP_SET_ICON = 1;
45 private static final int OP_REMOVE_ICON = 2;
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;
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;
88 private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
90 private final Object mLock = new Object();
91 private Callbacks mCallbacks;
92 private Handler mHandler = new H();
95 * These methods are called back on the main thread.
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();
131 void addQsTile(ComponentName tile);
132 void remQsTile(ComponentName tile);
133 void clickTile(ComponentName tile);
135 void handleSystemNavigationKey(int arg1);
138 public CommandQueue(Callbacks callbacks) {
139 mCallbacks = callbacks;
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();
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();
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();
164 public void animateExpandNotificationsPanel() {
165 synchronized (mLock) {
166 mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS);
167 mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS);
171 public void animateCollapsePanels() {
172 synchronized (mLock) {
173 mHandler.removeMessages(MSG_COLLAPSE_PANELS);
174 mHandler.sendEmptyMessage(MSG_COLLAPSE_PANELS);
178 public void animateExpandSettingsPanel(String subPanel) {
179 synchronized (mLock) {
180 mHandler.removeMessages(MSG_EXPAND_SETTINGS);
181 mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget();
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();
192 args.argi2 = fullscreenStackVis;
193 args.argi3 = dockedStackVis;
195 args.arg1 = fullscreenStackBounds;
196 args.arg2 = dockedStackBounds;
197 mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, args).sendToTarget();
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();
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);
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();
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();
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();
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();
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();
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();
265 public void dismissKeyboardShortcutsMenu() {
266 synchronized (mLock) {
267 mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS);
268 mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget();
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();
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();
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();
295 public void buzzBeepBlinked() {
296 synchronized (mLock) {
297 mHandler.removeMessages(MSG_BUZZ_BEEP_BLINKED);
298 mHandler.sendEmptyMessage(MSG_BUZZ_BEEP_BLINKED);
302 public void notificationLightOff() {
303 synchronized (mLock) {
304 mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
308 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
309 synchronized (mLock) {
310 mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
315 public void showScreenPinningRequest(int taskId) {
316 synchronized (mLock) {
317 mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null)
322 public void appTransitionPending() {
323 synchronized (mLock) {
324 mHandler.removeMessages(MSG_APP_TRANSITION_PENDING);
325 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_PENDING);
329 public void appTransitionCancelled() {
330 synchronized (mLock) {
331 mHandler.removeMessages(MSG_APP_TRANSITION_PENDING);
332 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_PENDING);
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))
345 public void appTransitionFinished() {
346 synchronized (mLock) {
347 mHandler.removeMessages(MSG_APP_TRANSITION_FINISHED);
348 mHandler.sendEmptyMessage(MSG_APP_TRANSITION_FINISHED);
352 public void showAssistDisclosure() {
353 synchronized (mLock) {
354 mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
355 mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget();
359 public void startAssist(Bundle args) {
360 synchronized (mLock) {
361 mHandler.removeMessages(MSG_START_ASSIST);
362 mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget();
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();
375 public void addQsTile(ComponentName tile) {
376 synchronized (mLock) {
377 mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget();
382 public void remQsTile(ComponentName tile) {
383 synchronized (mLock) {
384 mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget();
389 public void clickQsTile(ComponentName tile) {
390 synchronized (mLock) {
391 mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget();
396 public void handleSystemNavigationKey(int key) {
397 synchronized (mLock) {
398 mHandler.obtainMessage(MSG_HANDLE_SYSNAV_KEY, key, 0).sendToTarget();
402 private final class H extends Handler {
403 public void handleMessage(Message msg) {
404 final int what = msg.what & MSG_MASK;
409 Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj;
410 mCallbacks.setIcon(p.first, p.second);
414 mCallbacks.removeIcon((String) msg.obj);
420 mCallbacks.disable(msg.arg1, msg.arg2, true /* animate */);
422 case MSG_EXPAND_NOTIFICATIONS:
423 mCallbacks.animateExpandNotificationsPanel();
425 case MSG_COLLAPSE_PANELS:
426 mCallbacks.animateCollapsePanels(0);
428 case MSG_EXPAND_SETTINGS:
429 mCallbacks.animateExpandSettingsPanel((String) msg.obj);
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);
437 case MSG_TOP_APP_WINDOW_CHANGED:
438 mCallbacks.topAppWindowChanged(msg.arg1 != 0);
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));
444 case MSG_SHOW_RECENT_APPS:
445 mCallbacks.showRecentApps(msg.arg1 != 0, msg.arg2 != 0);
447 case MSG_HIDE_RECENT_APPS:
448 mCallbacks.hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
450 case MSG_TOGGLE_RECENT_APPS:
451 mCallbacks.toggleRecentApps();
453 case MSG_PRELOAD_RECENT_APPS:
454 mCallbacks.preloadRecentApps();
456 case MSG_CANCEL_PRELOAD_RECENT_APPS:
457 mCallbacks.cancelPreloadRecentApps();
459 case MSG_DISMISS_KEYBOARD_SHORTCUTS:
460 mCallbacks.dismissKeyboardShortcutsMenu();
462 case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
463 mCallbacks.toggleKeyboardShortcutsMenu(msg.arg1);
465 case MSG_SET_WINDOW_STATE:
466 mCallbacks.setWindowState(msg.arg1, msg.arg2);
468 case MSG_BUZZ_BEEP_BLINKED:
469 mCallbacks.buzzBeepBlinked();
471 case MSG_NOTIFICATION_LIGHT_OFF:
472 mCallbacks.notificationLightOff();
474 case MSG_NOTIFICATION_LIGHT_PULSE:
475 mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
477 case MSG_SHOW_SCREEN_PIN_REQUEST:
478 mCallbacks.showScreenPinningRequest(msg.arg1);
480 case MSG_APP_TRANSITION_PENDING:
481 mCallbacks.appTransitionPending();
483 case MSG_APP_TRANSITION_CANCELLED:
484 mCallbacks.appTransitionCancelled();
486 case MSG_APP_TRANSITION_STARTING:
487 Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
488 mCallbacks.appTransitionStarting(data.first, data.second);
490 case MSG_APP_TRANSITION_FINISHED:
491 mCallbacks.appTransitionFinished();
493 case MSG_ASSIST_DISCLOSURE:
494 mCallbacks.showAssistDisclosure();
496 case MSG_START_ASSIST:
497 mCallbacks.startAssist((Bundle) msg.obj);
499 case MSG_CAMERA_LAUNCH_GESTURE:
500 mCallbacks.onCameraLaunchGestureDetected(msg.arg1);
502 case MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU:
503 mCallbacks.showTvPictureInPictureMenu();
505 case MSG_ADD_QS_TILE:
506 mCallbacks.addQsTile((ComponentName) msg.obj);
508 case MSG_REMOVE_QS_TILE:
509 mCallbacks.remQsTile((ComponentName) msg.obj);
511 case MSG_CLICK_QS_TILE:
512 mCallbacks.clickTile((ComponentName) msg.obj);
514 case MSG_TOGGLE_APP_SPLIT_SCREEN:
515 mCallbacks.toggleSplitScreen();
517 case MSG_HANDLE_SYSNAV_KEY:
518 mCallbacks.handleSystemNavigationKey(msg.arg1);