From 80f4322b368e1eb4315222fdc1efd3075df07981 Mon Sep 17 00:00:00 2001 From: Lee Shombert Date: Mon, 10 Jan 2022 14:46:33 -0800 Subject: [PATCH] Clean up PropertyInvalidatedCache for SystemApi Bug: 152453213 Tag: #refactor This commit prepares PropertyInvalidatedCache to function as a system api. The changes may be summarized as follows: 1. Visibility changes - some formerly protected or public methods are now private. 2. Use of ParcelFileDescriptor instead of FileDescriptor. 3. Null-ness annotations have been added to public methods. 4. An onTrimMemory() method has been created that hides some class internals from ActivityThread. An existing test (os/PropertyInvalidatedCacheTest) has been deleted. Its contents have been merged into app/PropertyInvalidatedCacheTests. The deleted test may never have been used. Test: atest PropertyInvalidatedCacheTests Change-Id: I619e715c3deca016b21c69bf34a8e61771957e68 --- core/java/android/app/ActivityThread.java | 6 +- .../android/app/PropertyInvalidatedCache.java | 108 +++++++---- .../app/PropertyInvalidatedCacheTests.java | 167 ++++++++++++++++- .../os/PropertyInvalidatedCacheTest.java | 168 ------------------ .../server/am/ActivityManagerService.java | 4 - 5 files changed, 240 insertions(+), 213 deletions(-) delete mode 100644 core/tests/systemproperties/src/android/os/PropertyInvalidatedCacheTest.java diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1778ea4a32e2..371f615fea18 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1646,7 +1646,7 @@ public final class ActivityThread extends ClientTransactionHandler @Override public void dumpCacheInfo(ParcelFileDescriptor pfd, String[] args) { - PropertyInvalidatedCache.dumpCacheInfo(pfd.getFileDescriptor(), args); + PropertyInvalidatedCache.dumpCacheInfo(pfd, args); IoUtils.closeQuietly(pfd); } @@ -6378,9 +6378,7 @@ public final class ActivityThread extends ClientTransactionHandler if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { - for (PropertyInvalidatedCache pic : PropertyInvalidatedCache.getActiveCaches()) { - pic.clear(); - } + PropertyInvalidatedCache.onTrimMemory(); } final ArrayList callbacks = diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java index 978160c1c243..ec8d989c61d4 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.ParcelFileDescriptor; import android.os.SystemClock; import android.os.SystemProperties; import android.text.TextUtils; @@ -29,7 +30,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FastPrintWriter; -import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; @@ -355,11 +355,12 @@ public abstract class PropertyInvalidatedCache { private final int mMaxEntries; /** - * Make a new property invalidated cache. + * Make a new property invalidated cache. This constructor names the cache after the + * property name. New clients should prefer the constructor that takes an explicit + * cache name. * * @param maxEntries Maximum number of entries to cache; LRU discard - * @param propertyName Name of the system property holding the cache invalidation nonce - * Defaults the cache name to the property name. + * @param propertyName Name of the system property holding the cache invalidation nonce. */ public PropertyInvalidatedCache(int maxEntries, @NonNull String propertyName) { this(maxEntries, propertyName, propertyName); @@ -418,7 +419,7 @@ public abstract class PropertyInvalidatedCache { * Enable or disable testing. The testing property map is cleared every time this * method is called. */ - @VisibleForTesting + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public static void setTestMode(boolean mode) { sTesting = mode; synchronized (sTestingPropertyMap) { @@ -426,12 +427,12 @@ public abstract class PropertyInvalidatedCache { } } - /** - * Enable testing the specific cache key. Only keys in the map are subject to testing. - * There is no method to stop testing a property name. Just disable the test mode. - */ - @VisibleForTesting - public static void testPropertyName(String name) { + /** + * Enable testing the specific cache key. Only keys in the map are subject to testing. + * There is no method to stop testing a property name. Just disable the test mode. + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public static void testPropertyName(@NonNull String name) { synchronized (sTestingPropertyMap) { sTestingPropertyMap.put(name, (long) NONCE_UNSET); } @@ -505,21 +506,23 @@ public abstract class PropertyInvalidatedCache { * block. If this function returns null, the result of the cache query is null. There is no * "negative cache" in the query: we don't cache null results at all. */ - public abstract Result recompute(Query query); + public abstract @NonNull Result recompute(@NonNull Query query); /** * Return true if the query should bypass the cache. The default behavior is to * always use the cache but the method can be overridden for a specific class. */ - public boolean bypass(Query query) { + public boolean bypass(@NonNull Query query) { return false; } /** - * Determines if a pair of responses are considered equal. Used to determine whether - * a cache is inadvertently returning stale results when VERIFY is set to true. + * Determines if a pair of responses are considered equal. Used to determine whether a + * cache is inadvertently returning stale results when VERIFY is set to true. Some + * existing clients override this method, but it is now deprecated in favor of a valid + * equals() method on the Result class. */ - protected boolean resultEquals(Result cachedResult, Result fetchedResult) { + public boolean resultEquals(Result cachedResult, Result fetchedResult) { // If a service crashes and returns a null result, the cached value remains valid. if (fetchedResult != null) { return Objects.equals(cachedResult, fetchedResult); @@ -544,8 +547,11 @@ public abstract class PropertyInvalidatedCache { } /** - * Disable the use of this cache in this process. + * Disable the use of this cache in this process. This method is using during + * testing. To disable a cache in normal code, use disableLocal(). + * @hide */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public final void disableInstance() { synchronized (mLock) { mDisabled = true; @@ -558,7 +564,7 @@ public abstract class PropertyInvalidatedCache { * using the key will be disabled now, and all future cache instances that use the key will be * disabled in their constructor. */ - public static final void disableLocal(@NonNull String name) { + private static final void disableLocal(@NonNull String name) { synchronized (sCorkLock) { sDisabledKeys.add(name); for (PropertyInvalidatedCache cache : sCaches.keySet()) { @@ -569,8 +575,22 @@ public abstract class PropertyInvalidatedCache { } } + /** + * Stop disabling local caches with a particular name. Any caches that are currently + * disabled remain disabled (the "disabled" setting is sticky). However, new caches + * with this name will not be disabled. It is not an error if the cache name is not + * found in the list of disabled caches. + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public final void clearDisableLocal() { + synchronized (sCorkLock) { + sDisabledKeys.remove(mCacheName); + } + } + /** * Disable this cache in the current process, and all other caches that use the same + * name. This does not affect caches that have a different name but use the same * property. */ public final void disableLocal() { @@ -580,6 +600,7 @@ public abstract class PropertyInvalidatedCache { /** * Return whether the cache is disabled in this process. */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public final boolean isDisabledLocal() { return mDisabled || !sEnabled; } @@ -587,7 +608,7 @@ public abstract class PropertyInvalidatedCache { /** * Get a value from the cache or recompute it. */ - public Result query(Query query) { + public @NonNull Result query(@NonNull Query query) { // Let access to mDisabled race: it's atomic anyway. long currentNonce = (!isDisabledLocal()) ? getCurrentNonce() : NONCE_DISABLED; if (bypass(query)) { @@ -704,6 +725,7 @@ public abstract class PropertyInvalidatedCache { * the cache objects to invalidate all of the cache objects becomes confusing and you should * just use the static version of this function. */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public final void disableSystemWide() { disableSystemWide(mPropertyName); } @@ -714,7 +736,7 @@ public abstract class PropertyInvalidatedCache { * * @param name Name of the cache-key property to invalidate */ - public static void disableSystemWide(@NonNull String name) { + private static void disableSystemWide(@NonNull String name) { if (!sEnabled) { return; } @@ -784,8 +806,8 @@ public abstract class PropertyInvalidatedCache { "invalidating cache [%s]: [%s] -> [%s]", name, nonce, Long.toString(newValue))); } - // TODO(dancol): add an atomic compare and exchange property set operation to avoid a - // small race with concurrent disable here. + // There is a small race with concurrent disables here. A compare-and-exchange + // property operation would be required to eliminate the race condition. setNonce(name, newValue); long invalidateCount = sInvalidates.getOrDefault(name, (long) 0); sInvalidates.put(name, ++invalidateCount); @@ -990,6 +1012,10 @@ public abstract class PropertyInvalidatedCache { } } + /** + * Return the result generated by a given query to the cache, performing debugging checks when + * enabled. + */ private Result maybeCheckConsistency(Query query, Result proposedResult) { if (VERIFY) { Result resultToCompare = recompute(query); @@ -1007,24 +1033,27 @@ public abstract class PropertyInvalidatedCache { } /** - * Return the name of the cache, to be used in debug messages. The - * method is public so clients can use it. + * Return the name of the cache, to be used in debug messages. */ - public String cacheName() { + private final @NonNull String cacheName() { return mCacheName; } /** - * Return the query as a string, to be used in debug messages. The - * method is public so clients can use it in external debug messages. + * 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 + * class. */ - public String queryToString(Query query) { + protected @NonNull String queryToString(@NonNull Query query) { return Objects.toString(query); } /** - * Disable all caches in the local process. Once disabled it is not - * possible to re-enable caching in the current process. + * Disable all caches in the local process. This is primarily useful for testing when + * the test needs to bypass the cache or when the test is for a server, and the test + * process does not have privileges to write SystemProperties. Once disabled it is not + * possible to re-enable caching in the current process. If a client wants to + * temporarily disable caching, use the corking mechanism. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public static void disableForTestMode() { @@ -1044,7 +1073,7 @@ public abstract class PropertyInvalidatedCache { /** * Returns a list of caches alive at the current time. */ - public static ArrayList getActiveCaches() { + private static @NonNull ArrayList getActiveCaches() { synchronized (sCorkLock) { return new ArrayList(sCaches.keySet()); } @@ -1053,7 +1082,7 @@ public abstract class PropertyInvalidatedCache { /** * Returns a list of the active corks in a process. */ - public static ArrayList> getActiveCorks() { + private static @NonNull ArrayList> getActiveCorks() { synchronized (sCorkLock) { return new ArrayList>(sCorks.entrySet()); } @@ -1104,14 +1133,14 @@ public abstract class PropertyInvalidatedCache { } /** - * Dumps contents of every cache in the process to the provided FileDescriptor. + * Dumps the contents of every cache in the process to the provided ParcelFileDescriptor. */ - public static void dumpCacheInfo(FileDescriptor fd, String[] args) { + public static void dumpCacheInfo(@NonNull ParcelFileDescriptor pfd, @NonNull String[] args) { ArrayList activeCaches; ArrayList> activeCorks; try ( - FileOutputStream fout = new FileOutputStream(fd); + FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor()); PrintWriter pw = new FastPrintWriter(fout); ) { if (!sEnabled) { @@ -1142,4 +1171,13 @@ public abstract class PropertyInvalidatedCache { Log.e(TAG, "Failed to dump PropertyInvalidatedCache instances"); } } + + /** + * Trim memory by clearing all the caches. + */ + public static void onTrimMemory() { + for (PropertyInvalidatedCache pic : getActiveCaches()) { + pic.clear(); + } + } } diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java index fd3079fd295d..d3e8bb0ec317 100644 --- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java +++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java @@ -17,6 +17,8 @@ package android.app; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; import androidx.test.filters.SmallTest; @@ -25,7 +27,9 @@ import org.junit.Test; /** * Test for verifying the behavior of {@link PropertyInvalidatedCache}. This test does - * not use any actual binder calls - it is entirely self-contained. + * not use any actual binder calls - it is entirely self-contained. This test also relies + * on the test mode of {@link PropertyInvalidatedCache} because Android SELinux rules do + * not grant test processes the permission to set system properties. *

* Build/Install/Run: * atest FrameworksCoreTests:PropertyInvalidatedCacheTests @@ -33,6 +37,8 @@ import org.junit.Test; @SmallTest public class PropertyInvalidatedCacheTests { + // This property is never set. The test process does not have permission to set any + // properties. static final String CACHE_PROPERTY = "cache_key.cache_test_a"; // This class is a proxy for binder calls. It contains a counter that increments @@ -58,7 +64,8 @@ public class PropertyInvalidatedCacheTests { } } - // Clear the test mode after every test, in case this process is used for other tests. + // Clear the test mode after every test, in case this process is used for other + // tests. This also resets the test property map. @After public void tearDown() throws Exception { PropertyInvalidatedCache.setTestMode(false); @@ -176,5 +183,161 @@ public class PropertyInvalidatedCacheTests { } }; assertEquals(true, cache1.getDisabledState()); + + // Remove the record of caches being locally disabled. This is a clean-up step. + cache1.clearDisableLocal(); + assertEquals(true, cache1.getDisabledState()); + assertEquals(true, cache2.getDisabledState()); + assertEquals(false, cache3.getDisabledState()); + + // Create a new cache1. Verify that the new instance is not disabled. + cache1 = new PropertyInvalidatedCache<>(4, CACHE_PROPERTY) { + @Override + public Boolean recompute(Integer x) { + return tester.query(x); + } + }; + assertEquals(false, cache1.getDisabledState()); + } + + private static final String UNSET_KEY = "Aiw7woh6ie4toh7W"; + + private static class TestCache extends PropertyInvalidatedCache { + TestCache() { + this(CACHE_PROPERTY); + } + + TestCache(String key) { + super(4, key); + setTestMode(true); + testPropertyName(key); + } + + @Override + public String recompute(Integer qv) { + mRecomputeCount += 1; + return "foo" + qv.toString(); + } + + int getRecomputeCount() { + return mRecomputeCount; + } + + private int mRecomputeCount = 0; + } + + @Test + public void testCacheRecompute() { + TestCache cache = new TestCache(); + cache.invalidateCache(); + assertEquals(cache.isDisabledLocal(), false); + assertEquals("foo5", cache.query(5)); + assertEquals(1, cache.getRecomputeCount()); + assertEquals("foo5", cache.query(5)); + assertEquals(1, cache.getRecomputeCount()); + assertEquals("foo6", cache.query(6)); + assertEquals(2, cache.getRecomputeCount()); + cache.invalidateCache(); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(3, cache.getRecomputeCount()); + } + + @Test + public void testCacheInitialState() { + TestCache cache = new TestCache(); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(2, cache.getRecomputeCount()); + cache.invalidateCache(); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(3, cache.getRecomputeCount()); + } + + @Test + public void testCachePropertyUnset() { + TestCache cache = new TestCache(UNSET_KEY); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(2, cache.getRecomputeCount()); + } + + @Test + public void testCacheDisableState() { + TestCache cache = new TestCache(); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(2, cache.getRecomputeCount()); + cache.invalidateCache(); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(3, cache.getRecomputeCount()); + cache.disableSystemWide(); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(5, cache.getRecomputeCount()); + cache.invalidateCache(); // Should not reenable + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(7, cache.getRecomputeCount()); + } + + @Test + public void testRefreshSameObject() { + int[] refreshCount = new int[1]; + TestCache cache = new TestCache() { + @Override + public String refresh(String oldResult, Integer query) { + refreshCount[0] += 1; + return oldResult; + } + }; + cache.invalidateCache(); + String result1 = cache.query(5); + assertEquals("foo5", result1); + String result2 = cache.query(5); + assertSame(result1, result2); + assertEquals(1, cache.getRecomputeCount()); + assertEquals(1, refreshCount[0]); + assertEquals("foo5", cache.query(5)); + assertEquals(2, refreshCount[0]); + } + + @Test + public void testRefreshInvalidateRace() { + int[] refreshCount = new int[1]; + TestCache cache = new TestCache() { + @Override + public String refresh(String oldResult, Integer query) { + refreshCount[0] += 1; + invalidateCache(); + return new String(oldResult); + } + }; + cache.invalidateCache(); + String result1 = cache.query(5); + assertEquals("foo5", result1); + String result2 = cache.query(5); + assertEquals(result1, result2); + assertNotSame(result1, result2); + assertEquals(2, cache.getRecomputeCount()); + } + + @Test + public void testLocalProcessDisable() { + TestCache cache = new TestCache(); + assertEquals(cache.isDisabledLocal(), false); + cache.invalidateCache(); + assertEquals("foo5", cache.query(5)); + assertEquals(1, cache.getRecomputeCount()); + assertEquals("foo5", cache.query(5)); + assertEquals(1, cache.getRecomputeCount()); + assertEquals(cache.isDisabledLocal(), false); + cache.disableLocal(); + assertEquals(cache.isDisabledLocal(), true); + assertEquals("foo5", cache.query(5)); + assertEquals("foo5", cache.query(5)); + assertEquals(3, cache.getRecomputeCount()); } } diff --git a/core/tests/systemproperties/src/android/os/PropertyInvalidatedCacheTest.java b/core/tests/systemproperties/src/android/os/PropertyInvalidatedCacheTest.java deleted file mode 100644 index 182bf6d165a0..000000000000 --- a/core/tests/systemproperties/src/android/os/PropertyInvalidatedCacheTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.os; - -import android.app.PropertyInvalidatedCache; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.TestCase; - -public class PropertyInvalidatedCacheTest extends TestCase { - private static final String KEY = "sys.testkey"; - private static final String UNSET_KEY = "Aiw7woh6ie4toh7W"; - - private static class TestCache extends PropertyInvalidatedCache { - TestCache() { - this(KEY); - } - - TestCache(String key) { - super(4, key); - } - - @Override - public String recompute(Integer qv) { - mRecomputeCount += 1; - return "foo" + qv.toString(); - } - - int getRecomputeCount() { - return mRecomputeCount; - } - - private int mRecomputeCount = 0; - } - - @Override - protected void setUp() { - SystemProperties.set(KEY, ""); - } - - @SmallTest - public void testCacheRecompute() throws Exception { - TestCache cache = new TestCache(); - cache.invalidateCache(); - assertEquals("foo5", cache.query(5)); - assertEquals(1, cache.getRecomputeCount()); - assertEquals("foo5", cache.query(5)); - assertEquals(1, cache.getRecomputeCount()); - assertEquals("foo6", cache.query(6)); - assertEquals(2, cache.getRecomputeCount()); - cache.invalidateCache(); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(3, cache.getRecomputeCount()); - } - - @SmallTest - public void testCacheInitialState() throws Exception { - TestCache cache = new TestCache(); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(2, cache.getRecomputeCount()); - cache.invalidateCache(); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(3, cache.getRecomputeCount()); - } - - @SmallTest - public void testCachePropertyUnset() throws Exception { - TestCache cache = new TestCache(UNSET_KEY); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(2, cache.getRecomputeCount()); - } - - @SmallTest - public void testCacheDisableState() throws Exception { - TestCache cache = new TestCache(); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(2, cache.getRecomputeCount()); - cache.invalidateCache(); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(3, cache.getRecomputeCount()); - cache.disableSystemWide(); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(5, cache.getRecomputeCount()); - cache.invalidateCache(); // Should not reenable - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(7, cache.getRecomputeCount()); - } - - @SmallTest - public void testRefreshSameObject() throws Exception { - int[] refreshCount = new int[1]; - TestCache cache = new TestCache() { - @Override - protected String refresh(String oldResult, Integer query) { - refreshCount[0] += 1; - return oldResult; - } - }; - cache.invalidateCache(); - String result1 = cache.query(5); - assertEquals("foo5", result1); - String result2 = cache.query(5); - assertSame(result1, result2); - assertEquals(1, cache.getRecomputeCount()); - assertEquals(1, refreshCount[0]); - assertEquals("foo5", cache.query(5)); - assertEquals(2, refreshCount[0]); - } - - @SmallTest - public void testRefreshInvalidateRace() throws Exception { - int[] refreshCount = new int[1]; - TestCache cache = new TestCache() { - @Override - protected String refresh(String oldResult, Integer query) { - refreshCount[0] += 1; - invalidateCache(); - return new String(oldResult); - } - }; - cache.invalidateCache(); - String result1 = cache.query(5); - assertEquals("foo5", result1); - String result2 = cache.query(5); - assertEquals(result1, result2); - assertNotSame(result1, result2); - assertEquals(2, cache.getRecomputeCount()); - } - - @SmallTest - public void testLocalProcessDisable() throws Exception { - TestCache cache = new TestCache(); - cache.invalidateCache(); - assertEquals("foo5", cache.query(5)); - assertEquals(1, cache.getRecomputeCount()); - assertEquals("foo5", cache.query(5)); - assertEquals(1, cache.getRecomputeCount()); - assertEquals(cache.isDisabledLocal(), false); - cache.disableLocal(); - assertEquals(cache.isDisabledLocal(), true); - assertEquals("foo5", cache.query(5)); - assertEquals("foo5", cache.query(5)); - assertEquals(3, cache.getRecomputeCount()); - } - -} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index da8c407a501d..648f32643280 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -10359,10 +10359,6 @@ public class ActivityManagerService extends IActivityManager.Stub if (thread != null) { pw.println("\n\n** Cache info for pid " + pid + " [" + r.processName + "] **"); pw.flush(); - if (pid == MY_PID) { - PropertyInvalidatedCache.dumpCacheInfo(fd, args); - continue; - } try { TransferPipe tp = new TransferPipe(); try {