Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 423848fe authored by Lee Shombert's avatar Lee Shombert
Browse files

Fix concurrency issue in PropertyInvalidatedCache

Bug: 253063488

Ensure the global lock is held while fetching the list of active
caches.  The global lock is necessary while the list is being fetched;
it is not necessary while each cache in the list is cleared.

Added a new test for PropertyInvalidatedCache.onTrimMemory().  This
test will not catch race conditions but does verify that
onTrimMemory() behaves as expected.

Added an entry to TEST_MAPPING so that the PropertyInvalidatedCache
tests run when the source file is modified.

Test: atest
 * FrameworksCoreTests:PropertyInvalidatedCacheTests

Change-Id: Ib3ef355c88cb272334ccfc16f922c057828749ce
parent bb18fbe3
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -1405,6 +1405,17 @@ public class PropertyInvalidatedCache<Query, Result> {
        return isDisabled();
    }

    /**
     * Return the number of entries in the cache.  This is used for testing and has package-only
     * visibility.
     * @hide
     */
    public int size() {
        synchronized (mLock) {
            return mCache.size();
        }
    }

    /**
     * Returns a list of caches alive at the current time.
     */
@@ -1612,8 +1623,12 @@ public class PropertyInvalidatedCache<Query, Result> {
     * @hide
     */
    public static void onTrimMemory() {
        for (PropertyInvalidatedCache pic : getActiveCaches()) {
            pic.clear();
        ArrayList<PropertyInvalidatedCache> activeCaches;
        synchronized (sGlobalLock) {
            activeCaches = getActiveCaches();
        }
        for (int i = 0; i < activeCaches.size(); i++) {
            activeCaches.get(i).clear();
        }
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -175,6 +175,23 @@
            "file_patterns": [
                "(/|^)KeyguardManager.java"
            ]
        },
        {
            "name": "FrameworksCoreTests",
            "options": [
                {
                    "exclude-annotation": "androidx.test.filters.FlakyTest"
                },
                {
                    "exclude-annotation": "org.junit.Ignore"
                },
                {
                    "include-filter": "android.app.PropertyInvalidatedCacheTest"
                }
            ],
            "file_patterns": [
                "(/|^)PropertyInvalidatedCache.java"
            ]
        }
    ],
    "presubmit-large": [
+16 −0
Original line number Diff line number Diff line
@@ -368,4 +368,20 @@ public class PropertyInvalidatedCacheTests {
            PropertyInvalidatedCache.MODULE_BLUETOOTH, "getState");
        assertEquals(n1, "cache_key.bluetooth.get_state");
    }

    @Test
    public void testOnTrimMemory() {
        TestCache cache = new TestCache(MODULE, "trimMemoryTest");
        // The cache is not active until it has been invalidated once.
        cache.invalidateCache();
        // Populate the cache with six entries.
        for (int i = 0; i < 6; i++) {
            cache.query(i);
        }
        // The maximum number of entries in TestCache is 4, so even though six entries were
        // created, only four are retained.
        assertEquals(4, cache.size());
        PropertyInvalidatedCache.onTrimMemory();
        assertEquals(0, cache.size());
    }
}