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