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

Commit 2e457d31 authored by sangyun's avatar sangyun
Browse files

Change the resource cache key and limit the maximum size of cache

Change the key valus of ResoucesCache. Key contains package name and
configuration of resources.
Even the same context object can return different resources depending
on its state, such as language changes. So a Configuration that can
logically distinguish whether a resource is logically equal can be
used as a key. (context does not have localical equals for resources)
Also, since unique resources can be used for each package, package
name is added as a resource cache key.

Bug: 289045241
Test: atest CtsTelephonyTestCases
Test: atest CellBroadcastServiceTests
Change-Id: I492d314b4f1e1e83554bc098c3a41a9574e2ac6b
parent 3e40c03c
Loading
Loading
Loading
Loading
+32 −12
Original line number Diff line number Diff line
@@ -85,11 +85,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -1318,10 +1318,24 @@ public class SubscriptionManager {

    private final Context mContext;

    // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
    // the Context and subId.
    private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
            new ConcurrentHashMap<>();
    /**
     * In order to prevent the overflow of the heap size due to an indiscriminate increase in the
     * cache, the heap size of the resource cache is set sufficiently large.
     */
    private static final int MAX_RESOURCE_CACHE_ENTRY_COUNT = 10_000;

    /**
     * Cache of Resources that has been created in getResourcesForSubId. Key contains package name,
     * and Configuration of Resources. If more than the maximum number of resources are stored in
     * this cache, the least recently used Resources will be removed to maintain the maximum size.
     */
    private static final Map<Pair<String, Configuration>, Resources> sResourcesCache =
            Collections.synchronizedMap(new LinkedHashMap<>(16, 0.75f, true) {
                @Override
                protected boolean removeEldestEntry(Entry eldest) {
                    return size() > MAX_RESOURCE_CACHE_ENTRY_COUNT;
                }
            });

    /**
     * A listener class for monitoring changes to {@link SubscriptionInfo} records.
@@ -2807,14 +2821,20 @@ public class SubscriptionManager {
    @NonNull
    public static Resources getResourcesForSubId(Context context, int subId,
            boolean useRootLocale) {
        // Check if resources for this context and subId already exist in the resource cache.
        // Resources that use the root locale are not cached.
        Pair<Context, Integer> cacheKey = null;
        if (isValidSubscriptionId(subId) && !useRootLocale) {
            cacheKey = Pair.create(context, subId);
            if (sResourcesCache.containsKey(cacheKey)) {
        // Check if the Resources already exists in the cache based on the given context. Find a
        // Resource that match Configuration.
        Pair<String, Configuration> cacheKey = null;
        if (isValidSubscriptionId(subId)) {
            Configuration configurationKey =
                    new Configuration(context.getResources().getConfiguration());
            if (useRootLocale) {
                configurationKey.setLocale(Locale.ROOT);
            }
            cacheKey = Pair.create(context.getPackageName(), configurationKey);
            Resources cached = sResourcesCache.get(cacheKey);
            if (cached != null) {
                // Cache hit. Use cached Resources.
                return sResourcesCache.get(cacheKey);
                return cached;
            }
        }