Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/IAlarmManager.aidl \ core/java/android/app/IBackupAgent.aidl \ core/java/android/app/IInstrumentationWatcher.aidl \ core/java/android/app/INotificationListener.aidl \ core/java/android/app/INotificationManager.aidl \ core/java/android/app/IProcessObserver.aidl \ core/java/android/app/ISearchManager.aidl \ Loading core/java/android/app/INotificationListener.aidl 0 → 100644 +26 −0 Original line number Diff line number Diff line /** * Copyright (c) 2013, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import com.android.internal.statusbar.StatusBarNotification; /** @hide */ oneway interface INotificationListener { void onNotificationPosted(in StatusBarNotification notification); void onNotificationRemoved(in StatusBarNotification notification); } No newline at end of file core/java/android/app/INotificationManager.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.app.INotificationListener; import android.app.ITransientNotification; import android.app.Notification; import android.content.Intent; Loading @@ -39,5 +40,8 @@ interface INotificationManager StatusBarNotification[] getActiveNotifications(String callingPkg); StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count); void registerListener(in INotificationListener listener, int userid); void unregisterListener(in INotificationListener listener, int userid); } core/java/com/android/internal/statusbar/INotificationListener.java 0 → 100644 +0 −0 Empty file added. services/java/com/android/server/NotificationManagerService.java +91 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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>(); Loading @@ -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>(); Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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 } Loading Loading @@ -1341,6 +1431,7 @@ public class NotificationManagerService extends INotificationManager.Stub Binder.restoreCallingIdentity(identity); } r.statusBarKey = null; notifyRemovedLocked(r); } // sound Loading Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/IAlarmManager.aidl \ core/java/android/app/IBackupAgent.aidl \ core/java/android/app/IInstrumentationWatcher.aidl \ core/java/android/app/INotificationListener.aidl \ core/java/android/app/INotificationManager.aidl \ core/java/android/app/IProcessObserver.aidl \ core/java/android/app/ISearchManager.aidl \ Loading
core/java/android/app/INotificationListener.aidl 0 → 100644 +26 −0 Original line number Diff line number Diff line /** * Copyright (c) 2013, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import com.android.internal.statusbar.StatusBarNotification; /** @hide */ oneway interface INotificationListener { void onNotificationPosted(in StatusBarNotification notification); void onNotificationRemoved(in StatusBarNotification notification); } No newline at end of file
core/java/android/app/INotificationManager.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.app.INotificationListener; import android.app.ITransientNotification; import android.app.Notification; import android.content.Intent; Loading @@ -39,5 +40,8 @@ interface INotificationManager StatusBarNotification[] getActiveNotifications(String callingPkg); StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count); void registerListener(in INotificationListener listener, int userid); void unregisterListener(in INotificationListener listener, int userid); }
core/java/com/android/internal/statusbar/INotificationListener.java 0 → 100644 +0 −0 Empty file added.
services/java/com/android/server/NotificationManagerService.java +91 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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>(); Loading @@ -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>(); Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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 } Loading Loading @@ -1341,6 +1431,7 @@ public class NotificationManagerService extends INotificationManager.Stub Binder.restoreCallingIdentity(identity); } r.statusBarKey = null; notifyRemovedLocked(r); } // sound Loading