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

Commit 00ab9e2c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implement client side caching for queryIntentActivities" into main

parents e51c5ee2 66e20ef0
Loading
Loading
Loading
Loading
+118 −10
Original line number Diff line number Diff line
@@ -1552,6 +1552,16 @@ public class ApplicationPackageManager extends PackageManager {
    @SuppressWarnings("unchecked")
    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags,
            int userId) {
        if (android.content.pm.Flags.cacheQueryIntentActivitiesInClientSide()) {
            List<ResolveInfo> resolveInfos = sQueryIntentActivitiesCache.query(
                    new IntentActivitiesQuery(intent,
                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                            updateFlagsForComponent(flags.getValue(), userId, intent), userId));
            if (resolveInfos == null) {
                return Collections.emptyList();
            }
            return resolveInfos;
        } else {
            try {
                ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivities(
                        intent,
@@ -1566,6 +1576,7 @@ public class ApplicationPackageManager extends PackageManager {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    @Override
    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
@@ -4258,4 +4269,101 @@ public class ApplicationPackageManager extends PackageManager {
            return null;
        }
    }

    private static final class IntentActivitiesQuery {
        final Intent mIntent;
        final String mResolvedType;
        final long mFlags;
        final int mUserId;

        IntentActivitiesQuery(Intent intent, String resolvedType, long flags, int userId) {
            this.mIntent = intent;
            this.mResolvedType = resolvedType;
            this.mFlags = flags;
            this.mUserId = userId;
        }

        @Override
        public int hashCode() {
            int hash = mIntent.filterHashCode();
            hash = hash * 13 + Objects.hashCode(mResolvedType);
            hash = hash * 13 + Long.hashCode(mFlags);
            hash = hash * 13 + mUserId;
            return hash;
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj == null) {
                return false;
            }
            ApplicationPackageManager.IntentActivitiesQuery other;
            try {
                other = (ApplicationPackageManager.IntentActivitiesQuery) obj;
            } catch (ClassCastException ex) {
                return false;
            }
            return mIntent.filterEquals(other.mIntent)
                    && Objects.equals(mResolvedType, other.mResolvedType)
                    && mFlags == other.mFlags
                    && mUserId == other.mUserId;
        }
    }

    private static final String CACHE_KEY_QUERY_INTENT_ACTIVITIES_API = "query_intent_activities";

    /** @hide */
    @VisibleForTesting
    public static final PropertyInvalidatedCache<IntentActivitiesQuery, List<ResolveInfo>>
            sQueryIntentActivitiesCache = new PropertyInvalidatedCache<>(
                    new PropertyInvalidatedCache.Args(MODULE_SYSTEM).maxEntries(1024).api(
                            CACHE_KEY_QUERY_INTENT_ACTIVITIES_API).cacheNulls(true),
                    CACHE_KEY_QUERY_INTENT_ACTIVITIES_API, null) {
                @Override
                public List<ResolveInfo> recompute(IntentActivitiesQuery query) {
                    try {
                        ParceledListSlice<ResolveInfo> parceledList =
                                ActivityThread.currentActivityThread().getPackageManager()
                                        .queryIntentActivities(
                                        query.mIntent,
                                        query.mResolvedType,
                                        query.mFlags,
                                        query.mUserId);
                        if (parceledList == null) {
                            return Collections.emptyList();
                        }
                        return parceledList.getList();
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }

                @Override
                public String queryToString(IntentActivitiesQuery query) {
                    StringBuilder b = new StringBuilder(128);
                    b.append("Query { ");
                    b.append("intent=").append(query.mIntent.toString());
                    b.append(", resolvedType=").append(query.mResolvedType);
                    b.append(", flags=").append(Long.toHexString(query.mFlags));
                    b.append(", userId=").append(query.mUserId);
                    b.append(" }");
                    return b.toString();
                }
            };

    /** @hide */
    public static void disableQueryIntentActivitiesCacheForCurrentProcess() {
        if (!android.content.pm.Flags.cacheQueryIntentActivitiesInClientSide()) {
            return;
        }
        sQueryIntentActivitiesCache.disableForCurrentProcess();
    }

    /** @hide */
    public static void invalidateQueryIntentActivitiesCache() {
        if (!android.content.pm.Flags.cacheQueryIntentActivitiesInClientSide()) {
            return;
        }
        sQueryIntentActivitiesCache.invalidateCache();
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -332,3 +332,11 @@ flag {
    is_fixed_read_only: true
}

flag {
    name: "cache_query_intent_activities_in_client_side"
    namespace: "package_manager_service"
    description: "Feature flag to implement client side caching for queryIntentActivities."
    bug: "339648913"
    is_fixed_read_only: true
}
+1 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
        // be invalid.
        PackageManager.invalidatePackageInfoCache();
        ApplicationPackageManager.invalidateGetPackagesForUidCache();
        ApplicationPackageManager.invalidateQueryIntentActivitiesCache();
        dispatchChange(this);
    }

+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import static com.android.server.pm.PackageManagerService.TAG;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.apex.ApexInfo;
import android.app.ApplicationPackageManager;
import android.content.pm.DataLoaderType;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInfoLite;
@@ -626,6 +627,7 @@ class InstallingSession {
            request.setError("APEX installation failed", e);
        }
        PackageManagerService.invalidatePackageInfoCache();
        ApplicationPackageManager.invalidateQueryIntentActivitiesCache();
        mPm.notifyInstallObserver(request);
    }

+4 −0
Original line number Diff line number Diff line
@@ -772,6 +772,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            ApplicationPackageManager.disableGetPackagesForUidCache();
            ApplicationPackageManager.invalidateHasSystemFeatureCache();
            PackageManager.corkPackageInfoCache();
            ApplicationPackageManager.invalidateQueryIntentActivitiesCache();
            ApplicationPackageManager.disableQueryIntentActivitiesCacheForCurrentProcess();
        }

        @Override
@@ -1580,6 +1582,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        // coalesce settings writes, this strategy would have us invalidate the cache too late.
        // Invalidating on schedule addresses this problem.
        invalidatePackageInfoCache();
        ApplicationPackageManager.invalidateQueryIntentActivitiesCache();
        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
        }
@@ -1587,6 +1590,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService

    void scheduleWritePackageListLocked(int userId) {
        invalidatePackageInfoCache();
        ApplicationPackageManager.invalidateQueryIntentActivitiesCache();
        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
            msg.arg1 = userId;
Loading