Don't allow duplicate messages to appear in Sent folder
b/11224731
There is a problem in ImapService.processPendingUploads().
It was trying to process updates to existing messages
as uploads. This is wrong, it means that marking a sent
messages as Read can cause it to be uploaded again,
resuling in a new message being created.
Change-Id: I502df52a7b315daeee10c1041db8f30dbfd2c04e
diff --git a/src/com/android/email/service/ImapService.java b/src/com/android/email/service/ImapService.java
index 0f2df31..15bc5fd 100644
--- a/src/com/android/email/service/ImapService.java
+++ b/src/com/android/email/service/ImapService.java
@@ -156,9 +156,9 @@
* @return The status code for whether this operation succeeded.
* @throws MessagingException
*/
- public static int synchronizeMailboxSynchronous(Context context, final Account account,
- final Mailbox folder, final boolean loadMore, final boolean uiRefresh)
- throws MessagingException {
+ public static synchronized int synchronizeMailboxSynchronous(Context context,
+ final Account account, final Mailbox folder, final boolean loadMore,
+ final boolean uiRefresh) throws MessagingException {
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account));
NotificationController nc = NotificationController.getInstance(context);
try {
@@ -192,13 +192,12 @@
private static final int COLUMN_FLAG_FAVORITE = 2;
private static final int COLUMN_FLAG_LOADED = 3;
private static final int COLUMN_SERVER_ID = 4;
- private static final int COLUMN_FLAGS = 7;
- private static final int COLUMN_TIMESTAMP = 8;
+ private static final int COLUMN_FLAGS = 5;
+ private static final int COLUMN_TIMESTAMP = 6;
private static final String[] PROJECTION = new String[] {
- EmailContent.RECORD_ID,
- MessageColumns.FLAG_READ, MessageColumns.FLAG_FAVORITE, MessageColumns.FLAG_LOADED,
- SyncColumns.SERVER_ID, MessageColumns.MAILBOX_KEY, MessageColumns.ACCOUNT_KEY,
- MessageColumns.FLAGS, MessageColumns.TIMESTAMP
+ EmailContent.RECORD_ID, MessageColumns.FLAG_READ, MessageColumns.FLAG_FAVORITE,
+ MessageColumns.FLAG_LOADED, SyncColumns.SERVER_ID, MessageColumns.FLAGS,
+ MessageColumns.TIMESTAMP
};
final long mId;
@@ -874,35 +873,6 @@
upsyncs1.close();
}
}
-
- // Next, handle any updates (e.g. edited in place, although this shouldn't happen)
- Cursor upsyncs2 = resolver.query(EmailContent.Message.UPDATED_CONTENT_URI,
- EmailContent.Message.ID_PROJECTION,
- EmailContent.MessageColumns.MAILBOX_KEY + "=?", mailboxKeyArgs,
- null);
- try {
- while (upsyncs2.moveToNext()) {
- // Load the remote store if it will be needed
- if (remoteStore == null) {
- remoteStore = Store.getInstance(account, context);
- }
- // Load the mailbox if it will be needed
- if (mailbox == null) {
- mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
- if (mailbox == null) {
- continue; // Mailbox removed. Move to the next message.
- }
- }
- // upsync the message
- long id = upsyncs2.getLong(EmailContent.Message.ID_PROJECTION_COLUMN);
- lastMessageId = id;
- processUploadMessage(context, remoteStore, mailbox, id);
- }
- } finally {
- if (upsyncs2 != null) {
- upsyncs2.close();
- }
- }
}
} catch (MessagingException me) {
// Presumably an error here is an account connection failure, so there is
@@ -1327,12 +1297,15 @@
// 3. If a remote message could not be found, upload our local message
if (remoteMessage == null) {
+ // TODO:
+ // if we have a serverId and remoteMessage is still null, then probably the message
+ // has been deleted and we should delete locally.
// 3a. Create a legacy message to upload
Message localMessage = LegacyConversions.makeMessage(context, message);
-
// 3b. Upload it
//FetchProfile fp = new FetchProfile();
//fp.add(FetchProfile.Item.BODY);
+ // Note that this operation will assign the Uid to localMessage
remoteFolder.appendMessages(new Message[] { localMessage });
// 3b. And record the UID from the server
@@ -1341,6 +1314,10 @@
updateMessage = true;
} else {
// 4. If the remote message exists we need to determine which copy to keep.
+ // TODO:
+ // I don't see a good reason we should be here. If the message already has a serverId,
+ // then we should be handling it in processPendingUpdates(),
+ // not processPendingUploads()
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
@@ -1355,6 +1332,9 @@
// 4b. Otherwise we'll upload our message and then delete the remote message.
// Create a legacy message to upload
+ // TODO: This strategy has a problem: This will create a second message,
+ // so that at least temporarily, we will have two messages for what the
+ // user would think of as one.
Message localMessage = LegacyConversions.makeMessage(context, message);
// 4c. Upload it
@@ -1368,7 +1348,7 @@
updateInternalDate = true;
updateMessage = true;
- // 4e. And delete the old copy of the message from the server
+ // 4e. And delete the old copy of the message from the server.
remoteMessage.setFlag(Flag.DELETED, true);
}
}
diff --git a/src/com/android/email/service/PopImapSyncAdapterService.java b/src/com/android/email/service/PopImapSyncAdapterService.java
index 6723094..8a95af7 100644
--- a/src/com/android/email/service/PopImapSyncAdapterService.java
+++ b/src/com/android/email/service/PopImapSyncAdapterService.java
@@ -115,7 +115,7 @@
new String[] {Long.toString(mailbox.mId)});
return;
}
- LogUtils.d(TAG, "Mailbox: " + mailbox.mDisplayName);
+ LogUtils.d(TAG, "About to sync mailbox: " + mailbox.mDisplayName);
Uri mailboxUri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId);
ContentValues values = new ContentValues();