/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, you can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.cleanup; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.support.annotation.VisibleForTesting; import java.io.File; import java.util.ArrayList; import java.util.concurrent.TimeUnit; /** * Encapsulates the code to run the {@link FileCleanupService}. Call * {@link #startIfReady(Context, SharedPreferences, String)} to start the clean-up. * * Note: for simplicity, the current implementation does not cache which * files have been cleaned up and will attempt to delete the same files * each time it is run. If the file deletion list grows large, consider * keeping a cache. */ public class FileCleanupController { private static final long MILLIS_BETWEEN_CLEANUPS = TimeUnit.DAYS.toMillis(7); @VisibleForTesting static final String PREF_LAST_CLEANUP_MILLIS = "cleanup.lastFileCleanupMillis"; // These will be prepended with the path of the profile we're cleaning up. private static final String[] PROFILE_FILES_TO_CLEANUP = new String[] { "health.db", "health.db-journal", "health.db-shm", "health.db-wal", }; /** * Starts the clean-up if it's time to clean-up, otherwise returns. For simplicity, * it does not schedule the cleanup for some point in the future - this method will * have to be called again (i.e. polled) in order to run the clean-up service. * * @param context Context of the calling {@link android.app.Activity} * @param sharedPrefs The {@link SharedPreferences} instance to store the controller state to * @param profilePath The path to the profile the service should clean-up files from */ public static void startIfReady(final Context context, final SharedPreferences sharedPrefs, final String profilePath) { if (!isCleanupReady(sharedPrefs)) { return; } recordCleanupScheduled(sharedPrefs); final Intent fileCleanupIntent = new Intent(context, FileCleanupService.class); fileCleanupIntent.setAction(FileCleanupService.ACTION_DELETE_FILES); fileCleanupIntent.putExtra(FileCleanupService.EXTRA_FILE_PATHS_TO_DELETE, getFilesToCleanup(profilePath + "/")); context.startService(fileCleanupIntent); } private static boolean isCleanupReady(final SharedPreferences sharedPrefs) { final long lastCleanupMillis = sharedPrefs.getLong(PREF_LAST_CLEANUP_MILLIS, -1); return lastCleanupMillis + MILLIS_BETWEEN_CLEANUPS < System.currentTimeMillis(); } private static void recordCleanupScheduled(final SharedPreferences sharedPrefs) { final SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putLong(PREF_LAST_CLEANUP_MILLIS, System.currentTimeMillis()).apply(); } @VisibleForTesting static ArrayList getFilesToCleanup(final String profilePath) { final ArrayList out = new ArrayList<>(PROFILE_FILES_TO_CLEANUP.length); for (final String path : PROFILE_FILES_TO_CLEANUP) { // Append a file separator, just in-case the caller didn't include one. out.add(profilePath + File.separator + path); } return out; } }