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

Commit 8dc32f1a authored by lpeter's avatar lpeter
Browse files

According to the user Id to cache the ServiceInfo.

Currently it saves the ServiceInfo into the cache by using the
ComponentName as the key, it will return the wrong ServiceInfo
to other user. It needs to accord to the user Id to cache the
ServiceInfo.

Flag: android.content.pm.optimize_parsing_in_registered_services_cache

Bug: 396226221
Test: atest RegisteredServicesCacheTest
Change-Id: I8221e586273f78b561d7ba7ebc4e2375abc075ec
parent 3ca51a1e
Loading
Loading
Loading
Loading
+21 −15
Original line number Diff line number Diff line
@@ -31,13 +31,13 @@ import android.os.Environment;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.AttributeSet;
import android.util.IntArray;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArrayMap;
import android.util.Xml;

import com.android.internal.annotations.GuardedBy;
@@ -98,15 +98,16 @@ public abstract class RegisteredServicesCache<V> {
    @GuardedBy("mServicesLock")
    private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2);

    @GuardedBy("mServiceInfoCaches")
    private final ArrayMap<ComponentName, ServiceInfo<V>> mServiceInfoCaches = new ArrayMap<>();
    @GuardedBy("mUserIdToServiceInfoCaches")
    private final SparseArrayMap<ComponentName, ServiceInfo<V>> mUserIdToServiceInfoCaches =
            new SparseArrayMap<>();

    private final Handler mBackgroundHandler;

    private final Runnable mClearServiceInfoCachesRunnable = new Runnable() {
        public void run() {
            synchronized (mServiceInfoCaches) {
                mServiceInfoCaches.clear();
            synchronized (mUserIdToServiceInfoCaches) {
                mUserIdToServiceInfoCaches.clear();
            }
        }
    };
@@ -537,8 +538,8 @@ public abstract class RegisteredServicesCache<V> {
                    Slog.d(TAG, "Fail to get the PackageInfo in generateServicesMap: " + e);
                }
                if (lastUpdateTime >= 0) {
                    ServiceInfo<V> serviceInfo = getServiceInfoFromServiceCache(componentName,
                            lastUpdateTime);
                    ServiceInfo<V> serviceInfo = getServiceInfoFromServiceCache(userId,
                            componentName, lastUpdateTime);
                    if (serviceInfo != null) {
                        serviceInfos.add(serviceInfo);
                        continue;
@@ -553,8 +554,8 @@ public abstract class RegisteredServicesCache<V> {
                }
                serviceInfos.add(info);
                if (Flags.optimizeParsingInRegisteredServicesCache()) {
                    synchronized (mServiceInfoCaches) {
                        mServiceInfoCaches.put(componentName, info);
                    synchronized (mUserIdToServiceInfoCaches) {
                        mUserIdToServiceInfoCaches.add(userId, componentName, info);
                    }
                }
            } catch (XmlPullParserException | IOException e) {
@@ -563,8 +564,8 @@ public abstract class RegisteredServicesCache<V> {
        }

        if (Flags.optimizeParsingInRegisteredServicesCache()) {
            synchronized (mServiceInfoCaches) {
                if (!mServiceInfoCaches.isEmpty()) {
            synchronized (mUserIdToServiceInfoCaches) {
                if (mUserIdToServiceInfoCaches.numMaps() > 0) {
                    mBackgroundHandler.removeCallbacks(mClearServiceInfoCachesRunnable);
                    mBackgroundHandler.postDelayed(mClearServiceInfoCachesRunnable,
                            SERVICE_INFO_CACHES_TIMEOUT_MILLIS);
@@ -873,6 +874,11 @@ public abstract class RegisteredServicesCache<V> {
        synchronized (mServicesLock) {
            mUserServices.remove(userId);
        }
        if (Flags.optimizeParsingInRegisteredServicesCache()) {
            synchronized (mUserIdToServiceInfoCaches) {
                mUserIdToServiceInfoCaches.delete(userId);
            }
        }
    }

    @VisibleForTesting
@@ -916,10 +922,10 @@ public abstract class RegisteredServicesCache<V> {
        mContext.unregisterReceiver(mUserRemovedReceiver);
    }

    private ServiceInfo<V> getServiceInfoFromServiceCache(@NonNull ComponentName componentName,
            long lastUpdateTime) {
        synchronized (mServiceInfoCaches) {
            ServiceInfo<V> serviceCache = mServiceInfoCaches.get(componentName);
    private ServiceInfo<V> getServiceInfoFromServiceCache(int userId,
            @NonNull ComponentName componentName, long lastUpdateTime) {
        synchronized (mUserIdToServiceInfoCaches) {
            ServiceInfo<V> serviceCache = mUserIdToServiceInfoCaches.get(userId, componentName);
            if (serviceCache != null && serviceCache.lastUpdateTime == lastUpdateTime) {
                return serviceCache;
            }