use WorkManager to schedule temporary file cleanups
This commit is contained in:
parent
b29d98d5a2
commit
1593cc0826
|
@ -24,13 +24,8 @@ import java.util.HashMap;
|
|||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Application;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
@ -39,7 +34,6 @@ import org.sufficientlysecure.keychain.network.TlsCertificatePinning;
|
|||
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
|
||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.service.KeyserverSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.PRNGFixes;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import timber.log.Timber;
|
||||
|
@ -114,7 +108,7 @@ public class KeychainApplication extends Application {
|
|||
TlsCertificatePinning.addPinnedCertificate("api.keybase.io", getAssets(), "api.keybase.io.CA.cer");
|
||||
TlsCertificatePinning.addPinnedCertificate("keyserver.ubuntu.com", getAssets(), "DigiCertGlobalRootCA.cer");
|
||||
|
||||
new Handler().postDelayed(() -> TemporaryFileProvider.cleanUp(getApplicationContext()), 1000);
|
||||
TemporaryFileProvider.scheduleCleanupImmediately();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,8 +18,17 @@
|
|||
package org.sufficientlysecure.keychain.provider;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.ClipDescription;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
@ -29,18 +38,15 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import androidx.work.Worker;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.util.DatabaseUtil;
|
||||
import timber.log.Timber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* TemporaryStorageProvider stores decrypted files inside the app's cache directory previously to
|
||||
* sharing them with other applications.
|
||||
|
@ -81,16 +87,20 @@ public class TemporaryFileProvider extends ContentProvider {
|
|||
private static Pattern UUID_PATTERN = Pattern.compile("[a-fA-F0-9-]+");
|
||||
|
||||
public static Uri createFile(Context context, String targetName, String mimeType) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(TemporaryFileColumns.COLUMN_NAME, targetName);
|
||||
contentValues.put(TemporaryFileColumns.COLUMN_TYPE, mimeType);
|
||||
return context.getContentResolver().insert(CONTENT_URI, contentValues);
|
||||
contentValues.put(TemporaryFileColumns.COLUMN_TIME, System.currentTimeMillis());
|
||||
Uri resultUri = contentResolver.insert(CONTENT_URI, contentValues);
|
||||
|
||||
scheduleCleanupAfterTtl();
|
||||
return resultUri;
|
||||
}
|
||||
|
||||
public static Uri createFile(Context context, String targetName) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(TemporaryFileColumns.COLUMN_NAME, targetName);
|
||||
return context.getContentResolver().insert(CONTENT_URI, contentValues);
|
||||
return createFile(context, targetName, null);
|
||||
}
|
||||
|
||||
public static Uri createFile(Context context) {
|
||||
|
@ -110,15 +120,6 @@ public class TemporaryFileProvider extends ContentProvider {
|
|||
return context.getContentResolver().update(uri, values, null, null);
|
||||
}
|
||||
|
||||
public static int cleanUp(Context context) {
|
||||
Timber.d("Cleaning up temporary files…");
|
||||
return context.getContentResolver().delete(
|
||||
CONTENT_URI,
|
||||
TemporaryFileColumns.COLUMN_TIME + "< ?",
|
||||
new String[]{Long.toString(System.currentTimeMillis() - Constants.TEMPFILE_TTL)}
|
||||
);
|
||||
}
|
||||
|
||||
private class TemporaryStorageDatabase extends SQLiteOpenHelper {
|
||||
|
||||
public TemporaryStorageDatabase(Context context) {
|
||||
|
@ -247,9 +248,6 @@ public class TemporaryFileProvider extends ContentProvider {
|
|||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
if (!values.containsKey(TemporaryFileColumns.COLUMN_TIME)) {
|
||||
values.put(TemporaryFileColumns.COLUMN_TIME, System.currentTimeMillis());
|
||||
}
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
values.put(TemporaryFileColumns.COLUMN_UUID, uuid);
|
||||
int insert = (int) db.getWritableDatabase().insert(TABLE_FILES, null, values);
|
||||
|
@ -310,4 +308,34 @@ public class TemporaryFileProvider extends ContentProvider {
|
|||
return openFileHelper(uri, mode);
|
||||
}
|
||||
|
||||
public static void scheduleCleanupAfterTtl() {
|
||||
OneTimeWorkRequest cleanupWork = new OneTimeWorkRequest.Builder(CleanupWorker.class)
|
||||
.setInitialDelay(Constants.TEMPFILE_TTL, TimeUnit.MILLISECONDS).build();
|
||||
WorkManager.getInstance().enqueue(cleanupWork);
|
||||
}
|
||||
|
||||
public static void scheduleCleanupImmediately() {
|
||||
OneTimeWorkRequest cleanupWork = new OneTimeWorkRequest.Builder(CleanupWorker.class).build();
|
||||
WorkManager workManager = WorkManager.getInstance();
|
||||
if (workManager != null) { // it's possible this is null, if this is called in onCreate of secondary processes
|
||||
workManager.enqueue(cleanupWork);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CleanupWorker extends Worker {
|
||||
@NonNull
|
||||
@Override
|
||||
public WorkerResult doWork() {
|
||||
Timber.d("Cleaning up temporary files…");
|
||||
|
||||
ContentResolver contentResolver = getApplicationContext().getContentResolver();
|
||||
contentResolver.delete(
|
||||
CONTENT_URI,
|
||||
TemporaryFileColumns.COLUMN_TIME + " <= ?",
|
||||
new String[]{Long.toString(System.currentTimeMillis() - Constants.TEMPFILE_TTL)}
|
||||
);
|
||||
|
||||
return WorkerResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue