diff options
| author | 2019-07-02 12:28:34 -0700 | |
|---|---|---|
| committer | 2019-07-02 12:28:34 -0700 | |
| commit | a51df29cf567a41dc9c9ebc3d29770dbee7d331d (patch) | |
| tree | 911bee0522c9c0edf5b43fd65784321a912b458c | |
| parent | a708c799375229a02f78043de1c6caac58d7fbe4 (diff) | |
| parent | 660c234e9ad68cd23feb2e22cb43bd7a645b24e6 (diff) | |
Merge "Revert "Do not load xml metadata for unchanged packages in RegisteredServicesCache"" into qt-dev
am: 660c234e9a
Change-Id: I1142efdfe93ff9e5ac8f33af9f58e27d52f02236
| -rw-r--r-- | core/java/android/content/pm/RegisteredServicesCache.java | 59 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java | 41 |
2 files changed, 20 insertions, 80 deletions
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index b0b1874107ce..23fbefb73c50 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -17,7 +17,6 @@ package android.content.pm; import android.Manifest; -import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -177,8 +176,7 @@ public abstract class RegisteredServicesCache<V> { mContext.registerReceiver(mUserRemovedReceiver, userFilter); } - @VisibleForTesting - protected void handlePackageEvent(Intent intent, int userId) { + private void handlePackageEvent(Intent intent, int userId) { // Don't regenerate the services map when the package is removed or its // ASEC container unmounted as a step in replacement. The subsequent // _ADDED / _AVAILABLE call will regenerate the map in the final state. @@ -240,9 +238,6 @@ public abstract class RegisteredServicesCache<V> { public void invalidateCache(int userId) { synchronized (mServicesLock) { - if (DEBUG) { - Slog.d(TAG, "invalidating cache for " + userId + " " + mInterfaceName); - } final UserServices<V> user = findOrCreateUserLocked(userId); user.services = null; onServicesChangedLocked(userId); @@ -472,48 +467,34 @@ public abstract class RegisteredServicesCache<V> { * or null to assume that everything is affected. * @param userId the user for whom to update the services map. */ - private void generateServicesMap(@Nullable int[] changedUids, int userId) { + private void generateServicesMap(int[] changedUids, int userId) { if (DEBUG) { Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + Arrays.toString(changedUids)); } + final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>(); + final List<ResolveInfo> resolveInfos = queryIntentServices(userId); + for (ResolveInfo resolveInfo : resolveInfos) { + try { + ServiceInfo<V> info = parseServiceInfo(resolveInfo); + if (info == null) { + Log.w(TAG, "Unable to load service info " + resolveInfo.toString()); + continue; + } + serviceInfos.add(info); + } catch (XmlPullParserException | IOException e) { + Log.w(TAG, "Unable to load service info " + resolveInfo.toString(), e); + } + } + synchronized (mServicesLock) { final UserServices<V> user = findOrCreateUserLocked(userId); - final boolean cacheInvalid = user.services == null; - if (cacheInvalid) { + final boolean firstScan = user.services == null; + if (firstScan) { user.services = Maps.newHashMap(); } - final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>(); - final List<ResolveInfo> resolveInfos = queryIntentServices(userId); - - for (ResolveInfo resolveInfo : resolveInfos) { - try { - // when changedUids == null, we want to do a rescan of everything, this means - // it's the initial scan, and containsUid will trivially return true - // when changedUids != null, we got here because a package changed, but - // invalidateCache could have been called (thus user.services == null), and we - // should query from PackageManager again - if (!cacheInvalid - && !containsUid( - changedUids, resolveInfo.serviceInfo.applicationInfo.uid)) { - if (DEBUG) { - Slog.d(TAG, "Skipping parseServiceInfo for " + resolveInfo); - } - continue; - } - ServiceInfo<V> info = parseServiceInfo(resolveInfo); - if (info == null) { - Log.w(TAG, "Unable to load service info " + resolveInfo.toString()); - continue; - } - serviceInfos.add(info); - } catch (XmlPullParserException | IOException e) { - Log.w(TAG, "Unable to load service info " + resolveInfo.toString(), e); - } - } - StringBuilder changes = new StringBuilder(); boolean changed = false; for (ServiceInfo<V> info : serviceInfos) { @@ -534,7 +515,7 @@ public abstract class RegisteredServicesCache<V> { changed = true; user.services.put(info.type, info); user.persistentServices.put(info.type, info.uid); - if (!(user.mPersistentServicesFileDidNotExist && cacheInvalid)) { + if (!(user.mPersistentServicesFileDidNotExist && firstScan)) { notifyListener(info.type, userId, false /* removed */); } } else if (previousUid == info.uid) { diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java index c8150b12a23b..365e97ded928 100644 --- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java +++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java @@ -16,7 +16,6 @@ package android.content.pm; -import android.content.Intent; import android.content.res.Resources; import android.os.FileUtils; import android.os.Parcel; @@ -190,36 +189,6 @@ public class RegisteredServicesCacheTest extends AndroidTestCase { assertEquals(0, cache.getPersistentServicesSize(u1)); } - /** - * Check that an optimization to skip a call to PackageManager handles an invalidated cache. - * - * We added an optimization in generateServicesMap to only query PackageManager for packages - * that have been changed, because if a package is unchanged, we have already cached the - * services info for it, so we can save a query to PackageManager (and save some memory). - * However, if invalidateCache was called, we cannot optimize, and must do a full query. - * The initial optimization was buggy because it failed to check for an invalidated cache, and - * only scanned the changed packages, given in the ACTION_PACKAGE_CHANGED intent (b/122912184). - */ - public void testParseServiceInfoOptimizationHandlesInvalidatedCache() { - TestServicesCache cache = new TestServicesCache(); - cache.addServiceForQuerying(U0, r1, newServiceInfo(t1, UID1)); - cache.addServiceForQuerying(U0, r2, newServiceInfo(t2, UID2)); - assertEquals(2, cache.getAllServicesSize(U0)); - - // simulate the client of the cache invalidating it - cache.invalidateCache(U0); - - // there should be 0 services (userServices.services == null ) at this point, but we don't - // call getAllServicesSize since that would force a full scan of packages, - // instead we trigger a package change in a package that is in the list of services - Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED); - intent.putExtra(Intent.EXTRA_UID, UID1); - cache.handlePackageEvent(intent, U0); - - // check that the optimization does a full query and caches both services - assertEquals(2, cache.getAllServicesSize(U0)); - } - private static RegisteredServicesCache.ServiceInfo<TestServiceType> newServiceInfo( TestServiceType type, int uid) { final ComponentInfo info = new ComponentInfo(); @@ -297,11 +266,6 @@ public class RegisteredServicesCacheTest extends AndroidTestCase { map = new HashMap<>(); mServices.put(userId, map); } - // in actual cases, resolveInfo should always have a serviceInfo, since we specifically - // query for intent services - resolveInfo.serviceInfo = new android.content.pm.ServiceInfo(); - resolveInfo.serviceInfo.applicationInfo = - new ApplicationInfo(serviceInfo.componentInfo.applicationInfo); map.put(resolveInfo, serviceInfo); } @@ -340,11 +304,6 @@ public class RegisteredServicesCacheTest extends AndroidTestCase { public void onUserRemoved(int userId) { super.onUserRemoved(userId); } - - @Override - public void handlePackageEvent(Intent intent, int userId) { - super.handlePackageEvent(intent, userId); - } } static class TestSerializer implements XmlSerializerAndParser<TestServiceType> { |