mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 00:08:39 +09:00
pt 1 in reviving the android build (copied from pm 28a1, wish me luck)
This commit is contained in:
parent
efa9662725
commit
d7788a6d6d
4249 changed files with 468189 additions and 0 deletions
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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<String> getFilesToCleanup(final String profilePath) {
|
||||
final ArrayList<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.app.IntentService;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* An IntentService to delete files.
|
||||
*
|
||||
* It takes an {@link ArrayList} of String file paths to delete via the extra
|
||||
* {@link #EXTRA_FILE_PATHS_TO_DELETE}. If these file paths are directories, they will
|
||||
* not be traversed recursively and will only be deleted if empty. This is to avoid accidentally
|
||||
* trashing a users' profile if a folder is accidentally listed.
|
||||
*
|
||||
* An IntentService was chosen because:
|
||||
* * It generally won't be killed when the Activity is
|
||||
* * (unlike HandlerThread) The system handles scheduling, prioritizing,
|
||||
* and shutting down the underlying background thread
|
||||
* * (unlike an existing background thread) We don't block our background operations
|
||||
* for this, which doesn't directly affect the user.
|
||||
*
|
||||
* The major trade-off is that this Service is very dangerous if it's exported... so don't do that!
|
||||
*/
|
||||
public class FileCleanupService extends IntentService {
|
||||
private static final String LOGTAG = "Gecko" + FileCleanupService.class.getSimpleName();
|
||||
private static final String WORKER_THREAD_NAME = LOGTAG + "Worker";
|
||||
|
||||
public static final String ACTION_DELETE_FILES = "org.mozilla.gecko.intent.action.DELETE_FILES";
|
||||
public static final String EXTRA_FILE_PATHS_TO_DELETE = "org.mozilla.gecko.file_paths_to_delete";
|
||||
|
||||
public FileCleanupService() {
|
||||
super(WORKER_THREAD_NAME);
|
||||
|
||||
// We're likely to get scheduled again - let's wait until then in order to avoid:
|
||||
// * The coding complexity of re-running this
|
||||
// * Consuming system resources: we were probably killed for resource conservation purposes
|
||||
setIntentRedelivery(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(final Intent intent) {
|
||||
if (!isIntentValid(intent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<String> filesToDelete = intent.getStringArrayListExtra(EXTRA_FILE_PATHS_TO_DELETE);
|
||||
for (final String path : filesToDelete) {
|
||||
final File file = new File(path);
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isIntentValid(final Intent intent) {
|
||||
if (intent == null) {
|
||||
Log.w(LOGTAG, "Received null intent");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!intent.getAction().equals(ACTION_DELETE_FILES)) {
|
||||
Log.w(LOGTAG, "Received unknown intent action: " + intent.getAction());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!intent.hasExtra(EXTRA_FILE_PATHS_TO_DELETE)) {
|
||||
Log.w(LOGTAG, "Received intent with no files extra");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue