From 755fa67d172501b95ed08bdf5af8890d1d1ecde3 Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Sun, 16 Jan 2011 20:05:31 -0800 Subject: [PATCH] Delete message when Sync/Fetch fails with "object not found" Bug: 3361222 Change-Id: I885b18612e8b5b4e7b7f50bc73f2b6a76c2242ad --- .../exchange/adapter/AbstractSyncAdapter.java | 16 +++++++++ .../exchange/adapter/EmailSyncAdapter.java | 33 ++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/com/android/exchange/adapter/AbstractSyncAdapter.java b/src/com/android/exchange/adapter/AbstractSyncAdapter.java index 14cca36e3..e2b37a4f3 100644 --- a/src/com/android/exchange/adapter/AbstractSyncAdapter.java +++ b/src/com/android/exchange/adapter/AbstractSyncAdapter.java @@ -137,5 +137,21 @@ public abstract class AbstractSyncAdapter { public void setSyncKey(String syncKey, boolean inCommands) throws IOException { mMailbox.mSyncKey = syncKey; } + + /** + * Sync failures can use SyncStatusException, which includes the actual error status and + * server id + */ + static class SyncStatusException extends IOException { + private static final long serialVersionUID = 1L; + + public final int mStatus; + public final String mServerId; + + protected SyncStatusException(String serverId, int status) { + mServerId = serverId; + mStatus = status; + } + } } diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java index e79b17c11..2c1eabebe 100644 --- a/src/com/android/exchange/adapter/EmailSyncAdapter.java +++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java @@ -403,17 +403,26 @@ public class EmailSyncAdapter extends AbstractSyncAdapter { } } - private void addParser(ArrayList emails) throws IOException { + /** + * Parse a message from the server stream. + * @return the parsed Message + * @throws IOException + */ + private Message addParser() throws IOException { Message msg = new Message(); msg.mAccountKey = mAccount.mId; msg.mMailboxKey = mMailbox.mId; msg.mFlagLoaded = Message.FLAG_LOADED_COMPLETE; + int status = -1; while (nextTag(Tags.SYNC_ADD) != END) { switch (tag) { case Tags.SYNC_SERVER_ID: msg.mServerId = getValue(); break; + case Tags.SYNC_STATUS: + status = getValueInt(); + break; case Tags.SYNC_APPLICATION_DATA: addData(msg); break; @@ -421,7 +430,11 @@ public class EmailSyncAdapter extends AbstractSyncAdapter { skipTag(); } } - emails.add(msg); + // For sync, status 1 = success + if (status != 1) { + throw new SyncStatusException(msg.mServerId, status); + } + return msg; } // For now, we only care about the "active" state @@ -672,7 +685,7 @@ public class EmailSyncAdapter extends AbstractSyncAdapter { public void commandsParser() throws IOException { while (nextTag(Tags.SYNC_COMMANDS) != END) { if (tag == Tags.SYNC_ADD) { - addParser(newEmails); + newEmails.add(addParser()); incrementChangeCount(); } else if (tag == Tags.SYNC_DELETE || tag == Tags.SYNC_SOFT_DELETE) { deleteParser(deletedEmails, tag); @@ -691,7 +704,19 @@ public class EmailSyncAdapter extends AbstractSyncAdapter { if (tag == Tags.SYNC_ADD || tag == Tags.SYNC_CHANGE || tag == Tags.SYNC_DELETE) { // We can ignore all of these } else if (tag == Tags.SYNC_FETCH) { - addParser(fetchedEmails); + try { + fetchedEmails.add(addParser()); + } catch (SyncStatusException sse) { + if (sse.mStatus == 8) { + // 8 = object not found; delete the message from EmailProvider + // No other status should be seen in a fetch response, except, perhaps, + // for some temporary server failure + mBindArguments[0] = sse.mServerId; + mBindArguments[1] = mMailboxIdAsString; + mContentResolver.delete(Message.CONTENT_URI, + WHERE_SERVER_ID_AND_MAILBOX_KEY, mBindArguments); + } + } } } }