• 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.Bundle;
20 import android.os.Handler;
21 import android.os.IBinder;
22 import android.os.Message;
23 import android.util.Pair;
24 
25 import com.android.internal.statusbar.IStatusBar;
26 import com.android.internal.statusbar.StatusBarIcon;
27 import com.android.internal.statusbar.StatusBarIconList;
28 
29 /**
30  * This class takes the functions from IStatusBar that come in on
31  * binder pool threads and posts messages to get them onto the main
32  * thread, and calls onto Callbacks.  It also takes care of
33  * coalescing these calls so they don't stack up.  For the calls
34  * are coalesced, note that they are all idempotent.
35  */
36 public class CommandQueue extends IStatusBar.Stub {
37     private static final int INDEX_MASK = 0xffff;
38     private static final int MSG_SHIFT  = 16;
39     private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
40 
41     private static final int OP_SET_ICON    = 1;
42     private static final int OP_REMOVE_ICON = 2;
43 
44     private static final int MSG_ICON                       = 1 << MSG_SHIFT;
45     private static final int MSG_DISABLE                    = 2 << MSG_SHIFT;
46     private static final int MSG_EXPAND_NOTIFICATIONS       = 3 << MSG_SHIFT;
47     private static final int MSG_COLLAPSE_PANELS            = 4 << MSG_SHIFT;
48     private static final int MSG_EXPAND_SETTINGS            = 5 << MSG_SHIFT;
49     private static final int MSG_SET_SYSTEMUI_VISIBILITY    = 6 << MSG_SHIFT;
50     private static final int MSG_TOP_APP_WINDOW_CHANGED     = 7 << MSG_SHIFT;
51     private static final int MSG_SHOW_IME_BUTTON            = 8 << MSG_SHIFT;
52     private static final int MSG_TOGGLE_RECENT_APPS         = 9 << MSG_SHIFT;
53     private static final int MSG_PRELOAD_RECENT_APPS        = 10 << MSG_SHIFT;
54     private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 11 << MSG_SHIFT;
55     private static final int MSG_SET_WINDOW_STATE           = 12 << MSG_SHIFT;
56     private static final int MSG_SHOW_RECENT_APPS           = 13 << MSG_SHIFT;
57     private static final int MSG_HIDE_RECENT_APPS           = 14 << MSG_SHIFT;
58     private static final int MSG_BUZZ_BEEP_BLINKED          = 15 << MSG_SHIFT;
59     private static final int MSG_NOTIFICATION_LIGHT_OFF     = 16 << MSG_SHIFT;
60     private static final int MSG_NOTIFICATION_LIGHT_PULSE   = 17 << MSG_SHIFT;
61     private static final int MSG_SHOW_SCREEN_PIN_REQUEST    = 18 << MSG_SHIFT;
62     private static final int MSG_APP_TRANSITION_PENDING     = 19 << MSG_SHIFT;
63     private static final int MSG_APP_TRANSITION_CANCELLED   = 20 << MSG_SHIFT;
64     private static final int MSG_APP_TRANSITION_STARTING    = 21 << MSG_SHIFT;
65     private static final int MSG_ASSIST_DISCLOSURE          = 22 << MSG_SHIFT;
66     private static final int MSG_START_ASSIST               = 23 << MSG_SHIFT;
67     private static final int MSG_CAMERA_LAUNCH_GESTURE      = 24 << MSG_SHIFT;
68 
69     public static final int FLAG_EXCLUDE_NONE = 0;
70     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
71     public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1;
72     public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2;
73     public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3;
74     public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4;
75 
76     private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
77 
78     private StatusBarIconList mList;
79     private Callbacks mCallbacks;
80     private Handler mHandler = new H();
81 
82     /**
83      * These methods are called back on the main thread.
84      */
85     public interface Callbacks {
addIcon(String slot, int index, int viewIndex, StatusBarIcon icon)86         public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);
updateIcon(String slot, int index, int viewIndex, StatusBarIcon old, StatusBarIcon icon)87         public void updateIcon(String slot, int index, int viewIndex,
88                 StatusBarIcon old, StatusBarIcon icon);
removeIcon(String slot, int index, int viewIndex)89         public void removeIcon(String slot, int index, int viewIndex);
disable(int state1, int state2, boolean animate)90         public void disable(int state1, int state2, boolean animate);
animateExpandNotificationsPanel()91         public void animateExpandNotificationsPanel();
animateCollapsePanels(int flags)92         public void animateCollapsePanels(int flags);
animateExpandSettingsPanel()93         public void animateExpandSettingsPanel();
setSystemUiVisibility(int vis, int mask)94         public void setSystemUiVisibility(int vis, int mask);
topAppWindowChanged(boolean visible)95         public void topAppWindowChanged(boolean visible);
setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher)96         public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
97                 boolean showImeSwitcher);
showRecentApps(boolean triggeredFromAltTab)98         public void showRecentApps(boolean triggeredFromAltTab);
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)99         public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
toggleRecentApps()100         public void toggleRecentApps();
preloadRecentApps()101         public void preloadRecentApps();
cancelPreloadRecentApps()102         public void cancelPreloadRecentApps();
setWindowState(int window, int state)103         public void setWindowState(int window, int state);
buzzBeepBlinked()104         public void buzzBeepBlinked();
notificationLightOff()105         public void notificationLightOff();
notificationLightPulse(int argb, int onMillis, int offMillis)106         public void notificationLightPulse(int argb, int onMillis, int offMillis);
showScreenPinningRequest()107         public void showScreenPinningRequest();
appTransitionPending()108         public void appTransitionPending();
appTransitionCancelled()109         public void appTransitionCancelled();
appTransitionStarting(long startTime, long duration)110         public void appTransitionStarting(long startTime, long duration);
showAssistDisclosure()111         public void showAssistDisclosure();
startAssist(Bundle args)112         public void startAssist(Bundle args);
onCameraLaunchGestureDetected(int source)113         public void onCameraLaunchGestureDetected(int source);
114     }
115 
CommandQueue(Callbacks callbacks, StatusBarIconList list)116     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
117         mCallbacks = callbacks;
118         mList = list;
119     }
120 
setIcon(int index, StatusBarIcon icon)121     public void setIcon(int index, StatusBarIcon icon) {
122         synchronized (mList) {
123             int what = MSG_ICON | index;
124             mHandler.removeMessages(what);
125             mHandler.obtainMessage(what, OP_SET_ICON, 0, icon.clone()).sendToTarget();
126         }
127     }
128 
removeIcon(int index)129     public void removeIcon(int index) {
130         synchronized (mList) {
131             int what = MSG_ICON | index;
132             mHandler.removeMessages(what);
133             mHandler.obtainMessage(what, OP_REMOVE_ICON, 0, null).sendToTarget();
134         }
135     }
136 
disable(int state1, int state2)137     public void disable(int state1, int state2) {
138         synchronized (mList) {
139             mHandler.removeMessages(MSG_DISABLE);
140             mHandler.obtainMessage(MSG_DISABLE, state1, state2, null).sendToTarget();
141         }
142     }
143 
animateExpandNotificationsPanel()144     public void animateExpandNotificationsPanel() {
145         synchronized (mList) {
146             mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS);
147             mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS);
148         }
149     }
150 
animateCollapsePanels()151     public void animateCollapsePanels() {
152         synchronized (mList) {
153             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
154             mHandler.sendEmptyMessage(MSG_COLLAPSE_PANELS);
155         }
156     }
157 
animateExpandSettingsPanel()158     public void animateExpandSettingsPanel() {
159         synchronized (mList) {
160             mHandler.removeMessages(MSG_EXPAND_SETTINGS);
161             mHandler.sendEmptyMessage(MSG_EXPAND_SETTINGS);
162         }
163     }
164 
setSystemUiVisibility(int vis, int mask)165     public void setSystemUiVisibility(int vis, int mask) {
166         synchronized (mList) {
167             // Don't coalesce these, since it might have one time flags set such as
168             // STATUS_BAR_UNHIDE which might get lost.
169             mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, vis, mask, null).sendToTarget();
170         }
171     }
172 
topAppWindowChanged(boolean menuVisible)173     public void topAppWindowChanged(boolean menuVisible) {
174         synchronized (mList) {
175             mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED);
176             mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0,
177                     null).sendToTarget();
178         }
179     }
180 
setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher)181     public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
182             boolean showImeSwitcher) {
183         synchronized (mList) {
184             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
185             Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, vis, backDisposition, token);
186             m.getData().putBoolean(SHOW_IME_SWITCHER_KEY, showImeSwitcher);
187             m.sendToTarget();
188         }
189     }
190 
showRecentApps(boolean triggeredFromAltTab)191     public void showRecentApps(boolean triggeredFromAltTab) {
192         synchronized (mList) {
193             mHandler.removeMessages(MSG_SHOW_RECENT_APPS);
194             mHandler.obtainMessage(MSG_SHOW_RECENT_APPS,
195                     triggeredFromAltTab ? 1 : 0, 0, null).sendToTarget();
196         }
197     }
198 
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)199     public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
200         synchronized (mList) {
201             mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
202             mHandler.obtainMessage(MSG_HIDE_RECENT_APPS,
203                     triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0,
204                     null).sendToTarget();
205         }
206     }
207 
toggleRecentApps()208     public void toggleRecentApps() {
209         synchronized (mList) {
210             mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
211             mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
212         }
213     }
214 
preloadRecentApps()215     public void preloadRecentApps() {
216         synchronized (mList) {
217             mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS);
218             mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
219         }
220     }
221 
cancelPreloadRecentApps()222     public void cancelPreloadRecentApps() {
223         synchronized (mList) {
224             mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS);
225             mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
226         }
227     }
228 
setWindowState(int window, int state)229     public void setWindowState(int window, int state) {
230         synchronized (mList) {
231             // don't coalesce these
232             mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
233         }
234     }
235 
buzzBeepBlinked()236     public void buzzBeepBlinked() {
237         synchronized (mList) {
238             mHandler.removeMessages(MSG_BUZZ_BEEP_BLINKED);
239             mHandler.sendEmptyMessage(MSG_BUZZ_BEEP_BLINKED);
240         }
241     }
242 
notificationLightOff()243     public void notificationLightOff() {
244         synchronized (mList) {
245             mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
246         }
247     }
248 
notificationLightPulse(int argb, int onMillis, int offMillis)249     public void notificationLightPulse(int argb, int onMillis, int offMillis) {
250         synchronized (mList) {
251             mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
252                     .sendToTarget();
253         }
254     }
255 
showScreenPinningRequest()256     public void showScreenPinningRequest() {
257         synchronized (mList) {
258             mHandler.sendEmptyMessage(MSG_SHOW_SCREEN_PIN_REQUEST);
259         }
260     }
261 
appTransitionPending()262     public void appTransitionPending() {
263         synchronized (mList) {
264             mHandler.removeMessages(MSG_APP_TRANSITION_PENDING);
265             mHandler.sendEmptyMessage(MSG_APP_TRANSITION_PENDING);
266         }
267     }
268 
appTransitionCancelled()269     public void appTransitionCancelled() {
270         synchronized (mList) {
271             mHandler.removeMessages(MSG_APP_TRANSITION_PENDING);
272             mHandler.sendEmptyMessage(MSG_APP_TRANSITION_PENDING);
273         }
274     }
275 
appTransitionStarting(long startTime, long duration)276     public void appTransitionStarting(long startTime, long duration) {
277         synchronized (mList) {
278             mHandler.removeMessages(MSG_APP_TRANSITION_STARTING);
279             mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, Pair.create(startTime, duration))
280                     .sendToTarget();
281         }
282     }
283 
showAssistDisclosure()284     public void showAssistDisclosure() {
285         synchronized (mList) {
286             mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
287             mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget();
288         }
289     }
290 
startAssist(Bundle args)291     public void startAssist(Bundle args) {
292         synchronized (mList) {
293             mHandler.removeMessages(MSG_START_ASSIST);
294             mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget();
295         }
296     }
297 
298     @Override
onCameraLaunchGestureDetected(int source)299     public void onCameraLaunchGestureDetected(int source) {
300         synchronized (mList) {
301             mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE);
302             mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget();
303         }
304     }
305 
306     private final class H extends Handler {
handleMessage(Message msg)307         public void handleMessage(Message msg) {
308             final int what = msg.what & MSG_MASK;
309             switch (what) {
310                 case MSG_ICON: {
311                     final int index = msg.what & INDEX_MASK;
312                     final int viewIndex = mList.getViewIndex(index);
313                     switch (msg.arg1) {
314                         case OP_SET_ICON: {
315                             StatusBarIcon icon = (StatusBarIcon)msg.obj;
316                             StatusBarIcon old = mList.getIcon(index);
317                             if (old == null) {
318                                 mList.setIcon(index, icon);
319                                 mCallbacks.addIcon(mList.getSlot(index), index, viewIndex, icon);
320                             } else {
321                                 mList.setIcon(index, icon);
322                                 mCallbacks.updateIcon(mList.getSlot(index), index, viewIndex,
323                                         old, icon);
324                             }
325                             break;
326                         }
327                         case OP_REMOVE_ICON:
328                             if (mList.getIcon(index) != null) {
329                                 mList.removeIcon(index);
330                                 mCallbacks.removeIcon(mList.getSlot(index), index, viewIndex);
331                             }
332                             break;
333                     }
334                     break;
335                 }
336                 case MSG_DISABLE:
337                     mCallbacks.disable(msg.arg1, msg.arg2, true /* animate */);
338                     break;
339                 case MSG_EXPAND_NOTIFICATIONS:
340                     mCallbacks.animateExpandNotificationsPanel();
341                     break;
342                 case MSG_COLLAPSE_PANELS:
343                     mCallbacks.animateCollapsePanels(0);
344                     break;
345                 case MSG_EXPAND_SETTINGS:
346                     mCallbacks.animateExpandSettingsPanel();
347                     break;
348                 case MSG_SET_SYSTEMUI_VISIBILITY:
349                     mCallbacks.setSystemUiVisibility(msg.arg1, msg.arg2);
350                     break;
351                 case MSG_TOP_APP_WINDOW_CHANGED:
352                     mCallbacks.topAppWindowChanged(msg.arg1 != 0);
353                     break;
354                 case MSG_SHOW_IME_BUTTON:
355                     mCallbacks.setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2,
356                             msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false));
357                     break;
358                 case MSG_SHOW_RECENT_APPS:
359                     mCallbacks.showRecentApps(msg.arg1 != 0);
360                     break;
361                 case MSG_HIDE_RECENT_APPS:
362                     mCallbacks.hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
363                     break;
364                 case MSG_TOGGLE_RECENT_APPS:
365                     mCallbacks.toggleRecentApps();
366                     break;
367                 case MSG_PRELOAD_RECENT_APPS:
368                     mCallbacks.preloadRecentApps();
369                     break;
370                 case MSG_CANCEL_PRELOAD_RECENT_APPS:
371                     mCallbacks.cancelPreloadRecentApps();
372                     break;
373                 case MSG_SET_WINDOW_STATE:
374                     mCallbacks.setWindowState(msg.arg1, msg.arg2);
375                     break;
376                 case MSG_BUZZ_BEEP_BLINKED:
377                     mCallbacks.buzzBeepBlinked();
378                     break;
379                 case MSG_NOTIFICATION_LIGHT_OFF:
380                     mCallbacks.notificationLightOff();
381                     break;
382                 case MSG_NOTIFICATION_LIGHT_PULSE:
383                     mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
384                     break;
385                 case MSG_SHOW_SCREEN_PIN_REQUEST:
386                     mCallbacks.showScreenPinningRequest();
387                     break;
388                 case MSG_APP_TRANSITION_PENDING:
389                     mCallbacks.appTransitionPending();
390                     break;
391                 case MSG_APP_TRANSITION_CANCELLED:
392                     mCallbacks.appTransitionCancelled();
393                     break;
394                 case MSG_APP_TRANSITION_STARTING:
395                     Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
396                     mCallbacks.appTransitionStarting(data.first, data.second);
397                     break;
398                 case MSG_ASSIST_DISCLOSURE:
399                     mCallbacks.showAssistDisclosure();
400                     break;
401                 case MSG_START_ASSIST:
402                     mCallbacks.startAssist((Bundle) msg.obj);
403                     break;
404                 case MSG_CAMERA_LAUNCH_GESTURE:
405                     mCallbacks.onCameraLaunchGestureDetected(msg.arg1);
406                     break;
407             }
408         }
409     }
410 }
411 
412