summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDaniel Sandler <dsandler@android.com>2013-02-14 10:24:17 -0500
committerDaniel Sandler <dsandler@android.com>2013-02-19 15:26:37 -0500
commit09a247e9a86df068422cbe8b60430fb6583c028c (patch)
treed6f63d7f593bb9d062ff47ed655e0c73a1ba5893 /services
parent5acb33af357b56fffb055997718b1e4aa97f53fc (diff)
downloadframeworks_base-09a247e9a86df068422cbe8b60430fb6583c028c.zip
frameworks_base-09a247e9a86df068422cbe8b60430fb6583c028c.tar.gz
frameworks_base-09a247e9a86df068422cbe8b60430fb6583c028c.tar.bz2
New INotificationListener interface.
Use with INotificationManager.registerListener(). Limited to system only right now. Change-Id: I65b6a8778267022cdc5e58eb75ae607a54b1cc52
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/NotificationManagerService.java91
1 files changed, 91 insertions, 0 deletions
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 13bf39f..9f2685b 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -26,6 +26,7 @@ import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
+import android.app.INotificationListener;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.PendingIntent;
@@ -151,6 +152,7 @@ public class NotificationManagerService extends INotificationManager.Stub
private boolean mInCall = false;
private boolean mNotificationPulseEnabled;
+ // used as a mutex for access to all active notifications & listeners
private final ArrayList<NotificationRecord> mNotificationList =
new ArrayList<NotificationRecord>();
@@ -161,6 +163,8 @@ public class NotificationManagerService extends INotificationManager.Stub
private final AppOpsManager mAppOps;
+ private ArrayList<NotificationListenerInfo> mListeners = new ArrayList<NotificationListenerInfo>();
+
// Notification control database. For now just contains disabled packages.
private AtomicFile mPolicyFile;
private HashSet<String> mBlockedPackages = new HashSet<String>();
@@ -174,6 +178,38 @@ public class NotificationManagerService extends INotificationManager.Stub
private static final String TAG_PACKAGE = "package";
private static final String ATTR_NAME = "name";
+ private class NotificationListenerInfo implements DeathRecipient {
+ INotificationListener listener;
+ int userid;
+ public NotificationListenerInfo(INotificationListener listener, int userid) {
+ this.listener = listener;
+ this.userid = userid;
+ }
+
+ public void notifyPostedIfUserMatch(StatusBarNotification sbn) {
+ if (this.userid != sbn.getUserId()) return;
+ try {
+ listener.onNotificationPosted(sbn);
+ } catch (RemoteException ex) {
+ // not there?
+ }
+ }
+
+ public void notifyRemovedIfUserMatch(StatusBarNotification sbn) {
+ if (this.userid != sbn.getUserId()) return;
+ try {
+ listener.onNotificationRemoved(sbn);
+ } catch (RemoteException ex) {
+ // not there?
+ }
+ }
+
+ @Override
+ public void binderDied() {
+ unregisterListener(this.listener, this.userid);
+ }
+ }
+
private static class Archive {
static final int BUFFER_SIZE = 1000;
ArrayDeque<StatusBarNotification> mBuffer = new ArrayDeque<StatusBarNotification>(BUFFER_SIZE);
@@ -406,6 +442,56 @@ public class NotificationManagerService extends INotificationManager.Stub
return tmp;
}
+ @Override
+ public void registerListener(final INotificationListener listener, final int userid) {
+ checkCallerIsSystem();
+ synchronized (mNotificationList) {
+ try {
+ NotificationListenerInfo info = new NotificationListenerInfo(listener, userid);
+ listener.asBinder().linkToDeath(info, 0);
+ mListeners.add(info);
+ } catch (RemoteException e) {
+ // already dead
+ }
+ }
+ }
+
+ @Override
+ public void unregisterListener(INotificationListener listener, int userid) {
+ checkCallerIsSystem();
+ synchronized (mNotificationList) {
+ final int N = mListeners.size();
+ for (int i=N-1; i>=0; i--) {
+ final NotificationListenerInfo info = mListeners.get(i);
+ if (info.listener == listener && info.userid == userid) {
+ mListeners.remove(listener);
+ }
+ }
+ }
+ }
+
+ private void notifyPostedLocked(NotificationRecord n) {
+ final StatusBarNotification sbn = n.sbn;
+ for (final NotificationListenerInfo info : mListeners) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ info.notifyPostedIfUserMatch(sbn);
+ }});
+ }
+ }
+
+ private void notifyRemovedLocked(NotificationRecord n) {
+ final StatusBarNotification sbn = n.sbn;
+ for (final NotificationListenerInfo info : mListeners) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ info.notifyRemovedIfUserMatch(sbn);
+ }});
+ }
+ }
+
public static final class NotificationRecord
{
final StatusBarNotification sbn;
@@ -1165,6 +1251,8 @@ public class NotificationManagerService extends INotificationManager.Stub
// finally, keep some of this information around for later use
mArchive.record(n);
+
+ notifyPostedLocked(r);
} else {
Slog.e(TAG, "Ignoring notification with icon==0: " + notification);
if (old != null && old.statusBarKey != null) {
@@ -1175,6 +1263,8 @@ public class NotificationManagerService extends INotificationManager.Stub
finally {
Binder.restoreCallingIdentity(identity);
}
+
+ notifyRemovedLocked(r);
}
return; // do not play sounds, show lights, etc. for invalid notifications
}
@@ -1341,6 +1431,7 @@ public class NotificationManagerService extends INotificationManager.Stub
Binder.restoreCallingIdentity(identity);
}
r.statusBarKey = null;
+ notifyRemovedLocked(r);
}
// sound