• 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.os.Handler;
20 import android.os.IBinder;
21 import android.os.Message;
22 
23 import com.android.internal.statusbar.IStatusBar;
24 import com.android.internal.statusbar.StatusBarIcon;
25 import com.android.internal.statusbar.StatusBarIconList;
26 
27 /**
28  * This class takes the functions from IStatusBar that come in on
29  * binder pool threads and posts messages to get them onto the main
30  * thread, and calls onto Callbacks.  It also takes care of
31  * coalescing these calls so they don't stack up.  For the calls
32  * are coalesced, note that they are all idempotent.
33  */
34 public class CommandQueue extends IStatusBar.Stub {
35     private static final int INDEX_MASK = 0xffff;
36     private static final int MSG_SHIFT  = 16;
37     private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
38 
39     private static final int OP_SET_ICON    = 1;
40     private static final int OP_REMOVE_ICON = 2;
41 
42     private static final int MSG_ICON                       = 1 << MSG_SHIFT;
43     private static final int MSG_DISABLE                    = 2 << MSG_SHIFT;
44     private static final int MSG_EXPAND_NOTIFICATIONS       = 3 << MSG_SHIFT;
45     private static final int MSG_COLLAPSE_PANELS            = 4 << MSG_SHIFT;
46     private static final int MSG_EXPAND_SETTINGS            = 5 << MSG_SHIFT;
47     private static final int MSG_SET_SYSTEMUI_VISIBILITY    = 6 << MSG_SHIFT;
48     private static final int MSG_TOP_APP_WINDOW_CHANGED     = 7 << MSG_SHIFT;
49     private static final int MSG_SHOW_IME_BUTTON            = 8 << MSG_SHIFT;
50     private static final int MSG_TOGGLE_RECENT_APPS         = 9 << MSG_SHIFT;
51     private static final int MSG_PRELOAD_RECENT_APPS        = 10 << MSG_SHIFT;
52     private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 11 << MSG_SHIFT;
53     private static final int MSG_SET_WINDOW_STATE           = 12 << MSG_SHIFT;
54     private static final int MSG_SHOW_RECENT_APPS           = 13 << MSG_SHIFT;
55     private static final int MSG_HIDE_RECENT_APPS           = 14 << MSG_SHIFT;
56     private static final int MSG_BUZZ_BEEP_BLINKED          = 15 << MSG_SHIFT;
57     private static final int MSG_NOTIFICATION_LIGHT_OFF     = 16 << MSG_SHIFT;
58     private static final int MSG_NOTIFICATION_LIGHT_PULSE   = 17 << MSG_SHIFT;
59 
60     public static final int FLAG_EXCLUDE_NONE = 0;
61     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
62     public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1;
63     public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2;
64     public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3;
65     public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4;
66 
67     private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
68 
69     private StatusBarIconList mList;
70     private Callbacks mCallbacks;
71     private Handler mHandler = new H();
72 
73     /**
74      * These methods are called back on the main thread.
75      */
76     public interface Callbacks {
addIcon(String slot, int index, int viewIndex, StatusBarIcon icon)77         public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);
updateIcon(String slot, int index, int viewIndex, StatusBarIcon old, StatusBarIcon icon)78         public void updateIcon(String slot, int index, int viewIndex,
79                 StatusBarIcon old, StatusBarIcon icon);
removeIcon(String slot, int index, int viewIndex)80         public void removeIcon(String slot, int index, int viewIndex);
disable(int state, boolean animate)81         public void disable(int state, boolean animate);
animateExpandNotificationsPanel()82         public void animateExpandNotificationsPanel();
animateCollapsePanels(int flags)83         public void animateCollapsePanels(int flags);
animateExpandSettingsPanel()84         public void animateExpandSettingsPanel();
setSystemUiVisibility(int vis, int mask)85         public void setSystemUiVisibility(int vis, int mask);
topAppWindowChanged(boolean visible)86         public void topAppWindowChanged(boolean visible);
setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher)87         public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
88                 boolean showImeSwitcher);
showRecentApps(boolean triggeredFromAltTab)89         public void showRecentApps(boolean triggeredFromAltTab);
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)90         public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
toggleRecentApps()91         public void toggleRecentApps();
preloadRecentApps()92         public void preloadRecentApps();
cancelPreloadRecentApps()93         public void cancelPreloadRecentApps();
showSearchPanel()94         public void showSearchPanel();
hideSearchPanel()95         public void hideSearchPanel();
setWindowState(int window, int state)96         public void setWindowState(int window, int state);
buzzBeepBlinked()97         public void buzzBeepBlinked();
notificationLightOff()98         public void notificationLightOff();
notificationLightPulse(int argb, int onMillis, int offMillis)99         public void notificationLightPulse(int argb, int onMillis, int offMillis);
100     }
101 
CommandQueue(Callbacks callbacks, StatusBarIconList list)102     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
103         mCallbacks = callbacks;
104         mList = list;
105     }
106 
setIcon(int index, StatusBarIcon icon)107     public void setIcon(int index, StatusBarIcon icon) {
108         synchronized (mList) {
109             int what = MSG_ICON | index;
110             mHandler.removeMessages(what);
111             mHandler.obtainMessage(what, OP_SET_ICON, 0, icon.clone()).sendToTarget();
112         }
113     }
114 
removeIcon(int index)115     public void removeIcon(int index) {
116         synchronized (mList) {
117             int what = MSG_ICON | index;
118             mHandler.removeMessages(what);
119             mHandler.obtainMessage(what, OP_REMOVE_ICON, 0, null).sendToTarget();
120         }
121     }
122 
disable(int state)123     public void disable(int state) {
124         synchronized (mList) {
125             mHandler.removeMessages(MSG_DISABLE);
126             mHandler.obtainMessage(MSG_DISABLE, state, 0, null).sendToTarget();
127         }
128     }
129 
animateExpandNotificationsPanel()130     public void animateExpandNotificationsPanel() {
131         synchronized (mList) {
132             mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS);
133             mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS);
134         }
135     }
136 
animateCollapsePanels()137     public void animateCollapsePanels() {
138         synchronized (mList) {
139             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
140             mHandler.sendEmptyMessage(MSG_COLLAPSE_PANELS);
141         }
142     }
143 
animateExpandSettingsPanel()144     public void animateExpandSettingsPanel() {
145         synchronized (mList) {
146             mHandler.removeMessages(MSG_EXPAND_SETTINGS);
147             mHandler.sendEmptyMessage(MSG_EXPAND_SETTINGS);
148         }
149     }
150 
setSystemUiVisibility(int vis, int mask)151     public void setSystemUiVisibility(int vis, int mask) {
152         synchronized (mList) {
153             mHandler.removeMessages(MSG_SET_SYSTEMUI_VISIBILITY);
154             mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, vis, mask, null).sendToTarget();
155         }
156     }
157 
topAppWindowChanged(boolean menuVisible)158     public void topAppWindowChanged(boolean menuVisible) {
159         synchronized (mList) {
160             mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED);
161             mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0,
162                     null).sendToTarget();
163         }
164     }
165 
setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher)166     public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
167             boolean showImeSwitcher) {
168         synchronized (mList) {
169             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
170             Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, vis, backDisposition, token);
171             m.getData().putBoolean(SHOW_IME_SWITCHER_KEY, showImeSwitcher);
172             m.sendToTarget();
173         }
174     }
175 
showRecentApps(boolean triggeredFromAltTab)176     public void showRecentApps(boolean triggeredFromAltTab) {
177         synchronized (mList) {
178             mHandler.removeMessages(MSG_SHOW_RECENT_APPS);
179             mHandler.obtainMessage(MSG_SHOW_RECENT_APPS,
180                     triggeredFromAltTab ? 1 : 0, 0, null).sendToTarget();
181         }
182     }
183 
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)184     public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
185         synchronized (mList) {
186             mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
187             mHandler.obtainMessage(MSG_HIDE_RECENT_APPS,
188                     triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0,
189                     null).sendToTarget();
190         }
191     }
192 
toggleRecentApps()193     public void toggleRecentApps() {
194         synchronized (mList) {
195             mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
196             mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
197         }
198     }
199 
preloadRecentApps()200     public void preloadRecentApps() {
201         synchronized (mList) {
202             mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS);
203             mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
204         }
205     }
206 
cancelPreloadRecentApps()207     public void cancelPreloadRecentApps() {
208         synchronized (mList) {
209             mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS);
210             mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
211         }
212     }
213 
setWindowState(int window, int state)214     public void setWindowState(int window, int state) {
215         synchronized (mList) {
216             // don't coalesce these
217             mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
218         }
219     }
220 
buzzBeepBlinked()221     public void buzzBeepBlinked() {
222         synchronized (mList) {
223             mHandler.removeMessages(MSG_BUZZ_BEEP_BLINKED);
224             mHandler.sendEmptyMessage(MSG_BUZZ_BEEP_BLINKED);
225         }
226     }
227 
notificationLightOff()228     public void notificationLightOff() {
229         synchronized (mList) {
230             mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
231         }
232     }
233 
notificationLightPulse(int argb, int onMillis, int offMillis)234     public void notificationLightPulse(int argb, int onMillis, int offMillis) {
235         synchronized (mList) {
236             mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
237                     .sendToTarget();
238         }
239     }
240 
241     private final class H extends Handler {
handleMessage(Message msg)242         public void handleMessage(Message msg) {
243             final int what = msg.what & MSG_MASK;
244             switch (what) {
245                 case MSG_ICON: {
246                     final int index = msg.what & INDEX_MASK;
247                     final int viewIndex = mList.getViewIndex(index);
248                     switch (msg.arg1) {
249                         case OP_SET_ICON: {
250                             StatusBarIcon icon = (StatusBarIcon)msg.obj;
251                             StatusBarIcon old = mList.getIcon(index);
252                             if (old == null) {
253                                 mList.setIcon(index, icon);
254                                 mCallbacks.addIcon(mList.getSlot(index), index, viewIndex, icon);
255                             } else {
256                                 mList.setIcon(index, icon);
257                                 mCallbacks.updateIcon(mList.getSlot(index), index, viewIndex,
258                                         old, icon);
259                             }
260                             break;
261                         }
262                         case OP_REMOVE_ICON:
263                             if (mList.getIcon(index) != null) {
264                                 mList.removeIcon(index);
265                                 mCallbacks.removeIcon(mList.getSlot(index), index, viewIndex);
266                             }
267                             break;
268                     }
269                     break;
270                 }
271                 case MSG_DISABLE:
272                     mCallbacks.disable(msg.arg1, true /* animate */);
273                     break;
274                 case MSG_EXPAND_NOTIFICATIONS:
275                     mCallbacks.animateExpandNotificationsPanel();
276                     break;
277                 case MSG_COLLAPSE_PANELS:
278                     mCallbacks.animateCollapsePanels(0);
279                     break;
280                 case MSG_EXPAND_SETTINGS:
281                     mCallbacks.animateExpandSettingsPanel();
282                     break;
283                 case MSG_SET_SYSTEMUI_VISIBILITY:
284                     mCallbacks.setSystemUiVisibility(msg.arg1, msg.arg2);
285                     break;
286                 case MSG_TOP_APP_WINDOW_CHANGED:
287                     mCallbacks.topAppWindowChanged(msg.arg1 != 0);
288                     break;
289                 case MSG_SHOW_IME_BUTTON:
290                     mCallbacks.setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2,
291                             msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false));
292                     break;
293                 case MSG_SHOW_RECENT_APPS:
294                     mCallbacks.showRecentApps(msg.arg1 != 0);
295                     break;
296                 case MSG_HIDE_RECENT_APPS:
297                     mCallbacks.hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
298                     break;
299                 case MSG_TOGGLE_RECENT_APPS:
300                     mCallbacks.toggleRecentApps();
301                     break;
302                 case MSG_PRELOAD_RECENT_APPS:
303                     mCallbacks.preloadRecentApps();
304                     break;
305                 case MSG_CANCEL_PRELOAD_RECENT_APPS:
306                     mCallbacks.cancelPreloadRecentApps();
307                     break;
308                 case MSG_SET_WINDOW_STATE:
309                     mCallbacks.setWindowState(msg.arg1, msg.arg2);
310                     break;
311                 case MSG_BUZZ_BEEP_BLINKED:
312                     mCallbacks.buzzBeepBlinked();
313                     break;
314                 case MSG_NOTIFICATION_LIGHT_OFF:
315                     mCallbacks.notificationLightOff();
316                     break;
317                 case MSG_NOTIFICATION_LIGHT_PULSE:
318                     mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
319                     break;
320             }
321         }
322     }
323 }
324 
325