diff --git a/app/src/main/java/eu/faircode/email/DaoAttachment.java b/app/src/main/java/eu/faircode/email/DaoAttachment.java index a85205dc77..a45eec2139 100644 --- a/app/src/main/java/eu/faircode/email/DaoAttachment.java +++ b/app/src/main/java/eu/faircode/email/DaoAttachment.java @@ -39,12 +39,6 @@ public interface DaoAttachment { " WHERE message = :message") int getAttachmentCount(long message); - @Query("SELECT COUNT(id)" + - " FROM attachment" + - " WHERE message = :message" + - " AND name = :name") - int getAttachmentCount(long message, String name); - @Query("SELECT COUNT(id)" + " FROM attachment" + " WHERE id = :id") diff --git a/app/src/main/java/eu/faircode/email/EntityMessage.java b/app/src/main/java/eu/faircode/email/EntityMessage.java index acd5b4f954..8423b83ae5 100644 --- a/app/src/main/java/eu/faircode/email/EntityMessage.java +++ b/app/src/main/java/eu/faircode/email/EntityMessage.java @@ -125,8 +125,9 @@ public class EntityMessage implements Serializable { File file = getFile(context, id); BufferedWriter out = null; try { + this.body = (body == null ? "" : body); out = new BufferedWriter(new FileWriter(file)); - out.write(body == null ? "" : body); + out.write(body); } finally { if (out != null) try { diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index cd5ddaafb8..89abe94b7e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -129,8 +129,6 @@ public class FragmentCompose extends FragmentEx { private OpenPgpServiceConnection openPgpConnection = null; - private static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -613,7 +611,7 @@ public class FragmentCompose extends FragmentEx { os = new BufferedOutputStream(new FileOutputStream(file)); int size = 0; - byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE]; + byte[] buffer = new byte[Helper.ATTACHMENT_BUFFER_SIZE]; for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { size += len; os.write(buffer, 0, len); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessage.java b/app/src/main/java/eu/faircode/email/FragmentMessage.java index 2702e62c18..00b8610db7 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessage.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessage.java @@ -87,6 +87,8 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetHeaders; @@ -138,14 +140,15 @@ public class FragmentMessage extends FragmentEx { private boolean free = false; private AdapterAttachment adapter; - private String decrypted = null; private OpenPgpServiceConnection openPgpConnection = null; private boolean debug; private DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); + private ExecutorService executor = Executors.newCachedThreadPool(); + private static final long CACHE_IMAGE_DURATION = 3 * 24 * 3600 * 1000L; - static final String ACTION_DECRYPT_MESSAGE = BuildConfig.APPLICATION_ID + ".DECRYPT_MESSAGEs"; + static final String ACTION_DECRYPT_MESSAGE = BuildConfig.APPLICATION_ID + ".DECRYPT_MESSAGE"; @Override public void onCreate(Bundle savedInstanceState) { @@ -396,7 +399,6 @@ public class FragmentMessage extends FragmentEx { outState.putInt("tag_cc", (int) tvCc.getTag()); outState.putInt("tag_error", (int) tvError.getTag()); } - outState.putString("decrypted", decrypted); } @Override @@ -426,7 +428,6 @@ public class FragmentMessage extends FragmentEx { rvAttachment.setTag(savedInstanceState.getInt("tag_attachment")); tvError.setTag(savedInstanceState.getInt("tag_error")); } - decrypted = savedInstanceState.getString("decrypted"); } if (tvBody.getTag() == null) { @@ -568,7 +569,7 @@ public class FragmentMessage extends FragmentEx { menu.findItem(R.id.menu_thread).setVisible(!free && message.count > 1); menu.findItem(R.id.menu_forward).setVisible(!free && !inOutbox); menu.findItem(R.id.menu_reply_all).setVisible(!free && message.cc != null && !inOutbox); - menu.findItem(R.id.menu_decrypt).setVisible(decrypted == null && !inOutbox); + menu.findItem(R.id.menu_decrypt).setVisible(!inOutbox); } @Override @@ -1034,7 +1035,7 @@ public class FragmentMessage extends FragmentEx { protected Spanned onLoad(final Context context, final Bundle args) throws Throwable { final long id = args.getLong("id"); final boolean show_images = args.getBoolean("show_images"); - String body = (decrypted == null ? message.read(context) : decrypted); + String body = message.read(context); args.putInt("size", body.length()); return decodeHtml(context, id, body, show_images); } @@ -1189,69 +1190,71 @@ public class FragmentMessage extends FragmentEx { InternetHeaders ih = new InternetHeaders(); ih.addHeader("Content-Type", "multipart/alternative"); final MimeBodyPart part = new MimeBodyPart(ih, decrypted.getBytes()); - FragmentMessage.this.decrypted = MessageHelper.getHtml(part); + + String dbody = MessageHelper.getHtml(part); + message.write(getContext(), dbody); // Store attachments - new Thread(new Runnable() { + executor.submit(new Runnable() { @Override public void run() { + DB db = DB.getInstance(getContext()); try { - DB db = DB.getInstance(getContext()); - int sequence = db.attachment().getAttachmentCount(message.id); + db.beginTransaction(); + + for (EntityAttachment attachment : db.attachment().getAttachments(message.id)) + if ("encrypted.asc".equals(attachment.name)) + db.attachment().deleteAttachment(attachment.id); + + int sequence = 0; + for (EntityAttachment attachment : MessageHelper.getAttachments(part)) { + + attachment.message = message.id; + attachment.sequence = ++sequence; + attachment.id = db.attachment().insertAttachment(attachment); + + File file = EntityAttachment.getFile(getContext(), attachment.id); - for (EntityAttachment attachment : MessageHelper.getAttachments(part)) - if (db.attachment().getAttachmentCount(message.id, attachment.name) == 0) + // Store attachment + InputStream is = null; + OutputStream os = null; + try { + is = attachment.part.getInputStream(); + os = new BufferedOutputStream(new FileOutputStream(file)); + + int size = 0; + byte[] buffer = new byte[Helper.ATTACHMENT_BUFFER_SIZE]; + for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { + size += len; + os.write(buffer, 0, len); + } + + // Store attachment data + attachment.size = size; + attachment.progress = null; + attachment.available = true; + db.attachment().updateAttachment(attachment); + } finally { try { - db.beginTransaction(); - - attachment.message = message.id; - attachment.sequence = ++sequence; - attachment.id = db.attachment().insertAttachment(attachment); - - File file = EntityAttachment.getFile(getContext(), attachment.id); - - // Store attachment - InputStream is = null; - OutputStream os = null; - try { - is = attachment.part.getInputStream(); - os = new BufferedOutputStream(new FileOutputStream(file)); - - int size = 0; - byte[] buffer = new byte[4096]; - for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { - size += len; - os.write(buffer, 0, len); - } - - // Store attachment data - attachment.size = size; - attachment.progress = null; - attachment.available = true; - db.attachment().updateAttachment(attachment); - } finally { - try { - if (is != null) - is.close(); - } finally { - if (os != null) - os.close(); - } - } - - db.setTransactionSuccessful(); + if (is != null) + is.close(); } finally { - db.endTransaction(); + if (os != null) + os.close(); } + } + } + + db.setTransactionSuccessful(); } catch (Throwable ex) { Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); + } finally { + db.endTransaction(); } } - }).start(); + }); } else - FragmentMessage.this.decrypted = "
" + decrypted.replaceAll("\\r?\\n", "
") + "
"; - - getActivity().invalidateOptionsMenu(); + message.write(getContext(), "
" + decrypted.replaceAll("\\r?\\n", "
") + "
"); Bundle args = new Bundle(); args.putLong("id", message.id); diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index f5124d8f27..c45e83a467 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -57,6 +57,8 @@ public class Helper { static final int AUTH_TYPE_PASSWORD = 1; static final int AUTH_TYPE_GMAIL = 2; + static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes + static int resolveColor(Context context, int attr) { int[] attrs = new int[]{attr}; TypedArray a = context.getTheme().obtainStyledAttributes(attrs); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index e962246de5..7c729f5d9f 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -123,7 +123,6 @@ public class ServiceSynchronize extends LifecycleService { private static final int CONNECT_BACKOFF_START = 32; // seconds private static final int CONNECT_BACKOFF_MAX = 1024; // seconds (1024 sec ~ 17 min) private static final long STORE_NOOP_INTERVAL = 9 * 60 * 1000L; // ms - private static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes static final String ACTION_SYNCHRONIZE_FOLDER = BuildConfig.APPLICATION_ID + ".SYNCHRONIZE_FOLDER"; static final String ACTION_PROCESS_OPERATIONS = BuildConfig.APPLICATION_ID + ".PROCESS_OPERATIONS"; @@ -1073,7 +1072,7 @@ public class ServiceSynchronize extends LifecycleService { os = new BufferedOutputStream(new FileOutputStream(file)); int size = 0; - byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE]; + byte[] buffer = new byte[Helper.ATTACHMENT_BUFFER_SIZE]; for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { size += len; os.write(buffer, 0, len);