blob: 439eebe7bca41bec776c8b72a19be92b1c9c5259 [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
John Spurlock13451a22012-09-28 14:40:41 -040067 final 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;
John Spurlock13451a22012-09-28 14:40:41 -040078 int mCurrentUserId;
satok06487a52010-10-29 11:37:18 +090079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 private class DisableRecord implements IBinder.DeathRecipient {
John Spurlock13451a22012-09-28 14:40:41 -040081 int userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 String pkg;
83 int what;
84 IBinder token;
85
86 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080087 Slog.i(TAG, "binder died for pkg=" + pkg);
John Spurlock13451a22012-09-28 14:40:41 -040088 disableInternal(userId, 0, token, pkg);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -070089 token.unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 }
91 }
92
93 public interface NotificationCallbacks {
94 void onSetDisabled(int status);
95 void onClearAll();
Fred Quintana6ecaff12009-09-25 14:23:13 -070096 void onNotificationClick(String pkg, String tag, int id);
Daniel Sandler0f0b11c2010-08-04 15:54:58 -040097 void onNotificationClear(String pkg, String tag, int id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 void onPanelRevealed();
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -070099 void onNotificationError(String pkg, String tag, int id,
100 int uid, int initialPid, String message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 }
102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 /**
104 * Construct the service, add the status bar view to the window manager
105 */
Jeff Brown2992ea72011-01-28 22:04:14 -0800106 public StatusBarManagerService(Context context, WindowManagerService windowManager) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 mContext = context;
Jeff Brown2992ea72011-01-28 22:04:14 -0800108 mWindowManager = windowManager;
109 mWindowManager.setOnHardKeyboardStatusChangeListener(this);
Joe Onorato0cbda992010-05-02 16:28:15 -0700110
111 final Resources res = context.getResources();
Joe Onorato75144ea2010-06-07 12:36:25 -0700112 mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 }
114
115 public void setNotificationCallbacks(NotificationCallbacks listener) {
116 mNotificationCallbacks = listener;
117 }
118
119 // ================================================================================
Joe Onorato25f95f92010-04-08 18:37:10 -0500120 // From IStatusBarService
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 // ================================================================================
Daniel Sandler11cf1782012-09-27 14:03:08 -0400122 public void expandNotificationsPanel() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 enforceExpandStatusBar();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700124
125 if (mBar != null) {
126 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400127 mBar.animateExpandNotificationsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700128 } catch (RemoteException ex) {
129 }
130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 }
132
Daniel Sandler11cf1782012-09-27 14:03:08 -0400133 public void collapsePanels() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 enforceExpandStatusBar();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135
Joe Onorato4762c2d2010-05-17 15:42:59 -0700136 if (mBar != null) {
137 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400138 mBar.animateCollapsePanels();
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700139 } catch (RemoteException ex) {
140 }
141 }
142 }
143
Daniel Sandler11cf1782012-09-27 14:03:08 -0400144 public void expandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700145 enforceExpandStatusBar();
146
147 if (mBar != null) {
148 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400149 mBar.animateExpandSettingsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700150 } catch (RemoteException ex) {
151 }
152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 }
154
155 public void disable(int what, IBinder token, String pkg) {
John Spurlock13451a22012-09-28 14:40:41 -0400156 disableInternal(mCurrentUserId, what, token, pkg);
157 }
158
159 private void disableInternal(int userId, int what, IBinder token, String pkg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 enforceStatusBar();
Joe Onoratof3f0e052010-05-14 18:49:29 -0700161
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800162 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400163 disableLocked(userId, what, token, pkg);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800164 }
165 }
166
John Spurlock13451a22012-09-28 14:40:41 -0400167 private void disableLocked(int userId, int what, IBinder token, String pkg) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700168 // It's important that the the callback and the call to mBar get done
169 // in the same order when multiple threads are calling this function
170 // so they are paired correctly. The messages on the handler will be
171 // handled in the order they were enqueued, but will be outside the lock.
John Spurlock13451a22012-09-28 14:40:41 -0400172 manageDisableListLocked(userId, what, token, pkg);
173 final int net = gatherDisableActionsLocked(userId);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800174 if (net != mDisabled) {
175 mDisabled = net;
176 mHandler.post(new Runnable() {
177 public void run() {
178 mNotificationCallbacks.onSetDisabled(net);
Joe Onoratof3f0e052010-05-14 18:49:29 -0700179 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800180 });
181 if (mBar != null) {
182 try {
183 mBar.disable(net);
184 } catch (RemoteException ex) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700185 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 }
188 }
189
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700190 public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
191 String contentDescription) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700193
194 synchronized (mIcons) {
195 int index = mIcons.getSlotIndex(slot);
196 if (index < 0) {
197 throw new SecurityException("invalid status bar icon slot: " + slot);
198 }
199
Amith Yamasani98edc952012-09-25 14:09:27 -0700200 StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
201 iconLevel, 0,
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700202 contentDescription);
Joe Onorato66d7d012010-05-14 10:05:10 -0700203 //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
Joe Onorato0cbda992010-05-02 16:28:15 -0700204 mIcons.setIcon(index, icon);
205
Joe Onorato0cbda992010-05-02 16:28:15 -0700206 if (mBar != null) {
207 try {
208 mBar.setIcon(index, icon);
209 } catch (RemoteException ex) {
210 }
211 }
212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 }
214
Joe Onorato0cbda992010-05-02 16:28:15 -0700215 public void setIconVisibility(String slot, boolean visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700217
Joe Onorato514ad6632010-05-13 18:49:00 -0700218 synchronized (mIcons) {
219 int index = mIcons.getSlotIndex(slot);
220 if (index < 0) {
221 throw new SecurityException("invalid status bar icon slot: " + slot);
222 }
223
224 StatusBarIcon icon = mIcons.getIcon(index);
225 if (icon == null) {
226 return;
227 }
228
229 if (icon.visible != visible) {
230 icon.visible = visible;
231
Joe Onorato514ad6632010-05-13 18:49:00 -0700232 if (mBar != null) {
233 try {
234 mBar.setIcon(index, icon);
235 } catch (RemoteException ex) {
236 }
237 }
238 }
239 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700240 }
241
242 public void removeIcon(String slot) {
243 enforceStatusBar();
244
245 synchronized (mIcons) {
246 int index = mIcons.getSlotIndex(slot);
247 if (index < 0) {
248 throw new SecurityException("invalid status bar icon slot: " + slot);
249 }
250
251 mIcons.removeIcon(index);
252
Joe Onorato0cbda992010-05-02 16:28:15 -0700253 if (mBar != null) {
254 try {
255 mBar.removeIcon(index);
256 } catch (RemoteException ex) {
257 }
258 }
259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 }
261
Daniel Sandlere02d8082010-10-08 15:13:22 -0400262 /**
263 * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
264 * response to a window with FLAG_NEEDS_MENU_KEY set.
265 */
Dianne Hackborn7d049322011-06-14 15:00:32 -0700266 public void topAppWindowChanged(final boolean menuVisible) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400267 enforceStatusBar();
268
Dianne Hackborn7d049322011-06-14 15:00:32 -0700269 if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
Daniel Sandlere02d8082010-10-08 15:13:22 -0400270
271 synchronized(mLock) {
Dianne Hackborn7d049322011-06-14 15:00:32 -0700272 mMenuVisible = menuVisible;
273 mHandler.post(new Runnable() {
274 public void run() {
275 if (mBar != null) {
276 try {
277 mBar.topAppWindowChanged(menuVisible);
278 } catch (RemoteException ex) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400279 }
280 }
Dianne Hackborn7d049322011-06-14 15:00:32 -0700281 }
282 });
Daniel Sandlere02d8082010-10-08 15:13:22 -0400283 }
284 }
285
Joe Onorato857fd9b2011-01-27 15:08:35 -0800286 public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) {
satok06487a52010-10-29 11:37:18 +0900287 enforceStatusBar();
288
Joe Onorato857fd9b2011-01-27 15:08:35 -0800289 if (SPEW) {
290 Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
291 }
satok06487a52010-10-29 11:37:18 +0900292
293 synchronized(mLock) {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800294 // In case of IME change, we need to call up setImeWindowStatus() regardless of
295 // mImeWindowVis because mImeWindowVis may not have been set to false when the
satok06e07442010-11-02 19:46:55 +0900296 // previous IME was destroyed.
Joe Onorato857fd9b2011-01-27 15:08:35 -0800297 mImeWindowVis = vis;
298 mImeBackDisposition = backDisposition;
299 mImeToken = token;
satok06e07442010-11-02 19:46:55 +0900300 mHandler.post(new Runnable() {
301 public void run() {
302 if (mBar != null) {
303 try {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800304 mBar.setImeWindowStatus(token, vis, backDisposition);
satok06e07442010-11-02 19:46:55 +0900305 } catch (RemoteException ex) {
satok06487a52010-10-29 11:37:18 +0900306 }
307 }
satok06e07442010-11-02 19:46:55 +0900308 }
309 });
satok06487a52010-10-29 11:37:18 +0900310 }
311 }
312
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700313 public void setSystemUiVisibility(int vis, int mask) {
Joe Onorato55bf3802011-01-25 13:42:10 -0800314 // also allows calls from window manager which is in this process.
Joe Onoratof63b0f42010-09-12 17:03:19 -0400315 enforceStatusBarService();
316
Jeff Sharkey4519a022011-09-07 23:24:53 -0700317 if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
Daniel Sandler60ee2562011-07-22 12:34:33 -0400318
Joe Onoratof63b0f42010-09-12 17:03:19 -0400319 synchronized (mLock) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700320 updateUiVisibilityLocked(vis, mask);
John Spurlock13451a22012-09-28 14:40:41 -0400321 disableLocked(
322 mCurrentUserId,
323 vis & StatusBarManager.DISABLE_MASK,
324 mSysUiVisToken,
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800325 "WindowManager.LayoutParams");
Joe Onoratof63b0f42010-09-12 17:03:19 -0400326 }
327 }
328
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700329 private void updateUiVisibilityLocked(final int vis, final int mask) {
Daniel Sandler60ee2562011-07-22 12:34:33 -0400330 if (mSystemUiVisibility != vis) {
331 mSystemUiVisibility = vis;
Joe Onoratof63b0f42010-09-12 17:03:19 -0400332 mHandler.post(new Runnable() {
333 public void run() {
334 if (mBar != null) {
335 try {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700336 mBar.setSystemUiVisibility(vis, mask);
Joe Onoratof63b0f42010-09-12 17:03:19 -0400337 } catch (RemoteException ex) {
Joe Onorato93056472010-09-10 10:30:46 -0400338 }
339 }
Joe Onoratof63b0f42010-09-12 17:03:19 -0400340 }
341 });
Joe Onorato93056472010-09-10 10:30:46 -0400342 }
343 }
344
Jeff Brown2992ea72011-01-28 22:04:14 -0800345 public void setHardKeyboardEnabled(final boolean enabled) {
346 mHandler.post(new Runnable() {
347 public void run() {
348 mWindowManager.setHardKeyboardEnabled(enabled);
349 }
350 });
351 }
352
353 @Override
354 public void onHardKeyboardStatusChange(final boolean available, final boolean enabled) {
355 mHandler.post(new Runnable() {
356 public void run() {
357 if (mBar != null) {
358 try {
359 mBar.setHardKeyboardStatus(available, enabled);
360 } catch (RemoteException ex) {
361 }
362 }
363 }
364 });
365 }
366
Michael Jurka3b1fc472011-06-13 10:54:40 -0700367 @Override
368 public void toggleRecentApps() {
369 if (mBar != null) {
370 try {
371 mBar.toggleRecentApps();
372 } catch (RemoteException ex) {}
373 }
374 }
375
Michael Jurka7f2668c2012-03-27 07:49:52 -0700376 @Override
377 public void preloadRecentApps() {
378 if (mBar != null) {
379 try {
380 mBar.preloadRecentApps();
381 } catch (RemoteException ex) {}
382 }
383 }
384
385 @Override
386 public void cancelPreloadRecentApps() {
387 if (mBar != null) {
388 try {
389 mBar.cancelPreloadRecentApps();
390 } catch (RemoteException ex) {}
391 }
392 }
393
John Spurlock13451a22012-09-28 14:40:41 -0400394 @Override
395 public void setCurrentUser(int newUserId) {
396 if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
397 mCurrentUserId = newUserId;
398 }
399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 private void enforceStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700401 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700402 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 }
404
405 private void enforceExpandStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700406 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700407 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 }
409
Joe Onorato8bc6c512010-06-04 16:21:12 -0400410 private void enforceStatusBarService() {
411 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
412 "StatusBarManagerService");
413 }
414
Joe Onorato4762c2d2010-05-17 15:42:59 -0700415 // ================================================================================
416 // Callbacks from the status bar service.
417 // ================================================================================
Joe Onorato75199e32010-05-29 17:22:51 -0400418 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
Joe Onorato93056472010-09-10 10:30:46 -0400419 List<IBinder> notificationKeys, List<StatusBarNotification> notifications,
satokcd7cd292010-11-20 15:46:23 +0900420 int switches[], List<IBinder> binders) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400421 enforceStatusBarService();
422
Joe Onorato0cbda992010-05-02 16:28:15 -0700423 Slog.i(TAG, "registerStatusBar bar=" + bar);
424 mBar = bar;
Joe Onorato75199e32010-05-29 17:22:51 -0400425 synchronized (mIcons) {
426 iconList.copyFrom(mIcons);
427 }
428 synchronized (mNotifications) {
429 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
430 notificationKeys.add(e.getKey());
431 notifications.add(e.getValue());
432 }
433 }
Joe Onorato93056472010-09-10 10:30:46 -0400434 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400435 switches[0] = gatherDisableActionsLocked(mCurrentUserId);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400436 switches[1] = mSystemUiVisibility;
Joe Onoratoe4c7b3f2010-10-30 12:15:03 -0700437 switches[2] = mMenuVisible ? 1 : 0;
Joe Onorato857fd9b2011-01-27 15:08:35 -0800438 switches[3] = mImeWindowVis;
439 switches[4] = mImeBackDisposition;
440 binders.add(mImeToken);
Joe Onorato93056472010-09-10 10:30:46 -0400441 }
Jeff Brown2992ea72011-01-28 22:04:14 -0800442 switches[5] = mWindowManager.isHardKeyboardAvailable() ? 1 : 0;
443 switches[6] = mWindowManager.isHardKeyboardEnabled() ? 1 : 0;
Joe Onorato2314aab2010-04-08 16:41:23 -0500444 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400445
Joe Onorato4762c2d2010-05-17 15:42:59 -0700446 /**
Joe Onoratof1f25912010-06-07 11:52:41 -0700447 * The status bar service should call this each time the user brings the panel from
448 * invisible to visible in order to clear the notification light.
Joe Onorato4762c2d2010-05-17 15:42:59 -0700449 */
Joe Onoratof1f25912010-06-07 11:52:41 -0700450 public void onPanelRevealed() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400451 enforceStatusBarService();
452
Joe Onoratof1f25912010-06-07 11:52:41 -0700453 // tell the notification manager to turn off the lights.
454 mNotificationCallbacks.onPanelRevealed();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700455 }
456
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400457 public void onNotificationClick(String pkg, String tag, int id) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400458 enforceStatusBarService();
459
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400460 mNotificationCallbacks.onNotificationClick(pkg, tag, id);
461 }
462
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700463 public void onNotificationError(String pkg, String tag, int id,
464 int uid, int initialPid, String message) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400465 enforceStatusBarService();
466
Joe Onorato005847b2010-06-04 16:08:02 -0400467 // WARNING: this will call back into us to do the remove. Don't hold any locks.
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700468 mNotificationCallbacks.onNotificationError(pkg, tag, id, uid, initialPid, message);
Joe Onorato005847b2010-06-04 16:08:02 -0400469 }
470
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400471 public void onNotificationClear(String pkg, String tag, int id) {
472 enforceStatusBarService();
473
474 mNotificationCallbacks.onNotificationClear(pkg, tag, id);
475 }
476
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400477 public void onClearAllNotifications() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400478 enforceStatusBarService();
479
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400480 mNotificationCallbacks.onClearAll();
481 }
482
Joe Onorato18e69df2010-05-17 22:26:12 -0700483 // ================================================================================
484 // Callbacks for NotificationManagerService.
485 // ================================================================================
486 public IBinder addNotification(StatusBarNotification notification) {
487 synchronized (mNotifications) {
Joe Onoratoa0c56fe2010-05-20 10:21:52 -0700488 IBinder key = new Binder();
Joe Onorato75199e32010-05-29 17:22:51 -0400489 mNotifications.put(key, notification);
Joe Onoratoe345fff2010-05-23 15:18:27 -0400490 if (mBar != null) {
491 try {
492 mBar.addNotification(key, notification);
493 } catch (RemoteException ex) {
494 }
495 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700496 return key;
497 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700498 }
499
Joe Onorato18e69df2010-05-17 22:26:12 -0700500 public void updateNotification(IBinder key, StatusBarNotification notification) {
501 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400502 if (!mNotifications.containsKey(key)) {
503 throw new IllegalArgumentException("updateNotification key not found: " + key);
504 }
505 mNotifications.put(key, notification);
Joe Onoratoe345fff2010-05-23 15:18:27 -0400506 if (mBar != null) {
507 try {
508 mBar.updateNotification(key, notification);
509 } catch (RemoteException ex) {
510 }
511 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700512 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700513 }
514
515 public void removeNotification(IBinder key) {
Joe Onorato18e69df2010-05-17 22:26:12 -0700516 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400517 final StatusBarNotification n = mNotifications.remove(key);
518 if (n == null) {
Daniel Sandlerfe0806a2012-05-16 12:41:33 -0400519 Slog.e(TAG, "removeNotification key not found: " + key);
520 return;
Joe Onorato75199e32010-05-29 17:22:51 -0400521 }
Joe Onoratoe345fff2010-05-23 15:18:27 -0400522 if (mBar != null) {
523 try {
524 mBar.removeNotification(key);
525 } catch (RemoteException ex) {
526 }
527 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700528 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700529 }
Joe Onorato2314aab2010-04-08 16:41:23 -0500530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 // ================================================================================
532 // Can be called from any thread
533 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 // lock on mDisableRecords
John Spurlock13451a22012-09-28 14:40:41 -0400536 void manageDisableListLocked(int userId, int what, IBinder token, String pkg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 if (SPEW) {
John Spurlock13451a22012-09-28 14:40:41 -0400538 Slog.d(TAG, "manageDisableList userId=" + userId
539 + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 }
541 // update the list
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800542 final int N = mDisableRecords.size();
543 DisableRecord tok = null;
544 int i;
545 for (i=0; i<N; i++) {
546 DisableRecord t = mDisableRecords.get(i);
John Spurlock4e6922d2012-10-04 14:51:51 -0400547 if (t.token == token && t.userId == userId) {
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800548 tok = t;
549 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800551 }
552 if (what == 0 || !token.isBinderAlive()) {
553 if (tok != null) {
554 mDisableRecords.remove(i);
555 tok.token.unlinkToDeath(tok, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800557 } else {
558 if (tok == null) {
559 tok = new DisableRecord();
John Spurlock13451a22012-09-28 14:40:41 -0400560 tok.userId = userId;
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800561 try {
562 token.linkToDeath(tok, 0);
563 }
564 catch (RemoteException ex) {
565 return; // give up
566 }
567 mDisableRecords.add(tok);
568 }
569 tok.what = what;
570 tok.token = token;
571 tok.pkg = pkg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 }
573 }
574
575 // lock on mDisableRecords
John Spurlock13451a22012-09-28 14:40:41 -0400576 int gatherDisableActionsLocked(int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 final int N = mDisableRecords.size();
578 // gather the new net flags
579 int net = 0;
580 for (int i=0; i<N; i++) {
John Spurlock13451a22012-09-28 14:40:41 -0400581 final DisableRecord rec = mDisableRecords.get(i);
582 if (rec.userId == userId) {
583 net |= rec.what;
584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586 return net;
587 }
588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 // ================================================================================
590 // Always called from UI thread
591 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
594 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
595 != PackageManager.PERMISSION_GRANTED) {
596 pw.println("Permission Denial: can't dump StatusBar from from pid="
597 + Binder.getCallingPid()
598 + ", uid=" + Binder.getCallingUid());
599 return;
600 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700601
Joe Onorato0cbda992010-05-02 16:28:15 -0700602 synchronized (mIcons) {
603 mIcons.dump(pw);
604 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700605
606 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400607 int i=0;
608 pw.println("Notification list:");
609 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
610 pw.printf(" %2d: %s\n", i, e.getValue().toString());
611 i++;
612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700614
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800615 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400616 pw.println(" mDisabled=0x" + Integer.toHexString(mDisabled));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 final int N = mDisableRecords.size();
John Spurlock13451a22012-09-28 14:40:41 -0400618 pw.println(" mDisableRecords.size=" + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 for (int i=0; i<N; i++) {
620 DisableRecord tok = mDisableRecords.get(i);
John Spurlock13451a22012-09-28 14:40:41 -0400621 pw.println(" [" + i + "] userId=" + tok.userId
622 + " what=0x" + Integer.toHexString(tok.what)
623 + " pkg=" + tok.pkg
624 + " token=" + tok.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 }
626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 }
628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
630 public void onReceive(Context context, Intent intent) {
631 String action = intent.getAction();
Joe Onoratof9e0e6b2009-09-08 16:24:36 -0400632 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
633 || Intent.ACTION_SCREEN_OFF.equals(action)) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400634 collapsePanels();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700636 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
638 updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
639 intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
640 intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
641 intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
642 }
643 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
644 updateResources();
645 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700646 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 }
648 };
649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650}