From c720458e9d4f90388ac4fb77e58a0e07b1a16478 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 2 Sep 2022 12:28:38 +0200 Subject: [PATCH] Added idle restart for Outlook --- app/src/main/java/com/sun/mail/imap/IMAPFolder.java | 10 ++++++++++ app/src/main/java/com/sun/mail/imap/IMAPStore.java | 9 +++++++++ app/src/main/java/eu/faircode/email/EmailService.java | 4 ++++ .../java/eu/faircode/email/ServiceSynchronize.java | 5 +++++ 4 files changed, 28 insertions(+) diff --git a/app/src/main/java/com/sun/mail/imap/IMAPFolder.java b/app/src/main/java/com/sun/mail/imap/IMAPFolder.java index 7e1c345421..32ad6aa29b 100644 --- a/app/src/main/java/com/sun/mail/imap/IMAPFolder.java +++ b/app/src/main/java/com/sun/mail/imap/IMAPFolder.java @@ -16,6 +16,8 @@ package com.sun.mail.imap; +import android.os.SystemClock; + import java.util.Date; import java.util.Vector; import java.util.Hashtable; @@ -3284,6 +3286,8 @@ public class IMAPFolder extends Folder implements UIDFolder, ResponseHandler { */ boolean handleIdle(boolean once) throws MessagingException { Response r = null; + long start = SystemClock.elapsedRealtime(); + long restartIdleInterval = ((IMAPStore)store).getRestartIdleInterval() * 1000L; do { r = protocol.readIdleResponse(); try { @@ -3304,6 +3308,12 @@ public class IMAPFolder extends Folder implements UIDFolder, ResponseHandler { logger.finest( "handleIdle: ignoring socket timeout"); r = null; // repeat do/while loop + long elapsed = SystemClock.elapsedRealtime() - start; + if (restartIdleInterval > 0 && elapsed > restartIdleInterval) { + logger.finest("handleIdle: restart elapsed=" + elapsed); + protocol.idleAbort(); + idleState = ABORTING; + } } else { logger.finest("handleIdle: interrupting IDLE"); IdleManager im = idleManager; diff --git a/app/src/main/java/com/sun/mail/imap/IMAPStore.java b/app/src/main/java/com/sun/mail/imap/IMAPStore.java index 336afbe8f2..c47a3a7cb1 100644 --- a/app/src/main/java/com/sun/mail/imap/IMAPStore.java +++ b/app/src/main/java/com/sun/mail/imap/IMAPStore.java @@ -175,6 +175,8 @@ public class IMAPStore extends Store private final int minIdleTime; // minimum idle time + private final int restartIdleInterval; + private volatile int port = -1; // port to use // Auth info @@ -477,6 +479,9 @@ public class IMAPStore extends Store if (logger.isLoggable(Level.CONFIG)) logger.config("mail.imap.minidletime: " + minIdleTime); + restartIdleInterval = PropUtil.getIntProperty(props, + "mail." + name + ".restartidleinterval", 0); + // check if we should do a PROXYAUTH login String s = session.getProperty("mail." + name + ".proxyauth.user"); if (s != null) { @@ -1579,6 +1584,10 @@ public class IMAPStore extends Store return minIdleTime; } + int getRestartIdleInterval() { + return restartIdleInterval; + } + /** * Throw a SearchException if the search expression is too complex? */ diff --git a/app/src/main/java/eu/faircode/email/EmailService.java b/app/src/main/java/eu/faircode/email/EmailService.java index 3d52b1fc0a..c86eb1c361 100644 --- a/app/src/main/java/eu/faircode/email/EmailService.java +++ b/app/src/main/java/eu/faircode/email/EmailService.java @@ -329,6 +329,10 @@ public class EmailService implements AutoCloseable { properties.put("mail." + protocol + ".allow8bitmime", Boolean.toString(value)); } + void setRestartIdleInterval(int seconds) { + properties.put("mail." + protocol + ".restartidleinterval", Integer.toString(seconds)); + } + // https://tools.ietf.org/html/rfc3461 void setDsnNotify(String what) { properties.put("mail." + protocol + ".dsn.notify", what); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index d06b10bed7..49fc4578b8 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -1518,6 +1518,11 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences if (account.protocol != EntityAccount.TYPE_IMAP) iservice.setLeaveOnServer(account.leave_on_server); + if ("outlook.office365.com".equalsIgnoreCase(account.host)) { + int timeout = prefs.getInt("timeout", EmailService.DEFAULT_CONNECT_TIMEOUT); + iservice.setRestartIdleInterval(timeout * 2 * 6); // 20 x 2 x 6 = 4 min + } + final Date lastStillHere = new Date(0); iservice.setListener(new StoreListener() {