Loading core/java/android/app/ApplicationPackageManager.java +118 −10 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -1566,6 +1576,7 @@ public class ApplicationPackageManager extends PackageManager { throw e.rethrowFromSystemServer(); } } } @Override public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Loading Loading @@ -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(); } } core/java/android/content/pm/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -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 } services/core/java/com/android/server/pm/AppsFilterImpl.java +1 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, // be invalid. PackageManager.invalidatePackageInfoCache(); ApplicationPackageManager.invalidateGetPackagesForUidCache(); ApplicationPackageManager.invalidateQueryIntentActivitiesCache(); dispatchChange(this); } Loading services/core/java/com/android/server/pm/InstallingSession.java +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -626,6 +627,7 @@ class InstallingSession { request.setError("APEX installation failed", e); } PackageManagerService.invalidatePackageInfoCache(); ApplicationPackageManager.invalidateQueryIntentActivitiesCache(); mPm.notifyInstallObserver(request); } Loading services/core/java/com/android/server/pm/PackageManagerService.java +4 −0 Original line number Diff line number Diff line Loading @@ -772,6 +772,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService ApplicationPackageManager.disableGetPackagesForUidCache(); ApplicationPackageManager.invalidateHasSystemFeatureCache(); PackageManager.corkPackageInfoCache(); ApplicationPackageManager.invalidateQueryIntentActivitiesCache(); ApplicationPackageManager.disableQueryIntentActivitiesCacheForCurrentProcess(); } @Override Loading Loading @@ -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); } Loading @@ -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 Loading
core/java/android/app/ApplicationPackageManager.java +118 −10 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -1566,6 +1576,7 @@ public class ApplicationPackageManager extends PackageManager { throw e.rethrowFromSystemServer(); } } } @Override public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Loading Loading @@ -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(); } }
core/java/android/content/pm/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -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 }
services/core/java/com/android/server/pm/AppsFilterImpl.java +1 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, // be invalid. PackageManager.invalidatePackageInfoCache(); ApplicationPackageManager.invalidateGetPackagesForUidCache(); ApplicationPackageManager.invalidateQueryIntentActivitiesCache(); dispatchChange(this); } Loading
services/core/java/com/android/server/pm/InstallingSession.java +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -626,6 +627,7 @@ class InstallingSession { request.setError("APEX installation failed", e); } PackageManagerService.invalidatePackageInfoCache(); ApplicationPackageManager.invalidateQueryIntentActivitiesCache(); mPm.notifyInstallObserver(request); } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +4 −0 Original line number Diff line number Diff line Loading @@ -772,6 +772,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService ApplicationPackageManager.disableGetPackagesForUidCache(); ApplicationPackageManager.invalidateHasSystemFeatureCache(); PackageManager.corkPackageInfoCache(); ApplicationPackageManager.invalidateQueryIntentActivitiesCache(); ApplicationPackageManager.disableQueryIntentActivitiesCacheForCurrentProcess(); } @Override Loading Loading @@ -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); } Loading @@ -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