blob: e4b5f3ae0d416b5c208efa049e3db53369aecc34 [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
Adam Lesinski182f73f2013-12-05 16:48:06 -080017package com.android.server.statusbar;
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;
Adam Lesinski182f73f2013-12-05 16:48:06 -080020import android.os.Binder;
21import android.os.Handler;
22import android.os.IBinder;
23import android.os.RemoteException;
24import android.os.UserHandle;
Daniel Sandler5feceeb2013-03-22 18:29:23 -070025import android.service.notification.StatusBarNotification;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.content.Context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.content.pm.PackageManager;
28import android.content.res.Resources;
Joe Onorato8a9b2202010-02-26 18:56:32 -080029import android.util.Slog;
Joe Onorato0cbda992010-05-02 16:28:15 -070030
31import com.android.internal.statusbar.IStatusBar;
32import com.android.internal.statusbar.IStatusBarService;
33import com.android.internal.statusbar.StatusBarIcon;
34import com.android.internal.statusbar.StatusBarIconList;
Adam Lesinski182f73f2013-12-05 16:48:06 -080035import com.android.server.LocalServices;
36import com.android.server.notification.NotificationDelegate;
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{
Adam Lesinski182f73f2013-12-05 16:48:06 -080054 private static final String TAG = "StatusBarManagerService";
55 private static final boolean SPEW = false;
Joe Onoratodf7dbb62009-11-17 10:43:37 -080056
Adam Lesinski182f73f2013-12-05 16:48:06 -080057 private final Context mContext;
58 private final WindowManagerService mWindowManager;
59 private Handler mHandler = new Handler();
60 private NotificationDelegate mNotificationDelegate;
61 private volatile IStatusBar mBar;
62 private StatusBarIconList mIcons = new StatusBarIconList();
63 private HashMap<IBinder,StatusBarNotification> mNotifications
Joe Onorato75199e32010-05-29 17:22:51 -040064 = 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
Adam Lesinski182f73f2013-12-05 16:48:06 -080067 private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
68 private IBinder mSysUiVisToken = new Binder();
69 private int mDisabled = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
Adam Lesinski182f73f2013-12-05 16:48:06 -080071 private Object mLock = new Object();
Daniel Sandler60ee2562011-07-22 12:34:33 -040072 // encompasses lights-out mode and other flags defined on View
Adam Lesinski182f73f2013-12-05 16:48:06 -080073 private int mSystemUiVisibility = 0;
74 private boolean mMenuVisible = false;
75 private int mImeWindowVis = 0;
76 private int mImeBackDisposition;
77 private IBinder mImeToken = null;
78 private 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 /**
94 * Construct the service, add the status bar view to the window manager
95 */
Jeff Brown2992ea72011-01-28 22:04:14 -080096 public StatusBarManagerService(Context context, WindowManagerService windowManager) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 mContext = context;
Jeff Brown2992ea72011-01-28 22:04:14 -080098 mWindowManager = windowManager;
99 mWindowManager.setOnHardKeyboardStatusChangeListener(this);
Joe Onorato0cbda992010-05-02 16:28:15 -0700100
101 final Resources res = context.getResources();
Joe Onorato75144ea2010-06-07 12:36:25 -0700102 mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
Adam Lesinski182f73f2013-12-05 16:48:06 -0800103
104 LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 }
106
Adam Lesinski182f73f2013-12-05 16:48:06 -0800107 /**
108 * Private API used by NotificationManagerService.
109 */
110 private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
111 @Override
112 public void setNotificationDelegate(NotificationDelegate delegate) {
113 synchronized (mNotifications) {
114 mNotificationDelegate = delegate;
115 }
116 }
117
118 @Override
119 public IBinder addNotification(StatusBarNotification notification) {
120 synchronized (mNotifications) {
121 IBinder key = new Binder();
122 mNotifications.put(key, notification);
123 if (mBar != null) {
124 try {
125 mBar.addNotification(key, notification);
126 } catch (RemoteException ex) {
127 }
128 }
129 return key;
130 }
131 }
132
133 @Override
134 public void updateNotification(IBinder key, StatusBarNotification notification) {
135 synchronized (mNotifications) {
136 if (!mNotifications.containsKey(key)) {
137 throw new IllegalArgumentException("updateNotification key not found: " + key);
138 }
139 mNotifications.put(key, notification);
140 if (mBar != null) {
141 try {
142 mBar.updateNotification(key, notification);
143 } catch (RemoteException ex) {
144 }
145 }
146 }
147 }
148
149 @Override
150 public void removeNotification(IBinder key) {
151 synchronized (mNotifications) {
152 final StatusBarNotification n = mNotifications.remove(key);
153 if (n == null) {
154 Slog.e(TAG, "removeNotification key not found: " + key);
155 return;
156 }
157 if (mBar != null) {
158 try {
159 mBar.removeNotification(key);
160 } catch (RemoteException ex) {
161 }
162 }
163 }
164 }
165 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166
167 // ================================================================================
Joe Onorato25f95f92010-04-08 18:37:10 -0500168 // From IStatusBarService
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 // ================================================================================
Adam Lesinski182f73f2013-12-05 16:48:06 -0800170 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -0400171 public void expandNotificationsPanel() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 enforceExpandStatusBar();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700173
174 if (mBar != null) {
175 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400176 mBar.animateExpandNotificationsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700177 } catch (RemoteException ex) {
178 }
179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 }
181
Adam Lesinski182f73f2013-12-05 16:48:06 -0800182 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -0400183 public void collapsePanels() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 enforceExpandStatusBar();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
Joe Onorato4762c2d2010-05-17 15:42:59 -0700186 if (mBar != null) {
187 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400188 mBar.animateCollapsePanels();
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700189 } catch (RemoteException ex) {
190 }
191 }
192 }
193
Adam Lesinski182f73f2013-12-05 16:48:06 -0800194 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -0400195 public void expandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700196 enforceExpandStatusBar();
197
198 if (mBar != null) {
199 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400200 mBar.animateExpandSettingsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700201 } catch (RemoteException ex) {
202 }
203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 }
205
Adam Lesinski182f73f2013-12-05 16:48:06 -0800206 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 public void disable(int what, IBinder token, String pkg) {
John Spurlocke677d712014-02-13 12:52:19 -0500208 if (!mNotificationDelegate.allowDisable(what, token, pkg)) {
209 if (SPEW) Slog.d(TAG, "Blocking disable request from " + pkg);
210 return;
211 }
John Spurlock13451a22012-09-28 14:40:41 -0400212 disableInternal(mCurrentUserId, what, token, pkg);
213 }
214
215 private void disableInternal(int userId, int what, IBinder token, String pkg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 enforceStatusBar();
Joe Onoratof3f0e052010-05-14 18:49:29 -0700217
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800218 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400219 disableLocked(userId, what, token, pkg);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800220 }
221 }
222
John Spurlock13451a22012-09-28 14:40:41 -0400223 private void disableLocked(int userId, int what, IBinder token, String pkg) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700224 // It's important that the the callback and the call to mBar get done
225 // in the same order when multiple threads are calling this function
226 // so they are paired correctly. The messages on the handler will be
227 // handled in the order they were enqueued, but will be outside the lock.
John Spurlock13451a22012-09-28 14:40:41 -0400228 manageDisableListLocked(userId, what, token, pkg);
John Spurlock8f3e6d52012-11-29 13:56:24 -0500229
230 // Ensure state for the current user is applied, even if passed a non-current user.
231 final int net = gatherDisableActionsLocked(mCurrentUserId);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800232 if (net != mDisabled) {
233 mDisabled = net;
234 mHandler.post(new Runnable() {
235 public void run() {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800236 mNotificationDelegate.onSetDisabled(net);
Joe Onoratof3f0e052010-05-14 18:49:29 -0700237 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800238 });
239 if (mBar != null) {
240 try {
241 mBar.disable(net);
242 } catch (RemoteException ex) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 }
246 }
247
Adam Lesinski182f73f2013-12-05 16:48:06 -0800248 @Override
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700249 public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
250 String contentDescription) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700252
253 synchronized (mIcons) {
254 int index = mIcons.getSlotIndex(slot);
255 if (index < 0) {
256 throw new SecurityException("invalid status bar icon slot: " + slot);
257 }
258
Amith Yamasani98edc952012-09-25 14:09:27 -0700259 StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
260 iconLevel, 0,
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700261 contentDescription);
Joe Onorato66d7d012010-05-14 10:05:10 -0700262 //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
Joe Onorato0cbda992010-05-02 16:28:15 -0700263 mIcons.setIcon(index, icon);
264
Joe Onorato0cbda992010-05-02 16:28:15 -0700265 if (mBar != null) {
266 try {
267 mBar.setIcon(index, icon);
268 } catch (RemoteException ex) {
269 }
270 }
271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 }
273
Adam Lesinski182f73f2013-12-05 16:48:06 -0800274 @Override
Joe Onorato0cbda992010-05-02 16:28:15 -0700275 public void setIconVisibility(String slot, boolean visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700277
Joe Onorato514ad6632010-05-13 18:49:00 -0700278 synchronized (mIcons) {
279 int index = mIcons.getSlotIndex(slot);
280 if (index < 0) {
281 throw new SecurityException("invalid status bar icon slot: " + slot);
282 }
283
284 StatusBarIcon icon = mIcons.getIcon(index);
285 if (icon == null) {
286 return;
287 }
288
289 if (icon.visible != visible) {
290 icon.visible = visible;
291
Joe Onorato514ad6632010-05-13 18:49:00 -0700292 if (mBar != null) {
293 try {
294 mBar.setIcon(index, icon);
295 } catch (RemoteException ex) {
296 }
297 }
298 }
299 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700300 }
301
Adam Lesinski182f73f2013-12-05 16:48:06 -0800302 @Override
Joe Onorato0cbda992010-05-02 16:28:15 -0700303 public void removeIcon(String slot) {
304 enforceStatusBar();
305
306 synchronized (mIcons) {
307 int index = mIcons.getSlotIndex(slot);
308 if (index < 0) {
309 throw new SecurityException("invalid status bar icon slot: " + slot);
310 }
311
312 mIcons.removeIcon(index);
313
Joe Onorato0cbda992010-05-02 16:28:15 -0700314 if (mBar != null) {
315 try {
316 mBar.removeIcon(index);
317 } catch (RemoteException ex) {
318 }
319 }
320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 }
322
Daniel Sandlere02d8082010-10-08 15:13:22 -0400323 /**
324 * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
325 * response to a window with FLAG_NEEDS_MENU_KEY set.
326 */
Adam Lesinski182f73f2013-12-05 16:48:06 -0800327 @Override
Dianne Hackborn7d049322011-06-14 15:00:32 -0700328 public void topAppWindowChanged(final boolean menuVisible) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400329 enforceStatusBar();
330
Dianne Hackborn7d049322011-06-14 15:00:32 -0700331 if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
Daniel Sandlere02d8082010-10-08 15:13:22 -0400332
333 synchronized(mLock) {
Dianne Hackborn7d049322011-06-14 15:00:32 -0700334 mMenuVisible = menuVisible;
335 mHandler.post(new Runnable() {
336 public void run() {
337 if (mBar != null) {
338 try {
339 mBar.topAppWindowChanged(menuVisible);
340 } catch (RemoteException ex) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400341 }
342 }
Dianne Hackborn7d049322011-06-14 15:00:32 -0700343 }
344 });
Daniel Sandlere02d8082010-10-08 15:13:22 -0400345 }
346 }
347
Adam Lesinski182f73f2013-12-05 16:48:06 -0800348 @Override
Joe Onorato857fd9b2011-01-27 15:08:35 -0800349 public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) {
satok06487a52010-10-29 11:37:18 +0900350 enforceStatusBar();
351
Joe Onorato857fd9b2011-01-27 15:08:35 -0800352 if (SPEW) {
353 Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
354 }
satok06487a52010-10-29 11:37:18 +0900355
356 synchronized(mLock) {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800357 // In case of IME change, we need to call up setImeWindowStatus() regardless of
358 // mImeWindowVis because mImeWindowVis may not have been set to false when the
satok06e07442010-11-02 19:46:55 +0900359 // previous IME was destroyed.
Joe Onorato857fd9b2011-01-27 15:08:35 -0800360 mImeWindowVis = vis;
361 mImeBackDisposition = backDisposition;
362 mImeToken = token;
satok06e07442010-11-02 19:46:55 +0900363 mHandler.post(new Runnable() {
364 public void run() {
365 if (mBar != null) {
366 try {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800367 mBar.setImeWindowStatus(token, vis, backDisposition);
satok06e07442010-11-02 19:46:55 +0900368 } catch (RemoteException ex) {
satok06487a52010-10-29 11:37:18 +0900369 }
370 }
satok06e07442010-11-02 19:46:55 +0900371 }
372 });
satok06487a52010-10-29 11:37:18 +0900373 }
374 }
375
Adam Lesinski182f73f2013-12-05 16:48:06 -0800376 @Override
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700377 public void setSystemUiVisibility(int vis, int mask) {
Joe Onorato55bf3802011-01-25 13:42:10 -0800378 // also allows calls from window manager which is in this process.
Joe Onoratof63b0f42010-09-12 17:03:19 -0400379 enforceStatusBarService();
380
Jeff Sharkey4519a022011-09-07 23:24:53 -0700381 if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
Daniel Sandler60ee2562011-07-22 12:34:33 -0400382
Joe Onoratof63b0f42010-09-12 17:03:19 -0400383 synchronized (mLock) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700384 updateUiVisibilityLocked(vis, mask);
John Spurlock13451a22012-09-28 14:40:41 -0400385 disableLocked(
386 mCurrentUserId,
387 vis & StatusBarManager.DISABLE_MASK,
388 mSysUiVisToken,
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800389 "WindowManager.LayoutParams");
Joe Onoratof63b0f42010-09-12 17:03:19 -0400390 }
391 }
392
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700393 private void updateUiVisibilityLocked(final int vis, final int mask) {
Daniel Sandler60ee2562011-07-22 12:34:33 -0400394 if (mSystemUiVisibility != vis) {
395 mSystemUiVisibility = vis;
Joe Onoratof63b0f42010-09-12 17:03:19 -0400396 mHandler.post(new Runnable() {
397 public void run() {
398 if (mBar != null) {
399 try {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700400 mBar.setSystemUiVisibility(vis, mask);
Joe Onoratof63b0f42010-09-12 17:03:19 -0400401 } catch (RemoteException ex) {
Joe Onorato93056472010-09-10 10:30:46 -0400402 }
403 }
Joe Onoratof63b0f42010-09-12 17:03:19 -0400404 }
405 });
Joe Onorato93056472010-09-10 10:30:46 -0400406 }
407 }
408
Adam Lesinski182f73f2013-12-05 16:48:06 -0800409 @Override
Jeff Brown2992ea72011-01-28 22:04:14 -0800410 public void setHardKeyboardEnabled(final boolean enabled) {
411 mHandler.post(new Runnable() {
412 public void run() {
413 mWindowManager.setHardKeyboardEnabled(enabled);
414 }
415 });
416 }
417
418 @Override
419 public void onHardKeyboardStatusChange(final boolean available, final boolean enabled) {
420 mHandler.post(new Runnable() {
421 public void run() {
422 if (mBar != null) {
423 try {
424 mBar.setHardKeyboardStatus(available, enabled);
425 } catch (RemoteException ex) {
426 }
427 }
428 }
429 });
430 }
431
Michael Jurka3b1fc472011-06-13 10:54:40 -0700432 @Override
433 public void toggleRecentApps() {
434 if (mBar != null) {
435 try {
436 mBar.toggleRecentApps();
437 } catch (RemoteException ex) {}
438 }
439 }
440
Michael Jurka7f2668c2012-03-27 07:49:52 -0700441 @Override
442 public void preloadRecentApps() {
443 if (mBar != null) {
444 try {
445 mBar.preloadRecentApps();
446 } catch (RemoteException ex) {}
447 }
448 }
449
450 @Override
451 public void cancelPreloadRecentApps() {
452 if (mBar != null) {
453 try {
454 mBar.cancelPreloadRecentApps();
455 } catch (RemoteException ex) {}
456 }
457 }
458
John Spurlock13451a22012-09-28 14:40:41 -0400459 @Override
460 public void setCurrentUser(int newUserId) {
461 if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
462 mCurrentUserId = newUserId;
463 }
464
John Spurlock97642182013-07-29 17:58:39 -0400465 @Override
466 public void setWindowState(int window, int state) {
467 if (mBar != null) {
468 try {
469 mBar.setWindowState(window, state);
470 } catch (RemoteException ex) {}
471 }
472 }
473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 private void enforceStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700475 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700476 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 }
478
479 private void enforceExpandStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700480 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700481 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 }
483
Joe Onorato8bc6c512010-06-04 16:21:12 -0400484 private void enforceStatusBarService() {
485 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
486 "StatusBarManagerService");
487 }
488
Joe Onorato4762c2d2010-05-17 15:42:59 -0700489 // ================================================================================
490 // Callbacks from the status bar service.
491 // ================================================================================
Adam Lesinski182f73f2013-12-05 16:48:06 -0800492 @Override
Joe Onorato75199e32010-05-29 17:22:51 -0400493 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
Joe Onorato93056472010-09-10 10:30:46 -0400494 List<IBinder> notificationKeys, List<StatusBarNotification> notifications,
satokcd7cd292010-11-20 15:46:23 +0900495 int switches[], List<IBinder> binders) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400496 enforceStatusBarService();
497
Joe Onorato0cbda992010-05-02 16:28:15 -0700498 Slog.i(TAG, "registerStatusBar bar=" + bar);
499 mBar = bar;
Joe Onorato75199e32010-05-29 17:22:51 -0400500 synchronized (mIcons) {
501 iconList.copyFrom(mIcons);
502 }
503 synchronized (mNotifications) {
504 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
505 notificationKeys.add(e.getKey());
506 notifications.add(e.getValue());
507 }
508 }
Joe Onorato93056472010-09-10 10:30:46 -0400509 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400510 switches[0] = gatherDisableActionsLocked(mCurrentUserId);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400511 switches[1] = mSystemUiVisibility;
Joe Onoratoe4c7b3f2010-10-30 12:15:03 -0700512 switches[2] = mMenuVisible ? 1 : 0;
Joe Onorato857fd9b2011-01-27 15:08:35 -0800513 switches[3] = mImeWindowVis;
514 switches[4] = mImeBackDisposition;
515 binders.add(mImeToken);
Joe Onorato93056472010-09-10 10:30:46 -0400516 }
Jeff Brown2992ea72011-01-28 22:04:14 -0800517 switches[5] = mWindowManager.isHardKeyboardAvailable() ? 1 : 0;
518 switches[6] = mWindowManager.isHardKeyboardEnabled() ? 1 : 0;
Joe Onorato2314aab2010-04-08 16:41:23 -0500519 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400520
Joe Onorato4762c2d2010-05-17 15:42:59 -0700521 /**
Joe Onoratof1f25912010-06-07 11:52:41 -0700522 * The status bar service should call this each time the user brings the panel from
523 * invisible to visible in order to clear the notification light.
Joe Onorato4762c2d2010-05-17 15:42:59 -0700524 */
Adam Lesinski182f73f2013-12-05 16:48:06 -0800525 @Override
Joe Onoratof1f25912010-06-07 11:52:41 -0700526 public void onPanelRevealed() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400527 enforceStatusBarService();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800528 long identity = Binder.clearCallingIdentity();
529 try {
530 // tell the notification manager to turn off the lights.
531 mNotificationDelegate.onPanelRevealed();
532 } finally {
533 Binder.restoreCallingIdentity(identity);
534 }
Joe Onorato4762c2d2010-05-17 15:42:59 -0700535 }
536
Adam Lesinski182f73f2013-12-05 16:48:06 -0800537 @Override
Christoph Studer760ea552014-03-21 13:10:21 +0100538 public void onPanelHidden() throws RemoteException {
539 enforceStatusBarService();
540 long identity = Binder.clearCallingIdentity();
541 try {
542 mNotificationDelegate.onPanelHidden();
543 } finally {
544 Binder.restoreCallingIdentity(identity);
545 }
546 }
547
548 @Override
Kenny Guy3a7c4a52014-03-03 18:24:03 +0000549 public void onNotificationClick(String pkg, String tag, int id, int userId) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400550 enforceStatusBarService();
John Spurlocke6a7d932014-03-13 12:29:00 -0400551 final int callingUid = Binder.getCallingUid();
552 final int callingPid = Binder.getCallingPid();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800553 long identity = Binder.clearCallingIdentity();
554 try {
John Spurlocke6a7d932014-03-13 12:29:00 -0400555 mNotificationDelegate.onNotificationClick(callingUid, callingPid, pkg, tag, id, userId);
Adam Lesinski182f73f2013-12-05 16:48:06 -0800556 } finally {
557 Binder.restoreCallingIdentity(identity);
558 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400559 }
560
Adam Lesinski182f73f2013-12-05 16:48:06 -0800561 @Override
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700562 public void onNotificationError(String pkg, String tag, int id,
Kenny Guy3a7c4a52014-03-03 18:24:03 +0000563 int uid, int initialPid, String message, int userId) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400564 enforceStatusBarService();
John Spurlocke6a7d932014-03-13 12:29:00 -0400565 final int callingUid = Binder.getCallingUid();
566 final int callingPid = Binder.getCallingPid();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800567 long identity = Binder.clearCallingIdentity();
568 try {
569 // WARNING: this will call back into us to do the remove. Don't hold any locks.
John Spurlocke6a7d932014-03-13 12:29:00 -0400570 mNotificationDelegate.onNotificationError(callingUid, callingPid,
571 pkg, tag, id, uid, initialPid, message, userId);
Adam Lesinski182f73f2013-12-05 16:48:06 -0800572 } finally {
573 Binder.restoreCallingIdentity(identity);
574 }
Joe Onorato005847b2010-06-04 16:08:02 -0400575 }
576
Adam Lesinski182f73f2013-12-05 16:48:06 -0800577 @Override
Kenny Guy3a7c4a52014-03-03 18:24:03 +0000578 public void onNotificationClear(String pkg, String tag, int id, int userId) {
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400579 enforceStatusBarService();
John Spurlocke6a7d932014-03-13 12:29:00 -0400580 final int callingUid = Binder.getCallingUid();
581 final int callingPid = Binder.getCallingPid();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800582 long identity = Binder.clearCallingIdentity();
583 try {
John Spurlocke6a7d932014-03-13 12:29:00 -0400584 mNotificationDelegate.onNotificationClear(callingUid, callingPid, pkg, tag, id, userId);
Adam Lesinski182f73f2013-12-05 16:48:06 -0800585 } finally {
586 Binder.restoreCallingIdentity(identity);
587 }
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400588 }
589
Adam Lesinski182f73f2013-12-05 16:48:06 -0800590 @Override
Kenny Guy3a7c4a52014-03-03 18:24:03 +0000591 public void onClearAllNotifications(int userId) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400592 enforceStatusBarService();
John Spurlocke6a7d932014-03-13 12:29:00 -0400593 final int callingUid = Binder.getCallingUid();
594 final int callingPid = Binder.getCallingPid();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800595 long identity = Binder.clearCallingIdentity();
596 try {
John Spurlocke6a7d932014-03-13 12:29:00 -0400597 mNotificationDelegate.onClearAll(callingUid, callingPid, userId);
Adam Lesinski182f73f2013-12-05 16:48:06 -0800598 } finally {
599 Binder.restoreCallingIdentity(identity);
Joe Onorato18e69df2010-05-17 22:26:12 -0700600 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700601 }
602
Joe Onorato2314aab2010-04-08 16:41:23 -0500603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 // ================================================================================
605 // Can be called from any thread
606 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 // lock on mDisableRecords
John Spurlock13451a22012-09-28 14:40:41 -0400609 void manageDisableListLocked(int userId, int what, IBinder token, String pkg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 if (SPEW) {
John Spurlock13451a22012-09-28 14:40:41 -0400611 Slog.d(TAG, "manageDisableList userId=" + userId
612 + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 }
614 // update the list
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800615 final int N = mDisableRecords.size();
616 DisableRecord tok = null;
617 int i;
618 for (i=0; i<N; i++) {
619 DisableRecord t = mDisableRecords.get(i);
John Spurlock4e6922d2012-10-04 14:51:51 -0400620 if (t.token == token && t.userId == userId) {
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800621 tok = t;
622 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800624 }
625 if (what == 0 || !token.isBinderAlive()) {
626 if (tok != null) {
627 mDisableRecords.remove(i);
628 tok.token.unlinkToDeath(tok, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800630 } else {
631 if (tok == null) {
632 tok = new DisableRecord();
John Spurlock13451a22012-09-28 14:40:41 -0400633 tok.userId = userId;
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800634 try {
635 token.linkToDeath(tok, 0);
636 }
637 catch (RemoteException ex) {
638 return; // give up
639 }
640 mDisableRecords.add(tok);
641 }
642 tok.what = what;
643 tok.token = token;
644 tok.pkg = pkg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 }
646 }
647
648 // lock on mDisableRecords
John Spurlock13451a22012-09-28 14:40:41 -0400649 int gatherDisableActionsLocked(int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 final int N = mDisableRecords.size();
651 // gather the new net flags
652 int net = 0;
653 for (int i=0; i<N; i++) {
John Spurlock13451a22012-09-28 14:40:41 -0400654 final DisableRecord rec = mDisableRecords.get(i);
655 if (rec.userId == userId) {
656 net |= rec.what;
657 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 }
659 return net;
660 }
661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 // ================================================================================
663 // Always called from UI thread
664 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
667 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
668 != PackageManager.PERMISSION_GRANTED) {
669 pw.println("Permission Denial: can't dump StatusBar from from pid="
670 + Binder.getCallingPid()
671 + ", uid=" + Binder.getCallingUid());
672 return;
673 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700674
Joe Onorato0cbda992010-05-02 16:28:15 -0700675 synchronized (mIcons) {
676 mIcons.dump(pw);
677 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700678
679 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400680 int i=0;
681 pw.println("Notification list:");
682 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
683 pw.printf(" %2d: %s\n", i, e.getValue().toString());
684 i++;
685 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700687
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800688 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400689 pw.println(" mDisabled=0x" + Integer.toHexString(mDisabled));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 final int N = mDisableRecords.size();
John Spurlock13451a22012-09-28 14:40:41 -0400691 pw.println(" mDisableRecords.size=" + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 for (int i=0; i<N; i++) {
693 DisableRecord tok = mDisableRecords.get(i);
John Spurlock13451a22012-09-28 14:40:41 -0400694 pw.println(" [" + i + "] userId=" + tok.userId
695 + " what=0x" + Integer.toHexString(tok.what)
696 + " pkg=" + tok.pkg
697 + " token=" + tok.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 }
699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701}