From e8da25a67482049f03936a6834288a4a90e93ab8 Mon Sep 17 00:00:00 2001 From: M66B Date: Tue, 4 Sep 2018 07:02:54 +0000 Subject: [PATCH] Added daily cleanup job --- .idea/caches/build_file_checksums.ser | Bin 535 -> 535 bytes app/src/main/AndroidManifest.xml | 5 + .../email/BoundaryCallbackMessages.java | 21 +++- .../main/java/eu/faircode/email/DaoLog.java | 4 + .../eu/faircode/email/FragmentMessage.java | 2 +- .../main/java/eu/faircode/email/Helper.java | 15 +++ .../main/java/eu/faircode/email/JobDaily.java | 109 ++++++++++++++++++ .../eu/faircode/email/ServiceSynchronize.java | 29 +---- .../java/eu/faircode/email/SimpleTask.java | 13 +-- 9 files changed, 159 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/eu/faircode/email/JobDaily.java diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index e59db92c3c323265c496c9283a26f7f443acdade..c952cd824c7ec664a974f20c81108ac4fe5f6643 100644 GIT binary patch delta 15 XcmbQvGM#0@43@>}U1l5SR5JnqEkOmg delta 15 XcmbQvGM#0@43>GzZhqZ3r + + . + + Copyright 2018 by Marcel Bokhorst (M66B) +*/ + import android.content.Context; import android.os.Handler; import android.util.Log; @@ -35,7 +54,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback. + + Copyright 2018 by Marcel Bokhorst (M66B) +*/ + +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; +import android.content.Context; +import android.util.Log; + +import java.io.File; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class JobDaily extends JobService { + private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); + + public static void schedule(Context context) { + Log.i(Helper.TAG, "Scheduling daily job"); + + JobInfo.Builder job = new JobInfo.Builder(Helper.JOB_DAILY, new ComponentName(context, JobDaily.class)) + .setPeriodic(24 * 3600 * 1000L) + .setRequiresDeviceIdle(true); + + JobScheduler scheduler = context.getSystemService(JobScheduler.class); + scheduler.cancel(Helper.JOB_DAILY); + if (scheduler.schedule(job.build()) == JobScheduler.RESULT_SUCCESS) + Log.i(Helper.TAG, "Scheduled daily job"); + else + Log.e(Helper.TAG, "Failed to schedule daily job"); + } + + @Override + public boolean onStartJob(JobParameters args) { + Log.i(Helper.TAG, "Starting daily job"); + + final DB db = DB.getInstance(this); + + executor.submit(new Runnable() { + @Override + public void run() { + Log.i(Helper.TAG, "Start daily job"); + + // Cleanup message files + Log.i(Helper.TAG, "Cleanup message files"); + File[] messages = new File(getFilesDir(), "messages").listFiles(); + if (messages != null) + for (File file : messages) + if (file.isFile()) { + long id = Long.parseLong(file.getName()); + if (db.message().countMessage(id) == 0) { + Log.i(Helper.TAG, "Cleanup message id=" + id); + if (!file.delete()) + Log.w(Helper.TAG, "Error deleting " + file); + } + } + + // Cleanup attachment files + Log.i(Helper.TAG, "Cleanup attachment files"); + File[] attachments = new File(getFilesDir(), "attachments").listFiles(); + if (attachments != null) + for (File file : attachments) + if (file.isFile()) { + long id = Long.parseLong(file.getName()); + if (db.attachment().countAttachment(id) == 0) { + Log.i(Helper.TAG, "Cleanup attachment id=" + id); + if (!file.delete()) + Log.w(Helper.TAG, "Error deleting " + file); + } + } + + Log.i(Helper.TAG, "Cleanup log"); + long before = new Date().getTime() - 24 * 3600 * 1000L; + int logs = db.log().deleteLogs(before); + Log.i(Helper.TAG, "Deleted logs=" + logs); + + Log.i(Helper.TAG, "End daily job"); + } + }); + + return false; + } + + @Override + public boolean onStopJob(JobParameters args) { + return false; + } +} + diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index ebab416a..b6094ac3 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -386,7 +386,7 @@ public class ServiceSynchronize extends LifecycleService { private void monitorAccount(final EntityAccount account, final ServiceState state) throws NoSuchProviderException { final DB db = DB.getInstance(this); - final ExecutorService executor = Executors.newSingleThreadExecutor(); + final ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); int backoff = CONNECT_BACKOFF_START; while (state.running) { @@ -1270,28 +1270,6 @@ public class ServiceSynchronize extends LifecycleService { Log.w(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); } - // Cleanup files - File[] messages = new File(getFilesDir(), "messages").listFiles(); - if (messages != null) - for (File file : messages) - if (file.isFile()) { - long id = Long.parseLong(file.getName()); - if (db.message().countMessage(id) == 0) { - Log.i(Helper.TAG, "Cleanup message id=" + id); - file.delete(); - } - } - File[] attachments = new File(getFilesDir(), "attachments").listFiles(); - if (attachments != null) - for (File file : attachments) - if (file.isFile()) { - long id = Long.parseLong(file.getName()); - if (db.attachment().countAttachment(id) == 0) { - Log.i(Helper.TAG, "Cleanup attachment id=" + id); - file.delete(); - } - } - Log.w(Helper.TAG, folder.name + " statistics added=" + added + " updated=" + updated + " unchanged=" + unchanged); } finally { Log.v(Helper.TAG, folder.name + " end sync"); @@ -1439,8 +1417,8 @@ public class ServiceSynchronize extends LifecycleService { private boolean running = false; private Thread main; private EntityFolder outbox = null; - private ExecutorService lifecycle = Executors.newSingleThreadExecutor(); - private ExecutorService executor = Executors.newSingleThreadExecutor(); + private ExecutorService lifecycle = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); + private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); @Override public void onAvailable(Network network) { @@ -1648,6 +1626,7 @@ public class ServiceSynchronize extends LifecycleService { public static void start(Context context) { ContextCompat.startForegroundService(context, new Intent(context, ServiceSynchronize.class)); + JobDaily.schedule(context); } public static void reload(Context context, String reason) { diff --git a/app/src/main/java/eu/faircode/email/SimpleTask.java b/app/src/main/java/eu/faircode/email/SimpleTask.java index e15c1ca0..11a85015 100644 --- a/app/src/main/java/eu/faircode/email/SimpleTask.java +++ b/app/src/main/java/eu/faircode/email/SimpleTask.java @@ -22,12 +22,10 @@ package eu.faircode.email; import android.content.Context; import android.os.Bundle; import android.os.Handler; -import android.support.annotation.NonNull; import android.util.Log; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; @@ -37,8 +35,6 @@ import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleService; import androidx.lifecycle.OnLifecycleEvent; -import static android.os.Process.THREAD_PRIORITY_BACKGROUND; - // // This simple task is simple to use, but it is also simple to cause bugs that can easily lead to crashes // Make sure to not access any member in any outer scope from onLoad @@ -51,14 +47,7 @@ public abstract class SimpleTask implements LifecycleObserver { private Bundle args = null; private Result stored = null; - private ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() { - @Override - public Thread newThread(@NonNull Runnable runnable) { - Thread thread = new Thread(runnable); - thread.setPriority(THREAD_PRIORITY_BACKGROUND); - return thread; - } - }); + private ExecutorService executor = Executors.newCachedThreadPool(Helper.backgroundThreadFactory); public void load(Context context, LifecycleOwner owner, Bundle args) { run(context, owner, args);