Rebind managed services more

- Rebind all on user switched
- Rebind Ranker on package replacement

Bug: 27551241
Change-Id: I6b0fe25dd68e2f1f118fde2b8e638193e1ad1868
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 6cf3940..6d9fed4 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -238,7 +238,7 @@
                 rebuildRestoredPackages();
             }
             // make sure we're still bound to any of our services who may have just upgraded
-            rebindServices();
+            rebindServices(false);
         }
     }
 
@@ -249,13 +249,13 @@
             if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices().");
             return;
         }
-        rebindServices();
+        rebindServices(true);
     }
 
     public void onUserUnlocked(int user) {
         if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user);
         rebuildRestoredPackages();
-        rebindServices();
+        rebindServices(false);
     }
 
     public ManagedServiceInfo getServiceFromTokenLocked(IInterface service) {
@@ -543,7 +543,7 @@
      * Called whenever packages change, the user switches, or the secure setting
      * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
      */
-    private void rebindServices() {
+    private void rebindServices(boolean forceRebind) {
         if (DEBUG) Slog.d(TAG, "rebindServices");
         final int[] userIds = mUserProfiles.getCurrentProfileIds();
         final int nUserIds = userIds.length;
@@ -559,15 +559,15 @@
         final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>();
 
         synchronized (mMutex) {
-            // Potentially unbind automatically bound services, retain system services.
+            // Rebind to non-system services if user switched
             for (ManagedServiceInfo service : mServices) {
                 if (!service.isSystem && !service.isGuest(this)) {
                     removableBoundServices.add(service);
                 }
             }
 
-            final ArraySet<ComponentName> newEnabled = new ArraySet<>();
-            final ArraySet<String> newPackages = new ArraySet<>();
+            mEnabledServicesForCurrentProfiles.clear();
+            mEnabledServicesPackageNames.clear();
 
             for (int i = 0; i < nUserIds; ++i) {
                 // decode the list of components
@@ -591,15 +591,13 @@
 
                 toAdd.put(userIds[i], add);
 
-                newEnabled.addAll(userComponents);
+                mEnabledServicesForCurrentProfiles.addAll(userComponents);
 
                 for (int j = 0; j < userComponents.size(); j++) {
                     final ComponentName component = userComponents.valueAt(j);
-                    newPackages.add(component.getPackageName());
+                    mEnabledServicesPackageNames.add(component.getPackageName());
                 }
             }
-            mEnabledServicesForCurrentProfiles = newEnabled;
-            mEnabledServicesPackageNames = newPackages;
         }
 
         for (ManagedServiceInfo info : removableBoundServices) {
@@ -607,11 +605,11 @@
             final int oldUser = info.userid;
             final Set<ComponentName> allowedComponents = toAdd.get(info.userid);
             if (allowedComponents != null) {
-                if (allowedComponents.contains(component)) {
+                if (allowedComponents.contains(component) && !forceRebind) {
                     // Already bound, don't need to bind again.
                     allowedComponents.remove(component);
                 } else {
-                    // No longer allowed to be bound.
+                    // No longer allowed to be bound, or must rebind.
                     Slog.v(TAG, "disabling " + getCaption() + " for user "
                             + oldUser + ": " + component);
                     unregisterService(component, oldUser);
@@ -622,8 +620,7 @@
         for (int i = 0; i < nUserIds; ++i) {
             final Set<ComponentName> add = toAdd.get(userIds[i]);
             for (ComponentName component : add) {
-                Slog.v(TAG, "enabling " + getCaption() + " for user " + userIds[i] + ": "
-                        + component);
+                Slog.v(TAG, "enabling " + getCaption() + " for " + userIds[i] + ": " + component);
                 registerService(component, userIds[i]);
             }
         }
@@ -859,7 +856,7 @@
             if (uri == null || mSecureSettingsUri.equals(uri)) {
                 if (DEBUG) Slog.d(TAG, "Setting changed: mSecureSettingsUri=" + mSecureSettingsUri +
                         " / uri=" + uri);
-                rebindServices();
+                rebindServices(false);
                 rebuildRestoredPackages();
             }
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 516602e..6b92063 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -155,6 +155,7 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -943,19 +944,7 @@
         // This is a MangedServices object that keeps track of the ranker.
         mRankerServices = new NotificationRankers();
         // Find the updatable ranker and register it.
-        Set<ComponentName> rankerComponents = mRankerServices.queryPackageForServices(
-                mRankerServicePackageName, UserHandle.USER_SYSTEM, null);
-        Iterator<ComponentName> iterator = rankerComponents.iterator();
-        if (iterator.hasNext()) {
-            ComponentName rankerComponent = iterator.next();
-            if (iterator.hasNext()) {
-                Slog.e(TAG, "found multiple ranker services:" + rankerComponents);
-            } else {
-                mRankerServices.registerSystemService(rankerComponent, UserHandle.USER_SYSTEM);
-            }
-        } else {
-            Slog.w(TAG, "could not start ranker service: none found");
-        }
+        mRankerServices.registerRanker();
 
         mStatusBar = getLocalService(StatusBarManagerInternal.class);
         mStatusBar.setNotificationDelegate(mNotificationDelegate);
@@ -3574,6 +3563,45 @@
         public boolean isEnabled() {
             return !mServices.isEmpty();
         }
+
+        @Override
+        public void onUserSwitched(int user) {
+            for (ManagedServiceInfo info : mServices) {
+                unregisterService(info.service, info.userid);
+            }
+            registerRanker();
+        }
+
+        @Override
+        public void onPackagesChanged(boolean queryReplace, String[] pkgList) {
+            if (DEBUG) Slog.d(TAG, "onPackagesChanged queryReplace=" + queryReplace
+                    + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList)));
+
+            if (pkgList != null && (pkgList.length > 0)) {
+                for (String pkgName : pkgList) {
+                    if (mRankerServicePackageName.equals(pkgName)) {
+                        registerRanker();
+                    }
+                }
+            }
+        }
+
+        protected void registerRanker() {
+            // Find the updatable ranker and register it.
+            Set<ComponentName> rankerComponents = queryPackageForServices(
+                    mRankerServicePackageName, UserHandle.USER_SYSTEM, null);
+            Iterator<ComponentName> iterator = rankerComponents.iterator();
+            if (iterator.hasNext()) {
+                ComponentName rankerComponent = iterator.next();
+                if (iterator.hasNext()) {
+                    Slog.e(TAG, "found multiple ranker services:" + rankerComponents);
+                } else {
+                    registerSystemService(rankerComponent, UserHandle.USER_SYSTEM);
+                }
+            } else {
+                Slog.w(TAG, "could not start ranker service: none found");
+            }
+        }
     }
 
     public class NotificationListeners extends ManagedServices {