Enable in-process permission caches for system_server

Bug: 170472470

Do not disable the permission caches inside the system server.  This
is beneficial because permission checks require many binder calls, and
the cache, even though it is in-process, eliminates those calls.
1. Make the PermissionManager cache more effective by increasing the
   maximum size to 2048.  Experiments show that the high-water mark is
   about 600.
2. Suppress cache content in the 'dumpsys cacheinfo' output.  dumpsys
   fails if the output is too large in a single process, and the new
   caches push the system server cacheinfo over the limit.  The
   content can be added to the output by setting the new DETAILED
   boolean in PropertyInvalidatedCache to true, but this flag should
   never be committed with a value of true.

Test: two atest runs
 * atest FrameworksServicesTests:com.android.server.devicepolicy.DevicePolicyManagerTest#testGetPermissionGrantState
 * atest FrameworksServicesTests:NetworkPolicyManagerServiceTest

Change-Id: I7d3c1f34b44216bb510319ca5b6aced1cc53e05d
This commit is contained in:
Lee Shombert
2020-10-08 22:06:22 -07:00
parent 4c1deb59b7
commit 642aab2c50
3 changed files with 9 additions and 5 deletions

View File

@@ -206,6 +206,10 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
private static final String TAG = "PropertyInvalidatedCache";
private static final boolean DEBUG = false;
private static final boolean VERIFY = false;
// If this is true, dumpsys will dump the cache entries along with cache statistics.
// Most of the time this causes dumpsys to fail because the output stream is too
// large. Only set it to true in development images.
private static final boolean DETAILED = false;
// Per-Cache performance counters. As some cache instances are declared static,
@GuardedBy("mLock")
@@ -912,14 +916,13 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
" Current Size: %d, Max Size: %d, HW Mark: %d, Overflows: %d",
mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow));
pw.println(String.format(" Enabled: %s", mDisabled ? "false" : "true"));
pw.println("");
Set<Map.Entry<Query, Result>> cacheEntries = mCache.entrySet();
if (cacheEntries.size() == 0) {
pw.println("");
if (!DETAILED || cacheEntries.size() == 0) {
return;
}
pw.println("");
pw.println(" Contents:");
for (Map.Entry<Query, Result> entry : cacheEntries) {
String key = Objects.toString(entry.getKey());

View File

@@ -609,7 +609,7 @@ public final class PermissionManager {
/** @hide */
private static final PropertyInvalidatedCache<PermissionQuery, Integer> sPermissionCache =
new PropertyInvalidatedCache<PermissionQuery, Integer>(
16, CACHE_KEY_PACKAGE_INFO, "checkPermission") {
2048, CACHE_KEY_PACKAGE_INFO, "checkPermission") {
@Override
protected Integer recompute(PermissionQuery query) {
return checkPermissionUncached(query.permission, query.pid, query.uid);

View File

@@ -378,8 +378,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
@NonNull Injector injector) {
mInjector = injector;
// The package info cache is the cache for package and permission information.
// Disable the package info and package permission caches locally but leave the
// checkPermission cache active.
mInjector.invalidatePackageInfoCache();
mInjector.disablePermissionCache();
mInjector.disablePackageNamePermissionCache();
mContext = context;