diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index f48d78ac9cc3e..21f27f646fc14 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -8132,4 +8132,19 @@ public abstract class PackageManager { sPackageInfoCache.disableLocal(); } + /** + * Inhibit package info cache invalidations when correct. + * + * @hide */ + public static void corkPackageInfoCache() { + PropertyInvalidatedCache.corkInvalidations(PermissionManager.CACHE_KEY_PACKAGE_INFO); + } + + /** + * Enable package info cache invalidations. + * + * @hide */ + public static void uncorkPackageInfoCache() { + PropertyInvalidatedCache.uncorkInvalidations(PermissionManager.CACHE_KEY_PACKAGE_INFO); + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f96ab1d9a0427..14882f8039e7d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2810,10 +2810,14 @@ public class PackageManagerService extends IPackageManager.Stub } public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) { - PackageManager.invalidatePackageInfoCache(); PackageManager.disableApplicationInfoCache(); PackageManager.disablePackageInfoCache(); + // Avoid invalidation-thrashing by preventing cache invalidations from causing property + // writes if the cache isn't enabled yet. We re-enable writes later when we're + // done initializing. + PackageManager.corkPackageInfoCache(); + final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing", Trace.TRACE_TAG_PACKAGE_MANAGER); mPendingBroadcasts = new PendingPackageBroadcasts(); @@ -3614,6 +3618,9 @@ public class PackageManagerService extends IPackageManager.Stub mModuleInfoProvider = new ModuleInfoProvider(mContext, this); + // Uncork cache invalidations and allow clients to cache package information. + PackageManager.uncorkPackageInfoCache(); + // Now after opening every single application zip, make sure they // are all flushed. Not really needed, but keeps things nice and // tidy.