From 9cafc1223dc226f3a555697fc0a04687bcddc045 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 21 Sep 2018 17:19:02 +0000 Subject: [PATCH] Bring back polling --- FAQ.md | 12 ++-- SETUP.md | 5 -- .../eu/faircode/email/FragmentAccount.java | 12 ++-- .../eu/faircode/email/ServiceSynchronize.java | 69 ++++++++++--------- app/src/main/res/layout/fragment_account.xml | 30 ++++++-- app/src/main/res/values/strings.xml | 2 +- app/src/main/res/xml/providers.xml | 8 +-- 7 files changed, 83 insertions(+), 55 deletions(-) diff --git a/FAQ.md b/FAQ.md index 859a1c26..c1130077 100644 --- a/FAQ.md +++ b/FAQ.md @@ -49,13 +49,13 @@ See also [this FAQ](#FAQ16). Valid security certificates are officially signed (not self signed) and have matching a host name. -**(5) What does 'no IDLE support' mean?** +~~**(5) What does 'no IDLE support' mean?**~~ -Without [IMAP IDLE](https://en.wikipedia.org/wiki/IMAP_IDLE) emails need to be periodically fetched, -which is a waste of battery power and internet bandwidth and will delay notification of new emails. -Since the goal of FairEmail is to offer safe and fast email, providers without IMAP IDLE are not supported. -You should consider this a problem of the provider, not of the app. -Almost all email providers offer IMAP IDLE, with as notable exception Yahoo! +~~Without [IMAP IDLE](https://en.wikipedia.org/wiki/IMAP_IDLE) emails need to be periodically fetched,~~ +~~which is a waste of battery power and internet bandwidth and will delay notification of new emails.~~ +~~Since the goal of FairEmail is to offer safe and fast email, providers without IMAP IDLE are not supported.~~ +~~You should consider this a problem of the provider, not of the app.~~ +~~Almost all email providers offer IMAP IDLE, with as notable exception Yahoo!~~ **(6) How can I login to Gmail / G suite?** diff --git a/SETUP.md b/SETUP.md index 83ea84fd..121ba6ff 100644 --- a/SETUP.md +++ b/SETUP.md @@ -7,11 +7,6 @@ You'll need to add at least one account to receive email and at least one identi An internet connection is required to add accounts and identities. -Your email provider should support IMAP with the IDLE and UIDPLUS extensions. -All up-to-date email providers do, with as notable exception Yahoo! -IMAP IDLE is required to limit battery usage, -see [this FAQ](https://github.com/M66B/open-source-email/blob/master/FAQ.md#FAQ5) for more details. - Your email provider should support secure connections. If your provider doesn't support secure connections and you care at least a little about your privacy, you are strongly advised to switch to another provider. diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java index fe38cd9a..e551ca93 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAccount.java +++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java @@ -110,6 +110,7 @@ public class FragmentAccount extends FragmentEx { private ImageButton ibPro; private CheckBox cbSynchronize; private CheckBox cbPrimary; + private EditText etInterval; private Button btnCheck; private ProgressBar pbCheck; @@ -173,6 +174,7 @@ public class FragmentAccount extends FragmentEx { cbSynchronize = view.findViewById(R.id.cbSynchronize); cbPrimary = view.findViewById(R.id.cbPrimary); + etInterval = view.findViewById(R.id.etInterval); btnCheck = view.findViewById(R.id.btnCheck); pbCheck = view.findViewById(R.id.pbCheck); @@ -429,9 +431,6 @@ public class FragmentAccount extends FragmentEx { throw ex; } - if (!istore.hasCapability("IDLE")) - throw new MessagingException(getContext().getString(R.string.title_no_idle)); - if (!istore.hasCapability("UIDPLUS")) throw new MessagingException(getContext().getString(R.string.title_no_uidplus)); @@ -567,6 +566,7 @@ public class FragmentAccount extends FragmentEx { args.putInt("color", color); args.putString("signature", Html.toHtml(etSignature.getText())); args.putBoolean("primary", cbPrimary.isChecked()); + args.putString("interval", etInterval.getText().toString()); args.putParcelable("drafts", drafts); args.putParcelable("sent", sent); @@ -588,6 +588,7 @@ public class FragmentAccount extends FragmentEx { String signature = args.getString("signature"); boolean synchronize = args.getBoolean("synchronize"); boolean primary = args.getBoolean("primary"); + String interval = args.getString("interval"); EntityFolder drafts = args.getParcelable("drafts"); EntityFolder sent = args.getParcelable("sent"); @@ -603,6 +604,8 @@ public class FragmentAccount extends FragmentEx { throw new Throwable(getContext().getString(R.string.title_no_user)); if (TextUtils.isEmpty(password)) throw new Throwable(getContext().getString(R.string.title_no_password)); + if (TextUtils.isEmpty(interval)) + interval = "9"; if (synchronize && drafts == null) throw new Throwable(getContext().getString(R.string.title_no_drafts)); @@ -653,7 +656,7 @@ public class FragmentAccount extends FragmentEx { account.synchronize = synchronize; account.primary = (account.synchronize && primary); account.store_sent = false; - account.poll_interval = 9; + account.poll_interval = Integer.parseInt(interval); if (!synchronize) account.error = null; @@ -874,6 +877,7 @@ public class FragmentAccount extends FragmentEx { cbSynchronize.setChecked(account == null ? true : account.synchronize); cbPrimary.setChecked(account == null ? true : account.primary); + etInterval.setText(Long.toString(account == null ? 9 : account.poll_interval)); color = (account == null || account.color == null ? Color.TRANSPARENT : account.color); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index ed5c06ad..bf07d880 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -642,6 +642,8 @@ public class ServiceSynchronize extends LifecycleService { db.folder().setFolderState(folder.id, null); db.account().setAccountState(account.id, "connecting"); Helper.connect(this, istore, account); + final boolean capIdle = istore.hasCapability("IDLE"); + Log.i(Helper.TAG, account.name + " idle=" + capIdle); db.account().setAccountState(account.id, "connected"); db.account().setAccountError(account.id, null); @@ -813,15 +815,18 @@ public class ServiceSynchronize extends LifecycleService { try { Thread.sleep(account.poll_interval * 60 * 1000L); - Log.i(Helper.TAG, folder.name + " request NOOP"); - ifolder.doCommand(new IMAPFolder.ProtocolCommand() { - public Object doCommand(IMAPProtocol p) throws ProtocolException { - Log.i(Helper.TAG, ifolder.getName() + " start NOOP"); - p.simpleCommand("NOOP", null); - Log.i(Helper.TAG, ifolder.getName() + " end NOOP"); - return null; - } - }); + if (capIdle) { + Log.i(Helper.TAG, folder.name + " request NOOP"); + ifolder.doCommand(new IMAPFolder.ProtocolCommand() { + public Object doCommand(IMAPProtocol p) throws ProtocolException { + Log.i(Helper.TAG, ifolder.getName() + " start NOOP"); + p.simpleCommand("NOOP", null); + Log.i(Helper.TAG, ifolder.getName() + " end NOOP"); + return null; + } + }); + } else + synchronizeMessages(account, folder, ifolder, state); } catch (InterruptedException ex) { Log.w(Helper.TAG, folder.name + " noop " + ex.toString()); @@ -845,32 +850,34 @@ public class ServiceSynchronize extends LifecycleService { noops.add(noop); // Receive folder events - Thread idle = new Thread(new Runnable() { - @Override - public void run() { - try { - Log.i(Helper.TAG, folder.name + " start idle"); - while (state.running && ifolder.isOpen()) { - //Log.i(Helper.TAG, folder.name + " do idle"); - ifolder.idle(false); - //Log.i(Helper.TAG, folder.name + " done idle"); - } - } catch (Throwable ex) { - Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); - reportError(account.name, folder.name, ex); + if (capIdle) { + Thread idle = new Thread(new Runnable() { + @Override + public void run() { + try { + Log.i(Helper.TAG, folder.name + " start idle"); + while (state.running && ifolder.isOpen()) { + Log.i(Helper.TAG, folder.name + " do idle"); + ifolder.idle(false); + //Log.i(Helper.TAG, folder.name + " done idle"); + } + } catch (Throwable ex) { + Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); + reportError(account.name, folder.name, ex); - db.folder().setFolderError(folder.id, Helper.formatThrowable(ex)); + db.folder().setFolderError(folder.id, Helper.formatThrowable(ex)); - synchronized (state) { - state.notifyAll(); + synchronized (state) { + state.notifyAll(); + } + } finally { + Log.i(Helper.TAG, folder.name + " end idle"); } - } finally { - Log.i(Helper.TAG, folder.name + " end idle"); } - } - }, "sync.idle." + folder.id); - idle.start(); - idlers.add(idle); + }, "sync.idle." + folder.id); + idle.start(); + idlers.add(idle); + } } backoff = CONNECT_BACKOFF_START; diff --git a/app/src/main/res/layout/fragment_account.xml b/app/src/main/res/layout/fragment_account.xml index 1c2d1622..0af1037d 100644 --- a/app/src/main/res/layout/fragment_account.xml +++ b/app/src/main/res/layout/fragment_account.xml @@ -173,7 +173,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvUser" /> - + + + + + + +