Merge "Improve mailbox sync and load more." into jb-ub-mail-ur9

This commit is contained in:
Yu Ping Hu 2013-04-11 21:18:47 +00:00 committed by Android (Google) Code Review
commit 7dd26feaea
13 changed files with 147 additions and 150 deletions

View File

@ -1609,10 +1609,12 @@ public abstract class EmailContent {
// Other states, as a bit field, e.g. CHILDREN_VISIBLE, HAS_CHILDREN // Other states, as a bit field, e.g. CHILDREN_VISIBLE, HAS_CHILDREN
public static final String FLAGS = "flags"; public static final String FLAGS = "flags";
// Backward compatible // Backward compatible
@Deprecated
public static final String VISIBLE_LIMIT = "visibleLimit"; public static final String VISIBLE_LIMIT = "visibleLimit";
// Sync status (can be used as desired by sync services) // Sync status (can be used as desired by sync services)
public static final String SYNC_STATUS = "syncStatus"; public static final String SYNC_STATUS = "syncStatus";
// Number of messages in the mailbox. // Number of messages in the mailbox.
@Deprecated
public static final String MESSAGE_COUNT = "messageCount"; public static final String MESSAGE_COUNT = "messageCount";
// The last time a message in this mailbox has been read (in millis) // The last time a message in this mailbox has been read (in millis)
public static final String LAST_TOUCHED_TIME = "lastTouchedTime"; public static final String LAST_TOUCHED_TIME = "lastTouchedTime";

View File

@ -29,17 +29,18 @@ import android.util.Log;
import com.android.emailcommon.Logging; import com.android.emailcommon.Logging;
import com.android.emailcommon.R; import com.android.emailcommon.R;
import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.SyncColumns;
import com.android.emailcommon.utility.Utility; 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 final String TABLE_NAME = "Mailbox";
public static Uri CONTENT_URI; public static Uri CONTENT_URI;
public static Uri MESSAGE_COUNT_URI;
public static Uri FROM_ACCOUNT_AND_TYPE_URI; public static Uri FROM_ACCOUNT_AND_TYPE_URI;
public static void initMailbox() { public static void initMailbox() {
CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/mailbox"); 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 + FROM_ACCOUNT_AND_TYPE_URI = Uri.parse(EmailContent.CONTENT_URI +
"/mailboxIdFromAccountAndType"); "/mailboxIdFromAccountAndType");
} }
@ -57,7 +58,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
public long mSyncTime; public long mSyncTime;
public boolean mFlagVisible = true; public boolean mFlagVisible = true;
public int mFlags; public int mFlags;
public int mVisibleLimit;
public String mSyncStatus; public String mSyncStatus;
public long mLastTouchedTime; public long mLastTouchedTime;
public int mUiSyncStatus; 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_SYNC_TIME_COLUMN = 10;
public static final int CONTENT_FLAG_VISIBLE_COLUMN = 11; public static final int CONTENT_FLAG_VISIBLE_COLUMN = 11;
public static final int CONTENT_FLAGS_COLUMN = 12; 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 = 13;
public static final int CONTENT_SYNC_STATUS_COLUMN = 14; public static final int CONTENT_PARENT_KEY_COLUMN = 14;
public static final int CONTENT_PARENT_KEY_COLUMN = 15; public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 15;
public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 16; public static final int CONTENT_UI_SYNC_STATUS_COLUMN = 16;
public static final int CONTENT_UI_SYNC_STATUS_COLUMN = 17; public static final int CONTENT_UI_LAST_SYNC_RESULT_COLUMN = 17;
public static final int CONTENT_UI_LAST_SYNC_RESULT_COLUMN = 18; public static final int CONTENT_TOTAL_COUNT_COLUMN = 18;
public static final int CONTENT_TOTAL_COUNT_COLUMN = 19; public static final int CONTENT_HIERARCHICAL_NAME_COLUMN = 19;
public static final int CONTENT_HIERARCHICAL_NAME_COLUMN = 20;
/** /**
* <em>NOTE</em>: If fields are added or removed, the method {@link #getHashes()} * <em>NOTE</em>: 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, RECORD_ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.SERVER_ID,
MailboxColumns.PARENT_SERVER_ID, MailboxColumns.ACCOUNT_KEY, MailboxColumns.TYPE, MailboxColumns.PARENT_SERVER_ID, MailboxColumns.ACCOUNT_KEY, MailboxColumns.TYPE,
MailboxColumns.DELIMITER, MailboxColumns.SYNC_KEY, MailboxColumns.SYNC_LOOKBACK, MailboxColumns.DELIMITER, MailboxColumns.SYNC_KEY, MailboxColumns.SYNC_LOOKBACK,
MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_TIME, MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_TIME, MailboxColumns.FLAG_VISIBLE,
MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS, MailboxColumns.VISIBLE_LIMIT, MailboxColumns.FLAGS, MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY,
MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY, MailboxColumns.LAST_TOUCHED_TIME, MailboxColumns.LAST_TOUCHED_TIME, MailboxColumns.UI_SYNC_STATUS,
MailboxColumns.UI_SYNC_STATUS, MailboxColumns.UI_LAST_SYNC_RESULT, MailboxColumns.UI_LAST_SYNC_RESULT, MailboxColumns.TOTAL_COUNT,
MailboxColumns.TOTAL_COUNT, MailboxColumns.HIERARCHICAL_NAME 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 */ /** Selection by server pathname for a given account */
public static final String PATH_AND_ACCOUNT_SELECTION = public static final String PATH_AND_ACCOUNT_SELECTION =
MailboxColumns.SERVER_ID + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?"; 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 [] { private static final String[] MAILBOX_TYPE_PROJECTION = new String [] {
MailboxColumns.TYPE 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_DRAFTS = -5;
public static final long QUERY_ALL_OUTBOX = -6; 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() { public Mailbox() {
mBaseUri = CONTENT_URI; mBaseUri = CONTENT_URI;
} }
@ -380,7 +370,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
mSyncTime = cursor.getLong(CONTENT_SYNC_TIME_COLUMN); mSyncTime = cursor.getLong(CONTENT_SYNC_TIME_COLUMN);
mFlagVisible = cursor.getInt(CONTENT_FLAG_VISIBLE_COLUMN) == 1; mFlagVisible = cursor.getInt(CONTENT_FLAG_VISIBLE_COLUMN) == 1;
mFlags = cursor.getInt(CONTENT_FLAGS_COLUMN); mFlags = cursor.getInt(CONTENT_FLAGS_COLUMN);
mVisibleLimit = cursor.getInt(CONTENT_VISIBLE_LIMIT_COLUMN);
mSyncStatus = cursor.getString(CONTENT_SYNC_STATUS_COLUMN); mSyncStatus = cursor.getString(CONTENT_SYNC_STATUS_COLUMN);
mLastTouchedTime = cursor.getLong(CONTENT_LAST_TOUCHED_TIME_COLUMN); mLastTouchedTime = cursor.getLong(CONTENT_LAST_TOUCHED_TIME_COLUMN);
mUiSyncStatus = cursor.getInt(CONTENT_UI_SYNC_STATUS_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.SYNC_TIME, mSyncTime);
values.put(MailboxColumns.FLAG_VISIBLE, mFlagVisible); values.put(MailboxColumns.FLAG_VISIBLE, mFlagVisible);
values.put(MailboxColumns.FLAGS, mFlags); values.put(MailboxColumns.FLAGS, mFlags);
values.put(MailboxColumns.VISIBLE_LIMIT, mVisibleLimit);
values.put(MailboxColumns.SYNC_STATUS, mSyncStatus); values.put(MailboxColumns.SYNC_STATUS, mSyncStatus);
values.put(MailboxColumns.LAST_TOUCHED_TIME, mLastTouchedTime); values.put(MailboxColumns.LAST_TOUCHED_TIME, mLastTouchedTime);
values.put(MailboxColumns.UI_SYNC_STATUS, mUiSyncStatus); values.put(MailboxColumns.UI_SYNC_STATUS, mUiSyncStatus);
@ -415,6 +403,44 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
return values; 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 * 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 * 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; 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 * Return the mailbox for a message with a given id
* @param context the caller's context * @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); 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 * @param mailboxId ID of a mailbox. This method accepts magic mailbox IDs, such as
* {@link #QUERY_ALL_INBOXES}. (They're all non-refreshable.) * {@link #QUERY_ALL_INBOXES}. (They're all non-refreshable.)
@ -589,8 +607,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
= mFlagVisible; = mFlagVisible;
hash[CONTENT_FLAGS_COLUMN] hash[CONTENT_FLAGS_COLUMN]
= mFlags; = mFlags;
hash[CONTENT_VISIBLE_LIMIT_COLUMN]
= mVisibleLimit;
hash[CONTENT_SYNC_STATUS_COLUMN] hash[CONTENT_SYNC_STATUS_COLUMN]
= mSyncStatus; = mSyncStatus;
hash[CONTENT_PARENT_KEY_COLUMN] hash[CONTENT_PARENT_KEY_COLUMN]
@ -632,7 +648,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
dest.writeLong(mSyncTime); dest.writeLong(mSyncTime);
dest.writeInt(mFlagVisible ? 1 : 0); dest.writeInt(mFlagVisible ? 1 : 0);
dest.writeInt(mFlags); dest.writeInt(mFlags);
dest.writeInt(mVisibleLimit);
dest.writeString(mSyncStatus); dest.writeString(mSyncStatus);
dest.writeLong(mLastTouchedTime); dest.writeLong(mLastTouchedTime);
dest.writeInt(mUiSyncStatus); dest.writeInt(mUiSyncStatus);
@ -657,7 +672,6 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
mSyncTime = in.readLong(); mSyncTime = in.readLong();
mFlagVisible = in.readInt() == 1; mFlagVisible = in.readInt() == 1;
mFlags = in.readInt(); mFlags = in.readInt();
mVisibleLimit = in.readInt();
mSyncStatus = in.readString(); mSyncStatus = in.readString();
mLastTouchedTime = in.readLong(); mLastTouchedTime = in.readLong();
mUiSyncStatus = in.readInt(); mUiSyncStatus = in.readInt();

View File

@ -157,14 +157,16 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
* *
* @param mailboxId the id of the mailbox record * @param mailboxId the id of the mailbox record
* @param userRequest whether or not the user specifically asked for the sync * @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 @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() { setTask(new ProxyTask() {
@Override @Override
public void run() throws RemoteException { public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback); if (mCallback != null) mService.setCallback(mCallback);
mService.startSync(mailboxId, userRequest); mService.startSync(mailboxId, userRequest, deltaMessageCount);
} }
}, "startSync"); }, "startSync");
} }

View File

@ -26,9 +26,10 @@ import android.os.Bundle;
interface IEmailService { interface IEmailService {
Bundle validate(in HostAuth hostauth); 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); oneway void stopSync(long mailboxId);
// TODO: loadMore appears to be unused; if so, delete it.
oneway void loadMore(long messageId); oneway void loadMore(long messageId);
oneway void loadAttachment(long attachmentId, boolean background); oneway void loadAttachment(long attachmentId, boolean background);

View File

@ -198,6 +198,5 @@ public abstract class Store {
//mailbox.mSyncTime; //mailbox.mSyncTime;
mailbox.mType = type; mailbox.mType = type;
//box.mUnreadCount; //box.mUnreadCount;
mailbox.mVisibleLimit = MailActivityEmail.VISIBLE_LIMIT_DEFAULT;
} }
} }

View File

@ -110,8 +110,6 @@ public class Pop3Store extends Store {
if (mailbox == null) { if (mailbox == null) {
mailbox = Mailbox.newSystemMailbox(mContext, mAccount.mId, Mailbox.TYPE_INBOX); 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()) { if (mailbox.isSaved()) {
mailbox.update(mContext, mailbox.toContentValues()); mailbox.update(mContext, mailbox.toContentValues());
} else { } else {

View File

@ -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_ID_FROM_ACCOUNT_AND_TYPE = MAILBOX_BASE + 2;
private static final int MAILBOX_NOTIFICATION = MAILBOX_BASE + 3; 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_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_BASE = 0x2000;
private static final int MESSAGE = MESSAGE_BASE; private static final int MESSAGE = MESSAGE_BASE;
@ -1086,6 +1087,7 @@ public class EmailProvider extends ContentProvider {
MAILBOX_NOTIFICATION); MAILBOX_NOTIFICATION);
matcher.addURI(EmailContent.AUTHORITY, "mailboxMostRecentMessage/#", matcher.addURI(EmailContent.AUTHORITY, "mailboxMostRecentMessage/#",
MAILBOX_MOST_RECENT_MESSAGE); MAILBOX_MOST_RECENT_MESSAGE);
matcher.addURI(EmailContent.AUTHORITY, "mailboxCount/#", MAILBOX_MESSAGE_COUNT);
// All messages // All messages
matcher.addURI(EmailContent.AUTHORITY, "message", MESSAGE); matcher.addURI(EmailContent.AUTHORITY, "message", MESSAGE);
@ -1303,7 +1305,7 @@ public class EmailProvider extends ContentProvider {
c = uiFolderLoadMore(uri); c = uiFolderLoadMore(uri);
return c; return c;
case UI_FOLDER_REFRESH: case UI_FOLDER_REFRESH:
c = uiFolderRefresh(uri); c = uiFolderRefresh(uri, 0);
return c; return c;
case MAILBOX_NOTIFICATION: case MAILBOX_NOTIFICATION:
c = notificationQuery(uri); c = notificationQuery(uri);
@ -1311,6 +1313,9 @@ public class EmailProvider extends ContentProvider {
case MAILBOX_MOST_RECENT_MESSAGE: case MAILBOX_MOST_RECENT_MESSAGE:
c = mostRecentMessageQuery(uri); c = mostRecentMessageQuery(uri);
return c; return c;
case MAILBOX_MESSAGE_COUNT:
c = getMailboxMessageCount(uri);
return c;
case ACCOUNT_DEFAULT_ID: case ACCOUNT_DEFAULT_ID:
// Start with a snapshot of the cache // Start with a snapshot of the cache
Map<String, Cursor> accountCache = mCacheAccount.getSnapshot(); Map<String, Cursor> accountCache = mCacheAccount.getSnapshot();
@ -2064,7 +2069,14 @@ outer:
String mailboxId = uri.getLastPathSegment(); String mailboxId = uri.getLastPathSegment();
return db.rawQuery("select max(_id) from Message where mailboxKey=?", return db.rawQuery("select max(_id) from Message where mailboxKey=?",
new String[] {mailboxId}); 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 * Support for UnifiedEmail below
@ -3755,7 +3767,7 @@ outer:
final EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context, final EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context,
mServiceCallback, mailbox.mAccountKey); mServiceCallback, mailbox.mAccountKey);
try { try {
service.startSync(mailbox.mId, true); service.startSync(mailbox.mId, true, 0);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
final long originalMsgId = msg.mSourceKey; 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(); Context context = getContext();
String idString = uri.getLastPathSegment(); String idString = uri.getLastPathSegment();
long id = Long.parseLong(idString); long id = Long.parseLong(idString);
@ -4351,7 +4363,7 @@ outer:
EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context, EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context,
mServiceCallback, mailbox.mAccountKey); mServiceCallback, mailbox.mAccountKey);
try { try {
service.startSync(id, true); service.startSync(id, true, deltaMessageCount);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
return null; return null;
@ -4373,21 +4385,7 @@ outer:
mSearchParams.mOffset += SEARCH_MORE_INCREMENT; mSearchParams.mOffset += SEARCH_MORE_INCREMENT;
runSearchQuery(context, mailbox.mAccountKey, id); runSearchQuery(context, mailbox.mAccountKey, id);
} else { } else {
// Compute the new visibleLimit for this mailbox. uiFolderRefresh(uri, VISIBLE_LIMIT_INCREMENT);
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);
}
} }
return null; return null;
} }

View File

@ -79,6 +79,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
private static final int MAILBOX_COLUMN_TYPE = 2; private static final int MAILBOX_COLUMN_TYPE = 2;
public static final String SYNC_EXTRA_MAILBOX_ID = "__mailboxId__"; 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. */ /** System folders that should always exist. */
private final int[] DEFAULT_FOLDERS = { private final int[] DEFAULT_FOLDERS = {
@ -111,7 +112,8 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
} }
@Override @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); Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mailboxId);
if (mailbox == null) return; if (mailbox == null) return;
Account account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey); 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.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
} }
extras.putLong(SYNC_EXTRA_MAILBOX_ID, mailboxId); extras.putLong(SYNC_EXTRA_MAILBOX_ID, mailboxId);
if (deltaMessageCount != 0) {
extras.putInt(SYNC_EXTRA_DELTA_MESSAGE_COUNT, deltaMessageCount);
}
ContentResolver.requestSync(acct, EmailContent.AUTHORITY, extras); 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 we just created the inbox, sync it
if (inboxId != -1) { if (inboxId != -1) {
startSync(inboxId, true); startSync(inboxId, true, 0);
} }
} }
} }

View File

@ -58,7 +58,6 @@ import com.android.emailcommon.service.IEmailServiceCallback;
import com.android.emailcommon.service.SearchParams; import com.android.emailcommon.service.SearchParams;
import com.android.emailcommon.service.SyncWindow; import com.android.emailcommon.service.SyncWindow;
import com.android.mail.utils.LogUtils;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -597,7 +596,8 @@ public class EmailServiceUtils {
} }
@Override @Override
public void startSync(long mailboxId, boolean userRequest) throws RemoteException { public void startSync(long mailboxId, boolean userRequest, int deltaMessageCount)
throws RemoteException {
} }
@Override @Override

View File

@ -165,10 +165,11 @@ public class ImapService extends Service {
* TODO this should use ID's instead of fully-restored objects * TODO this should use ID's instead of fully-restored objects
* @param account * @param account
* @param folder * @param folder
* @param deltaMessageCount requested change in number of messages to sync
* @throws MessagingException * @throws MessagingException
*/ */
public static void synchronizeMailboxSynchronous(Context context, final Account account, 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); sendMailboxStatus(folder, EmailServiceStatus.IN_PROGRESS);
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account)); TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account));
@ -178,7 +179,7 @@ public class ImapService extends Service {
NotificationController nc = NotificationController.getInstance(context); NotificationController nc = NotificationController.getInstance(context);
try { try {
processPendingActionsSynchronous(context, account); processPendingActionsSynchronous(context, account);
synchronizeMailboxGeneric(context, account, folder); synchronizeMailboxGeneric(context, account, folder, deltaMessageCount);
// Clear authentication notification for this account // Clear authentication notification for this account
nc.cancelLoginFailedNotification(account.mId); nc.cancelLoginFailedNotification(account.mId);
sendMailboxStatus(folder, EmailServiceStatus.SUCCESS); sendMailboxStatus(folder, EmailServiceStatus.SUCCESS);
@ -335,12 +336,12 @@ public class ImapService extends Service {
* *
* @param account the account to sync * @param account the account to sync
* @param mailbox the mailbox to sync * @param mailbox the mailbox to sync
* @param deltaMessageCount requested change in number of messages to sync
* @return results of the sync pass * @return results of the sync pass
* @throws MessagingException * @throws MessagingException
*/ */
private static void synchronizeMailboxGeneric(final Context context, private static void synchronizeMailboxGeneric(final Context context, final Account account,
final Account account, final Mailbox mailbox) throws MessagingException { 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. * 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. * 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. // 4. Trash any remote messages that are marked as trashed locally.
// TODO - this comment was here, but no code was here. // 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. // 6. Update the total count and determine new message count to sync.
int remoteMessageCount = remoteFolder.getMessageCount(); final int messageCount = mailbox.handleCountsForSync(context, remoteMessageCount,
values.put(MailboxColumns.TOTAL_COUNT, remoteMessageCount); deltaMessageCount);
// 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);
// 7. Create a list of messages to download // 7. Create a list of messages to download
Message[] remoteMessages = new Message[0]; Message[] remoteMessages = new Message[0];
@ -443,7 +431,7 @@ public class ImapService extends Service {
/* /*
* Message numbers start at 1. * Message numbers start at 1.
*/ */
int remoteStart = Math.max(0, remoteMessageCount - visibleLimit) + 1; int remoteStart = Math.max(0, remoteMessageCount - messageCount) + 1;
int remoteEnd = remoteMessageCount; int remoteEnd = remoteMessageCount;
remoteMessages = remoteFolder.getMessages(remoteStart, remoteEnd, null); remoteMessages = remoteFolder.getMessages(remoteStart, remoteEnd, null);
// TODO Why are we running through the list twice? Combine w/ for loop below // 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)) { protocolSearchInfo.equals(mLastSearchServerId)) {
return mLastSearchRemoteMailbox; 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, Mailbox.CONTENT_PROJECTION, Mailbox.PATH_AND_ACCOUNT_SELECTION,
new String[] {protocolSearchInfo, Long.toString(accountKey)}, new String[] {protocolSearchInfo, Long.toString(accountKey)},
null); null);

View File

@ -103,7 +103,7 @@ public class Pop3Service extends Service {
long inboxId = Mailbox.findMailboxOfType(mContext, att.mAccountKey, Mailbox.TYPE_INBOX); long inboxId = Mailbox.findMailboxOfType(mContext, att.mAccountKey, Mailbox.TYPE_INBOX);
if (inboxId == Mailbox.NO_MAILBOX) return; if (inboxId == Mailbox.NO_MAILBOX) return;
// We load attachments during a sync // We load attachments during a sync
startSync(inboxId, true); startSync(inboxId, true, 0);
} }
@Override @Override
@ -129,10 +129,11 @@ public class Pop3Service extends Service {
* *
* @param account * @param account
* @param folder * @param folder
* @param deltaMessageCount the requested change in number of messages to sync.
* @throws MessagingException * @throws MessagingException
*/ */
public static void synchronizeMailboxSynchronous(Context context, final Account account, 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); sendMailboxStatus(folder, EmailServiceStatus.IN_PROGRESS);
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account)); TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account));
@ -141,7 +142,7 @@ public class Pop3Service extends Service {
} }
NotificationController nc = NotificationController.getInstance(context); NotificationController nc = NotificationController.getInstance(context);
try { try {
synchronizePop3Mailbox(context, account, folder); synchronizePop3Mailbox(context, account, folder, deltaMessageCount);
// Clear authentication notification for this account // Clear authentication notification for this account
nc.cancelLoginFailedNotification(account.mId); nc.cancelLoginFailedNotification(account.mId);
sendMailboxStatus(folder, EmailServiceStatus.SUCCESS); sendMailboxStatus(folder, EmailServiceStatus.SUCCESS);
@ -243,10 +244,11 @@ public class Pop3Service extends Service {
* *
* @param account the account to sync * @param account the account to sync
* @param mailbox the mailbox to sync * @param mailbox the mailbox to sync
* @param deltaMessageCount the requested change to number of messages to sync
* @throws MessagingException * @throws MessagingException
*/ */
private static void synchronizePop3Mailbox(final Context context, private static void synchronizePop3Mailbox(final Context context, final Account account,
final Account account, final Mailbox mailbox) throws MessagingException { final Mailbox mailbox, final int deltaMessageCount) throws MessagingException {
// TODO Break this into smaller pieces // TODO Break this into smaller pieces
ContentResolver resolver = context.getContentResolver(); ContentResolver resolver = context.getContentResolver();
@ -293,12 +295,6 @@ public class Pop3Service extends Service {
// count. // count.
remoteFolder.open(OpenMode.READ_WRITE); 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) }; String[] accountIdArgs = new String[] { Long.toString(account.mId) };
long trashMailboxId = Mailbox.findMailboxOfType(context, account.mId, Mailbox.TYPE_TRASH); long trashMailboxId = Mailbox.findMailboxOfType(context, account.mId, Mailbox.TYPE_TRASH);
Cursor updates = resolver.query( Cursor updates = resolver.query(
@ -328,11 +324,12 @@ public class Pop3Service extends Service {
updates.close(); updates.close();
} }
// Determine the limit # of messages to download // Get the remote message count.
int visibleLimit = mailbox.mVisibleLimit; final int remoteMessageCount = remoteFolder.getMessageCount();
if (visibleLimit <= 0) {
visibleLimit = MailActivityEmail.VISIBLE_LIMIT_DEFAULT; // 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 // Create a list of messages to download
Pop3Message[] remoteMessages = new Pop3Message[0]; Pop3Message[] remoteMessages = new Pop3Message[0];
@ -343,7 +340,7 @@ public class Pop3Service extends Service {
/* /*
* Message numbers start at 1. * 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 * 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, AttachmentColumns.UI_STATE + "=" + AttachmentState.DOWNLOADING,
new String[] {Long.toString(account.mId)}, null); new String[] {Long.toString(account.mId)}, null);
try { try {
values.clear(); final ContentValues values = new ContentValues();
while (c.moveToNext()) { while (c.moveToNext()) {
values.put(AttachmentColumns.UI_STATE, UIProvider.AttachmentState.SAVED); values.put(AttachmentColumns.UI_STATE, UIProvider.AttachmentState.SAVED);
Attachment att = new Attachment(); Attachment att = new Attachment();

View File

@ -109,7 +109,7 @@ public class PopImapSyncAdapterService extends Service {
} }
private static void sync(Context context, long mailboxId, SyncResult syncResult, private static void sync(Context context, long mailboxId, SyncResult syncResult,
boolean uiRefresh) { boolean uiRefresh, int deltaMessageCount) {
TempDirectory.setTempDirectory(context); TempDirectory.setTempDirectory(context);
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId); Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
if (mailbox == null) return; if (mailbox == null) return;
@ -139,9 +139,11 @@ public class PopImapSyncAdapterService extends Service {
if (mailbox.mType == Mailbox.TYPE_OUTBOX) { if (mailbox.mType == Mailbox.TYPE_OUTBOX) {
EmailServiceStub.sendMailImpl(context, account.mId); EmailServiceStub.sendMailImpl(context, account.mId);
} else if (protocol.equals(legacyImapProtocol)) { } else if (protocol.equals(legacyImapProtocol)) {
ImapService.synchronizeMailboxSynchronous(context, account, mailbox); ImapService.synchronizeMailboxSynchronous(context, account, mailbox,
deltaMessageCount);
} else { } else {
Pop3Service.synchronizeMailboxSynchronous(context, account, mailbox); Pop3Service.synchronizeMailboxSynchronous(context, account, mailbox,
deltaMessageCount);
} }
} catch (MessagingException e) { } catch (MessagingException e) {
int cause = e.getExceptionType(); int cause = e.getExceptionType();
@ -155,8 +157,9 @@ public class PopImapSyncAdapterService extends Service {
} }
} }
} finally { } 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.UI_SYNC_STATUS, EmailContent.SYNC_STATUS_NONE);
values.put(Mailbox.SYNC_TIME, System.currentTimeMillis());
resolver.update(mailboxUri, values, null, null); resolver.update(mailboxUri, values, null, null);
} }
} }
@ -200,7 +203,7 @@ public class PopImapSyncAdapterService extends Service {
} }
} }
for (long mailboxId: mailboxesToUpdate) { for (long mailboxId: mailboxesToUpdate) {
sync(context, mailboxId, syncResult, false); sync(context, mailboxId, syncResult, false, 0);
} }
} else { } else {
Log.d(TAG, "Sync request for " + acct.mDisplayName); Log.d(TAG, "Sync request for " + acct.mDisplayName);
@ -222,7 +225,9 @@ public class PopImapSyncAdapterService extends Service {
if (mailboxId == Mailbox.NO_MAILBOX) return; if (mailboxId == Mailbox.NO_MAILBOX) return;
boolean uiRefresh = boolean uiRefresh =
extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); 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 // Outbox is a special case here
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId); Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);

View File

@ -78,18 +78,6 @@ public class MailActivityEmail extends com.android.mail.ui.MailActivity {
*/ */
public static boolean sDebugInhibitGraphicsAcceleration = false; 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 * 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.) * the accounts list (e.g. deleting accounts in the Account Manager preferences.)