blob: 1d2072c2cc27324efc6d079e33f0fe8416579d64 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
Joe Onorato7a0f36b2010-06-07 10:24:36 -070017package com.android.server;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.app.PendingIntent;
20import android.app.StatusBarManager;
21import android.content.BroadcastReceiver;
Joe Onorato9e875fc2010-06-07 11:12:11 -070022import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
26import android.content.pm.PackageManager;
27import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.net.Uri;
29import android.os.IBinder;
30import android.os.RemoteException;
31import android.os.Binder;
Joe Onoratof3f0e052010-05-14 18:49:29 -070032import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.os.SystemClock;
Joe Onorato8a9b2202010-02-26 18:56:32 -080034import android.util.Slog;
Joe Onorato664644d2011-01-23 17:53:23 -080035import android.view.View;
Joe Onorato0cbda992010-05-02 16:28:15 -070036
37import com.android.internal.statusbar.IStatusBar;
38import com.android.internal.statusbar.IStatusBarService;
39import com.android.internal.statusbar.StatusBarIcon;
40import com.android.internal.statusbar.StatusBarIconList;
Joe Onorato18e69df2010-05-17 22:26:12 -070041import com.android.internal.statusbar.StatusBarNotification;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080042import com.android.server.wm.WindowManagerService;
The Android Open Source Project10592532009-03-18 17:39:46 -070043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import java.io.FileDescriptor;
45import java.io.PrintWriter;
46import java.util.ArrayList;
47import java.util.HashMap;
Joe Onorato75199e32010-05-29 17:22:51 -040048import java.util.List;
49import java.util.Map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
51
52/**
Joe Onoratof3f0e052010-05-14 18:49:29 -070053 * A note on locking: We rely on the fact that calls onto mBar are oneway or
54 * if they are local, that they just enqueue messages to not deadlock.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 */
Joe Onorato089de882010-04-12 08:18:45 -070056public class StatusBarManagerService extends IStatusBarService.Stub
Jeff Brown2992ea72011-01-28 22:04:14 -080057 implements WindowManagerService.OnHardKeyboardStatusChangeListener
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058{
Joe Onorato4762c2d2010-05-17 15:42:59 -070059 static final String TAG = "StatusBarManagerService";
Joe Onorato431bb222010-10-18 19:13:23 -040060 static final boolean SPEW = false;
Joe Onoratodf7dbb62009-11-17 10:43:37 -080061
Joe Onoratof3f0e052010-05-14 18:49:29 -070062 final Context mContext;
Jeff Brown2992ea72011-01-28 22:04:14 -080063 final WindowManagerService mWindowManager;
Joe Onoratof3f0e052010-05-14 18:49:29 -070064 Handler mHandler = new Handler();
65 NotificationCallbacks mNotificationCallbacks;
Joe Onorato4762c2d2010-05-17 15:42:59 -070066 volatile IStatusBar mBar;
Joe Onoratof3f0e052010-05-14 18:49:29 -070067 StatusBarIconList mIcons = new StatusBarIconList();
Joe Onorato75199e32010-05-29 17:22:51 -040068 HashMap<IBinder,StatusBarNotification> mNotifications
69 = new HashMap<IBinder,StatusBarNotification>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
Joe Onoratof3f0e052010-05-14 18:49:29 -070071 // for disabling the status bar
72 ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
Joe Onorato7bb8eeb2011-01-27 16:00:58 -080073 IBinder mSysUiVisToken = new Binder();
Joe Onoratof3f0e052010-05-14 18:49:29 -070074 int mDisabled = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075
Joe Onorato93056472010-09-10 10:30:46 -040076 Object mLock = new Object();
77 // We usually call it lights out mode, but double negatives are annoying
78 boolean mLightsOn = true;
Daniel Sandlere02d8082010-10-08 15:13:22 -040079 boolean mMenuVisible = false;
Joe Onorato857fd9b2011-01-27 15:08:35 -080080 int mImeWindowVis = 0;
81 int mImeBackDisposition;
82 IBinder mImeToken = null;
satok06487a52010-10-29 11:37:18 +090083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 private class DisableRecord implements IBinder.DeathRecipient {
85 String pkg;
86 int what;
87 IBinder token;
88
89 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080090 Slog.i(TAG, "binder died for pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 disable(0, token, pkg);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -070092 token.unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
94 }
95
96 public interface NotificationCallbacks {
97 void onSetDisabled(int status);
98 void onClearAll();
Fred Quintana6ecaff12009-09-25 14:23:13 -070099 void onNotificationClick(String pkg, String tag, int id);
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400100 void onNotificationClear(String pkg, String tag, int id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 void onPanelRevealed();
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700102 void onNotificationError(String pkg, String tag, int id,
103 int uid, int initialPid, String message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 }
105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 /**
107 * Construct the service, add the status bar view to the window manager
108 */
Jeff Brown2992ea72011-01-28 22:04:14 -0800109 public StatusBarManagerService(Context context, WindowManagerService windowManager) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 mContext = context;
Jeff Brown2992ea72011-01-28 22:04:14 -0800111 mWindowManager = windowManager;
112 mWindowManager.setOnHardKeyboardStatusChangeListener(this);
Joe Onorato0cbda992010-05-02 16:28:15 -0700113
114 final Resources res = context.getResources();
Joe Onorato75144ea2010-06-07 12:36:25 -0700115 mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 }
117
118 public void setNotificationCallbacks(NotificationCallbacks listener) {
119 mNotificationCallbacks = listener;
120 }
121
122 // ================================================================================
Joe Onorato25f95f92010-04-08 18:37:10 -0500123 // From IStatusBarService
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 // ================================================================================
Daniel Sandler1d4d30a2011-04-28 12:35:29 -0400125 public void userActivity() {
126 if (mBar != null) try {
127 mBar.userActivity();
128 } catch (RemoteException ex) {}
129 }
Joe Onoratof3f0e052010-05-14 18:49:29 -0700130 public void expand() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 enforceExpandStatusBar();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700132
133 if (mBar != null) {
134 try {
135 mBar.animateExpand();
136 } catch (RemoteException ex) {
137 }
138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 }
140
Joe Onoratof3f0e052010-05-14 18:49:29 -0700141 public void collapse() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 enforceExpandStatusBar();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143
Joe Onorato4762c2d2010-05-17 15:42:59 -0700144 if (mBar != null) {
145 try {
146 mBar.animateCollapse();
147 } catch (RemoteException ex) {
148 }
149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 }
151
152 public void disable(int what, IBinder token, String pkg) {
153 enforceStatusBar();
Joe Onoratof3f0e052010-05-14 18:49:29 -0700154
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800155 synchronized (mLock) {
156 disableLocked(what, token, pkg);
157 }
158 }
159
160 private void disableLocked(int what, IBinder token, String pkg) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700161 // It's important that the the callback and the call to mBar get done
162 // in the same order when multiple threads are calling this function
163 // so they are paired correctly. The messages on the handler will be
164 // handled in the order they were enqueued, but will be outside the lock.
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800165 manageDisableListLocked(what, token, pkg);
166 final int net = gatherDisableActionsLocked();
167 if (net != mDisabled) {
168 mDisabled = net;
169 mHandler.post(new Runnable() {
170 public void run() {
171 mNotificationCallbacks.onSetDisabled(net);
Joe Onoratof3f0e052010-05-14 18:49:29 -0700172 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800173 });
174 if (mBar != null) {
175 try {
176 mBar.disable(net);
177 } catch (RemoteException ex) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 }
181 }
182
Joe Onorato0cbda992010-05-02 16:28:15 -0700183 public void setIcon(String slot, String iconPackage, int iconId, int iconLevel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700185
186 synchronized (mIcons) {
187 int index = mIcons.getSlotIndex(slot);
188 if (index < 0) {
189 throw new SecurityException("invalid status bar icon slot: " + slot);
190 }
191
192 StatusBarIcon icon = new StatusBarIcon(iconPackage, iconId, iconLevel);
Joe Onorato66d7d012010-05-14 10:05:10 -0700193 //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
Joe Onorato0cbda992010-05-02 16:28:15 -0700194 mIcons.setIcon(index, icon);
195
Joe Onorato0cbda992010-05-02 16:28:15 -0700196 if (mBar != null) {
197 try {
198 mBar.setIcon(index, icon);
199 } catch (RemoteException ex) {
200 }
201 }
202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 }
204
Joe Onorato0cbda992010-05-02 16:28:15 -0700205 public void setIconVisibility(String slot, boolean visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700207
Joe Onorato514ad6632010-05-13 18:49:00 -0700208 synchronized (mIcons) {
209 int index = mIcons.getSlotIndex(slot);
210 if (index < 0) {
211 throw new SecurityException("invalid status bar icon slot: " + slot);
212 }
213
214 StatusBarIcon icon = mIcons.getIcon(index);
215 if (icon == null) {
216 return;
217 }
218
219 if (icon.visible != visible) {
220 icon.visible = visible;
221
Joe Onorato514ad6632010-05-13 18:49:00 -0700222 if (mBar != null) {
223 try {
224 mBar.setIcon(index, icon);
225 } catch (RemoteException ex) {
226 }
227 }
228 }
229 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700230 }
231
232 public void removeIcon(String slot) {
233 enforceStatusBar();
234
235 synchronized (mIcons) {
236 int index = mIcons.getSlotIndex(slot);
237 if (index < 0) {
238 throw new SecurityException("invalid status bar icon slot: " + slot);
239 }
240
241 mIcons.removeIcon(index);
242
Joe Onorato0cbda992010-05-02 16:28:15 -0700243 if (mBar != null) {
244 try {
245 mBar.removeIcon(index);
246 } catch (RemoteException ex) {
247 }
248 }
249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 }
251
Daniel Sandlere02d8082010-10-08 15:13:22 -0400252 /**
253 * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
254 * response to a window with FLAG_NEEDS_MENU_KEY set.
255 */
256 public void setMenuKeyVisible(final boolean visible) {
257 enforceStatusBar();
258
259 if (SPEW) Slog.d(TAG, (visible?"showing":"hiding") + " MENU key");
260
261 synchronized(mLock) {
262 if (mMenuVisible != visible) {
263 mMenuVisible = visible;
264 mHandler.post(new Runnable() {
265 public void run() {
266 if (mBar != null) {
267 try {
268 mBar.setMenuKeyVisible(visible);
269 } catch (RemoteException ex) {
270 }
271 }
272 }
273 });
274 }
275 }
276 }
277
Joe Onorato857fd9b2011-01-27 15:08:35 -0800278 public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) {
satok06487a52010-10-29 11:37:18 +0900279 enforceStatusBar();
280
Joe Onorato857fd9b2011-01-27 15:08:35 -0800281 if (SPEW) {
282 Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
283 }
satok06487a52010-10-29 11:37:18 +0900284
285 synchronized(mLock) {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800286 // In case of IME change, we need to call up setImeWindowStatus() regardless of
287 // mImeWindowVis because mImeWindowVis may not have been set to false when the
satok06e07442010-11-02 19:46:55 +0900288 // previous IME was destroyed.
Joe Onorato857fd9b2011-01-27 15:08:35 -0800289 mImeWindowVis = vis;
290 mImeBackDisposition = backDisposition;
291 mImeToken = token;
satok06e07442010-11-02 19:46:55 +0900292 mHandler.post(new Runnable() {
293 public void run() {
294 if (mBar != null) {
295 try {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800296 mBar.setImeWindowStatus(token, vis, backDisposition);
satok06e07442010-11-02 19:46:55 +0900297 } catch (RemoteException ex) {
satok06487a52010-10-29 11:37:18 +0900298 }
299 }
satok06e07442010-11-02 19:46:55 +0900300 }
301 });
satok06487a52010-10-29 11:37:18 +0900302 }
303 }
304
Joe Onorato664644d2011-01-23 17:53:23 -0800305 public void setSystemUiVisibility(int vis) {
Joe Onorato55bf3802011-01-25 13:42:10 -0800306 // also allows calls from window manager which is in this process.
Joe Onoratof63b0f42010-09-12 17:03:19 -0400307 enforceStatusBarService();
308
309 synchronized (mLock) {
Joe Onorato664644d2011-01-23 17:53:23 -0800310 final boolean lightsOn = (vis & View.STATUS_BAR_HIDDEN) == 0;
Joe Onoratof63b0f42010-09-12 17:03:19 -0400311 updateLightsOnLocked(lightsOn);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800312 disableLocked(vis & StatusBarManager.DISABLE_MASK, mSysUiVisToken,
313 "WindowManager.LayoutParams");
Joe Onoratof63b0f42010-09-12 17:03:19 -0400314 }
315 }
316
317 private void updateLightsOnLocked(final boolean lightsOn) {
318 if (mLightsOn != lightsOn) {
319 mLightsOn = lightsOn;
320 mHandler.post(new Runnable() {
321 public void run() {
322 if (mBar != null) {
323 try {
324 mBar.setLightsOn(lightsOn);
325 } catch (RemoteException ex) {
Joe Onorato93056472010-09-10 10:30:46 -0400326 }
327 }
Joe Onoratof63b0f42010-09-12 17:03:19 -0400328 }
329 });
Joe Onorato93056472010-09-10 10:30:46 -0400330 }
331 }
332
Jeff Brown2992ea72011-01-28 22:04:14 -0800333 public void setHardKeyboardEnabled(final boolean enabled) {
334 mHandler.post(new Runnable() {
335 public void run() {
336 mWindowManager.setHardKeyboardEnabled(enabled);
337 }
338 });
339 }
340
341 @Override
342 public void onHardKeyboardStatusChange(final boolean available, final boolean enabled) {
343 mHandler.post(new Runnable() {
344 public void run() {
345 if (mBar != null) {
346 try {
347 mBar.setHardKeyboardStatus(available, enabled);
348 } catch (RemoteException ex) {
349 }
350 }
351 }
352 });
353 }
354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 private void enforceStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700356 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700357 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 }
359
360 private void enforceExpandStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700361 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700362 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 }
364
Joe Onorato8bc6c512010-06-04 16:21:12 -0400365 private void enforceStatusBarService() {
366 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
367 "StatusBarManagerService");
368 }
369
Joe Onorato4762c2d2010-05-17 15:42:59 -0700370 // ================================================================================
371 // Callbacks from the status bar service.
372 // ================================================================================
Joe Onorato75199e32010-05-29 17:22:51 -0400373 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
Joe Onorato93056472010-09-10 10:30:46 -0400374 List<IBinder> notificationKeys, List<StatusBarNotification> notifications,
satokcd7cd292010-11-20 15:46:23 +0900375 int switches[], List<IBinder> binders) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400376 enforceStatusBarService();
377
Joe Onorato0cbda992010-05-02 16:28:15 -0700378 Slog.i(TAG, "registerStatusBar bar=" + bar);
379 mBar = bar;
Joe Onorato75199e32010-05-29 17:22:51 -0400380 synchronized (mIcons) {
381 iconList.copyFrom(mIcons);
382 }
383 synchronized (mNotifications) {
384 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
385 notificationKeys.add(e.getKey());
386 notifications.add(e.getValue());
387 }
388 }
Joe Onorato93056472010-09-10 10:30:46 -0400389 synchronized (mLock) {
Joe Onoratoe4c7b3f2010-10-30 12:15:03 -0700390 switches[0] = gatherDisableActionsLocked();
391 switches[1] = mLightsOn ? 1 : 0;
392 switches[2] = mMenuVisible ? 1 : 0;
Joe Onorato857fd9b2011-01-27 15:08:35 -0800393 switches[3] = mImeWindowVis;
394 switches[4] = mImeBackDisposition;
395 binders.add(mImeToken);
Joe Onorato93056472010-09-10 10:30:46 -0400396 }
Jeff Brown2992ea72011-01-28 22:04:14 -0800397 switches[5] = mWindowManager.isHardKeyboardAvailable() ? 1 : 0;
398 switches[6] = mWindowManager.isHardKeyboardEnabled() ? 1 : 0;
Joe Onorato2314aab2010-04-08 16:41:23 -0500399 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400400
Joe Onorato4762c2d2010-05-17 15:42:59 -0700401 /**
Joe Onoratof1f25912010-06-07 11:52:41 -0700402 * The status bar service should call this each time the user brings the panel from
403 * invisible to visible in order to clear the notification light.
Joe Onorato4762c2d2010-05-17 15:42:59 -0700404 */
Joe Onoratof1f25912010-06-07 11:52:41 -0700405 public void onPanelRevealed() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400406 enforceStatusBarService();
407
Joe Onoratof1f25912010-06-07 11:52:41 -0700408 // tell the notification manager to turn off the lights.
409 mNotificationCallbacks.onPanelRevealed();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700410 }
411
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400412 public void onNotificationClick(String pkg, String tag, int id) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400413 enforceStatusBarService();
414
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400415 mNotificationCallbacks.onNotificationClick(pkg, tag, id);
416 }
417
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700418 public void onNotificationError(String pkg, String tag, int id,
419 int uid, int initialPid, String message) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400420 enforceStatusBarService();
421
Joe Onorato005847b2010-06-04 16:08:02 -0400422 // WARNING: this will call back into us to do the remove. Don't hold any locks.
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700423 mNotificationCallbacks.onNotificationError(pkg, tag, id, uid, initialPid, message);
Joe Onorato005847b2010-06-04 16:08:02 -0400424 }
425
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400426 public void onNotificationClear(String pkg, String tag, int id) {
427 enforceStatusBarService();
428
429 mNotificationCallbacks.onNotificationClear(pkg, tag, id);
430 }
431
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400432 public void onClearAllNotifications() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400433 enforceStatusBarService();
434
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400435 mNotificationCallbacks.onClearAll();
436 }
437
Joe Onorato18e69df2010-05-17 22:26:12 -0700438 // ================================================================================
439 // Callbacks for NotificationManagerService.
440 // ================================================================================
441 public IBinder addNotification(StatusBarNotification notification) {
442 synchronized (mNotifications) {
Joe Onoratoa0c56fe2010-05-20 10:21:52 -0700443 IBinder key = new Binder();
Joe Onorato75199e32010-05-29 17:22:51 -0400444 mNotifications.put(key, notification);
Joe Onoratoe345fff2010-05-23 15:18:27 -0400445 if (mBar != null) {
446 try {
447 mBar.addNotification(key, notification);
448 } catch (RemoteException ex) {
449 }
450 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700451 return key;
452 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700453 }
454
Joe Onorato18e69df2010-05-17 22:26:12 -0700455 public void updateNotification(IBinder key, StatusBarNotification notification) {
456 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400457 if (!mNotifications.containsKey(key)) {
458 throw new IllegalArgumentException("updateNotification key not found: " + key);
459 }
460 mNotifications.put(key, notification);
Joe Onoratoe345fff2010-05-23 15:18:27 -0400461 if (mBar != null) {
462 try {
463 mBar.updateNotification(key, notification);
464 } catch (RemoteException ex) {
465 }
466 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700467 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700468 }
469
470 public void removeNotification(IBinder key) {
Joe Onorato18e69df2010-05-17 22:26:12 -0700471 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400472 final StatusBarNotification n = mNotifications.remove(key);
473 if (n == null) {
474 throw new IllegalArgumentException("removeNotification key not found: " + key);
475 }
Joe Onoratoe345fff2010-05-23 15:18:27 -0400476 if (mBar != null) {
477 try {
478 mBar.removeNotification(key);
479 } catch (RemoteException ex) {
480 }
481 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700482 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700483 }
Joe Onorato2314aab2010-04-08 16:41:23 -0500484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 // ================================================================================
486 // Can be called from any thread
487 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 // lock on mDisableRecords
490 void manageDisableListLocked(int what, IBinder token, String pkg) {
491 if (SPEW) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700492 Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 }
494 // update the list
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800495 final int N = mDisableRecords.size();
496 DisableRecord tok = null;
497 int i;
498 for (i=0; i<N; i++) {
499 DisableRecord t = mDisableRecords.get(i);
500 if (t.token == token) {
501 tok = t;
502 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800504 }
505 if (what == 0 || !token.isBinderAlive()) {
506 if (tok != null) {
507 mDisableRecords.remove(i);
508 tok.token.unlinkToDeath(tok, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800510 } else {
511 if (tok == null) {
512 tok = new DisableRecord();
513 try {
514 token.linkToDeath(tok, 0);
515 }
516 catch (RemoteException ex) {
517 return; // give up
518 }
519 mDisableRecords.add(tok);
520 }
521 tok.what = what;
522 tok.token = token;
523 tok.pkg = pkg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 }
525 }
526
527 // lock on mDisableRecords
528 int gatherDisableActionsLocked() {
529 final int N = mDisableRecords.size();
530 // gather the new net flags
531 int net = 0;
532 for (int i=0; i<N; i++) {
533 net |= mDisableRecords.get(i).what;
534 }
535 return net;
536 }
537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 // ================================================================================
539 // Always called from UI thread
540 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
543 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
544 != PackageManager.PERMISSION_GRANTED) {
545 pw.println("Permission Denial: can't dump StatusBar from from pid="
546 + Binder.getCallingPid()
547 + ", uid=" + Binder.getCallingUid());
548 return;
549 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700550
Joe Onorato0cbda992010-05-02 16:28:15 -0700551 synchronized (mIcons) {
552 mIcons.dump(pw);
553 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700554
555 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400556 int i=0;
557 pw.println("Notification list:");
558 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
559 pw.printf(" %2d: %s\n", i, e.getValue().toString());
560 i++;
561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700563
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800564 synchronized (mLock) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 final int N = mDisableRecords.size();
566 pw.println(" mDisableRecords.size=" + N
567 + " mDisabled=0x" + Integer.toHexString(mDisabled));
568 for (int i=0; i<N; i++) {
569 DisableRecord tok = mDisableRecords.get(i);
570 pw.println(" [" + i + "] what=0x" + Integer.toHexString(tok.what)
571 + " pkg=" + tok.pkg + " token=" + tok.token);
572 }
573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 }
575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
577 public void onReceive(Context context, Intent intent) {
578 String action = intent.getAction();
Joe Onoratof9e0e6b2009-09-08 16:24:36 -0400579 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
580 || Intent.ACTION_SCREEN_OFF.equals(action)) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700581 collapse();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700583 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
585 updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
586 intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
587 intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
588 intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
589 }
590 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
591 updateResources();
592 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700593 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595 };
596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597}