From 529a49ee3d6452f033cb43a57bf8c865e177e2b8 Mon Sep 17 00:00:00 2001 From: Lee Shombert Date: Fri, 8 Apr 2022 07:54:39 -0700 Subject: [PATCH] Helper classes for IpcDataCache clients Bug: 227653108 This adds a helper class that can reduce much of the boilerplate in code that uses IpcDataCache (or the internal-only variant, PropertyInvalidatedCache). See the changes to DevicePolicyManager for example usage. Two PropertyInvalidatedCaches APIs are exposed for testing. The method createPropertyName() is changed so that apis like "Foo" are converted to "foo", not "_foo". Unit tests for the new behavior are added to IpcDataCacheTest. This was manually tested by dumping the cache info from builds with and without this change. Special attention is paid to the DevicePolicyManager caches. The same caches were found (as identified by their key and api) and the caches were enabled/disabled the same. In the course of testing, multiple instances of DevicePolicyManager caches were observed. Cache performance is better if the caches are static; making them static will be addressed in b/228452829. Test: * atest FrameworksCoreTests:IpcDataCacheTest * atest FrameworksCoreTests:PropertyInvalidatedCacheTests * atest FrameworksServicesTests:DevicePolicyConstantsTest * atest FrameworksServicesTests:DevicePolicyEventLoggerTest * atest FrameworksServicesTests:DevicePolicyManagerServiceMigrationTest * atest FrameworksServicesTests:DevicePolicyManagerTest * atest FrameworksServicesTests:EnterpriseSpecificIdCalculatorTest * atest FrameworksServicesTests:OverlayPackagesProviderTest * atest FrameworksServicesTests:OwnersTest * atest FrameworksServicesTests:PolicyVersionUpgraderTest * atest FrameworksServicesTests:SecurityEventTest * atest FrameworksServicesTests:SystemUpdatePolicyTest * atest FrameworksServicesTests:TransferOwnershipMetadataManagerTest * atest MixedDeviceOwnerTest#testIsDeviceOrganizationOwnedWithManagedProfile * atest MixedDeviceOwnerTest#testSetKeyguardDisabledFeatures * atest MixedManagedProfileOwnerTest#testIsDeviceOrganizationOwnedWithManagedProfile * atest MixedManagedProfileOwnerTest#testNetworkLoggingDelegate * atest MixedManagedProfileOwnerTest#testSetKeyguardDisabledFeatures * atest OrgOwnedProfileOwnerTest#testIsDeviceOrganizationOwnedWithManagedProfile * atest OrgOwnedProfileOwnerTest#testNetworkLoggingDelegate * atest OrgOwnedProfileOwnerTest#testSetKeyguardDisabledFeatures * atest android.devicepolicy.cts.DevicePolicyManagerTest * atest android.devicepolicy.cts.NetworkLoggingTest * atest com.android.cts.devicepolicy.DeviceOwnerTest#testAdminActionBookkeeping Change-Id: I2f4fe4ed25db5fb3100334b9d2ce748ee928c10d --- .../android/app/PropertyInvalidatedCache.java | 21 +- .../app/admin/DevicePolicyManager.java | 249 ++++-------------- core/java/android/os/IpcDataCache.java | 213 ++++++++++++++- .../src/android/os/IpcDataCacheTest.java | 104 ++++++++ .../DevicePolicyManagerService.java | 2 +- 5 files changed, 388 insertions(+), 201 deletions(-) diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java index df7bf7b94700b..add891d40d957 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -313,6 +313,7 @@ public class PropertyInvalidatedCache { * one of the permitted values above. The API is a string that is a legal Java simple * identifier. The api is modified to conform to the system property style guide by * replacing every upper case letter with an underscore and the lower case equivalent. + * (An initial upper case letter is not prefixed with an underscore). * There is no requirement that the apiName be the name of an actual API. * * Be aware that SystemProperties has a maximum length which is private to the @@ -326,7 +327,7 @@ public class PropertyInvalidatedCache { @NonNull String apiName) { char[] api = apiName.toCharArray(); int upper = 0; - for (int i = 0; i < api.length; i++) { + for (int i = 1; i < api.length; i++) { if (Character.isUpperCase(api[i])) { upper++; } @@ -336,7 +337,9 @@ public class PropertyInvalidatedCache { for (int i = 0; i < api.length; i++) { if (Character.isJavaIdentifierPart(api[i])) { if (Character.isUpperCase(api[i])) { - suffix[j++] = '_'; + if (i > 0) { + suffix[j++] = '_'; + } suffix[j++] = Character.toLowerCase(api[i]); } else { suffix[j++] = api[i]; @@ -1286,12 +1289,22 @@ public class PropertyInvalidatedCache { } /** - * Return the name of the cache, to be used in debug messages. + * Return the name of the cache, to be used in debug messages. This is exposed + * primarily for testing. + * @hide */ - private final @NonNull String cacheName() { + public final @NonNull String cacheName() { return mCacheName; } + /** + * Return the property used by the cache. This is primarily for test purposes. + * @hide + */ + public final @NonNull String propertyName() { + return mPropertyName; + } + /** * Return the query as a string, to be used in debug messages. New clients should not * override this, but should instead add the necessary toString() method to the Query diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d375a9e1ba262..f5cf73b152c8c 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -185,6 +185,30 @@ public class DevicePolicyManager { mResourcesManager = new DevicePolicyResourcesManager(context, service); } + /** + * Fetch the current value of mService. This is used in the binder cache lambda + * expressions. + */ + private final IDevicePolicyManager getService() { + return mService; + } + + /** + * Fetch the current value of mParentInstance. This is used in the binder cache + * lambda expressions. + */ + private final boolean isParentInstance() { + return mParentInstance; + } + + /** + * Fetch the current value of mContext. This is used in the binder cache lambda + * expressions. + */ + private final Context getContext() { + return mContext; + } + /** @hide test will override it. */ @VisibleForTesting protected int myUserId() { @@ -3783,57 +3807,21 @@ public class DevicePolicyManager { "android.app.extra.RESOURCE_IDS"; /** - * A convenience class that wraps some IpcDataCache methods. Instantiate it with an - * API string. Instances can and should be final static. All instances of this class - * use the same key for invalidation. + * This object is a single place to tack on invalidation and disable calls. All + * binder caches in this class derive from this Config, so all can be invalidated or + * disabled through this Config. */ - private static class BinderApi { - private final static String KEY = "DevicePolicyManager"; - private final String mApi; - BinderApi(String api) { - mApi = api; - } - final String api() { - return mApi; - } - final String key() { - return KEY; - } - final static void invalidate() { - IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM, KEY); - } - final void disable() { - IpcDataCache.disableForCurrentProcess(mApi); - } - } + private static final IpcDataCache.Config sDpmCaches = + new IpcDataCache.Config(8, IpcDataCache.MODULE_SYSTEM, "DevicePolicyManagerCaches"); /** @hide */ public static void invalidateBinderCaches() { - BinderApi.invalidate(); + sDpmCaches.invalidateCache(); } - /** - * A simple wrapper for binder caches in this class. All caches are created with a - * maximum of 8 entries, the SYSTEM module, and a cache name that is the same as the api. - */ - private static class BinderCache extends IpcDataCache { - BinderCache(BinderApi api, IpcDataCache.QueryHandler handler) { - super(8, IpcDataCache.MODULE_SYSTEM, api.key(), api.api(), handler); - } - } - - /** - * Disable all caches in the local process. - * @hide - */ - public static void disableLocalProcessCaches() { - disableGetKeyguardDisabledFeaturesCache(); - disableHasDeviceOwnerCache(); - disableGetProfileOwnerOrDeviceOwnerSupervisionComponentCache(); - disableIsOrganizationOwnedDeviceWithManagedProfileCache(); - disableGetDeviceOwnerOrganizationNameCache(); - disableGetOrganizationNameForUserCache(); - disableIsNetworkLoggingEnabled(); + /** @hide */ + public static void disableLocalCaches() { + sDpmCaches.disableAllForCurrentProcess(); } /** @hide */ @@ -8435,54 +8423,16 @@ public class DevicePolicyManager { return getKeyguardDisabledFeatures(admin, myUserId()); } - // A key into the keyguard cache. - private static class KeyguardQuery { - private final ComponentName mAdmin; - private final int mUserHandle; - KeyguardQuery(@Nullable ComponentName admin, int userHandle) { - mAdmin = admin; - mUserHandle = userHandle; - } - public boolean equals(Object o) { - if (o instanceof KeyguardQuery) { - KeyguardQuery r = (KeyguardQuery) o; - return Objects.equals(mAdmin, r.mAdmin) && mUserHandle == r.mUserHandle; - } else { - return false; - } - } - public int hashCode() { - return ((mAdmin != null) ? mAdmin.hashCode() : 0) * 13 + mUserHandle; - } - } - - // The query handler does not cache wildcard user IDs, although they should never - // appear in the query. - private static final BinderApi sGetKeyguardDisabledFeatures = - new BinderApi("getKeyguardDisabledFeatures"); - private BinderCache mGetKeyGuardDisabledFeaturesCache = - new BinderCache<>(sGetKeyguardDisabledFeatures, - new IpcDataCache.QueryHandler() { - @Override - public Integer apply(KeyguardQuery query) { - try { - return mService.getKeyguardDisabledFeatures( - query.mAdmin, query.mUserHandle, mParentInstance); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - }}); - - /** @hide */ - public static void disableGetKeyguardDisabledFeaturesCache() { - sGetKeyguardDisabledFeatures.disable(); - } + private IpcDataCache, Integer> mGetKeyGuardDisabledFeaturesCache = + new IpcDataCache<>(sDpmCaches.child("getKeyguardDisabledFeatures"), + (query) -> getService().getKeyguardDisabledFeatures( + query.first, query.second, isParentInstance())); /** @hide per-user version */ @UnsupportedAppUsage public int getKeyguardDisabledFeatures(@Nullable ComponentName admin, int userHandle) { if (mService != null) { - return mGetKeyGuardDisabledFeaturesCache.query(new KeyguardQuery(admin, userHandle)); + return mGetKeyGuardDisabledFeaturesCache.query(new Pair<>(admin, userHandle)); } else { return KEYGUARD_DISABLE_FEATURES_NONE; } @@ -8864,23 +8814,9 @@ public class DevicePolicyManager { return name != null ? name.getPackageName() : null; } - private static final BinderApi sHasDeviceOwner = - new BinderApi("hasDeviceOwner"); - private BinderCache mHasDeviceOwnerCache = - new BinderCache<>(sHasDeviceOwner, - new IpcDataCache.QueryHandler() { - @Override - public Boolean apply(Void query) { - try { - return mService.hasDeviceOwner(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - }}); - /** @hide */ - public static void disableHasDeviceOwnerCache() { - sHasDeviceOwner.disable(); - } + private IpcDataCache mHasDeviceOwnerCache = + new IpcDataCache<>(sDpmCaches.child("hasDeviceOwner"), + (query) -> getService().hasDeviceOwner()); /** * Called by the system to find out whether the device is managed by a Device Owner. @@ -9256,25 +9192,10 @@ public class DevicePolicyManager { return null; } - private final static BinderApi sGetProfileOwnerOrDeviceOwnerSupervisionComponent = - new BinderApi("getProfileOwnerOrDeviceOwnerSupervisionComponent"); - private final BinderCache + private final IpcDataCache mGetProfileOwnerOrDeviceOwnerSupervisionComponentCache = - new BinderCache(sGetProfileOwnerOrDeviceOwnerSupervisionComponent, - new IpcDataCache.QueryHandler() { - @Override - public ComponentName apply(UserHandle user) { - try { - return mService.getProfileOwnerOrDeviceOwnerSupervisionComponent( - user); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - }}); - /** @hide */ - public static void disableGetProfileOwnerOrDeviceOwnerSupervisionComponentCache() { - sGetProfileOwnerOrDeviceOwnerSupervisionComponent.disable(); - } + new IpcDataCache<>(sDpmCaches.child("getProfileOwnerOrDeviceOwnerSupervisionComponent"), + (arg) -> getService().getProfileOwnerOrDeviceOwnerSupervisionComponent(arg)); /** * Returns the configured supervision app if it exists and is the device owner or policy owner. @@ -9329,23 +9250,9 @@ public class DevicePolicyManager { return null; } - private final static BinderApi sIsOrganizationOwnedDeviceWithManagedProfile = - new BinderApi("isOrganizationOwnedDeviceWithManagedProfile"); - private final BinderCache mIsOrganizationOwnedDeviceWithManagedProfileCache = - new BinderCache(sIsOrganizationOwnedDeviceWithManagedProfile, - new IpcDataCache.QueryHandler() { - @Override - public Boolean apply(Void query) { - try { - return mService.isOrganizationOwnedDeviceWithManagedProfile(); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - }}); - /** @hide */ - public static void disableIsOrganizationOwnedDeviceWithManagedProfileCache() { - sIsOrganizationOwnedDeviceWithManagedProfile.disable(); - } + private final IpcDataCache mIsOrganizationOwnedDeviceWithManagedProfileCache = + new IpcDataCache(sDpmCaches.child("isOrganizationOwnedDeviceWithManagedProfile"), + (query) -> getService().isOrganizationOwnedDeviceWithManagedProfile()); /** * Apps can use this method to find out if the device was provisioned as @@ -12927,23 +12834,9 @@ public class DevicePolicyManager { } } - private final static BinderApi sGetDeviceOwnerOrganizationName = - new BinderApi("getDeviceOwnerOrganizationName"); - private final BinderCache mGetDeviceOwnerOrganizationNameCache = - new BinderCache(sGetDeviceOwnerOrganizationName, - new IpcDataCache.QueryHandler() { - @Override - public CharSequence apply(Void query) { - try { - return mService.getDeviceOwnerOrganizationName(); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - }}); - /** @hide */ - public static void disableGetDeviceOwnerOrganizationNameCache() { - sGetDeviceOwnerOrganizationName.disable(); - } + private final IpcDataCache mGetDeviceOwnerOrganizationNameCache = + new IpcDataCache(sDpmCaches.child("getDeviceOwnerOrganizationName"), + (query) -> getService().getDeviceOwnerOrganizationName()); /** * Called by the system to retrieve the name of the organization managing the device. @@ -12960,23 +12853,9 @@ public class DevicePolicyManager { return mGetDeviceOwnerOrganizationNameCache.query(null); } - private final static BinderApi sGetOrganizationNameForUser = - new BinderApi("getOrganizationNameForUser"); - private final BinderCache mGetOrganizationNameForUserCache = - new BinderCache(sGetOrganizationNameForUser, - new IpcDataCache.QueryHandler() { - @Override - public CharSequence apply(Integer userHandle) { - try { - return mService.getOrganizationNameForUser(userHandle); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - }}); - /** @hide */ - public static void disableGetOrganizationNameForUserCache() { - sGetOrganizationNameForUser.disable(); - } + private final IpcDataCache mGetOrganizationNameForUserCache = + new IpcDataCache<>(sDpmCaches.child("getOrganizationNameForUser"), + (query) -> getService().getOrganizationNameForUser(query)); /** * Retrieve the default title message used in the confirm credentials screen for a given user. @@ -13372,24 +13251,10 @@ public class DevicePolicyManager { } } - private final static BinderApi sNetworkLoggingApi = new BinderApi("isNetworkLoggingEnabled"); - private BinderCache mIsNetworkLoggingEnabledCache = - new BinderCache<>(sNetworkLoggingApi, - new IpcDataCache.QueryHandler() { - @Override - public Boolean apply(ComponentName admin) { - try { - return mService.isNetworkLoggingEnabled( - admin, mContext.getPackageName()); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - }}); - - /** @hide */ - public static void disableIsNetworkLoggingEnabled() { - sNetworkLoggingApi.disable(); - } + private IpcDataCache mIsNetworkLoggingEnabledCache = + new IpcDataCache<>(sDpmCaches.child("isNetworkLoggingEnabled"), + (admin) -> getService().isNetworkLoggingEnabled(admin, + getContext().getPackageName())); /** * Return whether network logging is enabled by a device owner or profile owner of diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java index 0efa34cdc47fe..bf44d65c40023 100644 --- a/core/java/android/os/IpcDataCache.java +++ b/core/java/android/os/IpcDataCache.java @@ -23,7 +23,7 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.PropertyInvalidatedCache; import android.text.TextUtils; -import android.util.Log; +import android.util.ArraySet; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.FastPrintWriter; @@ -35,7 +35,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; @@ -324,8 +323,8 @@ public class IpcDataCache extends PropertyInvalidatedCache computer) { + @NonNull String api, @NonNull String cacheName, + @NonNull QueryHandler computer) { super(maxEntries, module, api, cacheName, computer); } @@ -382,4 +381,210 @@ public class IpcDataCache extends PropertyInvalidatedCache mChildren; + + /** + * True if registered children are disabled in the current process. If this is + * true then all new children are disabled as they are registered. + */ + private boolean mDisabled = false; + + public Config(int maxEntries, @NonNull @IpcDataCacheModule String module, + @NonNull String api, @NonNull String name) { + mMaxEntries = maxEntries; + mModule = module; + mApi = api; + mName = name; + } + + /** + * A short-hand constructor that makes the name the same as the api. + */ + public Config(int maxEntries, @NonNull @IpcDataCacheModule String module, + @NonNull String api) { + this(maxEntries, module, api, api); + } + + /** + * Copy the module and max entries from the Config and take the api and name from + * the parameter list. + */ + public Config(@NonNull Config root, @NonNull String api, @NonNull String name) { + this(root.maxEntries(), root.module(), api, name); + } + + /** + * Copy the module and max entries from the Config and take the api and name from + * the parameter list. + */ + public Config(@NonNull Config root, @NonNull String api) { + this(root.maxEntries(), root.module(), api, api); + } + + /** + * Fetch a config that is a child of . The child shares the same api as the + * parent and is registered with the parent for the purposes of disabling in the + * current process. + */ + public Config child(@NonNull String name) { + final Config result = new Config(this, api(), name); + registerChild(name); + return result; + } + + public final int maxEntries() { + return mMaxEntries; + } + + @IpcDataCacheModule + public final @NonNull String module() { + return mModule; + } + + public final @NonNull String api() { + return mApi; + } + + public final @NonNull String name() { + return mName; + } + + /** + * Register a child cache name. If disableForCurrentProcess() has been called + * against this cache, disable th new child. + */ + private final void registerChild(String name) { + synchronized (this) { + if (mChildren == null) { + mChildren = new ArraySet<>(); + } + mChildren.add(name); + if (mDisabled) { + IpcDataCache.disableForCurrentProcess(name); + } + } + } + + /** + * Invalidate all caches that share this Config's module and api. + */ + public void invalidateCache() { + IpcDataCache.invalidateCache(mModule, mApi); + } + + /** + * Disable all caches that share this Config's name. + */ + public void disableForCurrentProcess() { + IpcDataCache.disableForCurrentProcess(mName); + } + + /** + * Disable this cache and all children. Any child that is added in the future + * will alwo be disabled. + */ + public void disableAllForCurrentProcess() { + synchronized (this) { + mDisabled = true; + disableForCurrentProcess(); + if (mChildren != null) { + for (String c : mChildren) { + IpcDataCache.disableForCurrentProcess(c); + } + } + } + } + } + + /** + * Create a new cache using a config. + * @hide + */ + public IpcDataCache(@NonNull Config config, @NonNull QueryHandler computer) { + super(config.maxEntries(), config.module(), config.api(), config.name(), computer); + } + + /** + * An interface suitable for a lambda expression instead of a QueryHandler. + * @hide + */ + public interface RemoteCall { + Result apply(Query query) throws RemoteException; + } + + /** + * This is a query handler that is created with a lambda expression that is invoked + * every time the handler is called. The handler is specifically meant for services + * hosted by system_server; the handler automatically rethrows RemoteException as a + * RuntimeException, which is the usual handling for failed binder calls. + */ + private static class SystemServerCallHandler + extends IpcDataCache.QueryHandler { + private final RemoteCall mHandler; + public SystemServerCallHandler(RemoteCall handler) { + mHandler = handler; + } + @Override + public Result apply(Query query) { + try { + return mHandler.apply(query); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Create a cache using a config and a lambda expression. + * @hide + */ + public IpcDataCache(@NonNull Config config, @NonNull RemoteCall computer) { + this(config, new SystemServerCallHandler<>(computer)); + } } diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java index fa7d7214d2899..34712ce54e0ff 100644 --- a/core/tests/coretests/src/android/os/IpcDataCacheTest.java +++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java @@ -53,6 +53,14 @@ public class IpcDataCacheTest { return value(x); } + // A single query but this can throw an exception. + boolean query(int x, boolean y) throws RemoteException { + if (y) { + throw new RemoteException(); + } + return query(x); + } + // Return the expected value of an input, without incrementing the query count. boolean value(int x) { return x % 3 == 0; @@ -138,6 +146,47 @@ public class IpcDataCacheTest { tester.verify(9); } + // This test is disabled pending an sepolicy change that allows any app to set the + // test property. + @Test + public void testRemoteCall() { + + // A stand-in for the binder. The test verifies that calls are passed through to + // this class properly. + ServerProxy tester = new ServerProxy(); + + // Create a cache that uses simple arithmetic to computer its values. + IpcDataCache.Config config = new IpcDataCache.Config(4, MODULE, API, "testCache2"); + IpcDataCache testCache = + new IpcDataCache<>(config, (x) -> tester.query(x, x % 10 == 9)); + + IpcDataCache.setTestMode(true); + testCache.testPropertyName(); + + tester.verify(0); + assertEquals(tester.value(3), testCache.query(3)); + tester.verify(1); + assertEquals(tester.value(3), testCache.query(3)); + tester.verify(2); + testCache.invalidateCache(); + assertEquals(tester.value(3), testCache.query(3)); + tester.verify(3); + assertEquals(tester.value(5), testCache.query(5)); + tester.verify(4); + assertEquals(tester.value(5), testCache.query(5)); + tester.verify(4); + assertEquals(tester.value(3), testCache.query(3)); + tester.verify(4); + + try { + testCache.query(9); + assertEquals(false, true); // The code should not reach this point. + } catch (RuntimeException e) { + assertEquals(e.getCause() instanceof RemoteException, true); + } + tester.verify(4); + } + @Test public void testDisableCache() { @@ -225,6 +274,17 @@ public class IpcDataCacheTest { testPropertyName(); } + TestCache(IpcDataCache.Config c) { + this(c, new TestQuery()); + } + + TestCache(IpcDataCache.Config c, TestQuery query) { + super(c, query); + mQuery = query; + setTestMode(true); + testPropertyName(); + } + int getRecomputeCount() { return mQuery.getRecomputeCount(); } @@ -309,4 +369,48 @@ public class IpcDataCacheTest { assertEquals("foo5", cache.query(5)); assertEquals(3, cache.getRecomputeCount()); } + + @Test + public void testConfig() { + IpcDataCache.Config a = new IpcDataCache.Config(8, MODULE, "apiA"); + TestCache ac = new TestCache(a); + assertEquals(8, a.maxEntries()); + assertEquals(MODULE, a.module()); + assertEquals("apiA", a.api()); + assertEquals("apiA", a.name()); + IpcDataCache.Config b = new IpcDataCache.Config(a, "apiB"); + TestCache bc = new TestCache(b); + assertEquals(8, b.maxEntries()); + assertEquals(MODULE, b.module()); + assertEquals("apiB", b.api()); + assertEquals("apiB", b.name()); + IpcDataCache.Config c = new IpcDataCache.Config(a, "apiC", "nameC"); + TestCache cc = new TestCache(c); + assertEquals(8, c.maxEntries()); + assertEquals(MODULE, c.module()); + assertEquals("apiC", c.api()); + assertEquals("nameC", c.name()); + IpcDataCache.Config d = a.child("nameD"); + TestCache dc = new TestCache(d); + assertEquals(8, d.maxEntries()); + assertEquals(MODULE, d.module()); + assertEquals("apiA", d.api()); + assertEquals("nameD", d.name()); + + a.disableForCurrentProcess(); + assertEquals(ac.isDisabled(), true); + assertEquals(bc.isDisabled(), false); + assertEquals(cc.isDisabled(), false); + assertEquals(dc.isDisabled(), false); + + a.disableAllForCurrentProcess(); + assertEquals(ac.isDisabled(), true); + assertEquals(bc.isDisabled(), false); + assertEquals(cc.isDisabled(), false); + assertEquals(dc.isDisabled(), true); + + IpcDataCache.Config e = a.child("nameE"); + TestCache ec = new TestCache(e); + assertEquals(ec.isDisabled(), true); + } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 268d588bd9070..35dbb157aaf45 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1781,7 +1781,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @VisibleForTesting DevicePolicyManagerService(Injector injector) { - DevicePolicyManager.disableGetKeyguardDisabledFeaturesCache(); + DevicePolicyManager.disableLocalCaches(); mInjector = injector; mContext = Objects.requireNonNull(injector.mContext);