diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 4de64c41e913e..59b022ded9bfb 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -628,4 +628,6 @@ interface IPackageManager { ParceledListSlice getSharedLibraries(int flags, int userId); boolean canRequestPackageInstalls(String packageName, int userId); + + void deletePreloadsFileCache(); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index d2c505507fd1e..f5ea74d6606be 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3818,6 +3818,16 @@ public class PackageManagerService extends IPackageManager.Stub { return normalizedPackageName != null ? normalizedPackageName : packageName; } + @Override + public void deletePreloadsFileCache() { + if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) { + throw new SecurityException("Only system or settings may call deletePreloadsFileCache"); + } + File dir = Environment.getDataPreloadsFileCacheDirectory(); + Slog.i(TAG, "Deleting preloaded file cache " + dir); + FileUtils.deleteContents(dir); + } + @Override public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, final IPackageDataObserver observer) { @@ -3871,19 +3881,27 @@ public class PackageManagerService extends IPackageManager.Stub { public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException { final StorageManager storage = mContext.getSystemService(StorageManager.class); final File file = storage.findPathForUuid(volumeUuid); + if (file.getUsableSpace() >= bytes) return; if (ENABLE_FREE_CACHE_V2) { final boolean aggressive = (storageFlags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0; + final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, + volumeUuid); // 1. Pre-flight to determine if we have any chance to succeed // 2. Consider preloaded data (after 1w honeymoon, unless aggressive) + if (internalVolume && (aggressive || SystemProperties + .getBoolean("persist.sys.preloads.file_cache_expired", false))) { + deletePreloadsFileCache(); + if (file.getUsableSpace() >= bytes) return; + } // 3. Consider parsed APK data (aggressive only) - if (aggressive) { + if (internalVolume && aggressive) { FileUtils.deleteContents(mCacheDir); + if (file.getUsableSpace() >= bytes) return; } - if (file.getUsableSpace() >= bytes) return; // 4. Consider cached app data (above quotas) try {