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

Commit 075254e1 authored by Neharika Jali's avatar Neharika Jali Committed by Android (Google) Code Review
Browse files

Merge "Periodically clear cache under high storage threshold"

parents fca5e3a1 0c0d3505
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -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;
+17 −0
Original line number Original line Diff line number Diff line
@@ -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.
+62 −21
Original line number Original line Diff line number Diff line
@@ -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
@@ -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();


@@ -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);
        }
        }
    }
    }


@@ -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;
                }
                }
            }
            }
@@ -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
@@ -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;
@@ -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;
@@ -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;