diff options
author | Daniel Sandler <dsandler@android.com> | 2013-02-14 10:24:17 -0500 |
---|---|---|
committer | Daniel Sandler <dsandler@android.com> | 2013-02-19 15:26:37 -0500 |
commit | 09a247e9a86df068422cbe8b60430fb6583c028c (patch) | |
tree | d6f63d7f593bb9d062ff47ed655e0c73a1ba5893 /services | |
parent | 5acb33af357b56fffb055997718b1e4aa97f53fc (diff) | |
download | frameworks_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.java | 91 |
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 |