Reduced memory usage of cleanup worker

pull/214/head
M66B 2 years ago
parent 215d03c9c9
commit 66d00d710e

@ -19,6 +19,8 @@ package eu.faircode.email;
Copyright 2018-2023 by Marcel Bokhorst (M66B) Copyright 2018-2023 by Marcel Bokhorst (M66B)
*/ */
import android.database.Cursor;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
@ -64,7 +66,7 @@ public interface DaoAttachment {
@Query("SELECT id FROM attachment" + @Query("SELECT id FROM attachment" +
" WHERE available") " WHERE available")
List<Long> getAttachmentAvailable(); Cursor getAttachmentAvailable();
@Query("UPDATE attachment" + @Query("UPDATE attachment" +
" SET message = :message" + " SET message = :message" +

@ -384,7 +384,7 @@ public interface DaoMessage {
" FROM message" + " FROM message" +
" WHERE content" + " WHERE content" +
" ORDER BY message.received DESC") " ORDER BY message.received DESC")
List<Long> getMessageWithContent(); Cursor getMessageWithContent();
@Query("SELECT message.id" + @Query("SELECT message.id" +
" FROM message" + " FROM message" +

@ -109,8 +109,8 @@ public class WorkerCleanup extends Worker {
if (manual) { if (manual) {
// Check message files // Check message files
Log.i("Checking message files"); Log.i("Checking message files");
List<Long> mids = db.message().getMessageWithContent(); try (Cursor cursor = db.message().getMessageWithContent()) {
for (Long mid : mids) { long mid = cursor.getLong(0);
EntityMessage message = db.message().getMessage(mid); EntityMessage message = db.message().getMessage(mid);
if (message != null) { if (message != null) {
File file = message.getFile(context); File file = message.getFile(context);
@ -123,8 +123,8 @@ public class WorkerCleanup extends Worker {
// Check attachments files // Check attachments files
Log.i("Checking attachments files"); Log.i("Checking attachments files");
List<Long> aids = db.attachment().getAttachmentAvailable(); try (Cursor cursor = db.attachment().getAttachmentAvailable()) {
for (Long aid : aids) { long aid = cursor.getLong(0);
EntityAttachment attachment = db.attachment().getAttachment(aid); EntityAttachment attachment = db.attachment().getAttachment(aid);
if (attachment != null) { if (attachment != null) {
File file = attachment.getFile(context); File file = attachment.getFile(context);
@ -206,46 +206,14 @@ public class WorkerCleanup extends Worker {
long now = new Date().getTime(); long now = new Date().getTime();
List<File> files = new ArrayList<>();
File[] messages = Helper.listFiles(new File(context.getFilesDir(), "messages")).toArray(new File[0]);
File[] revision = new File(context.getFilesDir(), "revision").listFiles();
File[] references = new File(context.getFilesDir(), "references").listFiles();
File[] encryption = new File(context.getFilesDir(), "encryption").listFiles();
File[] photos = new File(context.getFilesDir(), "photo").listFiles();
File[] calendars = new File(context.getFilesDir(), "calendar").listFiles();
if (messages != null)
files.addAll(Arrays.asList(messages));
if (revision != null)
files.addAll(Arrays.asList(revision));
if (references != null)
files.addAll(Arrays.asList(references));
if (encryption != null)
files.addAll(Arrays.asList(encryption));
if (photos != null)
files.addAll(Arrays.asList(photos));
if (calendars != null)
files.addAll(Arrays.asList(calendars));
// Cleanup message files // Cleanup message files
Log.i("Cleanup message files"); Log.i("Cleanup message files");
for (File file : files) cleanupMessageFiles(db, manual, Helper.listFiles(new File(context.getFilesDir(), "messages")).toArray(new File[0]));
if (manual || file.lastModified() + KEEP_FILES_DURATION < now) cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "revision").listFiles());
try { cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "references").listFiles());
String name = file.getName().split("\\.")[0]; cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "encryption").listFiles());
int us = name.indexOf('_'); cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "photo").listFiles());
if (us > 0) cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "calendar").listFiles());
name = name.substring(0, us);
long id = Long.parseLong(name);
EntityMessage message = db.message().getMessage(id);
if (message == null || !message.content) {
Log.i("Deleting " + file);
Helper.secureDelete(file);
}
} catch (NumberFormatException ex) {
Log.e(file.getAbsolutePath(), ex);
Helper.secureDelete(file);
}
// Cleanup raw message files // Cleanup raw message files
if (!download_eml) { if (!download_eml) {
@ -276,49 +244,55 @@ public class WorkerCleanup extends Worker {
// Cleanup attachment files // Cleanup attachment files
Log.i("Cleanup attachment files"); Log.i("Cleanup attachment files");
File[] attachments = new File(EntityAttachment.getRoot(context), "attachments").listFiles(); {
if (attachments != null) File[] attachments = new File(EntityAttachment.getRoot(context), "attachments").listFiles();
for (File file : attachments) if (attachments != null)
if (manual || file.lastModified() + KEEP_FILES_DURATION < now) for (File file : attachments)
try { if (manual || file.lastModified() + KEEP_FILES_DURATION < now)
long id = Long.parseLong(file.getName().split("\\.")[0]); try {
EntityAttachment attachment = db.attachment().getAttachment(id); long id = Long.parseLong(file.getName().split("\\.")[0]);
if (attachment == null || !attachment.available) { EntityAttachment attachment = db.attachment().getAttachment(id);
Log.i("Deleting " + file); if (attachment == null || !attachment.available) {
Log.i("Deleting " + file);
Helper.secureDelete(file);
}
} catch (NumberFormatException ex) {
Log.e(file.getAbsolutePath(), ex);
Helper.secureDelete(file); Helper.secureDelete(file);
} }
} catch (NumberFormatException ex) { }
Log.e(file.getAbsolutePath(), ex);
Helper.secureDelete(file);
}
// Cleanup cached images // Cleanup cached images
Log.i("Cleanup cached image files"); Log.i("Cleanup cached image files");
File[] images = new File(context.getFilesDir(), "images").listFiles(); {
if (images != null) File[] images = new File(context.getFilesDir(), "images").listFiles();
for (File file : images) if (images != null)
if (manual || file.lastModified() + KEEP_FILES_DURATION < now) for (File file : images)
try { if (manual || file.lastModified() + KEEP_FILES_DURATION < now)
long id = Long.parseLong(file.getName().split("[_\\.]")[0]); try {
EntityMessage message = db.message().getMessage(id); long id = Long.parseLong(file.getName().split("[_\\.]")[0]);
if (manual || message == null || EntityMessage message = db.message().getMessage(id);
file.lastModified() + KEEP_IMAGES_DURATION < now) { if (manual || message == null ||
Log.i("Deleting " + file); file.lastModified() + KEEP_IMAGES_DURATION < now) {
Log.i("Deleting " + file);
Helper.secureDelete(file);
}
} catch (NumberFormatException ex) {
Log.e(file.getAbsolutePath(), ex);
Helper.secureDelete(file); Helper.secureDelete(file);
} }
} catch (NumberFormatException ex) { }
Log.e(file.getAbsolutePath(), ex);
Helper.secureDelete(file);
}
// Cleanup shared files // Cleanup shared files
File[] shared = new File(context.getFilesDir(), "shared").listFiles(); {
if (shared != null) File[] shared = new File(context.getFilesDir(), "shared").listFiles();
for (File file : shared) if (shared != null)
if (manual || file.lastModified() + KEEP_FILES_DURATION < now) { for (File file : shared)
Log.i("Deleting " + file); if (manual || file.lastModified() + KEEP_FILES_DURATION < now) {
Helper.secureDelete(file); Log.i("Deleting " + file);
} Helper.secureDelete(file);
}
}
// Cleanup contact info // Cleanup contact info
if (manual) if (manual)
@ -400,6 +374,29 @@ public class WorkerCleanup extends Worker {
} }
} }
static void cleanupMessageFiles(DB db, boolean manual, File[] files) {
if (files == null)
return;
long now = new Date().getTime();
for (File file : files)
if (manual || file.lastModified() + KEEP_FILES_DURATION < now)
try {
String name = file.getName().split("\\.")[0];
int us = name.indexOf('_');
if (us > 0)
name = name.substring(0, us);
long id = Long.parseLong(name);
EntityMessage message = db.message().getMessage(id);
if (message == null || !message.content) {
Log.i("Deleting " + file);
Helper.secureDelete(file);
}
} catch (NumberFormatException ex) {
Log.e(file.getAbsolutePath(), ex);
Helper.secureDelete(file);
}
}
static void init(Context context) { static void init(Context context) {
try { try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

Loading…
Cancel
Save