Merge "Move stub logging classes to org.apache.james.mime4j"
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index cd255ee..418b1ea 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -91,6 +91,9 @@
static private final String PING_COMMAND = "Ping";
static private final int COMMAND_TIMEOUT = 20*SECONDS;
+ // Define our default protocol version as 2.5 (Exchange 2003)
+ static private final String DEFAULT_PROTOCOL_VERSION = "2.5";
+
/**
* We start with an 8 minute timeout, and increase/decrease by 3 minutes at a time. There's
* no point having a timeout shorter than 5 minutes, I think; at that point, we can just let
@@ -119,7 +122,7 @@
static private final int PING_FALLBACK_PIM = 25;
// Reasonable default
- String mProtocolVersion = "2.5";
+ public String mProtocolVersion = DEFAULT_PROTOCOL_VERSION;
public Double mProtocolVersionDouble;
protected String mDeviceId = null;
private String mDeviceType = "Android";
@@ -557,7 +560,7 @@
SyncManager.kick("change ping boxes to push");
}
- // Determine our protocol version, if we haven't already
+ // Determine our protocol version, if we haven't already and save it in the Account
if (mAccount.mProtocolVersion == null) {
userLog("Determine EAS protocol version");
HttpResponse resp = sendHttpClientOptions();
@@ -574,6 +577,10 @@
}
mProtocolVersionDouble = Double.parseDouble(mProtocolVersion);
mAccount.mProtocolVersion = mProtocolVersion;
+ // Save the protocol version
+ cv.clear();
+ cv.put(Account.PROTOCOL_VERSION, mProtocolVersion);
+ mAccount.update(mContext, cv);
userLog(versions);
userLog("Using version ", mProtocolVersion);
} else {
@@ -588,7 +595,7 @@
// Change all pushable boxes to push when we start the account mailbox
if (mAccount.mSyncInterval == Account.CHECK_INTERVAL_PUSH) {
- cv = new ContentValues();
+ cv.clear();
cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
if (mContentResolver.update(Mailbox.CONTENT_URI, cv,
SyncManager.WHERE_IN_ACCOUNT_AND_PUSHABLE,
@@ -623,7 +630,7 @@
}
// Change all push/hold boxes to push
- cv = new ContentValues();
+ cv.clear();
cv.put(Mailbox.SYNC_INTERVAL, Account.CHECK_INTERVAL_PUSH);
if (mContentResolver.update(Mailbox.CONTENT_URI, cv,
WHERE_PUSH_HOLD_NOT_ACCOUNT_MAILBOX,
@@ -1101,11 +1108,13 @@
mUserName = ha.mLogin;
mPassword = ha.mPassword;
- // Set up our protocol version
+ // Set up our protocol version from the Account
mProtocolVersion = mAccount.mProtocolVersion;
- if (mProtocolVersion != null) {
- mProtocolVersionDouble = Double.parseDouble(mProtocolVersion);
+ // If it hasn't been set up, start with default version
+ if (mProtocolVersion == null) {
+ mProtocolVersion = DEFAULT_PROTOCOL_VERSION;
}
+ mProtocolVersionDouble = Double.parseDouble(mProtocolVersion);
return true;
}
diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
index a75b293..94c5ef0 100644
--- a/src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -320,7 +320,7 @@
WHERE_SERVER_ID_AND_MAILBOX_KEY, mBindArguments, null);
}
- private void deleteParser(ArrayList<Long> deletes, int entryTag) throws IOException {
+ /*package*/ void deleteParser(ArrayList<Long> deletes, int entryTag) throws IOException {
while (nextTag(entryTag) != END) {
switch (tag) {
case Tags.SYNC_SERVER_ID:
@@ -357,7 +357,7 @@
}
}
- private void changeParser(ArrayList<ServerChange> changes) throws IOException {
+ /*package*/ void changeParser(ArrayList<ServerChange> changes) throws IOException {
String serverId = null;
Boolean oldRead = false;
Boolean oldFlag = false;
diff --git a/src/com/android/exchange/adapter/Parser.java b/src/com/android/exchange/adapter/Parser.java
index ca99a77..01051c0 100644
--- a/src/com/android/exchange/adapter/Parser.java
+++ b/src/com/android/exchange/adapter/Parser.java
@@ -304,6 +304,10 @@
tagTable = tagTables[0];
}
+ /*package*/ void resetInput(InputStream in) {
+ this.in = in;
+ }
+
void log(String str) {
int cr = str.indexOf('\n');
if (cr > 0) {
diff --git a/src/com/android/exchange/adapter/Serializer.java b/src/com/android/exchange/adapter/Serializer.java
index f314772..7c0a3cf 100644
--- a/src/com/android/exchange/adapter/Serializer.java
+++ b/src/com/android/exchange/adapter/Serializer.java
@@ -54,12 +54,20 @@
private int tagPage;
public Serializer() {
+ this(true);
+ }
+
+ public Serializer(boolean startDocument) {
super();
- try {
- startDocument();
- //logging = Eas.PARSER_LOG;
- } catch (IOException e) {
- // Nothing to be done
+ if (startDocument) {
+ try {
+ startDocument();
+ //logging = Eas.PARSER_LOG;
+ } catch (IOException e) {
+ // Nothing to be done
+ }
+ } else {
+ out.write(0);
}
}
diff --git a/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java b/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
index a702428..e378b03 100644
--- a/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
+++ b/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
@@ -23,8 +23,10 @@
import com.android.email.provider.EmailContent.Body;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message;
+import com.android.email.provider.EmailContent.SyncColumns;
import com.android.exchange.EasSyncService;
import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
+import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser.ServerChange;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -43,6 +45,11 @@
EmailProvider mProvider;
Context mMockContext;
+ ContentResolver mMockResolver;
+ Mailbox mMailbox;
+ Account mAccount;
+ EmailSyncAdapter mSyncAdapter;
+ EasEmailSyncParser mSyncParser;
public EmailSyncAdapterTests() {
super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY);
@@ -52,6 +59,7 @@
public void setUp() throws Exception {
super.setUp();
mMockContext = getMockContext();
+ mMockResolver = mMockContext.getContentResolver();
}
@Override
@@ -74,7 +82,15 @@
Mailbox mailbox = new Mailbox();
mailbox.mId = -1;
EasSyncService service = new EasSyncService();
- service.mContext = getContext();
+ service.mContext = mMockContext;
+ service.mMailbox = mailbox;
+ service.mAccount = account;
+ return service;
+ }
+
+ EasSyncService getTestService(Account account, Mailbox mailbox) {
+ EasSyncService service = new EasSyncService();
+ service.mContext = mMockContext;
service.mMailbox = mailbox;
service.mAccount = account;
return service;
@@ -136,36 +152,35 @@
ArrayList<Long> ids = new ArrayList<Long>();
ArrayList<Long> deletedIds = new ArrayList<Long>();
- Context context = mMockContext;
- adapter.mContext = context;
- final ContentResolver resolver = context.getContentResolver();
+ adapter.mContext = mMockContext;
// Create account and two mailboxes
- Account acct = ProviderTestUtils.setupAccount("account", true, context);
+ Account acct = ProviderTestUtils.setupAccount("account", true, mMockContext);
adapter.mAccount = acct;
- Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
+ Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, mMockContext);
adapter.mMailbox = box1;
// Create 3 messages
- Message msg1 =
- ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context);
+ Message msg1 = ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId,
+ true, true, mMockContext);
ids.add(msg1.mId);
- Message msg2 =
- ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context);
+ Message msg2 = ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId,
+ true, true, mMockContext);
ids.add(msg2.mId);
- Message msg3 =
- ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context);
+ Message msg3 = ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId,
+ true, true, mMockContext);
ids.add(msg3.mId);
- assertEquals(3, EmailContent.count(context, Message.CONTENT_URI, null, null));
+ assertEquals(3, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
// Delete them
for (long id: ids) {
- resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id), null, null);
+ mMockResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id),
+ null, null);
}
// Confirm that the messages are in the proper table
- assertEquals(0, EmailContent.count(context, Message.CONTENT_URI, null, null));
- assertEquals(3, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
+ assertEquals(0, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
+ assertEquals(3, EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, null, null));
// Call code to send deletions; the id's of the ones actually deleted will be in the
// deletedIds list
@@ -176,15 +191,15 @@
deletedIds.clear();
// Create a new message
- Message msg4 =
- ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context);
- assertEquals(1, EmailContent.count(context, Message.CONTENT_URI, null, null));
+ Message msg4 = ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId,
+ true, true, mMockContext);
+ assertEquals(1, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
// Find the body for this message
- Body body = Body.restoreBodyWithMessageId(context, msg4.mId);
+ Body body = Body.restoreBodyWithMessageId(mMockContext, msg4.mId);
// Set its source message to msg2's id
ContentValues values = new ContentValues();
values.put(Body.SOURCE_MESSAGE_KEY, msg2.mId);
- body.update(context, values);
+ body.update(mMockContext, values);
// Now send deletions again; this time only two should get deleted; msg2 should NOT be
// deleted as it's referenced by msg4
@@ -192,4 +207,128 @@
assertEquals(2, deletedIds.size());
assertFalse(deletedIds.contains(msg2.mId));
}
+
+ void setupSyncParserAndAdapter(Account account, Mailbox mailbox) throws IOException {
+ EasSyncService service = getTestService(account, mailbox);
+ mSyncAdapter = new EmailSyncAdapter(mailbox, service);
+ mSyncParser = mSyncAdapter.new EasEmailSyncParser(getTestInputStream(), mSyncAdapter);
+ }
+
+ ArrayList<Long> setupAccountMailboxAndMessages(int numMessages) {
+ ArrayList<Long> ids = new ArrayList<Long>();
+
+ // Create account and two mailboxes
+ mAccount = ProviderTestUtils.setupAccount("account", true, mMockContext);
+ mMailbox = ProviderTestUtils.setupMailbox("box1", mAccount.mId, true, mMockContext);
+
+ for (int i = 0; i < numMessages; i++) {
+ Message msg = ProviderTestUtils.setupMessage("message" + i, mAccount.mId, mMailbox.mId,
+ true, true, mMockContext);
+ ids.add(msg.mId);
+ }
+
+ assertEquals(numMessages, EmailContent.count(mMockContext, Message.CONTENT_URI,
+ null, null));
+ return ids;
+ }
+
+ public void testDeleteParser() throws IOException {
+ // Setup some messages
+ ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
+ ContentValues cv = new ContentValues();
+ cv.put(SyncColumns.SERVER_ID, "1:22");
+ long deleteMessageId = messageIds.get(1);
+ mMockResolver.update(ContentUris.withAppendedId(Message.CONTENT_URI, deleteMessageId), cv,
+ null, null);
+
+ // Setup our adapter and parser
+ setupSyncParserAndAdapter(mAccount, mMailbox);
+
+ // Set up an input stream with a delete command
+ Serializer s = new Serializer(false);
+ s.start(Tags.SYNC_DELETE).data(Tags.SYNC_SERVER_ID, "1:22").end().done();
+ byte[] bytes = s.toByteArray();
+ mSyncParser.resetInput(new ByteArrayInputStream(bytes));
+ mSyncParser.nextTag(0);
+
+ // Run the delete parser
+ ArrayList<Long> deleteList = new ArrayList<Long>();
+ mSyncParser.deleteParser(deleteList, Tags.SYNC_DELETE);
+ // It should have found the message
+ assertEquals(1, deleteList.size());
+ long id = deleteList.get(0);
+ // And the id's should match
+ assertEquals(deleteMessageId, id);
+ }
+
+ public void testChangeParser() throws IOException {
+ // Setup some messages
+ ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
+ ContentValues cv = new ContentValues();
+ cv.put(SyncColumns.SERVER_ID, "1:22");
+ long changeMessageId = messageIds.get(1);
+ mMockResolver.update(ContentUris.withAppendedId(Message.CONTENT_URI, changeMessageId), cv,
+ null, null);
+
+ // Setup our adapter and parser
+ setupSyncParserAndAdapter(mAccount, mMailbox);
+
+ // Set up an input stream with a change command (marking 1:22 unread)
+ // Note that the test message creation code sets read to "true"
+ Serializer s = new Serializer(false);
+ s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, "1:22");
+ s.start(Tags.SYNC_APPLICATION_DATA).data(Tags.EMAIL_READ, "0").end();
+ s.end().done();
+ byte[] bytes = s.toByteArray();
+ mSyncParser.resetInput(new ByteArrayInputStream(bytes));
+ mSyncParser.nextTag(0);
+
+ // Run the delete parser
+ ArrayList<ServerChange> changeList = new ArrayList<ServerChange>();
+ mSyncParser.changeParser(changeList);
+ // It should have found the message
+ assertEquals(1, changeList.size());
+ // And the id's should match
+ ServerChange change = changeList.get(0);
+ assertEquals(changeMessageId, change.id);
+ assertNotNull(change.read);
+ assertFalse(change.read);
+ }
+
+ public void testCleanup() throws IOException {
+ // Setup some messages
+ ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
+ // Setup our adapter and parser
+ setupSyncParserAndAdapter(mAccount, mMailbox);
+
+ // Delete two of the messages, change one
+ long id = messageIds.get(0);
+ mMockResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id),
+ null, null);
+ mSyncAdapter.mDeletedIdList.add(id);
+ id = messageIds.get(1);
+ mMockResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,
+ id), null, null);
+ mSyncAdapter.mDeletedIdList.add(id);
+ id = messageIds.get(2);
+ ContentValues cv = new ContentValues();
+ cv.put(Message.FLAG_READ, 0);
+ mMockResolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,
+ id), cv, null, null);
+ mSyncAdapter.mUpdatedIdList.add(id);
+
+ // The changed message should still exist
+ assertEquals(1, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
+
+ // As well, the two deletions and one update
+ assertEquals(2, EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, null, null));
+ assertEquals(1, EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, null, null));
+
+ // Cleanup (i.e. after sync); should remove items from delete/update tables
+ mSyncAdapter.cleanup();
+
+ // The three should be gone
+ assertEquals(0, EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, null, null));
+ assertEquals(0, EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, null, null));
+ }
}