blob: 76aff733a6acc14e9d2e9a1ad893e3da008eeb7b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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;
}
}
|