Loading core/java/android/content/pm/RegisteredServicesCache.java +43 −9 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.SparseArray; import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.google.android.collect.Lists; import com.google.android.collect.Maps; Loading Loading @@ -155,9 +156,19 @@ public abstract class RegisteredServicesCache<V> { // package is going away, but it's the middle of an upgrade: keep the current // state and do nothing here. This clause is intentionally empty. } else { int[] uids = null; // either we're adding/changing, or it's a removal without replacement, so // we need to recalculate the set of available services generateServicesMap(userId); // we need to update the set of available services if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action) || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { uids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); } else { int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); if (uid > 0) { uids = new int[] { uid }; } } generateServicesMap(uids, userId); } } Loading Loading @@ -270,7 +281,7 @@ public abstract class RegisteredServicesCache<V> { // Find user and lazily populate cache final UserServices<V> user = findOrCreateUserLocked(userId); if (user.services == null) { generateServicesMap(userId); generateServicesMap(null, userId); } return user.services.get(type); } Loading @@ -285,7 +296,7 @@ public abstract class RegisteredServicesCache<V> { // Find user and lazily populate cache final UserServices<V> user = findOrCreateUserLocked(userId); if (user.services == null) { generateServicesMap(userId); generateServicesMap(null, userId); } return Collections.unmodifiableCollection( new ArrayList<ServiceInfo<V>>(user.services.values())); Loading @@ -311,10 +322,13 @@ public abstract class RegisteredServicesCache<V> { /** * Populate {@link UserServices#services} by scanning installed packages for * given {@link UserHandle}. * @param changedUids the array of uids that have been affected, as mentioned in the broadcast * or null to assume that everything is affected. * @param userId the user for whom to update the services map. */ private void generateServicesMap(int userId) { private void generateServicesMap(int[] changedUids, int userId) { if (DEBUG) { Slog.d(TAG, "generateServicesMap() for " + userId); Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + changedUids); } final PackageManager pm = mContext.getPackageManager(); Loading @@ -341,8 +355,6 @@ public abstract class RegisteredServicesCache<V> { final boolean firstScan = user.services == null; if (firstScan) { user.services = Maps.newHashMap(); } else { user.services.clear(); } StringBuilder changes = new StringBuilder(); Loading Loading @@ -399,7 +411,10 @@ public abstract class RegisteredServicesCache<V> { ArrayList<V> toBeRemoved = Lists.newArrayList(); for (V v1 : user.persistentServices.keySet()) { if (!containsType(serviceInfos, v1)) { // Remove a persisted service that's not in the currently available services list. // And only if it is in the list of changedUids. if (!containsType(serviceInfos, v1) && containsUid(changedUids, user.persistentServices.get(v1))) { toBeRemoved.add(v1); } } Loading @@ -409,8 +424,19 @@ public abstract class RegisteredServicesCache<V> { } changed = true; user.persistentServices.remove(v1); user.services.remove(v1); notifyListener(v1, userId, true /* removed */); } if (DEBUG) { Log.d(TAG, "user.services="); for (V v : user.services.keySet()) { Log.d(TAG, " " + v + " " + user.services.get(v)); } Log.d(TAG, "user.persistentServices="); for (V v : user.persistentServices.keySet()) { Log.d(TAG, " " + v + " " + user.persistentServices.get(v)); } } if (DEBUG) { if (changes.length() > 0) { Log.d(TAG, "generateServicesMap(" + mInterfaceName + "): " + Loading @@ -426,6 +452,14 @@ public abstract class RegisteredServicesCache<V> { } } /** * Returns true if the list of changed uids is null (wildcard) or the specified uid * is contained in the list of changed uids. */ private boolean containsUid(int[] changedUids, int uid) { return changedUids == null || ArrayUtils.contains(changedUids, uid); } private boolean containsType(ArrayList<ServiceInfo<V>> serviceInfos, V type) { for (int i = 0, N = serviceInfos.size(); i < N; i++) { if (serviceInfos.get(i).type.equals(type)) { Loading Loading
core/java/android/content/pm/RegisteredServicesCache.java +43 −9 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.SparseArray; import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.google.android.collect.Lists; import com.google.android.collect.Maps; Loading Loading @@ -155,9 +156,19 @@ public abstract class RegisteredServicesCache<V> { // package is going away, but it's the middle of an upgrade: keep the current // state and do nothing here. This clause is intentionally empty. } else { int[] uids = null; // either we're adding/changing, or it's a removal without replacement, so // we need to recalculate the set of available services generateServicesMap(userId); // we need to update the set of available services if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action) || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { uids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); } else { int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); if (uid > 0) { uids = new int[] { uid }; } } generateServicesMap(uids, userId); } } Loading Loading @@ -270,7 +281,7 @@ public abstract class RegisteredServicesCache<V> { // Find user and lazily populate cache final UserServices<V> user = findOrCreateUserLocked(userId); if (user.services == null) { generateServicesMap(userId); generateServicesMap(null, userId); } return user.services.get(type); } Loading @@ -285,7 +296,7 @@ public abstract class RegisteredServicesCache<V> { // Find user and lazily populate cache final UserServices<V> user = findOrCreateUserLocked(userId); if (user.services == null) { generateServicesMap(userId); generateServicesMap(null, userId); } return Collections.unmodifiableCollection( new ArrayList<ServiceInfo<V>>(user.services.values())); Loading @@ -311,10 +322,13 @@ public abstract class RegisteredServicesCache<V> { /** * Populate {@link UserServices#services} by scanning installed packages for * given {@link UserHandle}. * @param changedUids the array of uids that have been affected, as mentioned in the broadcast * or null to assume that everything is affected. * @param userId the user for whom to update the services map. */ private void generateServicesMap(int userId) { private void generateServicesMap(int[] changedUids, int userId) { if (DEBUG) { Slog.d(TAG, "generateServicesMap() for " + userId); Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + changedUids); } final PackageManager pm = mContext.getPackageManager(); Loading @@ -341,8 +355,6 @@ public abstract class RegisteredServicesCache<V> { final boolean firstScan = user.services == null; if (firstScan) { user.services = Maps.newHashMap(); } else { user.services.clear(); } StringBuilder changes = new StringBuilder(); Loading Loading @@ -399,7 +411,10 @@ public abstract class RegisteredServicesCache<V> { ArrayList<V> toBeRemoved = Lists.newArrayList(); for (V v1 : user.persistentServices.keySet()) { if (!containsType(serviceInfos, v1)) { // Remove a persisted service that's not in the currently available services list. // And only if it is in the list of changedUids. if (!containsType(serviceInfos, v1) && containsUid(changedUids, user.persistentServices.get(v1))) { toBeRemoved.add(v1); } } Loading @@ -409,8 +424,19 @@ public abstract class RegisteredServicesCache<V> { } changed = true; user.persistentServices.remove(v1); user.services.remove(v1); notifyListener(v1, userId, true /* removed */); } if (DEBUG) { Log.d(TAG, "user.services="); for (V v : user.services.keySet()) { Log.d(TAG, " " + v + " " + user.services.get(v)); } Log.d(TAG, "user.persistentServices="); for (V v : user.persistentServices.keySet()) { Log.d(TAG, " " + v + " " + user.persistentServices.get(v)); } } if (DEBUG) { if (changes.length() > 0) { Log.d(TAG, "generateServicesMap(" + mInterfaceName + "): " + Loading @@ -426,6 +452,14 @@ public abstract class RegisteredServicesCache<V> { } } /** * Returns true if the list of changed uids is null (wildcard) or the specified uid * is contained in the list of changed uids. */ private boolean containsUid(int[] changedUids, int uid) { return changedUids == null || ArrayUtils.contains(changedUids, uid); } private boolean containsType(ArrayList<ServiceInfo<V>> serviceInfos, V type) { for (int i = 0, N = serviceInfos.size(); i < N; i++) { if (serviceInfos.get(i).type.equals(type)) { Loading