Loading services/core/java/com/android/server/pm/Installer.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,8 @@ public class Installer extends SystemService { public static final int FLAG_FREE_CACHE_V2 = IInstalld.FLAG_FREE_CACHE_V2; public static final int FLAG_FREE_CACHE_V2 = IInstalld.FLAG_FREE_CACHE_V2; public static final int FLAG_FREE_CACHE_V2_DEFY_QUOTA = IInstalld.FLAG_FREE_CACHE_V2_DEFY_QUOTA; public static final int FLAG_FREE_CACHE_V2_DEFY_QUOTA = IInstalld.FLAG_FREE_CACHE_V2_DEFY_QUOTA; public static final int FLAG_FREE_CACHE_NOOP = IInstalld.FLAG_FREE_CACHE_NOOP; public static final int FLAG_FREE_CACHE_NOOP = IInstalld.FLAG_FREE_CACHE_NOOP; public static final int FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES = IInstalld.FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES; public static final int FLAG_USE_QUOTA = IInstalld.FLAG_USE_QUOTA; public static final int FLAG_USE_QUOTA = IInstalld.FLAG_USE_QUOTA; public static final int FLAG_FORCE = IInstalld.FLAG_FORCE; public static final int FLAG_FORCE = IInstalld.FLAG_FORCE; Loading services/core/java/com/android/server/pm/PackageManagerService.java +17 −0 Original line number Original line Diff line number Diff line Loading @@ -2779,6 +2779,23 @@ public class PackageManagerService extends IPackageManager.Stub }); }); } } /** * Blocking call to clear all cached app data above quota. */ public void freeAllAppCacheAboveQuota(String volumeUuid) throws IOException { synchronized (mInstallLock) { // To avoid refactoring Installer.freeCache() and InstalldNativeService.freeCache(), // Long.MAX_VALUE is passed as an argument which is used in neither of two methods // when FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES is set try { mInstaller.freeCache(volumeUuid, Long.MAX_VALUE, Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES); } catch (InstallerException ignored) { } } return; } /** /** * Blocking call to clear various types of cached data across the system * Blocking call to clear various types of cached data across the system * until the requested bytes are available. * until the requested bytes are available. Loading services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +62 −21 Original line number Original line Diff line number Diff line Loading @@ -75,10 +75,12 @@ public class DeviceStorageMonitorService extends SystemService { */ */ public static final String EXTRA_SEQUENCE = "seq"; public static final String EXTRA_SEQUENCE = "seq"; private static final int MSG_CHECK = 1; private static final int MSG_CHECK_LOW = 1; private static final int MSG_CHECK_HIGH = 2; private static final long DEFAULT_LOG_DELTA_BYTES = DataUnit.MEBIBYTES.toBytes(64); private static final long DEFAULT_LOG_DELTA_BYTES = DataUnit.MEBIBYTES.toBytes(64); private static final long DEFAULT_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS; private static final long LOW_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS; private static final long HIGH_CHECK_INTERVAL = 10 * DateUtils.HOUR_IN_MILLIS; // com.android.internal.R.string.low_internal_storage_view_text_no_boot // com.android.internal.R.string.low_internal_storage_view_text_no_boot // hard codes 250MB in the message as the storage space required for the // hard codes 250MB in the message as the storage space required for the Loading Loading @@ -165,12 +167,12 @@ public class DeviceStorageMonitorService extends SystemService { } } /** /** * Core logic that checks the storage state of every mounted private volume. * Core logic that checks the storage state of every mounted private volume and clears cache * Since this can do heavy I/O, callers should invoke indirectly using * under low storage state. Since this can do heavy I/O, callers should invoke indirectly using * {@link #MSG_CHECK}. * {@link #MSG_CHECK_LOW}. */ */ @WorkerThread @WorkerThread private void check() { private void checkLow() { final StorageManager storage = getContext().getSystemService(StorageManager.class); final StorageManager storage = getContext().getSystemService(StorageManager.class); final int seq = mSeq.get(); final int seq = mSeq.get(); Loading Loading @@ -234,9 +236,45 @@ public class DeviceStorageMonitorService extends SystemService { // Loop around to check again in future; we don't remove messages since // Loop around to check again in future; we don't remove messages since // there might be an immediate request pending. // there might be an immediate request pending. if (!mHandler.hasMessages(MSG_CHECK)) { if (!mHandler.hasMessages(MSG_CHECK_LOW)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK), mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_LOW), DEFAULT_CHECK_INTERVAL); LOW_CHECK_INTERVAL); } if (!mHandler.hasMessages(MSG_CHECK_HIGH)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_HIGH), HIGH_CHECK_INTERVAL); } } /** * Core logic that checks the storage state of every mounted private volume and clears cache if * free space is under 20% of total space. Since this can do heavy I/O, callers should invoke * indirectly using {@link #MSG_CHECK_HIGH}. */ @WorkerThread private void checkHigh() { final StorageManager storage = getContext().getSystemService(StorageManager.class); // Check every mounted private volume to see if they're under the high storage threshold // which is StorageManager.STORAGE_THRESHOLD_PERCENT_HIGH of total space for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final File file = vol.getPath(); if (file.getUsableSpace() < file.getTotalSpace() * StorageManager.STORAGE_THRESHOLD_PERCENT_HIGH / 100) { final PackageManagerService pms = (PackageManagerService) ServiceManager .getService("package"); try { pms.freeAllAppCacheAboveQuota(vol.getFsUuid()); } catch (IOException e) { Slog.w(TAG, e); } } } // Loop around to check again in future; we don't remove messages since // there might be an immediate request pending if (!mHandler.hasMessages(MSG_CHECK_HIGH)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_HIGH), HIGH_CHECK_INTERVAL); } } } } Loading @@ -250,8 +288,11 @@ public class DeviceStorageMonitorService extends SystemService { @Override @Override public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { switch (msg.what) { case MSG_CHECK: case MSG_CHECK_LOW: check(); checkLow(); return; case MSG_CHECK_HIGH: checkHigh(); return; return; } } } } Loading Loading @@ -282,16 +323,16 @@ public class DeviceStorageMonitorService extends SystemService { publishLocalService(DeviceStorageMonitorInternal.class, mLocalService); publishLocalService(DeviceStorageMonitorInternal.class, mLocalService); // Kick off pass to examine storage state // Kick off pass to examine storage state mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); } } private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() { private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() { @Override @Override public void checkMemory() { public void checkMemory() { // Kick off pass to examine storage state // Kick off pass to examine storage state mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); } } @Override @Override Loading Loading @@ -360,8 +401,8 @@ public class DeviceStorageMonitorService extends SystemService { mForceLevel = State.LEVEL_LOW; mForceLevel = State.LEVEL_LOW; int seq = mSeq.incrementAndGet(); int seq = mSeq.incrementAndGet(); if ((opts & OPTION_FORCE_UPDATE) != 0) { if ((opts & OPTION_FORCE_UPDATE) != 0) { mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); pw.println(seq); pw.println(seq); } } } break; } break; Loading @@ -372,8 +413,8 @@ public class DeviceStorageMonitorService extends SystemService { mForceLevel = State.LEVEL_NORMAL; mForceLevel = State.LEVEL_NORMAL; int seq = mSeq.incrementAndGet(); int seq = mSeq.incrementAndGet(); if ((opts & OPTION_FORCE_UPDATE) != 0) { if ((opts & OPTION_FORCE_UPDATE) != 0) { mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); pw.println(seq); pw.println(seq); } } } break; } break; Loading @@ -384,8 +425,8 @@ public class DeviceStorageMonitorService extends SystemService { mForceLevel = State.LEVEL_UNKNOWN; mForceLevel = State.LEVEL_UNKNOWN; int seq = mSeq.incrementAndGet(); int seq = mSeq.incrementAndGet(); if ((opts & OPTION_FORCE_UPDATE) != 0) { if ((opts & OPTION_FORCE_UPDATE) != 0) { mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); pw.println(seq); pw.println(seq); } } } break; } break; Loading Loading
services/core/java/com/android/server/pm/Installer.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,8 @@ public class Installer extends SystemService { public static final int FLAG_FREE_CACHE_V2 = IInstalld.FLAG_FREE_CACHE_V2; public static final int FLAG_FREE_CACHE_V2 = IInstalld.FLAG_FREE_CACHE_V2; public static final int FLAG_FREE_CACHE_V2_DEFY_QUOTA = IInstalld.FLAG_FREE_CACHE_V2_DEFY_QUOTA; public static final int FLAG_FREE_CACHE_V2_DEFY_QUOTA = IInstalld.FLAG_FREE_CACHE_V2_DEFY_QUOTA; public static final int FLAG_FREE_CACHE_NOOP = IInstalld.FLAG_FREE_CACHE_NOOP; public static final int FLAG_FREE_CACHE_NOOP = IInstalld.FLAG_FREE_CACHE_NOOP; public static final int FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES = IInstalld.FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES; public static final int FLAG_USE_QUOTA = IInstalld.FLAG_USE_QUOTA; public static final int FLAG_USE_QUOTA = IInstalld.FLAG_USE_QUOTA; public static final int FLAG_FORCE = IInstalld.FLAG_FORCE; public static final int FLAG_FORCE = IInstalld.FLAG_FORCE; Loading
services/core/java/com/android/server/pm/PackageManagerService.java +17 −0 Original line number Original line Diff line number Diff line Loading @@ -2779,6 +2779,23 @@ public class PackageManagerService extends IPackageManager.Stub }); }); } } /** * Blocking call to clear all cached app data above quota. */ public void freeAllAppCacheAboveQuota(String volumeUuid) throws IOException { synchronized (mInstallLock) { // To avoid refactoring Installer.freeCache() and InstalldNativeService.freeCache(), // Long.MAX_VALUE is passed as an argument which is used in neither of two methods // when FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES is set try { mInstaller.freeCache(volumeUuid, Long.MAX_VALUE, Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES); } catch (InstallerException ignored) { } } return; } /** /** * Blocking call to clear various types of cached data across the system * Blocking call to clear various types of cached data across the system * until the requested bytes are available. * until the requested bytes are available. Loading
services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +62 −21 Original line number Original line Diff line number Diff line Loading @@ -75,10 +75,12 @@ public class DeviceStorageMonitorService extends SystemService { */ */ public static final String EXTRA_SEQUENCE = "seq"; public static final String EXTRA_SEQUENCE = "seq"; private static final int MSG_CHECK = 1; private static final int MSG_CHECK_LOW = 1; private static final int MSG_CHECK_HIGH = 2; private static final long DEFAULT_LOG_DELTA_BYTES = DataUnit.MEBIBYTES.toBytes(64); private static final long DEFAULT_LOG_DELTA_BYTES = DataUnit.MEBIBYTES.toBytes(64); private static final long DEFAULT_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS; private static final long LOW_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS; private static final long HIGH_CHECK_INTERVAL = 10 * DateUtils.HOUR_IN_MILLIS; // com.android.internal.R.string.low_internal_storage_view_text_no_boot // com.android.internal.R.string.low_internal_storage_view_text_no_boot // hard codes 250MB in the message as the storage space required for the // hard codes 250MB in the message as the storage space required for the Loading Loading @@ -165,12 +167,12 @@ public class DeviceStorageMonitorService extends SystemService { } } /** /** * Core logic that checks the storage state of every mounted private volume. * Core logic that checks the storage state of every mounted private volume and clears cache * Since this can do heavy I/O, callers should invoke indirectly using * under low storage state. Since this can do heavy I/O, callers should invoke indirectly using * {@link #MSG_CHECK}. * {@link #MSG_CHECK_LOW}. */ */ @WorkerThread @WorkerThread private void check() { private void checkLow() { final StorageManager storage = getContext().getSystemService(StorageManager.class); final StorageManager storage = getContext().getSystemService(StorageManager.class); final int seq = mSeq.get(); final int seq = mSeq.get(); Loading Loading @@ -234,9 +236,45 @@ public class DeviceStorageMonitorService extends SystemService { // Loop around to check again in future; we don't remove messages since // Loop around to check again in future; we don't remove messages since // there might be an immediate request pending. // there might be an immediate request pending. if (!mHandler.hasMessages(MSG_CHECK)) { if (!mHandler.hasMessages(MSG_CHECK_LOW)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK), mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_LOW), DEFAULT_CHECK_INTERVAL); LOW_CHECK_INTERVAL); } if (!mHandler.hasMessages(MSG_CHECK_HIGH)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_HIGH), HIGH_CHECK_INTERVAL); } } /** * Core logic that checks the storage state of every mounted private volume and clears cache if * free space is under 20% of total space. Since this can do heavy I/O, callers should invoke * indirectly using {@link #MSG_CHECK_HIGH}. */ @WorkerThread private void checkHigh() { final StorageManager storage = getContext().getSystemService(StorageManager.class); // Check every mounted private volume to see if they're under the high storage threshold // which is StorageManager.STORAGE_THRESHOLD_PERCENT_HIGH of total space for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final File file = vol.getPath(); if (file.getUsableSpace() < file.getTotalSpace() * StorageManager.STORAGE_THRESHOLD_PERCENT_HIGH / 100) { final PackageManagerService pms = (PackageManagerService) ServiceManager .getService("package"); try { pms.freeAllAppCacheAboveQuota(vol.getFsUuid()); } catch (IOException e) { Slog.w(TAG, e); } } } // Loop around to check again in future; we don't remove messages since // there might be an immediate request pending if (!mHandler.hasMessages(MSG_CHECK_HIGH)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_HIGH), HIGH_CHECK_INTERVAL); } } } } Loading @@ -250,8 +288,11 @@ public class DeviceStorageMonitorService extends SystemService { @Override @Override public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { switch (msg.what) { case MSG_CHECK: case MSG_CHECK_LOW: check(); checkLow(); return; case MSG_CHECK_HIGH: checkHigh(); return; return; } } } } Loading Loading @@ -282,16 +323,16 @@ public class DeviceStorageMonitorService extends SystemService { publishLocalService(DeviceStorageMonitorInternal.class, mLocalService); publishLocalService(DeviceStorageMonitorInternal.class, mLocalService); // Kick off pass to examine storage state // Kick off pass to examine storage state mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); } } private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() { private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() { @Override @Override public void checkMemory() { public void checkMemory() { // Kick off pass to examine storage state // Kick off pass to examine storage state mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); } } @Override @Override Loading Loading @@ -360,8 +401,8 @@ public class DeviceStorageMonitorService extends SystemService { mForceLevel = State.LEVEL_LOW; mForceLevel = State.LEVEL_LOW; int seq = mSeq.incrementAndGet(); int seq = mSeq.incrementAndGet(); if ((opts & OPTION_FORCE_UPDATE) != 0) { if ((opts & OPTION_FORCE_UPDATE) != 0) { mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); pw.println(seq); pw.println(seq); } } } break; } break; Loading @@ -372,8 +413,8 @@ public class DeviceStorageMonitorService extends SystemService { mForceLevel = State.LEVEL_NORMAL; mForceLevel = State.LEVEL_NORMAL; int seq = mSeq.incrementAndGet(); int seq = mSeq.incrementAndGet(); if ((opts & OPTION_FORCE_UPDATE) != 0) { if ((opts & OPTION_FORCE_UPDATE) != 0) { mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); pw.println(seq); pw.println(seq); } } } break; } break; Loading @@ -384,8 +425,8 @@ public class DeviceStorageMonitorService extends SystemService { mForceLevel = State.LEVEL_UNKNOWN; mForceLevel = State.LEVEL_UNKNOWN; int seq = mSeq.incrementAndGet(); int seq = mSeq.incrementAndGet(); if ((opts & OPTION_FORCE_UPDATE) != 0) { if ((opts & OPTION_FORCE_UPDATE) != 0) { mHandler.removeMessages(MSG_CHECK); mHandler.removeMessages(MSG_CHECK_LOW); mHandler.obtainMessage(MSG_CHECK).sendToTarget(); mHandler.obtainMessage(MSG_CHECK_LOW).sendToTarget(); pw.println(seq); pw.println(seq); } } } break; } break; Loading