From 17d5bbf768c27ac7782b155e2ab25bcd480f5dcf Mon Sep 17 00:00:00 2001 From: Yu Ping Hu Date: Thu, 4 Apr 2013 18:30:39 -0700 Subject: [PATCH] Improve mailbox sync and load more. - Update syncTime for IMAP and POP whenever we sync. - Change load more to simply include the delta in the RPC rather than using the visibleLimit column. - Add a query to get the message count for a Mailbox. - Refactor code for updating totalCount and determining the new message count when syncing. - Remove dead code from Mailbox. - Remove uses of visibleLimit from code. Note that visibleLimit and messageCount in Mailbox table are no longer useful and will be removed in a later change. Bug: 8579767 Bug: 8523146 Change-Id: Ieb67e3b6f1c82c3b21b972c5a1e557cd75dc21db --- .../emailcommon/provider/EmailContent.java | 2 + .../android/emailcommon/provider/Mailbox.java | 132 ++++++++++-------- .../service/EmailServiceProxy.java | 6 +- .../emailcommon/service/IEmailService.aidl | 3 +- src/com/android/email/mail/Store.java | 1 - .../android/email/mail/store/Pop3Store.java | 2 - .../android/email/provider/EmailProvider.java | 38 +++-- .../email/service/EmailServiceStub.java | 9 +- .../email/service/EmailServiceUtils.java | 4 +- .../android/email/service/ImapService.java | 38 ++--- .../android/email/service/Pop3Service.java | 33 ++--- .../service/PopImapSyncAdapterService.java | 17 ++- .../android/email2/ui/MailActivityEmail.java | 12 -- 13 files changed, 147 insertions(+), 150 deletions(-) diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index d8a9a174d..6fe98142f 100755 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -1609,10 +1609,12 @@ public abstract class EmailContent { // Other states, as a bit field, e.g. CHILDREN_VISIBLE, HAS_CHILDREN public static final String FLAGS = "flags"; // Backward compatible + @Deprecated public static final String VISIBLE_LIMIT = "visibleLimit"; // Sync status (can be used as desired by sync services) public static final String SYNC_STATUS = "syncStatus"; // Number of messages in the mailbox. + @Deprecated public static final String MESSAGE_COUNT = "messageCount"; // The last time a message in this mailbox has been read (in millis) public static final String LAST_TOUCHED_TIME = "lastTouchedTime"; diff --git a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java index a4d33bb84..ee3a41d02 100644 --- a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java +++ b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java @@ -29,17 +29,18 @@ import android.util.Log; import com.android.emailcommon.Logging; import com.android.emailcommon.R; import com.android.emailcommon.provider.EmailContent.MailboxColumns; -import com.android.emailcommon.provider.EmailContent.SyncColumns; import com.android.emailcommon.utility.Utility; -public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns, Parcelable { +public class Mailbox extends EmailContent implements MailboxColumns, Parcelable { public static final String TABLE_NAME = "Mailbox"; public static Uri CONTENT_URI; + public static Uri MESSAGE_COUNT_URI; public static Uri FROM_ACCOUNT_AND_TYPE_URI; public static void initMailbox() { CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/mailbox"); + MESSAGE_COUNT_URI = Uri.parse(EmailContent.CONTENT_URI + "/mailboxCount"); FROM_ACCOUNT_AND_TYPE_URI = Uri.parse(EmailContent.CONTENT_URI + "/mailboxIdFromAccountAndType"); } @@ -57,7 +58,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns public long mSyncTime; public boolean mFlagVisible = true; public int mFlags; - public int mVisibleLimit; public String mSyncStatus; public long mLastTouchedTime; public int mUiSyncStatus; @@ -78,14 +78,13 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns public static final int CONTENT_SYNC_TIME_COLUMN = 10; public static final int CONTENT_FLAG_VISIBLE_COLUMN = 11; public static final int CONTENT_FLAGS_COLUMN = 12; - public static final int CONTENT_VISIBLE_LIMIT_COLUMN = 13; - public static final int CONTENT_SYNC_STATUS_COLUMN = 14; - public static final int CONTENT_PARENT_KEY_COLUMN = 15; - public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 16; - public static final int CONTENT_UI_SYNC_STATUS_COLUMN = 17; - public static final int CONTENT_UI_LAST_SYNC_RESULT_COLUMN = 18; - public static final int CONTENT_TOTAL_COUNT_COLUMN = 19; - public static final int CONTENT_HIERARCHICAL_NAME_COLUMN = 20; + public static final int CONTENT_SYNC_STATUS_COLUMN = 13; + public static final int CONTENT_PARENT_KEY_COLUMN = 14; + public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 15; + public static final int CONTENT_UI_SYNC_STATUS_COLUMN = 16; + public static final int CONTENT_UI_LAST_SYNC_RESULT_COLUMN = 17; + public static final int CONTENT_TOTAL_COUNT_COLUMN = 18; + public static final int CONTENT_HIERARCHICAL_NAME_COLUMN = 19; /** * NOTE: If fields are added or removed, the method {@link #getHashes()} @@ -95,31 +94,17 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns RECORD_ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.SERVER_ID, MailboxColumns.PARENT_SERVER_ID, MailboxColumns.ACCOUNT_KEY, MailboxColumns.TYPE, MailboxColumns.DELIMITER, MailboxColumns.SYNC_KEY, MailboxColumns.SYNC_LOOKBACK, - MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_TIME, - MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS, MailboxColumns.VISIBLE_LIMIT, - MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY, MailboxColumns.LAST_TOUCHED_TIME, - MailboxColumns.UI_SYNC_STATUS, MailboxColumns.UI_LAST_SYNC_RESULT, - MailboxColumns.TOTAL_COUNT, MailboxColumns.HIERARCHICAL_NAME + MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_TIME, MailboxColumns.FLAG_VISIBLE, + MailboxColumns.FLAGS, MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY, + MailboxColumns.LAST_TOUCHED_TIME, MailboxColumns.UI_SYNC_STATUS, + MailboxColumns.UI_LAST_SYNC_RESULT, MailboxColumns.TOTAL_COUNT, + MailboxColumns.HIERARCHICAL_NAME }; - private static final String ACCOUNT_AND_MAILBOX_TYPE_SELECTION = - MailboxColumns.ACCOUNT_KEY + " =? AND " + - MailboxColumns.TYPE + " =?"; - private static final String MAILBOX_TYPE_SELECTION = - MailboxColumns.TYPE + " =?"; /** Selection by server pathname for a given account */ public static final String PATH_AND_ACCOUNT_SELECTION = MailboxColumns.SERVER_ID + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?"; - private static final String[] MAILBOX_SUM_OF_UNREAD_COUNT_PROJECTION = new String [] { - "sum(" + MailboxColumns.UNREAD_COUNT + ")" - }; - private static final int UNREAD_COUNT_COUNT_COLUMN = 0; - private static final String[] MAILBOX_SUM_OF_MESSAGE_COUNT_PROJECTION = new String [] { - "sum(" + MailboxColumns.MESSAGE_COUNT + ")" - }; - private static final int MESSAGE_COUNT_COUNT_COLUMN = 0; - private static final String[] MAILBOX_TYPE_PROJECTION = new String [] { MailboxColumns.TYPE }; @@ -228,6 +213,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns public static final long QUERY_ALL_DRAFTS = -5; public static final long QUERY_ALL_OUTBOX = -6; + /** + * Specifies how many messages will be shown in a folder when it is first synced. + */ + public static final int FIRST_SYNC_MESSAGE_COUNT = 25; + public Mailbox() { mBaseUri = CONTENT_URI; } @@ -380,7 +370,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns mSyncTime = cursor.getLong(CONTENT_SYNC_TIME_COLUMN); mFlagVisible = cursor.getInt(CONTENT_FLAG_VISIBLE_COLUMN) == 1; mFlags = cursor.getInt(CONTENT_FLAGS_COLUMN); - mVisibleLimit = cursor.getInt(CONTENT_VISIBLE_LIMIT_COLUMN); mSyncStatus = cursor.getString(CONTENT_SYNC_STATUS_COLUMN); mLastTouchedTime = cursor.getLong(CONTENT_LAST_TOUCHED_TIME_COLUMN); mUiSyncStatus = cursor.getInt(CONTENT_UI_SYNC_STATUS_COLUMN); @@ -405,7 +394,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns values.put(MailboxColumns.SYNC_TIME, mSyncTime); values.put(MailboxColumns.FLAG_VISIBLE, mFlagVisible); values.put(MailboxColumns.FLAGS, mFlags); - values.put(MailboxColumns.VISIBLE_LIMIT, mVisibleLimit); values.put(MailboxColumns.SYNC_STATUS, mSyncStatus); values.put(MailboxColumns.LAST_TOUCHED_TIME, mLastTouchedTime); values.put(MailboxColumns.UI_SYNC_STATUS, mUiSyncStatus); @@ -415,6 +403,44 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns return values; } + /** + * During sync, updates the remote message count, and determine how many messages to sync down + * for this mailbox. + * @param c + * @param remoteMessageCount the current message count on the server; this might be different + * from this object's current message count (in which case it will be written back to the db). + * @param deltaMessageCount the minimum number of additional messages to sync for this request. + * @return + */ + public int handleCountsForSync(Context c, final int remoteMessageCount, + final int deltaMessageCount) { + // Write the remote message count to the DB if necessary. + if (remoteMessageCount != mTotalCount) { + ContentValues values = new ContentValues(); + values.put(MailboxColumns.TOTAL_COUNT, remoteMessageCount); + update(c, values); + } + + // TODO: The value computed below is not quite right if the messages we have are not + // actually a subset of the server side messages, but it's close enough? + + final int currentMessageCount = getMailboxMessageCount(c, mId); + + // Determine how many "new" messages we have. If we've never synced before, then use a + // default value, otherwise it's the actual change in remote count. + final int newMessageCount; + if (mSyncTime == 0) { + newMessageCount = FIRST_SYNC_MESSAGE_COUNT; + } else { + newMessageCount = Math.max(0, remoteMessageCount - mTotalCount); + } + + // Determine the desired number of messages to sync. + final int messageCount = currentMessageCount + Math.max(newMessageCount, deltaMessageCount); + // Limit to [0, remoteMessageCount]. + return Math.min(Math.max(0, messageCount), remoteMessageCount); + } + /** * Convenience method to return the id of a given type of Mailbox for a given Account; the * common Mailbox types (Inbox, Outbox, Sent, Drafts, Trash, and Search) are all cached by @@ -461,29 +487,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns return null; } - public static int getUnreadCountByAccountAndMailboxType(Context context, long accountId, - int type) { - return Utility.getFirstRowInt(context, Mailbox.CONTENT_URI, - MAILBOX_SUM_OF_UNREAD_COUNT_PROJECTION, - ACCOUNT_AND_MAILBOX_TYPE_SELECTION, - new String[] { String.valueOf(accountId), String.valueOf(type) }, - null, UNREAD_COUNT_COUNT_COLUMN, 0); - } - - public static int getUnreadCountByMailboxType(Context context, int type) { - return Utility.getFirstRowInt(context, Mailbox.CONTENT_URI, - MAILBOX_SUM_OF_UNREAD_COUNT_PROJECTION, - MAILBOX_TYPE_SELECTION, - new String[] { String.valueOf(type) }, null, UNREAD_COUNT_COUNT_COLUMN, 0); - } - - public static int getMessageCountByMailboxType(Context context, int type) { - return Utility.getFirstRowInt(context, Mailbox.CONTENT_URI, - MAILBOX_SUM_OF_MESSAGE_COUNT_PROJECTION, - MAILBOX_TYPE_SELECTION, - new String[] { String.valueOf(type) }, null, MESSAGE_COUNT_COUNT_COLUMN, 0); - } - /** * Return the mailbox for a message with a given id * @param context the caller's context @@ -517,6 +520,21 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns null, null, null, MAILBOX_DISPLAY_NAME_COLUMN); } + public static int getMailboxMessageCount(Context c, long mailboxId) { + Cursor cursor = c.getContentResolver().query( + ContentUris.withAppendedId(MESSAGE_COUNT_URI, mailboxId), null, null, null, null); + if (cursor != null) { + try { + if (cursor.moveToFirst()) { + return cursor.getInt(0); + } + } finally { + cursor.close(); + } + } + return 0; + } + /** * @param mailboxId ID of a mailbox. This method accepts magic mailbox IDs, such as * {@link #QUERY_ALL_INBOXES}. (They're all non-refreshable.) @@ -589,8 +607,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns = mFlagVisible; hash[CONTENT_FLAGS_COLUMN] = mFlags; - hash[CONTENT_VISIBLE_LIMIT_COLUMN] - = mVisibleLimit; hash[CONTENT_SYNC_STATUS_COLUMN] = mSyncStatus; hash[CONTENT_PARENT_KEY_COLUMN] @@ -632,7 +648,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns dest.writeLong(mSyncTime); dest.writeInt(mFlagVisible ? 1 : 0); dest.writeInt(mFlags); - dest.writeInt(mVisibleLimit); dest.writeString(mSyncStatus); dest.writeLong(mLastTouchedTime); dest.writeInt(mUiSyncStatus); @@ -657,7 +672,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns mSyncTime = in.readLong(); mFlagVisible = in.readInt() == 1; mFlags = in.readInt(); - mVisibleLimit = in.readInt(); mSyncStatus = in.readString(); mLastTouchedTime = in.readLong(); mUiSyncStatus = in.readInt(); diff --git a/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java b/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java index c7c77b897..208904262 100644 --- a/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java +++ b/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java @@ -163,14 +163,16 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService { * * @param mailboxId the id of the mailbox record * @param userRequest whether or not the user specifically asked for the sync + * @param deltaMessageCount amount by which to change the number of messages synced. */ @Override - public void startSync(final long mailboxId, final boolean userRequest) throws RemoteException { + public void startSync(final long mailboxId, final boolean userRequest, + final int deltaMessageCount) throws RemoteException { setTask(new ProxyTask() { @Override public void run() throws RemoteException { if (mCallback != null) mService.setCallback(mCallback); - mService.startSync(mailboxId, userRequest); + mService.startSync(mailboxId, userRequest, deltaMessageCount); } }, "startSync"); } diff --git a/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl b/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl index 43c52eae7..3595f64c3 100644 --- a/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl +++ b/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl @@ -26,9 +26,10 @@ import android.os.Bundle; interface IEmailService { Bundle validate(in HostAuth hostauth); - oneway void startSync(long mailboxId, boolean userRequest); + oneway void startSync(long mailboxId, boolean userRequest, int deltaMessageCount); oneway void stopSync(long mailboxId); + // TODO: loadMore appears to be unused; if so, delete it. oneway void loadMore(long messageId); oneway void loadAttachment(long attachmentId, boolean background); diff --git a/src/com/android/email/mail/Store.java b/src/com/android/email/mail/Store.java index f23325745..c3ea23d3c 100644 --- a/src/com/android/email/mail/Store.java +++ b/src/com/android/email/mail/Store.java @@ -198,6 +198,5 @@ public abstract class Store { //mailbox.mSyncTime; mailbox.mType = type; //box.mUnreadCount; - mailbox.mVisibleLimit = MailActivityEmail.VISIBLE_LIMIT_DEFAULT; } } diff --git a/src/com/android/email/mail/store/Pop3Store.java b/src/com/android/email/mail/store/Pop3Store.java index fe24c92dc..cee369b1b 100644 --- a/src/com/android/email/mail/store/Pop3Store.java +++ b/src/com/android/email/mail/store/Pop3Store.java @@ -110,8 +110,6 @@ public class Pop3Store extends Store { if (mailbox == null) { mailbox = Mailbox.newSystemMailbox(mContext, mAccount.mId, Mailbox.TYPE_INBOX); } - // TODO: Mailbox.newSystemMailbox should be aware of these default values for inbox? - mailbox.mVisibleLimit = MailActivityEmail.VISIBLE_LIMIT_DEFAULT; if (mailbox.isSaved()) { mailbox.update(mContext, mailbox.toContentValues()); } else { diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java index da94e1085..4498aa8a7 100644 --- a/src/com/android/email/provider/EmailProvider.java +++ b/src/com/android/email/provider/EmailProvider.java @@ -192,6 +192,7 @@ public class EmailProvider extends ContentProvider { private static final int MAILBOX_ID_FROM_ACCOUNT_AND_TYPE = MAILBOX_BASE + 2; private static final int MAILBOX_NOTIFICATION = MAILBOX_BASE + 3; private static final int MAILBOX_MOST_RECENT_MESSAGE = MAILBOX_BASE + 4; + private static final int MAILBOX_MESSAGE_COUNT = MAILBOX_BASE + 5; private static final int MESSAGE_BASE = 0x2000; private static final int MESSAGE = MESSAGE_BASE; @@ -1086,6 +1087,7 @@ public class EmailProvider extends ContentProvider { MAILBOX_NOTIFICATION); matcher.addURI(EmailContent.AUTHORITY, "mailboxMostRecentMessage/#", MAILBOX_MOST_RECENT_MESSAGE); + matcher.addURI(EmailContent.AUTHORITY, "mailboxCount/#", MAILBOX_MESSAGE_COUNT); // All messages matcher.addURI(EmailContent.AUTHORITY, "message", MESSAGE); @@ -1303,7 +1305,7 @@ public class EmailProvider extends ContentProvider { c = uiFolderLoadMore(uri); return c; case UI_FOLDER_REFRESH: - c = uiFolderRefresh(uri); + c = uiFolderRefresh(uri, 0); return c; case MAILBOX_NOTIFICATION: c = notificationQuery(uri); @@ -1311,6 +1313,9 @@ public class EmailProvider extends ContentProvider { case MAILBOX_MOST_RECENT_MESSAGE: c = mostRecentMessageQuery(uri); return c; + case MAILBOX_MESSAGE_COUNT: + c = getMailboxMessageCount(uri); + return c; case ACCOUNT_DEFAULT_ID: // Start with a snapshot of the cache Map accountCache = mCacheAccount.getSnapshot(); @@ -2064,7 +2069,14 @@ outer: String mailboxId = uri.getLastPathSegment(); return db.rawQuery("select max(_id) from Message where mailboxKey=?", new String[] {mailboxId}); - } + } + + private Cursor getMailboxMessageCount(Uri uri) { + SQLiteDatabase db = getDatabase(getContext()); + String mailboxId = uri.getLastPathSegment(); + return db.rawQuery("select count(*) from Message where mailboxKey=?", + new String[] {mailboxId}); + } /** * Support for UnifiedEmail below @@ -3755,7 +3767,7 @@ outer: final EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context, mServiceCallback, mailbox.mAccountKey); try { - service.startSync(mailbox.mId, true); + service.startSync(mailbox.mId, true, 0); } catch (RemoteException e) { } final long originalMsgId = msg.mSourceKey; @@ -4342,7 +4354,7 @@ outer: } }; - private Cursor uiFolderRefresh(Uri uri) { + private Cursor uiFolderRefresh(Uri uri, int deltaMessageCount) { Context context = getContext(); String idString = uri.getLastPathSegment(); long id = Long.parseLong(idString); @@ -4351,7 +4363,7 @@ outer: EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context, mServiceCallback, mailbox.mAccountKey); try { - service.startSync(id, true); + service.startSync(id, true, deltaMessageCount); } catch (RemoteException e) { } return null; @@ -4373,21 +4385,7 @@ outer: mSearchParams.mOffset += SEARCH_MORE_INCREMENT; runSearchQuery(context, mailbox.mAccountKey, id); } else { - // Compute the new visibleLimit for this mailbox. - int newLimit = mailbox.mVisibleLimit + VISIBLE_LIMIT_INCREMENT; - if (newLimit > mailbox.mTotalCount) { - newLimit = mailbox.mTotalCount; - } - // Only do something if the limit is changing. - if (newLimit != mailbox.mVisibleLimit) { - // Save the new limit to the db. - ContentValues values = new ContentValues(); - values.put(MailboxColumns.VISIBLE_LIMIT, newLimit); - context.getContentResolver().update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, - id), values, null, null); - // And order a refresh - uiFolderRefresh(uri); - } + uiFolderRefresh(uri, VISIBLE_LIMIT_INCREMENT); } return null; } diff --git a/src/com/android/email/service/EmailServiceStub.java b/src/com/android/email/service/EmailServiceStub.java index 79eeeb33a..950c890e1 100644 --- a/src/com/android/email/service/EmailServiceStub.java +++ b/src/com/android/email/service/EmailServiceStub.java @@ -79,6 +79,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm private static final int MAILBOX_COLUMN_TYPE = 2; public static final String SYNC_EXTRA_MAILBOX_ID = "__mailboxId__"; + public static final String SYNC_EXTRA_DELTA_MESSAGE_COUNT = "__deltaMessageCount__"; /** System folders that should always exist. */ private final int[] DEFAULT_FOLDERS = { @@ -111,7 +112,8 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm } @Override - public void startSync(long mailboxId, boolean userRequest) throws RemoteException { + public void startSync(long mailboxId, boolean userRequest, int deltaMessageCount) + throws RemoteException { Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mailboxId); if (mailbox == null) return; Account account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey); @@ -126,6 +128,9 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); } extras.putLong(SYNC_EXTRA_MAILBOX_ID, mailboxId); + if (deltaMessageCount != 0) { + extras.putInt(SYNC_EXTRA_DELTA_MESSAGE_COUNT, deltaMessageCount); + } ContentResolver.requestSync(acct, EmailContent.AUTHORITY, extras); } @@ -420,7 +425,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm } // If we just created the inbox, sync it if (inboxId != -1) { - startSync(inboxId, true); + startSync(inboxId, true, 0); } } } diff --git a/src/com/android/email/service/EmailServiceUtils.java b/src/com/android/email/service/EmailServiceUtils.java index cb64286ce..4dabefc94 100644 --- a/src/com/android/email/service/EmailServiceUtils.java +++ b/src/com/android/email/service/EmailServiceUtils.java @@ -58,7 +58,6 @@ import com.android.emailcommon.service.IEmailServiceCallback; import com.android.emailcommon.service.SearchParams; import com.android.emailcommon.service.SyncWindow; -import com.android.mail.utils.LogUtils; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.xmlpull.v1.XmlPullParserException; @@ -597,7 +596,8 @@ public class EmailServiceUtils { } @Override - public void startSync(long mailboxId, boolean userRequest) throws RemoteException { + public void startSync(long mailboxId, boolean userRequest, int deltaMessageCount) + throws RemoteException { } @Override diff --git a/src/com/android/email/service/ImapService.java b/src/com/android/email/service/ImapService.java index 998fc1e59..b2d2733e3 100644 --- a/src/com/android/email/service/ImapService.java +++ b/src/com/android/email/service/ImapService.java @@ -165,10 +165,11 @@ public class ImapService extends Service { * TODO this should use ID's instead of fully-restored objects * @param account * @param folder + * @param deltaMessageCount requested change in number of messages to sync * @throws MessagingException */ public static void synchronizeMailboxSynchronous(Context context, final Account account, - final Mailbox folder) throws MessagingException { + final Mailbox folder, final int deltaMessageCount) throws MessagingException { sendMailboxStatus(folder, EmailServiceStatus.IN_PROGRESS); TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account)); @@ -178,7 +179,7 @@ public class ImapService extends Service { NotificationController nc = NotificationController.getInstance(context); try { processPendingActionsSynchronous(context, account); - synchronizeMailboxGeneric(context, account, folder); + synchronizeMailboxGeneric(context, account, folder, deltaMessageCount); // Clear authentication notification for this account nc.cancelLoginFailedNotification(account.mId); sendMailboxStatus(folder, EmailServiceStatus.SUCCESS); @@ -335,12 +336,12 @@ public class ImapService extends Service { * * @param account the account to sync * @param mailbox the mailbox to sync + * @param deltaMessageCount requested change in number of messages to sync * @return results of the sync pass * @throws MessagingException */ - private static void synchronizeMailboxGeneric(final Context context, - final Account account, final Mailbox mailbox) throws MessagingException { - + private static void synchronizeMailboxGeneric(final Context context, final Account account, + final Mailbox mailbox, final int deltaMessageCount) throws MessagingException { /* * A list of IDs for messages that were downloaded and did not have the seen flag set. * This serves as the "true" new message count reported to the user via notification. @@ -414,25 +415,12 @@ public class ImapService extends Service { // 4. Trash any remote messages that are marked as trashed locally. // TODO - this comment was here, but no code was here. - ContentValues values = new ContentValues(); + // 5. Get the number of messages on the server. + final int remoteMessageCount = remoteFolder.getMessageCount(); - // 5. Get the remote message count. - int remoteMessageCount = remoteFolder.getMessageCount(); - values.put(MailboxColumns.TOTAL_COUNT, remoteMessageCount); - - // 6. Determine the limit # of messages to download - int visibleLimit = mailbox.mVisibleLimit; - if (visibleLimit <= 0) { - visibleLimit = MailActivityEmail.VISIBLE_LIMIT_DEFAULT; - } - if (visibleLimit > remoteMessageCount) { - visibleLimit = remoteMessageCount; - } - if (visibleLimit != mailbox.mVisibleLimit) { - values.put(MailboxColumns.VISIBLE_LIMIT, visibleLimit); - } - - mailbox.update(context, values); + // 6. Update the total count and determine new message count to sync. + final int messageCount = mailbox.handleCountsForSync(context, remoteMessageCount, + deltaMessageCount); // 7. Create a list of messages to download Message[] remoteMessages = new Message[0]; @@ -443,7 +431,7 @@ public class ImapService extends Service { /* * Message numbers start at 1. */ - int remoteStart = Math.max(0, remoteMessageCount - visibleLimit) + 1; + int remoteStart = Math.max(0, remoteMessageCount - messageCount) + 1; int remoteEnd = remoteMessageCount; remoteMessages = remoteFolder.getMessages(remoteStart, remoteEnd, null); // TODO Why are we running through the list twice? Combine w/ for loop below @@ -616,7 +604,7 @@ public class ImapService extends Service { protocolSearchInfo.equals(mLastSearchServerId)) { return mLastSearchRemoteMailbox; } - Cursor c = context.getContentResolver().query(Mailbox.CONTENT_URI, + Cursor c = context.getContentResolver().query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION, Mailbox.PATH_AND_ACCOUNT_SELECTION, new String[] {protocolSearchInfo, Long.toString(accountKey)}, null); diff --git a/src/com/android/email/service/Pop3Service.java b/src/com/android/email/service/Pop3Service.java index 600694445..1f2cfdedd 100644 --- a/src/com/android/email/service/Pop3Service.java +++ b/src/com/android/email/service/Pop3Service.java @@ -103,7 +103,7 @@ public class Pop3Service extends Service { long inboxId = Mailbox.findMailboxOfType(mContext, att.mAccountKey, Mailbox.TYPE_INBOX); if (inboxId == Mailbox.NO_MAILBOX) return; // We load attachments during a sync - startSync(inboxId, true); + startSync(inboxId, true, 0); } @Override @@ -129,10 +129,11 @@ public class Pop3Service extends Service { * * @param account * @param folder + * @param deltaMessageCount the requested change in number of messages to sync. * @throws MessagingException */ public static void synchronizeMailboxSynchronous(Context context, final Account account, - final Mailbox folder) throws MessagingException { + final Mailbox folder, final int deltaMessageCount) throws MessagingException { sendMailboxStatus(folder, EmailServiceStatus.IN_PROGRESS); TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account)); @@ -141,7 +142,7 @@ public class Pop3Service extends Service { } NotificationController nc = NotificationController.getInstance(context); try { - synchronizePop3Mailbox(context, account, folder); + synchronizePop3Mailbox(context, account, folder, deltaMessageCount); // Clear authentication notification for this account nc.cancelLoginFailedNotification(account.mId); sendMailboxStatus(folder, EmailServiceStatus.SUCCESS); @@ -243,10 +244,11 @@ public class Pop3Service extends Service { * * @param account the account to sync * @param mailbox the mailbox to sync + * @param deltaMessageCount the requested change to number of messages to sync * @throws MessagingException */ - private static void synchronizePop3Mailbox(final Context context, - final Account account, final Mailbox mailbox) throws MessagingException { + private static void synchronizePop3Mailbox(final Context context, final Account account, + final Mailbox mailbox, final int deltaMessageCount) throws MessagingException { // TODO Break this into smaller pieces ContentResolver resolver = context.getContentResolver(); @@ -293,12 +295,6 @@ public class Pop3Service extends Service { // count. remoteFolder.open(OpenMode.READ_WRITE); - // Get the remote message count. - int remoteMessageCount = remoteFolder.getMessageCount(); - ContentValues values = new ContentValues(); - values.put(MailboxColumns.TOTAL_COUNT, remoteMessageCount); - mailbox.update(context, values); - String[] accountIdArgs = new String[] { Long.toString(account.mId) }; long trashMailboxId = Mailbox.findMailboxOfType(context, account.mId, Mailbox.TYPE_TRASH); Cursor updates = resolver.query( @@ -328,11 +324,12 @@ public class Pop3Service extends Service { updates.close(); } - // Determine the limit # of messages to download - int visibleLimit = mailbox.mVisibleLimit; - if (visibleLimit <= 0) { - visibleLimit = MailActivityEmail.VISIBLE_LIMIT_DEFAULT; - } + // Get the remote message count. + final int remoteMessageCount = remoteFolder.getMessageCount(); + + // Update the total count and determine new message count to sync. + final int messageCount = mailbox.handleCountsForSync(context, remoteMessageCount, + deltaMessageCount); // Create a list of messages to download Pop3Message[] remoteMessages = new Pop3Message[0]; @@ -343,7 +340,7 @@ public class Pop3Service extends Service { /* * Message numbers start at 1. */ - remoteMessages = remoteFolder.getMessages(remoteMessageCount, visibleLimit); + remoteMessages = remoteFolder.getMessages(remoteMessageCount, messageCount); /* * Get a list of the messages that are in the remote list but not on @@ -378,7 +375,7 @@ public class Pop3Service extends Service { AttachmentColumns.UI_STATE + "=" + AttachmentState.DOWNLOADING, new String[] {Long.toString(account.mId)}, null); try { - values.clear(); + final ContentValues values = new ContentValues(); while (c.moveToNext()) { values.put(AttachmentColumns.UI_STATE, UIProvider.AttachmentState.SAVED); Attachment att = new Attachment(); diff --git a/src/com/android/email/service/PopImapSyncAdapterService.java b/src/com/android/email/service/PopImapSyncAdapterService.java index 2677c849b..d266f7b6d 100644 --- a/src/com/android/email/service/PopImapSyncAdapterService.java +++ b/src/com/android/email/service/PopImapSyncAdapterService.java @@ -109,7 +109,7 @@ public class PopImapSyncAdapterService extends Service { } private static void sync(Context context, long mailboxId, SyncResult syncResult, - boolean uiRefresh) { + boolean uiRefresh, int deltaMessageCount) { TempDirectory.setTempDirectory(context); Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId); if (mailbox == null) return; @@ -139,9 +139,11 @@ public class PopImapSyncAdapterService extends Service { if (mailbox.mType == Mailbox.TYPE_OUTBOX) { EmailServiceStub.sendMailImpl(context, account.mId); } else if (protocol.equals(legacyImapProtocol)) { - ImapService.synchronizeMailboxSynchronous(context, account, mailbox); + ImapService.synchronizeMailboxSynchronous(context, account, mailbox, + deltaMessageCount); } else { - Pop3Service.synchronizeMailboxSynchronous(context, account, mailbox); + Pop3Service.synchronizeMailboxSynchronous(context, account, mailbox, + deltaMessageCount); } } catch (MessagingException e) { int cause = e.getExceptionType(); @@ -155,8 +157,9 @@ public class PopImapSyncAdapterService extends Service { } } } finally { - // Always clear our sync state + // Always clear our sync state and update sync time. values.put(Mailbox.UI_SYNC_STATUS, EmailContent.SYNC_STATUS_NONE); + values.put(Mailbox.SYNC_TIME, System.currentTimeMillis()); resolver.update(mailboxUri, values, null, null); } } @@ -200,7 +203,7 @@ public class PopImapSyncAdapterService extends Service { } } for (long mailboxId: mailboxesToUpdate) { - sync(context, mailboxId, syncResult, false); + sync(context, mailboxId, syncResult, false, 0); } } else { Log.d(TAG, "Sync request for " + acct.mDisplayName); @@ -222,7 +225,9 @@ public class PopImapSyncAdapterService extends Service { if (mailboxId == Mailbox.NO_MAILBOX) return; boolean uiRefresh = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); - sync(context, mailboxId, syncResult, uiRefresh); + int deltaMessageCount = + extras.getInt(EmailServiceStub.SYNC_EXTRA_DELTA_MESSAGE_COUNT, 0); + sync(context, mailboxId, syncResult, uiRefresh, deltaMessageCount); // Outbox is a special case here Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId); diff --git a/src/com/android/email2/ui/MailActivityEmail.java b/src/com/android/email2/ui/MailActivityEmail.java index 36aaefdfd..1a259d1c9 100644 --- a/src/com/android/email2/ui/MailActivityEmail.java +++ b/src/com/android/email2/ui/MailActivityEmail.java @@ -78,18 +78,6 @@ public class MailActivityEmail extends com.android.mail.ui.MailActivity { */ public static boolean sDebugInhibitGraphicsAcceleration = false; - /** - * Specifies how many messages will be shown in a folder by default. This number is set - * on each new folder and can be incremented with "Load more messages..." by the - * VISIBLE_LIMIT_INCREMENT - */ - public static final int VISIBLE_LIMIT_DEFAULT = 25; - - /** - * Number of additional messages to load when a user selects "Load more messages..." - */ - public static final int VISIBLE_LIMIT_INCREMENT = 25; - /** * This is used to force stacked UI to return to the "welcome" screen any time we change * the accounts list (e.g. deleting accounts in the Account Manager preferences.)