blob: 87b0eb313a7c01047eee5c01a6c933ca32093cbe [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.StatusBarManager;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.content.pm.PackageManager;
24import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.Binder;
Joe Onoratof3f0e052010-05-14 18:49:29 -070026import android.os.Handler;
Svetoslav Ganov6179ea32011-06-28 01:12:41 -070027import android.os.IBinder;
28import android.os.RemoteException;
Amith Yamasani98edc952012-09-25 14:09:27 -070029import android.os.UserHandle;
Joe Onorato8a9b2202010-02-26 18:56:32 -080030import android.util.Slog;
Joe Onorato0cbda992010-05-02 16:28:15 -070031
32import com.android.internal.statusbar.IStatusBar;
33import com.android.internal.statusbar.IStatusBarService;
34import com.android.internal.statusbar.StatusBarIcon;
35import com.android.internal.statusbar.StatusBarIconList;
Joe Onorato18e69df2010-05-17 22:26:12 -070036import com.android.internal.statusbar.StatusBarNotification;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080037import com.android.server.wm.WindowManagerService;
The Android Open Source Project10592532009-03-18 17:39:46 -070038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import java.io.FileDescriptor;
40import java.io.PrintWriter;
41import java.util.ArrayList;
42import java.util.HashMap;
Joe Onorato75199e32010-05-29 17:22:51 -040043import java.util.List;
44import java.util.Map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045
46
47/**
Joe Onoratof3f0e052010-05-14 18:49:29 -070048 * A note on locking: We rely on the fact that calls onto mBar are oneway or
49 * if they are local, that they just enqueue messages to not deadlock.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 */
Joe Onorato089de882010-04-12 08:18:45 -070051public class StatusBarManagerService extends IStatusBarService.Stub
Jeff Brown2992ea72011-01-28 22:04:14 -080052 implements WindowManagerService.OnHardKeyboardStatusChangeListener
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053{
Joe Onorato4762c2d2010-05-17 15:42:59 -070054 static final String TAG = "StatusBarManagerService";
Joe Onorato431bb222010-10-18 19:13:23 -040055 static final boolean SPEW = false;
Joe Onoratodf7dbb62009-11-17 10:43:37 -080056
Joe Onoratof3f0e052010-05-14 18:49:29 -070057 final Context mContext;
Jeff Brown2992ea72011-01-28 22:04:14 -080058 final WindowManagerService mWindowManager;
Joe Onoratof3f0e052010-05-14 18:49:29 -070059 Handler mHandler = new Handler();
60 NotificationCallbacks mNotificationCallbacks;
Joe Onorato4762c2d2010-05-17 15:42:59 -070061 volatile IStatusBar mBar;
Joe Onoratof3f0e052010-05-14 18:49:29 -070062 StatusBarIconList mIcons = new StatusBarIconList();
Joe Onorato75199e32010-05-29 17:22:51 -040063 HashMap<IBinder,StatusBarNotification> mNotifications
64 = new HashMap<IBinder,StatusBarNotification>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065
Joe Onoratof3f0e052010-05-14 18:49:29 -070066 // for disabling the status bar
67 ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
Joe Onorato7bb8eeb2011-01-27 16:00:58 -080068 IBinder mSysUiVisToken = new Binder();
Joe Onoratof3f0e052010-05-14 18:49:29 -070069 int mDisabled = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
Joe Onorato93056472010-09-10 10:30:46 -040071 Object mLock = new Object();
Daniel Sandler60ee2562011-07-22 12:34:33 -040072 // encompasses lights-out mode and other flags defined on View
73 int mSystemUiVisibility = 0;
Daniel Sandlere02d8082010-10-08 15:13:22 -040074 boolean mMenuVisible = false;
Joe Onorato857fd9b2011-01-27 15:08:35 -080075 int mImeWindowVis = 0;
76 int mImeBackDisposition;
77 IBinder mImeToken = null;
satok06487a52010-10-29 11:37:18 +090078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 private class DisableRecord implements IBinder.DeathRecipient {
80 String pkg;
81 int what;
82 IBinder token;
83
84 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080085 Slog.i(TAG, "binder died for pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 disable(0, token, pkg);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -070087 token.unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 }
89 }
90
91 public interface NotificationCallbacks {
92 void onSetDisabled(int status);
93 void onClearAll();
Fred Quintana6ecaff12009-09-25 14:23:13 -070094 void onNotificationClick(String pkg, String tag, int id);
Daniel Sandler0f0b11c2010-08-04 15:54:58 -040095 void onNotificationClear(String pkg, String tag, int id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 void onPanelRevealed();
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -070097 void onNotificationError(String pkg, String tag, int id,
98 int uid, int initialPid, String message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 }
100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 /**
102 * Construct the service, add the status bar view to the window manager
103 */
Jeff Brown2992ea72011-01-28 22:04:14 -0800104 public StatusBarManagerService(Context context, WindowManagerService windowManager) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 mContext = context;
Jeff Brown2992ea72011-01-28 22:04:14 -0800106 mWindowManager = windowManager;
107 mWindowManager.setOnHardKeyboardStatusChangeListener(this);
Joe Onorato0cbda992010-05-02 16:28:15 -0700108
109 final Resources res = context.getResources();
Joe Onorato75144ea2010-06-07 12:36:25 -0700110 mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 }
112
113 public void setNotificationCallbacks(NotificationCallbacks listener) {
114 mNotificationCallbacks = listener;
115 }
116
117 // ================================================================================
Joe Onorato25f95f92010-04-08 18:37:10 -0500118 // From IStatusBarService
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 // ================================================================================
Daniel Sandler11cf17812012-09-27 14:03:08 -0400120 public void expandNotificationsPanel() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 enforceExpandStatusBar();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700122
123 if (mBar != null) {
124 try {
Daniel Sandler11cf17812012-09-27 14:03:08 -0400125 mBar.animateExpandNotificationsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700126 } catch (RemoteException ex) {
127 }
128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 }
130
Daniel Sandler11cf17812012-09-27 14:03:08 -0400131 public void collapsePanels() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 enforceExpandStatusBar();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133
Joe Onorato4762c2d2010-05-17 15:42:59 -0700134 if (mBar != null) {
135 try {
Daniel Sandler11cf17812012-09-27 14:03:08 -0400136 mBar.animateCollapsePanels();
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700137 } catch (RemoteException ex) {
138 }
139 }
140 }
141
Daniel Sandler11cf17812012-09-27 14:03:08 -0400142 public void expandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700143 enforceExpandStatusBar();
144
145 if (mBar != null) {
146 try {
Daniel Sandler11cf17812012-09-27 14:03:08 -0400147 mBar.animateExpandSettingsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700148 } catch (RemoteException ex) {
149 }
150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 }
152
153 public void disable(int what, IBinder token, String pkg) {
154 enforceStatusBar();
Joe Onoratof3f0e052010-05-14 18:49:29 -0700155
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800156 synchronized (mLock) {
157 disableLocked(what, token, pkg);
158 }
159 }
160
161 private void disableLocked(int what, IBinder token, String pkg) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700162 // It's important that the the callback and the call to mBar get done
163 // in the same order when multiple threads are calling this function
164 // so they are paired correctly. The messages on the handler will be
165 // handled in the order they were enqueued, but will be outside the lock.
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800166 manageDisableListLocked(what, token, pkg);
167 final int net = gatherDisableActionsLocked();
168 if (net != mDisabled) {
169 mDisabled = net;
170 mHandler.post(new Runnable() {
171 public void run() {
172 mNotificationCallbacks.onSetDisabled(net);
Joe Onoratof3f0e052010-05-14 18:49:29 -0700173 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800174 });
175 if (mBar != null) {
176 try {
177 mBar.disable(net);
178 } catch (RemoteException ex) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 }
182 }
183
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700184 public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
185 String contentDescription) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700187
188 synchronized (mIcons) {
189 int index = mIcons.getSlotIndex(slot);
190 if (index < 0) {
191 throw new SecurityException("invalid status bar icon slot: " + slot);
192 }
193
Amith Yamasani98edc952012-09-25 14:09:27 -0700194 StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
195 iconLevel, 0,
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700196 contentDescription);
Joe Onorato66d7d012010-05-14 10:05:10 -0700197 //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
Joe Onorato0cbda992010-05-02 16:28:15 -0700198 mIcons.setIcon(index, icon);
199
Joe Onorato0cbda992010-05-02 16:28:15 -0700200 if (mBar != null) {
201 try {
202 mBar.setIcon(index, icon);
203 } catch (RemoteException ex) {
204 }
205 }
206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 }
208
Joe Onorato0cbda992010-05-02 16:28:15 -0700209 public void setIconVisibility(String slot, boolean visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700211
Joe Onorato514ad6632010-05-13 18:49:00 -0700212 synchronized (mIcons) {
213 int index = mIcons.getSlotIndex(slot);
214 if (index < 0) {
215 throw new SecurityException("invalid status bar icon slot: " + slot);
216 }
217
218 StatusBarIcon icon = mIcons.getIcon(index);
219 if (icon == null) {
220 return;
221 }
222
223 if (icon.visible != visible) {
224 icon.visible = visible;
225
Joe Onorato514ad6632010-05-13 18:49:00 -0700226 if (mBar != null) {
227 try {
228 mBar.setIcon(index, icon);
229 } catch (RemoteException ex) {
230 }
231 }
232 }
233 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700234 }
235
236 public void removeIcon(String slot) {
237 enforceStatusBar();
238
239 synchronized (mIcons) {
240 int index = mIcons.getSlotIndex(slot);
241 if (index < 0) {
242 throw new SecurityException("invalid status bar icon slot: " + slot);
243 }
244
245 mIcons.removeIcon(index);
246
Joe Onorato0cbda992010-05-02 16:28:15 -0700247 if (mBar != null) {
248 try {
249 mBar.removeIcon(index);
250 } catch (RemoteException ex) {
251 }
252 }
253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 }
255
Daniel Sandlere02d8082010-10-08 15:13:22 -0400256 /**
257 * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
258 * response to a window with FLAG_NEEDS_MENU_KEY set.
259 */
Dianne Hackborn7d049322011-06-14 15:00:32 -0700260 public void topAppWindowChanged(final boolean menuVisible) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400261 enforceStatusBar();
262
Dianne Hackborn7d049322011-06-14 15:00:32 -0700263 if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
Daniel Sandlere02d8082010-10-08 15:13:22 -0400264
265 synchronized(mLock) {
Dianne Hackborn7d049322011-06-14 15:00:32 -0700266 mMenuVisible = menuVisible;
267 mHandler.post(new Runnable() {
268 public void run() {
269 if (mBar != null) {
270 try {
271 mBar.topAppWindowChanged(menuVisible);
272 } catch (RemoteException ex) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400273 }
274 }
Dianne Hackborn7d049322011-06-14 15:00:32 -0700275 }
276 });
Daniel Sandlere02d8082010-10-08 15:13:22 -0400277 }
278 }
279
Joe Onorato857fd9b2011-01-27 15:08:35 -0800280 public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) {
satok06487a52010-10-29 11:37:18 +0900281 enforceStatusBar();
282
Joe Onorato857fd9b2011-01-27 15:08:35 -0800283 if (SPEW) {
284 Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
285 }
satok06487a52010-10-29 11:37:18 +0900286
287 synchronized(mLock) {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800288 // In case of IME change, we need to call up setImeWindowStatus() regardless of
289 // mImeWindowVis because mImeWindowVis may not have been set to false when the
satok06e07442010-11-02 19:46:55 +0900290 // previous IME was destroyed.
Joe Onorato857fd9b2011-01-27 15:08:35 -0800291 mImeWindowVis = vis;
292 mImeBackDisposition = backDisposition;
293 mImeToken = token;
satok06e07442010-11-02 19:46:55 +0900294 mHandler.post(new Runnable() {
295 public void run() {
296 if (mBar != null) {
297 try {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800298 mBar.setImeWindowStatus(token, vis, backDisposition);
satok06e07442010-11-02 19:46:55 +0900299 } catch (RemoteException ex) {
satok06487a52010-10-29 11:37:18 +0900300 }
301 }
satok06e07442010-11-02 19:46:55 +0900302 }
303 });
satok06487a52010-10-29 11:37:18 +0900304 }
305 }
306
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700307 public void setSystemUiVisibility(int vis, int mask) {
Joe Onorato55bf3802011-01-25 13:42:10 -0800308 // also allows calls from window manager which is in this process.
Joe Onoratof63b0f42010-09-12 17:03:19 -0400309 enforceStatusBarService();
310
Jeff Sharkey4519a022011-09-07 23:24:53 -0700311 if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
Daniel Sandler60ee2562011-07-22 12:34:33 -0400312
Joe Onoratof63b0f42010-09-12 17:03:19 -0400313 synchronized (mLock) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700314 updateUiVisibilityLocked(vis, mask);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800315 disableLocked(vis & StatusBarManager.DISABLE_MASK, mSysUiVisToken,
316 "WindowManager.LayoutParams");
Joe Onoratof63b0f42010-09-12 17:03:19 -0400317 }
318 }
319
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700320 private void updateUiVisibilityLocked(final int vis, final int mask) {
Daniel Sandler60ee2562011-07-22 12:34:33 -0400321 if (mSystemUiVisibility != vis) {
322 mSystemUiVisibility = vis;
Joe Onoratof63b0f42010-09-12 17:03:19 -0400323 mHandler.post(new Runnable() {
324 public void run() {
325 if (mBar != null) {
326 try {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700327 mBar.setSystemUiVisibility(vis, mask);
Joe Onoratof63b0f42010-09-12 17:03:19 -0400328 } catch (RemoteException ex) {
Joe Onorato93056472010-09-10 10:30:46 -0400329 }
330 }
Joe Onoratof63b0f42010-09-12 17:03:19 -0400331 }
332 });
Joe Onorato93056472010-09-10 10:30:46 -0400333 }
334 }
335
Jeff Brown2992ea72011-01-28 22:04:14 -0800336 public void setHardKeyboardEnabled(final boolean enabled) {
337 mHandler.post(new Runnable() {
338 public void run() {
339 mWindowManager.setHardKeyboardEnabled(enabled);
340 }
341 });
342 }
343
344 @Override
345 public void onHardKeyboardStatusChange(final boolean available, final boolean enabled) {
346 mHandler.post(new Runnable() {
347 public void run() {
348 if (mBar != null) {
349 try {
350 mBar.setHardKeyboardStatus(available, enabled);
351 } catch (RemoteException ex) {
352 }
353 }
354 }
355 });
356 }
357
Michael Jurka3b1fc472011-06-13 10:54:40 -0700358 @Override
359 public void toggleRecentApps() {
360 if (mBar != null) {
361 try {
362 mBar.toggleRecentApps();
363 } catch (RemoteException ex) {}
364 }
365 }
366
Michael Jurka7f2668c2012-03-27 07:49:52 -0700367 @Override
368 public void preloadRecentApps() {
369 if (mBar != null) {
370 try {
371 mBar.preloadRecentApps();
372 } catch (RemoteException ex) {}
373 }
374 }
375
376 @Override
377 public void cancelPreloadRecentApps() {
378 if (mBar != null) {
379 try {
380 mBar.cancelPreloadRecentApps();
381 } catch (RemoteException ex) {}
382 }
383 }
384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 private void enforceStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700386 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700387 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
389
390 private void enforceExpandStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700391 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700392 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 }
394
Joe Onorato8bc6c512010-06-04 16:21:12 -0400395 private void enforceStatusBarService() {
396 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
397 "StatusBarManagerService");
398 }
399
Joe Onorato4762c2d2010-05-17 15:42:59 -0700400 // ================================================================================
401 // Callbacks from the status bar service.
402 // ================================================================================
Joe Onorato75199e32010-05-29 17:22:51 -0400403 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
Joe Onorato93056472010-09-10 10:30:46 -0400404 List<IBinder> notificationKeys, List<StatusBarNotification> notifications,
satokcd7cd292010-11-20 15:46:23 +0900405 int switches[], List<IBinder> binders) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400406 enforceStatusBarService();
407
Joe Onorato0cbda992010-05-02 16:28:15 -0700408 Slog.i(TAG, "registerStatusBar bar=" + bar);
409 mBar = bar;
Joe Onorato75199e32010-05-29 17:22:51 -0400410 synchronized (mIcons) {
411 iconList.copyFrom(mIcons);
412 }
413 synchronized (mNotifications) {
414 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
415 notificationKeys.add(e.getKey());
416 notifications.add(e.getValue());
417 }
418 }
Joe Onorato93056472010-09-10 10:30:46 -0400419 synchronized (mLock) {
Joe Onoratoe4c7b3f2010-10-30 12:15:03 -0700420 switches[0] = gatherDisableActionsLocked();
Daniel Sandler60ee2562011-07-22 12:34:33 -0400421 switches[1] = mSystemUiVisibility;
Joe Onoratoe4c7b3f2010-10-30 12:15:03 -0700422 switches[2] = mMenuVisible ? 1 : 0;
Joe Onorato857fd9b2011-01-27 15:08:35 -0800423 switches[3] = mImeWindowVis;
424 switches[4] = mImeBackDisposition;
425 binders.add(mImeToken);
Joe Onorato93056472010-09-10 10:30:46 -0400426 }
Jeff Brown2992ea72011-01-28 22:04:14 -0800427 switches[5] = mWindowManager.isHardKeyboardAvailable() ? 1 : 0;
428 switches[6] = mWindowManager.isHardKeyboardEnabled() ? 1 : 0;
Joe Onorato2314aab2010-04-08 16:41:23 -0500429 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400430
Joe Onorato4762c2d2010-05-17 15:42:59 -0700431 /**
Joe Onoratof1f25912010-06-07 11:52:41 -0700432 * The status bar service should call this each time the user brings the panel from
433 * invisible to visible in order to clear the notification light.
Joe Onorato4762c2d2010-05-17 15:42:59 -0700434 */
Joe Onoratof1f25912010-06-07 11:52:41 -0700435 public void onPanelRevealed() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400436 enforceStatusBarService();
437
Joe Onoratof1f25912010-06-07 11:52:41 -0700438 // tell the notification manager to turn off the lights.
439 mNotificationCallbacks.onPanelRevealed();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700440 }
441
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400442 public void onNotificationClick(String pkg, String tag, int id) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400443 enforceStatusBarService();
444
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400445 mNotificationCallbacks.onNotificationClick(pkg, tag, id);
446 }
447
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700448 public void onNotificationError(String pkg, String tag, int id,
449 int uid, int initialPid, String message) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400450 enforceStatusBarService();
451
Joe Onorato005847b2010-06-04 16:08:02 -0400452 // WARNING: this will call back into us to do the remove. Don't hold any locks.
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700453 mNotificationCallbacks.onNotificationError(pkg, tag, id, uid, initialPid, message);
Joe Onorato005847b2010-06-04 16:08:02 -0400454 }
455
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400456 public void onNotificationClear(String pkg, String tag, int id) {
457 enforceStatusBarService();
458
459 mNotificationCallbacks.onNotificationClear(pkg, tag, id);
460 }
461
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400462 public void onClearAllNotifications() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400463 enforceStatusBarService();
464
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400465 mNotificationCallbacks.onClearAll();
466 }
467
Joe Onorato18e69df2010-05-17 22:26:12 -0700468 // ================================================================================
469 // Callbacks for NotificationManagerService.
470 // ================================================================================
471 public IBinder addNotification(StatusBarNotification notification) {
472 synchronized (mNotifications) {
Joe Onoratoa0c56fe2010-05-20 10:21:52 -0700473 IBinder key = new Binder();
Joe Onorato75199e32010-05-29 17:22:51 -0400474 mNotifications.put(key, notification);
Joe Onoratoe345fff2010-05-23 15:18:27 -0400475 if (mBar != null) {
476 try {
477 mBar.addNotification(key, notification);
478 } catch (RemoteException ex) {
479 }
480 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700481 return key;
482 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700483 }
484
Joe Onorato18e69df2010-05-17 22:26:12 -0700485 public void updateNotification(IBinder key, StatusBarNotification notification) {
486 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400487 if (!mNotifications.containsKey(key)) {
488 throw new IllegalArgumentException("updateNotification key not found: " + key);
489 }
490 mNotifications.put(key, notification);
Joe Onoratoe345fff2010-05-23 15:18:27 -0400491 if (mBar != null) {
492 try {
493 mBar.updateNotification(key, notification);
494 } catch (RemoteException ex) {
495 }
496 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700497 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700498 }
499
500 public void removeNotification(IBinder key) {
Joe Onorato18e69df2010-05-17 22:26:12 -0700501 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400502 final StatusBarNotification n = mNotifications.remove(key);
503 if (n == null) {
Daniel Sandlerfe0806a2012-05-16 12:41:33 -0400504 Slog.e(TAG, "removeNotification key not found: " + key);
505 return;
Joe Onorato75199e32010-05-29 17:22:51 -0400506 }
Joe Onoratoe345fff2010-05-23 15:18:27 -0400507 if (mBar != null) {
508 try {
509 mBar.removeNotification(key);
510 } catch (RemoteException ex) {
511 }
512 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700513 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700514 }
Joe Onorato2314aab2010-04-08 16:41:23 -0500515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 // ================================================================================
517 // Can be called from any thread
518 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 // lock on mDisableRecords
521 void manageDisableListLocked(int what, IBinder token, String pkg) {
522 if (SPEW) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700523 Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 }
525 // update the list
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800526 final int N = mDisableRecords.size();
527 DisableRecord tok = null;
528 int i;
529 for (i=0; i<N; i++) {
530 DisableRecord t = mDisableRecords.get(i);
531 if (t.token == token) {
532 tok = t;
533 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800535 }
536 if (what == 0 || !token.isBinderAlive()) {
537 if (tok != null) {
538 mDisableRecords.remove(i);
539 tok.token.unlinkToDeath(tok, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800541 } else {
542 if (tok == null) {
543 tok = new DisableRecord();
544 try {
545 token.linkToDeath(tok, 0);
546 }
547 catch (RemoteException ex) {
548 return; // give up
549 }
550 mDisableRecords.add(tok);
551 }
552 tok.what = what;
553 tok.token = token;
554 tok.pkg = pkg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 }
556 }
557
558 // lock on mDisableRecords
559 int gatherDisableActionsLocked() {
560 final int N = mDisableRecords.size();
561 // gather the new net flags
562 int net = 0;
563 for (int i=0; i<N; i++) {
564 net |= mDisableRecords.get(i).what;
565 }
566 return net;
567 }
568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 // ================================================================================
570 // Always called from UI thread
571 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
574 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
575 != PackageManager.PERMISSION_GRANTED) {
576 pw.println("Permission Denial: can't dump StatusBar from from pid="
577 + Binder.getCallingPid()
578 + ", uid=" + Binder.getCallingUid());
579 return;
580 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700581
Joe Onorato0cbda992010-05-02 16:28:15 -0700582 synchronized (mIcons) {
583 mIcons.dump(pw);
584 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700585
586 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400587 int i=0;
588 pw.println("Notification list:");
589 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
590 pw.printf(" %2d: %s\n", i, e.getValue().toString());
591 i++;
592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700594
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800595 synchronized (mLock) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 final int N = mDisableRecords.size();
597 pw.println(" mDisableRecords.size=" + N
598 + " mDisabled=0x" + Integer.toHexString(mDisabled));
599 for (int i=0; i<N; i++) {
600 DisableRecord tok = mDisableRecords.get(i);
601 pw.println(" [" + i + "] what=0x" + Integer.toHexString(tok.what)
602 + " pkg=" + tok.pkg + " token=" + tok.token);
603 }
604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
608 public void onReceive(Context context, Intent intent) {
609 String action = intent.getAction();
Joe Onoratof9e0e6b2009-09-08 16:24:36 -0400610 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
611 || Intent.ACTION_SCREEN_OFF.equals(action)) {
Daniel Sandler11cf17812012-09-27 14:03:08 -0400612 collapsePanels();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700614 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
616 updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
617 intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
618 intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
619 intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
620 }
621 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
622 updateResources();
623 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700624 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 }
626 };
627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628}