summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2015-04-04 20:42:30 +0200
committerJorge Ruesga <jorge@ruesga.com>2015-04-05 02:12:05 +0200
commit65e3d0520abbf8dc7da1104e0581ae324407dbf2 (patch)
tree53b4c0550914422a6370b7f7a8d1aa88dcd72ebe
parent8a8470083e8bd70539a194832cc44c6b3d503fef (diff)
downloadandroid_packages_apps_Email-65e3d0520abbf8dc7da1104e0581ae324407dbf2.tar.gz
android_packages_apps_Email-65e3d0520abbf8dc7da1104e0581ae324407dbf2.tar.bz2
android_packages_apps_Email-65e3d0520abbf8dc7da1104e0581ae324407dbf2.zip
email: support for auto-sync multiple IMAP folders
This enables to auto-sync multiple IMAP folders, not only Inbox. Default to Inbox only. This changes relays in the syncloopback attribute to configure the folders to add to sync process. Change-Id: I8973cfd6ddec33446256bc8b48418558e27596b5 Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r--emailcommon/src/com/android/emailcommon/provider/Mailbox.java17
-rw-r--r--emailcommon/src/com/android/emailcommon/service/SyncWindow.java2
-rw-r--r--provider_src/com/android/email/provider/DBHelper.java25
-rwxr-xr-xprovider_src/com/android/email/service/EmailServiceStub.java5
-rw-r--r--provider_src/com/android/email/service/ImapService.java39
-rw-r--r--provider_src/com/android/email/service/PopImapSyncAdapterService.java72
-rw-r--r--res/xml/services.xml2
7 files changed, 111 insertions, 51 deletions
diff --git a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java
index 952a73147..c726b94c3 100644
--- a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java
+++ b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java
@@ -299,6 +299,10 @@ public class Mailbox extends EmailContent implements EmailContent.MailboxColumns
MailboxColumns.SYNC_INTERVAL + "=1 and " + MailboxColumns.TYPE + "=? and " +
MailboxColumns.ACCOUNT_KEY + "=?";
+ /** Selection for mailboxes that are configured for sync for an account. */
+ private static final String SYNCING_MAILBOXES_FOR_ACCOUNT_SELECTION =
+ MailboxColumns.SYNC_INTERVAL + "=1 and " + MailboxColumns.ACCOUNT_KEY + "=?";
+
// Types of mailboxes. The list is ordered to match a typical UI presentation, e.g.
// placing the inbox at the top.
// Arrays of "special_mailbox_display_names" and "special_mailbox_icons" are depends on
@@ -911,6 +915,19 @@ public class Mailbox extends EmailContent implements EmailContent.MailboxColumns
}
/**
+ * Get the mailbox ids for an account that are configured for sync by the user.
+ * @param cr The {@link ContentResolver}.
+ * @param accountId The id for the account that is syncing.
+ * @return A cursor (with one column, containing ids) with all mailbox ids that match.
+ */
+ public static Cursor getLoopBackMailboxIdsForSync(final ContentResolver cr,
+ final long accountId) {
+ return cr.query(Mailbox.CONTENT_URI, Mailbox.ID_PROJECTION,
+ SYNCING_MAILBOXES_FOR_ACCOUNT_SELECTION,
+ new String[] {Long.toString(accountId) }, null);
+ }
+
+ /**
* Get the account id for a mailbox.
* @param context The {@link Context}.
* @param mailboxId The id of the mailbox we're interested in, as a {@link String}.
diff --git a/emailcommon/src/com/android/emailcommon/service/SyncWindow.java b/emailcommon/src/com/android/emailcommon/service/SyncWindow.java
index 8dfe4ad2e..af1edea7d 100644
--- a/emailcommon/src/com/android/emailcommon/service/SyncWindow.java
+++ b/emailcommon/src/com/android/emailcommon/service/SyncWindow.java
@@ -42,7 +42,7 @@ public class SyncWindow {
return 365*10;
case SYNC_WINDOW_ACCOUNT:
default:
- return 14;
+ return 7;
}
}
}
diff --git a/provider_src/com/android/email/provider/DBHelper.java b/provider_src/com/android/email/provider/DBHelper.java
index 63262a5ec..b5255ac2b 100644
--- a/provider_src/com/android/email/provider/DBHelper.java
+++ b/provider_src/com/android/email/provider/DBHelper.java
@@ -186,7 +186,8 @@ public final class DBHelper {
// Version 126: Decode address lists for To, From, Cc, Bcc and Reply-To columns in Message.
// Version 127: Force mFlags to contain the correct flags for EAS accounts given a protocol
// version above 12.0
- public static final int DATABASE_VERSION = 128;
+ // Version 129: Update all IMAP INBOX mailboxes to force synchronization
+ public static final int DATABASE_VERSION = 129;
// Any changes to the database format *must* include update-in-place code.
// Original version: 2
@@ -1538,6 +1539,28 @@ public final class DBHelper {
LogUtils.w(TAG, "Exception upgrading EmailProvider.db from v127 to v128", e);
}
}
+
+ // This statement changes the syncInterval column to 1 for all IMAP INBOX mailboxes.
+ // It does this by matching mailboxes against all account IDs whose receive auth is
+ // either R.string.protocol_legacy_imap, R.string.protocol_imap or "imap"
+ // It needed in order to mark
+ // We do it here to avoid the minor collisions with aosp main db
+ if (oldVersion <= 129) {
+ db.execSQL("update " + Mailbox.TABLE_NAME + " set "
+ + MailboxColumns.SYNC_INTERVAL + "= 1 where "
+ + MailboxColumns.TYPE + "= " + Mailbox.TYPE_INBOX + " and "
+ + MailboxColumns.ACCOUNT_KEY + " in (select "
+ + Account.TABLE_NAME + "." + AccountColumns._ID + " from "
+ + Account.TABLE_NAME + " join " + HostAuth.TABLE_NAME + " where "
+ + HostAuth.TABLE_NAME + "." + HostAuthColumns._ID + "="
+ + Account.TABLE_NAME + "." + AccountColumns.HOST_AUTH_KEY_RECV
+ + " and (" + HostAuth.TABLE_NAME + "."
+ + HostAuthColumns.PROTOCOL + "='"
+ + mContext.getString(R.string.protocol_legacy_imap) + "' or "
+ + HostAuth.TABLE_NAME + "." + HostAuthColumns.PROTOCOL + "='"
+ + mContext.getString(R.string.protocol_imap) + "' or "
+ + HostAuth.TABLE_NAME + "." + HostAuthColumns.PROTOCOL + "='imap'));");
+ }
}
@Override
diff --git a/provider_src/com/android/email/service/EmailServiceStub.java b/provider_src/com/android/email/service/EmailServiceStub.java
index 51779bacc..4044ccb49 100755
--- a/provider_src/com/android/email/service/EmailServiceStub.java
+++ b/provider_src/com/android/email/service/EmailServiceStub.java
@@ -418,6 +418,11 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
mailbox.save(mContext);
if (type == Mailbox.TYPE_INBOX) {
inboxId = mailbox.mId;
+
+ // In a clean start we must mark the Inbox mailbox as syncable. This
+ // is required by the new multiple mailboxes sync. Initially Inbox
+ // should start marked
+ mailbox.mSyncInterval = 1;
}
}
}
diff --git a/provider_src/com/android/email/service/ImapService.java b/provider_src/com/android/email/service/ImapService.java
index a55671fc8..a26572aa8 100644
--- a/provider_src/com/android/email/service/ImapService.java
+++ b/provider_src/com/android/email/service/ImapService.java
@@ -74,7 +74,6 @@ import java.util.List;
public class ImapService extends Service {
// TODO get these from configurations or settings.
private static final long QUICK_SYNC_WINDOW_MILLIS = DateUtils.DAY_IN_MILLIS;
- private static final long FULL_SYNC_WINDOW_MILLIS = 7 * DateUtils.DAY_IN_MILLIS;
private static final long FULL_SYNC_INTERVAL_MILLIS = 4 * DateUtils.HOUR_IN_MILLIS;
private static final String TAG = "ImapService";
@@ -501,38 +500,12 @@ public class ImapService extends Service {
final boolean fullSync = (uiRefresh || loadMore ||
timeSinceLastFullSync >= FULL_SYNC_INTERVAL_MILLIS || timeSinceLastFullSync < 0);
- if (account.mSyncLookback == SyncWindow.SYNC_WINDOW_ALL) {
- // This is really for testing. There is no UI that allows setting the sync window for
- // IMAP, but it can be set by sending a special intent to AccountSetupFinal activity.
- endDate = 0;
- } else if (fullSync) {
- // Find the oldest message in the local store. We need our time window to include
- // all messages that are currently present locally.
- endDate = System.currentTimeMillis() - FULL_SYNC_WINDOW_MILLIS;
- Cursor localOldestCursor = null;
- try {
- // b/11520812 Ignore message with timestamp = 0 (which includes NULL)
- localOldestCursor = resolver.query(EmailContent.Message.CONTENT_URI,
- OldestTimestampInfo.PROJECTION,
- EmailContent.MessageColumns.ACCOUNT_KEY + "=?" + " AND " +
- MessageColumns.MAILBOX_KEY + "=? AND " +
- MessageColumns.TIMESTAMP + "!=0",
- new String[] {String.valueOf(account.mId), String.valueOf(mailbox.mId)},
- null);
- if (localOldestCursor != null && localOldestCursor.moveToFirst()) {
- long oldestLocalMessageDate = localOldestCursor.getLong(
- OldestTimestampInfo.COLUMN_OLDEST_TIMESTAMP);
- if (oldestLocalMessageDate > 0) {
- endDate = Math.min(endDate, oldestLocalMessageDate);
- LogUtils.d(
- Logging.LOG_TAG, "oldest local message " + oldestLocalMessageDate);
- }
- }
- } finally {
- if (localOldestCursor != null) {
- localOldestCursor.close();
- }
- }
+ if (fullSync) {
+ int syncLookBack = mailbox.mSyncLookback == SyncWindow.SYNC_WINDOW_ACCOUNT
+ ? account.mSyncLookback
+ : mailbox.mSyncLookback;
+ endDate = System.currentTimeMillis() -
+ (SyncWindow.toDays(syncLookBack) * DateUtils.DAY_IN_MILLIS);
LogUtils.d(Logging.LOG_TAG, "full sync: original window: now - " + endDate);
} else {
// We are doing a frequent, quick sync. This only syncs a small time window, so that
diff --git a/provider_src/com/android/email/service/PopImapSyncAdapterService.java b/provider_src/com/android/email/service/PopImapSyncAdapterService.java
index 08a6f3adb..432cdd107 100644
--- a/provider_src/com/android/email/service/PopImapSyncAdapterService.java
+++ b/provider_src/com/android/email/service/PopImapSyncAdapterService.java
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.IBinder;
import com.android.email.R;
+import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
import com.android.emailcommon.TempDirectory;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.provider.Account;
@@ -50,6 +51,9 @@ public class PopImapSyncAdapterService extends Service {
private static final String TAG = "PopImapSyncService";
private SyncAdapterImpl mSyncAdapter = null;
+ private static String sPop3Protocol;
+ private static String sLegacyImapProtocol;
+
public PopImapSyncAdapterService() {
super();
}
@@ -82,17 +86,15 @@ public class PopImapSyncAdapterService extends Service {
* @return whether or not this mailbox retrieves its data from the server (as opposed to just
* a local mailbox that is never synced).
*/
- private static boolean loadsFromServer(Context context, Mailbox m, String protocol) {
- String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
- String pop3Protocol = context.getString(R.string.protocol_pop3);
- if (legacyImapProtocol.equals(protocol)) {
+ private static boolean loadsFromServer(Context context, Mailbox m, Account acct) {
+ if (isLegacyImapProtocol(context, acct)) {
// TODO: actually use a sync flag when creating the mailboxes. Right now we use an
// approximation for IMAP.
return m.mType != Mailbox.TYPE_DRAFTS
&& m.mType != Mailbox.TYPE_OUTBOX
&& m.mType != Mailbox.TYPE_SEARCH;
- } else if (pop3Protocol.equals(protocol)) {
+ } else if (isPop3Protocol(context, acct)) {
return Mailbox.TYPE_INBOX == m.mType;
}
@@ -108,9 +110,8 @@ public class PopImapSyncAdapterService extends Service {
Account account = Account.restoreAccountWithId(context, mailbox.mAccountKey);
if (account == null) return;
ContentResolver resolver = context.getContentResolver();
- String protocol = account.getProtocol(context);
if ((mailbox.mType != Mailbox.TYPE_OUTBOX) &&
- !loadsFromServer(context, mailbox, protocol)) {
+ !loadsFromServer(context, mailbox, account)) {
// This is an update to a message in a non-syncing mailbox; delete this from the
// updates table and return
resolver.delete(Message.UPDATED_CONTENT_URI, MessageColumns.MAILBOX_KEY + "=?",
@@ -129,7 +130,6 @@ public class PopImapSyncAdapterService extends Service {
try {
int lastSyncResult;
try {
- String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (mailbox.mType == Mailbox.TYPE_OUTBOX) {
EmailServiceStub.sendMailImpl(context, account.mId);
} else {
@@ -138,7 +138,7 @@ public class PopImapSyncAdapterService extends Service {
EmailServiceStatus.syncMailboxStatus(resolver, extras, mailboxId,
EmailServiceStatus.IN_PROGRESS, 0, lastSyncResult);
final int status;
- if (protocol.equals(legacyImapProtocol)) {
+ if (isLegacyImapProtocol(context, account)) {
status = ImapService.synchronizeMailboxSynchronous(context, account,
mailbox, deltaMessageCount != 0, uiRefresh);
} else {
@@ -240,13 +240,20 @@ public class PopImapSyncAdapterService extends Service {
// Get the id for the mailbox we want to sync.
long [] mailboxIds = Mailbox.getMailboxIdsFromBundle(extras);
if (mailboxIds == null || mailboxIds.length == 0) {
- // No mailbox specified, just sync the inbox.
- // TODO: IMAP may eventually want to allow multiple auto-sync mailboxes.
- final long inboxId = Mailbox.findMailboxOfType(context, acct.mId,
- Mailbox.TYPE_INBOX);
- if (inboxId != Mailbox.NO_MAILBOX) {
- mailboxIds = new long[1];
- mailboxIds[0] = inboxId;
+ EmailServiceInfo info = EmailServiceUtils.getServiceInfo(
+ context, acct.getProtocol(context));
+ // No mailbox specified, check if the protocol support auto-sync
+ // multiple mailboxes. In that case retrieve the mailboxes to sync
+ // from the account settings. Otherwise just sync the inbox.
+ if (info.offerLookback) {
+ mailboxIds = getLoopBackMailboxIdsForSync(context, acct);
+ } else {
+ final long inboxId = Mailbox.findMailboxOfType(context, acct.mId,
+ Mailbox.TYPE_INBOX);
+ if (inboxId != Mailbox.NO_MAILBOX) {
+ mailboxIds = new long[1];
+ mailboxIds[0] = inboxId;
+ }
}
}
@@ -270,4 +277,37 @@ public class PopImapSyncAdapterService extends Service {
}
}
}
+
+ private static boolean isLegacyImapProtocol(Context ctx, Account acct) {
+ if (sLegacyImapProtocol == null) {
+ sLegacyImapProtocol = ctx.getString(R.string.protocol_legacy_imap);
+ }
+ return acct.getProtocol(ctx).equals(sLegacyImapProtocol);
+ }
+
+ private static boolean isPop3Protocol(Context ctx, Account acct) {
+ if (sPop3Protocol == null) {
+ sPop3Protocol = ctx.getString(R.string.protocol_pop3);
+ }
+ return acct.getProtocol(ctx).equals(sPop3Protocol);
+ }
+
+ private static long[] getLoopBackMailboxIdsForSync(Context ctx, Account acct) {
+ final Cursor c = Mailbox.getLoopBackMailboxIdsForSync(ctx.getContentResolver(), acct.mId);
+ if (c == null) {
+ // No mailboxes
+ return null;
+ }
+ long[] mailboxes = new long[c.getCount()];
+ try {
+ int i = 0;
+ while (c.moveToNext()) {
+ mailboxes[i] = c.getLong(Mailbox.CONTENT_ID_COLUMN);
+ i++;
+ }
+ } finally {
+ c.close();
+ }
+ return mailboxes;
+ }
}
diff --git a/res/xml/services.xml b/res/xml/services.xml
index d3e381af2..1bd882306 100644
--- a/res/xml/services.xml
+++ b/res/xml/services.xml
@@ -87,6 +87,8 @@
email:offerOAuth="true"
email:offerLoadMore="true"
email:offerMoveTo="true"
+ email:offerLookback="true"
+ email:defaultLookback="auto"
/>
<emailservice
email:protocol="@string/protocol_eas"