Handle "responses" properly in Email sync
* We need to parse our way through the Responses tag (this was
never used before EAS 14) and retry those updates that fail
* Also, small tweaks to improve Parser logging
Bug: 5123688
Change-Id: I78ae35145d85fd14413dadcc69388dfc619ae416
diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
index 1f8aee9..e951cfc 100644
--- a/src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -47,6 +47,7 @@
import com.android.emailcommon.provider.EmailContent.SyncColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.provider.Policy;
+import com.android.emailcommon.provider.ProviderUnavailableException;
import com.android.emailcommon.service.SyncWindow;
import com.android.emailcommon.utility.AttachmentUtilities;
import com.android.emailcommon.utility.ConversionUtilities;
@@ -841,8 +842,10 @@
private Cursor getServerIdCursor(String serverId, String[] projection) {
mBindArguments[0] = serverId;
mBindArguments[1] = mMailboxIdAsString;
- return mContentResolver.query(Message.CONTENT_URI, projection,
+ Cursor c = mContentResolver.query(Message.CONTENT_URI, projection,
WHERE_SERVER_ID_AND_MAILBOX_KEY, mBindArguments, null);
+ if (c == null) throw new ProviderUnavailableException();
+ return c;
}
@VisibleForTesting
@@ -974,11 +977,43 @@
}
}
+ /**
+ * Removed any messages with status 7 (mismatch) from the updatedIdList
+ * @param endTag the tag we end with
+ * @throws IOException
+ */
+ public void failedUpdateParser(int endTag) throws IOException {
+ // We get serverId and status in the responses
+ String serverId = null;
+ while (nextTag(endTag) != END) {
+ if (tag == Tags.SYNC_STATUS) {
+ int status = getValueInt();
+ if (status == 7 && serverId != null) {
+ Cursor c = getServerIdCursor(serverId, Message.ID_COLUMN_PROJECTION);
+ try {
+ if (c.moveToFirst()) {
+ Long id = c.getLong(Message.ID_PROJECTION_COLUMN);
+ mService.userLog("Update of " + serverId + " failed; will retry");
+ mUpdatedIdList.remove(id);
+ mService.mUpsyncFailed = true;
+ }
+ } finally {
+ c.close();
+ }
+ }
+ } else if (tag == Tags.SYNC_SERVER_ID) {
+ serverId = getValue();
+ } else {
+ skipTag();
+ }
+ }
+ }
+
@Override
public void responsesParser() throws IOException {
while (nextTag(Tags.SYNC_RESPONSES) != END) {
if (tag == Tags.SYNC_ADD || tag == Tags.SYNC_CHANGE || tag == Tags.SYNC_DELETE) {
- // We can ignore all of these
+ failedUpdateParser(tag);
} else if (tag == Tags.SYNC_FETCH) {
try {
fetchedEmails.add(addParser());
diff --git a/src/com/android/exchange/adapter/Parser.java b/src/com/android/exchange/adapter/Parser.java
index dd11290..3b89863 100644
--- a/src/com/android/exchange/adapter/Parser.java
+++ b/src/com/android/exchange/adapter/Parser.java
@@ -38,6 +38,8 @@
*
*/
public abstract class Parser {
+ private static final boolean LOG_VERBOSE = false;
+
// The following constants are Wbxml standard
public static final int START_DOCUMENT = 0;
public static final int DONE = 1;
@@ -403,6 +405,7 @@
private void pop() {
if (logging) {
name = nameArray[depth];
+ log("</" + name + '>');
}
// Retrieve the now-current startTag from our stack
startTag = endTag = startTagArray[depth];
@@ -418,9 +421,7 @@
if (logging) {
name = tagTable[startTag - TAG_BASE];
nameArray[depth] = name;
- if (noContent) {
- log("<" + name + "/>");
- }
+ log("<" + name + (noContent ? '/' : "") + '>');
}
// Save the startTag to our stack
startTagArray[depth] = startTag;
@@ -453,6 +454,9 @@
int pg = readByte();
// Save the shifted page to add into the startTag in nextTag
page = pg << Tags.PAGE_SHIFT;
+ if (LOG_VERBOSE) {
+ log("Page: " + page);
+ }
// Retrieve the current tag table
tagTable = tagTables[pg];
id = nextId();
@@ -519,6 +523,9 @@
if (capture) {
captureArray.add(i);
}
+ if (LOG_VERBOSE) {
+ log("Byte: " + i);
+ }
return i;
}