Merge "Binder cache for getPackagesForUid()."

This commit is contained in:
TreeHugger Robot
2020-03-23 18:15:07 +00:00
committed by Android (Google) Code Review
2 changed files with 92 additions and 6 deletions

View File

@@ -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

View File

@@ -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) {