OSDN Git Service

DO NOT MERGE: Maintain binding to crashed listeners.
authorDan Sandler <dsandler@android.com>
Fri, 14 Mar 2014 18:48:31 +0000 (14:48 -0400)
committerDan Sandler <dsandler@android.com>
Mon, 17 Mar 2014 20:10:50 +0000 (20:10 +0000)
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

services/java/com/android/server/NotificationManagerService.java

index 0438675..dedc9bd 100644 (file)
@@ -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;
     }
 
     /**