From 4d460833b955fcb669c59d4384bdf7938cc71705 Mon Sep 17 00:00:00 2001 From: Dan Sandler Date: Fri, 14 Mar 2014 14:48:31 -0400 Subject: DO NOT MERGE: Maintain binding to crashed listeners. Adapted from change I44ce250e, "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: I41d0c6733046ee9760bcfae4407e754592b805ea --- .../android/server/NotificationManagerService.java | 37 ++++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 0438675..dedc9bd 100644 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -260,10 +260,11 @@ public class NotificationManagerService extends INotificationManager.Stub @Override public void binderDied() { - if (connection == null) { - // This is not a service; it won't be recreated. We can give up this connection. - unregisterListener(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 */ @@ -757,26 +758,36 @@ public class NotificationManagerService extends INotificationManager.Stub } /** - * Remove a listener binder directly + * Removes a listener from the list and unbinds from its service. */ - @Override - public void unregisterListener(INotificationListener listener, int userid) { - // no need to check permissions; if your listener binder is in the list, - // that's proof that you had permission to add it in the first place + public void unregisterListener(final INotificationListener listener, final int userid) { + if (listener == null) return; + + NotificationListenerInfo info = removeListenerImpl(listener, userid); + if (info != null && info.connection != null) { + mContext.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) { - mContext.unbindService(info.connection); - } + listenerInfo = mListeners.remove(i); } } } + return listenerInfo; } /** -- cgit v1.1