summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2020-03-23 18:15:07 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-03-23 18:15:07 +0000
commit5dc3088cc1e311fae2e28a48d2fd060919d3f0e7 (patch)
tree0d6e83fffcd6533ad9d347148a411989cf586e61
parenta4ea2cfa12e2c857f9de7e2c0179daa6c0b9ae2f (diff)
parentf2e011daaec1cc243577e4272ad3c858a8cfddda (diff)
Merge "Binder cache for getPackagesForUid()."
-rw-r--r--core/java/android/app/ApplicationPackageManager.java87
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java11
2 files changed, 92 insertions, 6 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index a1ec27b3e9f7..bd3c8baa92ef 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -110,6 +110,7 @@ import libcore.util.EmptyArray;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -942,13 +943,89 @@ public class ApplicationPackageManager extends PackageManager {
}
}
+ /**
+ * Wrap the cached value in a class that does deep compares on string
+ * arrays. The comparison is needed only for the verification mode of
+ * PropertyInvalidatedCache; this mode is only enabled for debugging.
+ * The return result is an array of strings but the order in the array
+ * is not important. To properly compare two arrays, the arrays are
+ * sorted before the comparison.
+ */
+ private static class GetPackagesForUidResult {
+ private final String [] mValue;
+ GetPackagesForUidResult(String []s) {
+ mValue = s;
+ }
+ public String[] value() {
+ return mValue;
+ }
+ @Override
+ public String toString() {
+ return Arrays.toString(mValue);
+ }
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(mValue);
+ }
+ /**
+ * Arrays.sort() throws an NPE if passed a null pointer, so nulls
+ * are handled first.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof GetPackagesForUidResult) {
+ String [] r = ((GetPackagesForUidResult) o).mValue;
+ String [] l = mValue;
+ if ((r == null) != (l == null)) {
+ return false;
+ } else if (r == null) {
+ return true;
+ }
+ // Both arrays are non-null. Sort before comparing.
+ Arrays.sort(r);
+ Arrays.sort(l);
+ return Arrays.equals(l, r);
+ } else {
+ return false;
+ }
+ }
+ }
+
+ private static final String CACHE_KEY_PACKAGES_FOR_UID_PROPERTY =
+ "cache_key.get_packages_for_uid";
+ private static final PropertyInvalidatedCache<Integer, GetPackagesForUidResult>
+ mGetPackagesForUidCache =
+ new PropertyInvalidatedCache<Integer, GetPackagesForUidResult>(
+ 32, CACHE_KEY_PACKAGES_FOR_UID_PROPERTY) {
+ @Override
+ protected GetPackagesForUidResult recompute(Integer uid) {
+ try {
+ return new GetPackagesForUidResult(
+ ActivityThread.currentActivityThread().
+ getPackageManager().getPackagesForUid(uid));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ @Override
+ public String queryToString(Integer uid) {
+ return String.format("uid=%d", uid.intValue());
+ }
+ };
+
@Override
public String[] getPackagesForUid(int uid) {
- try {
- return mPM.getPackagesForUid(uid);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return mGetPackagesForUidCache.query(uid).value();
+ }
+
+ /** @hide */
+ public static void disableGetPackagesForUidCache() {
+ mGetPackagesForUidCache.disableLocal();
+ }
+
+ /** @hide */
+ public static void invalidateGetPackagesForUidCache() {
+ PropertyInvalidatedCache.invalidateCache(CACHE_KEY_PACKAGES_FOR_UID_PROPERTY);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c6f67dcce58e..fb2cca41e35d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2654,6 +2654,9 @@ public class PackageManagerService extends IPackageManager.Stub
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
PackageManager.disableApplicationInfoCache();
PackageManager.disablePackageInfoCache();
+ ApplicationPackageManager.invalidateGetPackagesForUidCache();
+ ApplicationPackageManager.disableGetPackagesForUidCache();
+ ApplicationPackageManager.invalidateHasSystemFeatureCache();
// Avoid invalidation-thrashing by preventing cache invalidations from causing property
// writes if the cache isn't enabled yet. We re-enable writes later when we're
@@ -2747,7 +2750,6 @@ public class PackageManagerService extends IPackageManager.Stub
t.traceBegin("get system config");
SystemConfig systemConfig = SystemConfig.getInstance();
mAvailableFeatures = systemConfig.getAvailableFeatures();
- ApplicationPackageManager.invalidateHasSystemFeatureCache();
t.traceEnd();
mProtectedPackages = new ProtectedPackages(mContext);
@@ -5947,6 +5949,11 @@ public class PackageManagerService extends IPackageManager.Stub
* </ol>
* The second is an artifact of the current data structures and should be fixed. See
* b/111075456 for one such instance.
+ * This binder API is cached. If the algorithm in this method changes,
+ * or if the underlying objecs (as returned by getSettingLPr()) change
+ * then the logic that invalidates the cache must be revisited. See
+ * calls to invalidateGetPackagesForUidCache() to locate the points at
+ * which the cache is invalidated.
*/
@Override
public String[] getPackagesForUid(int uid) {
@@ -16216,6 +16223,7 @@ public class PackageManagerService extends IPackageManager.Stub
updateInstantAppInstallerLocked(packageName);
}
}
+ ApplicationPackageManager.invalidateGetPackagesForUidCache();
}
/**
@@ -17834,6 +17842,7 @@ public class PackageManagerService extends IPackageManager.Stub
updateInstantAppInstallerLocked(packageName);
}
}
+ ApplicationPackageManager.invalidateGetPackagesForUidCache();
}
if (res) {