summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Will Haldean Brown <haldean@google.com> 2014-02-28 11:04:41 -0800
committer Will Haldean Brown <haldean@google.com> 2014-02-28 11:26:47 -0800
commit866b25425e84f72911abc0e0ff8141f11c0980cc (patch)
treef645bfea039209bb5ec7898b906d0a5f76e7c5b3
parent6ca90042b398153e063cf69dea784e201e76a9ee (diff)
Maintain binding to crashed listeners from NotificationManagerService.
This fixes the logic on the death handlers for notification listeners, and doesn't unbind from the listener services so that the system will bring them back up again. Bug: 12587702 Change-Id: I44ce250e0e1c2583836dc823d9a333dabec51df9
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java32
1 files changed, 24 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2ba6c711bce3..bd4442e696f3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -258,10 +258,11 @@ public class NotificationManagerService extends SystemService {
@Override
public void binderDied() {
- if (connection == null) {
- // This is not a service; it won't be recreated. We can give up this connection.
- unregisterListenerImpl(this.listener, this.userid);
- }
+ // Remove the listener, but don't unbind from the service. The system will bring the
+ // service back up, and the onServiceConnected handler will readd the listener with the
+ // new binding. If this isn't a bound service, and is just a registered
+ // INotificationListener, just removing it from the list is all we need to do anyway.
+ removeListenerImpl(this.listener, this.userid);
}
/** convenience method for looking in mEnabledListenersForCurrentUser */
@@ -1999,20 +2000,35 @@ public class NotificationManagerService extends SystemService {
}
}
+ /**
+ * Removes a listener from the list and unbinds from its service.
+ */
void unregisterListenerImpl(final INotificationListener listener, final int userid) {
+ NotificationListenerInfo info = removeListenerImpl(listener, userid);
+ if (info != null && info.connection != null) {
+ getContext().unbindService(info.connection);
+ }
+ }
+
+ /**
+ * Removes a listener from the list but does not unbind from the listener's service.
+ *
+ * @return the removed listener.
+ */
+ NotificationListenerInfo removeListenerImpl(
+ final INotificationListener listener, final int userid) {
+ NotificationListenerInfo listenerInfo = null;
synchronized (mNotificationList) {
final int N = mListeners.size();
for (int i=N-1; i>=0; i--) {
final NotificationListenerInfo info = mListeners.get(i);
if (info.listener.asBinder() == listener.asBinder()
&& info.userid == userid) {
- mListeners.remove(i);
- if (info.connection != null) {
- getContext().unbindService(info.connection);
- }
+ listenerInfo = mListeners.remove(i);
}
}
}
+ return listenerInfo;
}
void showNextToastLocked() {