diff options
| author | 2014-02-28 11:04:41 -0800 | |
|---|---|---|
| committer | 2014-02-28 11:26:47 -0800 | |
| commit | 866b25425e84f72911abc0e0ff8141f11c0980cc (patch) | |
| tree | f645bfea039209bb5ec7898b906d0a5f76e7c5b3 | |
| parent | 6ca90042b398153e063cf69dea784e201e76a9ee (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.java | 32 |
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() { |