Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d460833 authored by Dan Sandler's avatar Dan Sandler
Browse files

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
parent 65325236
Loading
Loading
Loading
Loading
+24 −13
Original line number Diff line number Diff line
@@ -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;
    }

    /**