blob: 2ae467eabdd1c95675a4b466fe8e419ba80236a2 [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.BroadcastReceiver;
27import android.content.Context;
28import android.content.Intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.content.pm.PackageManager;
30import android.content.res.Resources;
Joe Onorato8a9b2202010-02-26 18:56:32 -080031import android.util.Slog;
Joe Onorato0cbda992010-05-02 16:28:15 -070032
33import com.android.internal.statusbar.IStatusBar;
34import com.android.internal.statusbar.IStatusBarService;
35import com.android.internal.statusbar.StatusBarIcon;
36import com.android.internal.statusbar.StatusBarIconList;
Adam Lesinski182f73f2013-12-05 16:48:06 -080037import com.android.server.LocalServices;
38import com.android.server.notification.NotificationDelegate;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080039import com.android.server.wm.WindowManagerService;
The Android Open Source Project10592532009-03-18 17:39:46 -070040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import java.io.FileDescriptor;
42import java.io.PrintWriter;
43import java.util.ArrayList;
44import java.util.HashMap;
Joe Onorato75199e32010-05-29 17:22:51 -040045import java.util.List;
46import java.util.Map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
48
49/**
Joe Onoratof3f0e052010-05-14 18:49:29 -070050 * A note on locking: We rely on the fact that calls onto mBar are oneway or
51 * if they are local, that they just enqueue messages to not deadlock.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 */
Joe Onorato089de882010-04-12 08:18:45 -070053public class StatusBarManagerService extends IStatusBarService.Stub
Jeff Brown2992ea72011-01-28 22:04:14 -080054 implements WindowManagerService.OnHardKeyboardStatusChangeListener
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055{
Adam Lesinski182f73f2013-12-05 16:48:06 -080056 private static final String TAG = "StatusBarManagerService";
57 private static final boolean SPEW = false;
Joe Onoratodf7dbb62009-11-17 10:43:37 -080058
Adam Lesinski182f73f2013-12-05 16:48:06 -080059 private final Context mContext;
60 private final WindowManagerService mWindowManager;
61 private Handler mHandler = new Handler();
62 private NotificationDelegate mNotificationDelegate;
63 private volatile IStatusBar mBar;
64 private StatusBarIconList mIcons = new StatusBarIconList();
65 private HashMap<IBinder,StatusBarNotification> mNotifications
Joe Onorato75199e32010-05-29 17:22:51 -040066 = new HashMap<IBinder,StatusBarNotification>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Joe Onoratof3f0e052010-05-14 18:49:29 -070068 // for disabling the status bar
Adam Lesinski182f73f2013-12-05 16:48:06 -080069 private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
70 private IBinder mSysUiVisToken = new Binder();
71 private int mDisabled = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
Adam Lesinski182f73f2013-12-05 16:48:06 -080073 private Object mLock = new Object();
Daniel Sandler60ee2562011-07-22 12:34:33 -040074 // encompasses lights-out mode and other flags defined on View
Adam Lesinski182f73f2013-12-05 16:48:06 -080075 private int mSystemUiVisibility = 0;
76 private boolean mMenuVisible = false;
77 private int mImeWindowVis = 0;
78 private int mImeBackDisposition;
79 private IBinder mImeToken = null;
80 private int mCurrentUserId;
satok06487a52010-10-29 11:37:18 +090081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 private class DisableRecord implements IBinder.DeathRecipient {
John Spurlock13451a22012-09-28 14:40:41 -040083 int userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 String pkg;
85 int what;
86 IBinder token;
87
88 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080089 Slog.i(TAG, "binder died for pkg=" + pkg);
John Spurlock13451a22012-09-28 14:40:41 -040090 disableInternal(userId, 0, token, pkg);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -070091 token.unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 }
93 }
94
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 /**
96 * Construct the service, add the status bar view to the window manager
97 */
Jeff Brown2992ea72011-01-28 22:04:14 -080098 public StatusBarManagerService(Context context, WindowManagerService windowManager) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 mContext = context;
Jeff Brown2992ea72011-01-28 22:04:14 -0800100 mWindowManager = windowManager;
101 mWindowManager.setOnHardKeyboardStatusChangeListener(this);
Joe Onorato0cbda992010-05-02 16:28:15 -0700102
103 final Resources res = context.getResources();
Joe Onorato75144ea2010-06-07 12:36:25 -0700104 mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
Adam Lesinski182f73f2013-12-05 16:48:06 -0800105
106 LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 }
108
Adam Lesinski182f73f2013-12-05 16:48:06 -0800109 /**
110 * Private API used by NotificationManagerService.
111 */
112 private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
113 @Override
114 public void setNotificationDelegate(NotificationDelegate delegate) {
115 synchronized (mNotifications) {
116 mNotificationDelegate = delegate;
117 }
118 }
119
120 @Override
121 public IBinder addNotification(StatusBarNotification notification) {
122 synchronized (mNotifications) {
123 IBinder key = new Binder();
124 mNotifications.put(key, notification);
125 if (mBar != null) {
126 try {
127 mBar.addNotification(key, notification);
128 } catch (RemoteException ex) {
129 }
130 }
131 return key;
132 }
133 }
134
135 @Override
136 public void updateNotification(IBinder key, StatusBarNotification notification) {
137 synchronized (mNotifications) {
138 if (!mNotifications.containsKey(key)) {
139 throw new IllegalArgumentException("updateNotification key not found: " + key);
140 }
141 mNotifications.put(key, notification);
142 if (mBar != null) {
143 try {
144 mBar.updateNotification(key, notification);
145 } catch (RemoteException ex) {
146 }
147 }
148 }
149 }
150
151 @Override
152 public void removeNotification(IBinder key) {
153 synchronized (mNotifications) {
154 final StatusBarNotification n = mNotifications.remove(key);
155 if (n == null) {
156 Slog.e(TAG, "removeNotification key not found: " + key);
157 return;
158 }
159 if (mBar != null) {
160 try {
161 mBar.removeNotification(key);
162 } catch (RemoteException ex) {
163 }
164 }
165 }
166 }
167 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168
169 // ================================================================================
Joe Onorato25f95f92010-04-08 18:37:10 -0500170 // From IStatusBarService
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 // ================================================================================
Adam Lesinski182f73f2013-12-05 16:48:06 -0800172 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -0400173 public void expandNotificationsPanel() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 enforceExpandStatusBar();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700175
176 if (mBar != null) {
177 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400178 mBar.animateExpandNotificationsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700179 } catch (RemoteException ex) {
180 }
181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 }
183
Adam Lesinski182f73f2013-12-05 16:48:06 -0800184 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -0400185 public void collapsePanels() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 enforceExpandStatusBar();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187
Joe Onorato4762c2d2010-05-17 15:42:59 -0700188 if (mBar != null) {
189 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400190 mBar.animateCollapsePanels();
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700191 } catch (RemoteException ex) {
192 }
193 }
194 }
195
Adam Lesinski182f73f2013-12-05 16:48:06 -0800196 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -0400197 public void expandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -0700198 enforceExpandStatusBar();
199
200 if (mBar != null) {
201 try {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400202 mBar.animateExpandSettingsPanel();
Joe Onorato4762c2d2010-05-17 15:42:59 -0700203 } catch (RemoteException ex) {
204 }
205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 }
207
Adam Lesinski182f73f2013-12-05 16:48:06 -0800208 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 public void disable(int what, IBinder token, String pkg) {
John Spurlock13451a22012-09-28 14:40:41 -0400210 disableInternal(mCurrentUserId, what, token, pkg);
211 }
212
213 private void disableInternal(int userId, int what, IBinder token, String pkg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 enforceStatusBar();
Joe Onoratof3f0e052010-05-14 18:49:29 -0700215
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800216 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400217 disableLocked(userId, what, token, pkg);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800218 }
219 }
220
John Spurlock13451a22012-09-28 14:40:41 -0400221 private void disableLocked(int userId, int what, IBinder token, String pkg) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700222 // It's important that the the callback and the call to mBar get done
223 // in the same order when multiple threads are calling this function
224 // so they are paired correctly. The messages on the handler will be
225 // handled in the order they were enqueued, but will be outside the lock.
John Spurlock13451a22012-09-28 14:40:41 -0400226 manageDisableListLocked(userId, what, token, pkg);
John Spurlock8f3e6d52012-11-29 13:56:24 -0500227
228 // Ensure state for the current user is applied, even if passed a non-current user.
229 final int net = gatherDisableActionsLocked(mCurrentUserId);
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800230 if (net != mDisabled) {
231 mDisabled = net;
232 mHandler.post(new Runnable() {
233 public void run() {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800234 mNotificationDelegate.onSetDisabled(net);
Joe Onoratof3f0e052010-05-14 18:49:29 -0700235 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800236 });
237 if (mBar != null) {
238 try {
239 mBar.disable(net);
240 } catch (RemoteException ex) {
Joe Onoratof3f0e052010-05-14 18:49:29 -0700241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 }
244 }
245
Adam Lesinski182f73f2013-12-05 16:48:06 -0800246 @Override
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700247 public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
248 String contentDescription) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700250
251 synchronized (mIcons) {
252 int index = mIcons.getSlotIndex(slot);
253 if (index < 0) {
254 throw new SecurityException("invalid status bar icon slot: " + slot);
255 }
256
Amith Yamasani98edc952012-09-25 14:09:27 -0700257 StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
258 iconLevel, 0,
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700259 contentDescription);
Joe Onorato66d7d012010-05-14 10:05:10 -0700260 //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
Joe Onorato0cbda992010-05-02 16:28:15 -0700261 mIcons.setIcon(index, icon);
262
Joe Onorato0cbda992010-05-02 16:28:15 -0700263 if (mBar != null) {
264 try {
265 mBar.setIcon(index, icon);
266 } catch (RemoteException ex) {
267 }
268 }
269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 }
271
Adam Lesinski182f73f2013-12-05 16:48:06 -0800272 @Override
Joe Onorato0cbda992010-05-02 16:28:15 -0700273 public void setIconVisibility(String slot, boolean visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 enforceStatusBar();
Joe Onorato0cbda992010-05-02 16:28:15 -0700275
Joe Onorato514ad6632010-05-13 18:49:00 -0700276 synchronized (mIcons) {
277 int index = mIcons.getSlotIndex(slot);
278 if (index < 0) {
279 throw new SecurityException("invalid status bar icon slot: " + slot);
280 }
281
282 StatusBarIcon icon = mIcons.getIcon(index);
283 if (icon == null) {
284 return;
285 }
286
287 if (icon.visible != visible) {
288 icon.visible = visible;
289
Joe Onorato514ad6632010-05-13 18:49:00 -0700290 if (mBar != null) {
291 try {
292 mBar.setIcon(index, icon);
293 } catch (RemoteException ex) {
294 }
295 }
296 }
297 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700298 }
299
Adam Lesinski182f73f2013-12-05 16:48:06 -0800300 @Override
Joe Onorato0cbda992010-05-02 16:28:15 -0700301 public void removeIcon(String slot) {
302 enforceStatusBar();
303
304 synchronized (mIcons) {
305 int index = mIcons.getSlotIndex(slot);
306 if (index < 0) {
307 throw new SecurityException("invalid status bar icon slot: " + slot);
308 }
309
310 mIcons.removeIcon(index);
311
Joe Onorato0cbda992010-05-02 16:28:15 -0700312 if (mBar != null) {
313 try {
314 mBar.removeIcon(index);
315 } catch (RemoteException ex) {
316 }
317 }
318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
320
Daniel Sandlere02d8082010-10-08 15:13:22 -0400321 /**
322 * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
323 * response to a window with FLAG_NEEDS_MENU_KEY set.
324 */
Adam Lesinski182f73f2013-12-05 16:48:06 -0800325 @Override
Dianne Hackborn7d049322011-06-14 15:00:32 -0700326 public void topAppWindowChanged(final boolean menuVisible) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400327 enforceStatusBar();
328
Dianne Hackborn7d049322011-06-14 15:00:32 -0700329 if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
Daniel Sandlere02d8082010-10-08 15:13:22 -0400330
331 synchronized(mLock) {
Dianne Hackborn7d049322011-06-14 15:00:32 -0700332 mMenuVisible = menuVisible;
333 mHandler.post(new Runnable() {
334 public void run() {
335 if (mBar != null) {
336 try {
337 mBar.topAppWindowChanged(menuVisible);
338 } catch (RemoteException ex) {
Daniel Sandlere02d8082010-10-08 15:13:22 -0400339 }
340 }
Dianne Hackborn7d049322011-06-14 15:00:32 -0700341 }
342 });
Daniel Sandlere02d8082010-10-08 15:13:22 -0400343 }
344 }
345
Adam Lesinski182f73f2013-12-05 16:48:06 -0800346 @Override
Joe Onorato857fd9b2011-01-27 15:08:35 -0800347 public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) {
satok06487a52010-10-29 11:37:18 +0900348 enforceStatusBar();
349
Joe Onorato857fd9b2011-01-27 15:08:35 -0800350 if (SPEW) {
351 Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
352 }
satok06487a52010-10-29 11:37:18 +0900353
354 synchronized(mLock) {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800355 // In case of IME change, we need to call up setImeWindowStatus() regardless of
356 // mImeWindowVis because mImeWindowVis may not have been set to false when the
satok06e07442010-11-02 19:46:55 +0900357 // previous IME was destroyed.
Joe Onorato857fd9b2011-01-27 15:08:35 -0800358 mImeWindowVis = vis;
359 mImeBackDisposition = backDisposition;
360 mImeToken = token;
satok06e07442010-11-02 19:46:55 +0900361 mHandler.post(new Runnable() {
362 public void run() {
363 if (mBar != null) {
364 try {
Joe Onorato857fd9b2011-01-27 15:08:35 -0800365 mBar.setImeWindowStatus(token, vis, backDisposition);
satok06e07442010-11-02 19:46:55 +0900366 } catch (RemoteException ex) {
satok06487a52010-10-29 11:37:18 +0900367 }
368 }
satok06e07442010-11-02 19:46:55 +0900369 }
370 });
satok06487a52010-10-29 11:37:18 +0900371 }
372 }
373
Adam Lesinski182f73f2013-12-05 16:48:06 -0800374 @Override
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700375 public void setSystemUiVisibility(int vis, int mask) {
Joe Onorato55bf3802011-01-25 13:42:10 -0800376 // also allows calls from window manager which is in this process.
Joe Onoratof63b0f42010-09-12 17:03:19 -0400377 enforceStatusBarService();
378
Jeff Sharkey4519a022011-09-07 23:24:53 -0700379 if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
Daniel Sandler60ee2562011-07-22 12:34:33 -0400380
Joe Onoratof63b0f42010-09-12 17:03:19 -0400381 synchronized (mLock) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700382 updateUiVisibilityLocked(vis, mask);
John Spurlock13451a22012-09-28 14:40:41 -0400383 disableLocked(
384 mCurrentUserId,
385 vis & StatusBarManager.DISABLE_MASK,
386 mSysUiVisToken,
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800387 "WindowManager.LayoutParams");
Joe Onoratof63b0f42010-09-12 17:03:19 -0400388 }
389 }
390
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700391 private void updateUiVisibilityLocked(final int vis, final int mask) {
Daniel Sandler60ee2562011-07-22 12:34:33 -0400392 if (mSystemUiVisibility != vis) {
393 mSystemUiVisibility = vis;
Joe Onoratof63b0f42010-09-12 17:03:19 -0400394 mHandler.post(new Runnable() {
395 public void run() {
396 if (mBar != null) {
397 try {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700398 mBar.setSystemUiVisibility(vis, mask);
Joe Onoratof63b0f42010-09-12 17:03:19 -0400399 } catch (RemoteException ex) {
Joe Onorato93056472010-09-10 10:30:46 -0400400 }
401 }
Joe Onoratof63b0f42010-09-12 17:03:19 -0400402 }
403 });
Joe Onorato93056472010-09-10 10:30:46 -0400404 }
405 }
406
Adam Lesinski182f73f2013-12-05 16:48:06 -0800407 @Override
Jeff Brown2992ea72011-01-28 22:04:14 -0800408 public void setHardKeyboardEnabled(final boolean enabled) {
409 mHandler.post(new Runnable() {
410 public void run() {
411 mWindowManager.setHardKeyboardEnabled(enabled);
412 }
413 });
414 }
415
416 @Override
417 public void onHardKeyboardStatusChange(final boolean available, final boolean enabled) {
418 mHandler.post(new Runnable() {
419 public void run() {
420 if (mBar != null) {
421 try {
422 mBar.setHardKeyboardStatus(available, enabled);
423 } catch (RemoteException ex) {
424 }
425 }
426 }
427 });
428 }
429
Michael Jurka3b1fc472011-06-13 10:54:40 -0700430 @Override
431 public void toggleRecentApps() {
432 if (mBar != null) {
433 try {
434 mBar.toggleRecentApps();
435 } catch (RemoteException ex) {}
436 }
437 }
438
Michael Jurka7f2668c2012-03-27 07:49:52 -0700439 @Override
440 public void preloadRecentApps() {
441 if (mBar != null) {
442 try {
443 mBar.preloadRecentApps();
444 } catch (RemoteException ex) {}
445 }
446 }
447
448 @Override
449 public void cancelPreloadRecentApps() {
450 if (mBar != null) {
451 try {
452 mBar.cancelPreloadRecentApps();
453 } catch (RemoteException ex) {}
454 }
455 }
456
John Spurlock13451a22012-09-28 14:40:41 -0400457 @Override
458 public void setCurrentUser(int newUserId) {
459 if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
460 mCurrentUserId = newUserId;
461 }
462
John Spurlock97642182013-07-29 17:58:39 -0400463 @Override
464 public void setWindowState(int window, int state) {
465 if (mBar != null) {
466 try {
467 mBar.setWindowState(window, state);
468 } catch (RemoteException ex) {}
469 }
470 }
471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 private void enforceStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700473 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700474 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 }
476
477 private void enforceExpandStatusBar() {
Joe Onorato0cbda992010-05-02 16:28:15 -0700478 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
Joe Onorato089de882010-04-12 08:18:45 -0700479 "StatusBarManagerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 }
481
Joe Onorato8bc6c512010-06-04 16:21:12 -0400482 private void enforceStatusBarService() {
483 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
484 "StatusBarManagerService");
485 }
486
Joe Onorato4762c2d2010-05-17 15:42:59 -0700487 // ================================================================================
488 // Callbacks from the status bar service.
489 // ================================================================================
Adam Lesinski182f73f2013-12-05 16:48:06 -0800490 @Override
Joe Onorato75199e32010-05-29 17:22:51 -0400491 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
Joe Onorato93056472010-09-10 10:30:46 -0400492 List<IBinder> notificationKeys, List<StatusBarNotification> notifications,
satokcd7cd292010-11-20 15:46:23 +0900493 int switches[], List<IBinder> binders) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400494 enforceStatusBarService();
495
Joe Onorato0cbda992010-05-02 16:28:15 -0700496 Slog.i(TAG, "registerStatusBar bar=" + bar);
497 mBar = bar;
Joe Onorato75199e32010-05-29 17:22:51 -0400498 synchronized (mIcons) {
499 iconList.copyFrom(mIcons);
500 }
501 synchronized (mNotifications) {
502 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
503 notificationKeys.add(e.getKey());
504 notifications.add(e.getValue());
505 }
506 }
Joe Onorato93056472010-09-10 10:30:46 -0400507 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400508 switches[0] = gatherDisableActionsLocked(mCurrentUserId);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400509 switches[1] = mSystemUiVisibility;
Joe Onoratoe4c7b3f2010-10-30 12:15:03 -0700510 switches[2] = mMenuVisible ? 1 : 0;
Joe Onorato857fd9b2011-01-27 15:08:35 -0800511 switches[3] = mImeWindowVis;
512 switches[4] = mImeBackDisposition;
513 binders.add(mImeToken);
Joe Onorato93056472010-09-10 10:30:46 -0400514 }
Jeff Brown2992ea72011-01-28 22:04:14 -0800515 switches[5] = mWindowManager.isHardKeyboardAvailable() ? 1 : 0;
516 switches[6] = mWindowManager.isHardKeyboardEnabled() ? 1 : 0;
Joe Onorato2314aab2010-04-08 16:41:23 -0500517 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400518
Joe Onorato4762c2d2010-05-17 15:42:59 -0700519 /**
Joe Onoratof1f25912010-06-07 11:52:41 -0700520 * The status bar service should call this each time the user brings the panel from
521 * invisible to visible in order to clear the notification light.
Joe Onorato4762c2d2010-05-17 15:42:59 -0700522 */
Adam Lesinski182f73f2013-12-05 16:48:06 -0800523 @Override
Joe Onoratof1f25912010-06-07 11:52:41 -0700524 public void onPanelRevealed() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400525 enforceStatusBarService();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800526 long identity = Binder.clearCallingIdentity();
527 try {
528 // tell the notification manager to turn off the lights.
529 mNotificationDelegate.onPanelRevealed();
530 } finally {
531 Binder.restoreCallingIdentity(identity);
532 }
Joe Onorato4762c2d2010-05-17 15:42:59 -0700533 }
534
Adam Lesinski182f73f2013-12-05 16:48:06 -0800535 @Override
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400536 public void onNotificationClick(String pkg, String tag, int id) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400537 enforceStatusBarService();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800538 long identity = Binder.clearCallingIdentity();
539 try {
540 mNotificationDelegate.onNotificationClick(pkg, tag, id);
541 } finally {
542 Binder.restoreCallingIdentity(identity);
543 }
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400544 }
545
Adam Lesinski182f73f2013-12-05 16:48:06 -0800546 @Override
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700547 public void onNotificationError(String pkg, String tag, int id,
548 int uid, int initialPid, String message) {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400549 enforceStatusBarService();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800550 long identity = Binder.clearCallingIdentity();
551 try {
552 // WARNING: this will call back into us to do the remove. Don't hold any locks.
553 mNotificationDelegate.onNotificationError(pkg, tag, id, uid, initialPid, message);
554 } finally {
555 Binder.restoreCallingIdentity(identity);
556 }
Joe Onorato005847b2010-06-04 16:08:02 -0400557 }
558
Adam Lesinski182f73f2013-12-05 16:48:06 -0800559 @Override
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400560 public void onNotificationClear(String pkg, String tag, int id) {
561 enforceStatusBarService();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800562 long identity = Binder.clearCallingIdentity();
563 try {
564 mNotificationDelegate.onNotificationClear(pkg, tag, id);
565 } finally {
566 Binder.restoreCallingIdentity(identity);
567 }
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400568 }
569
Adam Lesinski182f73f2013-12-05 16:48:06 -0800570 @Override
Joe Onoratoaaba60b2010-05-23 15:18:41 -0400571 public void onClearAllNotifications() {
Joe Onorato8bc6c512010-06-04 16:21:12 -0400572 enforceStatusBarService();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800573 long identity = Binder.clearCallingIdentity();
574 try {
575 mNotificationDelegate.onClearAll();
576 } finally {
577 Binder.restoreCallingIdentity(identity);
Joe Onorato18e69df2010-05-17 22:26:12 -0700578 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700579 }
580
Joe Onorato2314aab2010-04-08 16:41:23 -0500581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 // ================================================================================
583 // Can be called from any thread
584 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 // lock on mDisableRecords
John Spurlock13451a22012-09-28 14:40:41 -0400587 void manageDisableListLocked(int userId, int what, IBinder token, String pkg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 if (SPEW) {
John Spurlock13451a22012-09-28 14:40:41 -0400589 Slog.d(TAG, "manageDisableList userId=" + userId
590 + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 }
592 // update the list
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800593 final int N = mDisableRecords.size();
594 DisableRecord tok = null;
595 int i;
596 for (i=0; i<N; i++) {
597 DisableRecord t = mDisableRecords.get(i);
John Spurlock4e6922d2012-10-04 14:51:51 -0400598 if (t.token == token && t.userId == userId) {
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800599 tok = t;
600 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800602 }
603 if (what == 0 || !token.isBinderAlive()) {
604 if (tok != null) {
605 mDisableRecords.remove(i);
606 tok.token.unlinkToDeath(tok, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 }
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800608 } else {
609 if (tok == null) {
610 tok = new DisableRecord();
John Spurlock13451a22012-09-28 14:40:41 -0400611 tok.userId = userId;
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800612 try {
613 token.linkToDeath(tok, 0);
614 }
615 catch (RemoteException ex) {
616 return; // give up
617 }
618 mDisableRecords.add(tok);
619 }
620 tok.what = what;
621 tok.token = token;
622 tok.pkg = pkg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 }
624 }
625
626 // lock on mDisableRecords
John Spurlock13451a22012-09-28 14:40:41 -0400627 int gatherDisableActionsLocked(int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 final int N = mDisableRecords.size();
629 // gather the new net flags
630 int net = 0;
631 for (int i=0; i<N; i++) {
John Spurlock13451a22012-09-28 14:40:41 -0400632 final DisableRecord rec = mDisableRecords.get(i);
633 if (rec.userId == userId) {
634 net |= rec.what;
635 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 }
637 return net;
638 }
639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 // ================================================================================
641 // Always called from UI thread
642 // ================================================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
645 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
646 != PackageManager.PERMISSION_GRANTED) {
647 pw.println("Permission Denial: can't dump StatusBar from from pid="
648 + Binder.getCallingPid()
649 + ", uid=" + Binder.getCallingUid());
650 return;
651 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700652
Joe Onorato0cbda992010-05-02 16:28:15 -0700653 synchronized (mIcons) {
654 mIcons.dump(pw);
655 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700656
657 synchronized (mNotifications) {
Joe Onorato75199e32010-05-29 17:22:51 -0400658 int i=0;
659 pw.println("Notification list:");
660 for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
661 pw.printf(" %2d: %s\n", i, e.getValue().toString());
662 i++;
663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700665
Joe Onorato7bb8eeb2011-01-27 16:00:58 -0800666 synchronized (mLock) {
John Spurlock13451a22012-09-28 14:40:41 -0400667 pw.println(" mDisabled=0x" + Integer.toHexString(mDisabled));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 final int N = mDisableRecords.size();
John Spurlock13451a22012-09-28 14:40:41 -0400669 pw.println(" mDisableRecords.size=" + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 for (int i=0; i<N; i++) {
671 DisableRecord tok = mDisableRecords.get(i);
John Spurlock13451a22012-09-28 14:40:41 -0400672 pw.println(" [" + i + "] userId=" + tok.userId
673 + " what=0x" + Integer.toHexString(tok.what)
674 + " pkg=" + tok.pkg
675 + " token=" + tok.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 }
677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 }
679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
681 public void onReceive(Context context, Intent intent) {
682 String action = intent.getAction();
Joe Onoratof9e0e6b2009-09-08 16:24:36 -0400683 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
684 || Intent.ACTION_SCREEN_OFF.equals(action)) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400685 collapsePanels();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700687 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688 else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
689 updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
690 intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
691 intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
692 intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
693 }
694 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
695 updateResources();
696 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700697 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 }
699 };
700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701}