From cfb11a0cb63ebdddf3d94ea7182f764911cd1d06 Mon Sep 17 00:00:00 2001 From: M66B Date: Tue, 17 Sep 2019 14:22:18 +0200 Subject: [PATCH] Check send messages with exists operation --- FAQ.md | 1 + app/src/main/java/eu/faircode/email/Core.java | 43 ++++++++++++++++--- .../eu/faircode/email/EntityOperation.java | 1 + .../java/eu/faircode/email/ServiceSend.java | 16 ++----- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/FAQ.md b/FAQ.md index 16c56f48e4..81c5df2af9 100644 --- a/FAQ.md +++ b/FAQ.md @@ -325,6 +325,7 @@ The low priority status bar notification shows the number of pending operations, * *sync*: synchronize local and remote messages * *subscribe*: subscribe to remote folder * *send*: send message +* *exists*: check if message exists Operations are processed only when there is a connection to the email server or when manually synchronizing. See also [this FAQ](#user-content-faq16). diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index 222c00ab7b..4fe79af373 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -115,6 +115,7 @@ class Core { private static int lastUnseen = -1; private static final int MAX_NOTIFICATION_COUNT = 100; // per group + private static final long AFTER_SEND_DELAY = 10 * 1000L; // milliseconds private static final int SYNC_CHUNCK_SIZE = 200; private static final int SYNC_BATCH_SIZE = 20; private static final int DOWNLOAD_BATCH_SIZE = 20; @@ -221,7 +222,7 @@ class Core { break; case EntityOperation.HEADERS: - onHeaders(context, folder, message, (IMAPFolder) ifolder); + onHeaders(context, jargs, folder, message, (IMAPFolder) ifolder); break; case EntityOperation.RAW: @@ -229,13 +230,17 @@ class Core { break; case EntityOperation.BODY: - onBody(context, folder, message, (IMAPFolder) ifolder); + onBody(context, jargs, folder, message, (IMAPFolder) ifolder); break; case EntityOperation.ATTACHMENT: onAttachment(context, jargs, folder, message, op, (IMAPFolder) ifolder); break; + case EntityOperation.EXISTS: + onExists(context, jargs, folder, message, op, (IMAPFolder) ifolder); + break; + case EntityOperation.SYNC: onSynchronizeMessages(context, jargs, account, folder, (IMAPFolder) ifolder, state); break; @@ -322,6 +327,8 @@ class Core { return; if (EntityOperation.ADD.equals(op.name)) return; + if (EntityOperation.EXISTS.equals(op.name)) + return; if (EntityOperation.DELETE.equals(op.name) && !TextUtils.isEmpty(message.msgid)) return; @@ -461,7 +468,7 @@ class Core { } } - private static void onAdd(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPStore istore, IMAPFolder ifolder) throws MessagingException, JSONException, IOException { + private static void onAdd(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPStore istore, IMAPFolder ifolder) throws MessagingException, IOException { // Add message DB db = DB.getInstance(context); @@ -736,7 +743,7 @@ class Core { } } - private static void onHeaders(Context context, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException { + private static void onHeaders(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException { // Download headers DB db = DB.getInstance(context); @@ -783,7 +790,7 @@ class Core { } } - private static void onBody(Context context, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException, IOException { + private static void onBody(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException, IOException { // Download message body DB db = DB.getInstance(context); @@ -837,6 +844,32 @@ class Core { parts.downloadAttachment(context, attachment); } + private static void onExists(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, EntityOperation op, IMAPFolder ifolder) throws MessagingException { + if (message.uid != null) + return; + + if (EntityFolder.SENT.equals(folder.type)) { + long ago = new Date().getTime() - op.created; + long delay = AFTER_SEND_DELAY - ago; + if (delay > 0) { + Log.i(folder.name + " send delay=" + delay); + try { + Thread.sleep(delay); + } catch (InterruptedException ex) { + Log.w(ex); + } + } + } + + Message[] imessages = ifolder.search(new MessageIDTerm(message.msgid)); + if (imessages == null || imessages.length == 0) + EntityOperation.queue(context, message, EntityOperation.ADD); + else { + long uid = ifolder.getUID(imessages[0]); + EntityOperation.queue(context, message, EntityOperation.FETCH, uid); + } + } + static void onSynchronizeFolders(Context context, EntityAccount account, Store istore, State state) throws MessagingException { DB db = DB.getInstance(context); diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index a727bc5882..90a2092c8c 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -90,6 +90,7 @@ public class EntityOperation { static final String SYNC = "sync"; static final String SUBSCRIBE = "subscribe"; static final String SEND = "send"; + static final String EXISTS = "exists"; static void queue(Context context, EntityMessage message, String name, Object... values) { DB db = DB.getInstance(context); diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java index bb87ee8e3f..4c5ce9b4c6 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSend.java +++ b/app/src/main/java/eu/faircode/email/ServiceSend.java @@ -68,7 +68,6 @@ public class ServiceSend extends ServiceBase { private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); private static final int IDENTITY_ERROR_AFTER = 30; // minutes - private static final long AFTER_SEND_DELAY = 10 * 1000L; // milliseconds @Override public void onCreate() { @@ -423,6 +422,10 @@ public class ServiceSend extends ServiceBase { db.message().setMessageSent(sid, time); db.message().setMessageUiHide(sid, 0L); + + // Check for sent orphans + EntityMessage orphan = db.message().getMessage(sid); + EntityOperation.queue(this, orphan, EntityOperation.EXISTS); } if (message.inreplyto != null) { @@ -442,17 +445,6 @@ public class ServiceSend extends ServiceBase { NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.cancel("send:" + message.identity, 1); - - // Check for sent orphans - if (sent != null) { - // Give server time to store message into the sent folder - try { - Thread.sleep(AFTER_SEND_DELAY); - } catch (InterruptedException ex) { - Log.w(ex); - } - EntityOperation.sync(this, sent.id, false); - } } catch (MessagingException ex) { Log.e(ex);