Add initial support for uploading new Contacts to Exchange server
* Refactor the sync adapters to separate out parsing from commit
* Use ContactsProvider to save the SyncKey for contacts
* Fixes #2072664 and #2072456
Change-Id: I1e85c498496e83d9523489636a75f366f7fbd106
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 62e770b..4f70c44 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -29,6 +29,7 @@
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.email.provider.EmailContent.Message;
import com.android.exchange.adapter.AbstractSyncAdapter;
+import com.android.exchange.adapter.AccountSyncAdapter;
import com.android.exchange.adapter.ContactsSyncAdapter;
import com.android.exchange.adapter.EmailSyncAdapter;
import com.android.exchange.adapter.FolderSyncParser;
@@ -536,7 +537,8 @@
InputStream is = entity.getContent();
// Returns true if we need to sync again
userLog("FolderSync, deviceId = ", mDeviceId);
- if (new FolderSyncParser(is, this).parse()) {
+ if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this))
+ .parse()) {
continue;
}
}
@@ -901,22 +903,19 @@
}
Serializer s = new Serializer();
- if (mailbox.mSyncKey == null) {
- userLog("Mailbox syncKey RESET");
- mailbox.mSyncKey = "0";
- }
String className = target.getCollectionName();
- userLog("Sending ", className, " syncKey: ", mailbox.mSyncKey);
+ String syncKey = target.getSyncKey();
+ userLog("Sending ", className, " syncKey: ", syncKey);
s.start(Tags.SYNC_SYNC)
.start(Tags.SYNC_COLLECTIONS)
.start(Tags.SYNC_COLLECTION)
.data(Tags.SYNC_CLASS, className)
- .data(Tags.SYNC_SYNC_KEY, mailbox.mSyncKey)
+ .data(Tags.SYNC_SYNC_KEY, syncKey)
.data(Tags.SYNC_COLLECTION_ID, mailbox.mServerId)
.tag(Tags.SYNC_DELETES_AS_MOVES);
// EAS doesn't like GetChanges if the syncKey is "0"; not documented
- if (!mailbox.mSyncKey.equals("0")) {
+ if (!syncKey.equals("0")) {
s.tag(Tags.SYNC_GET_CHANGES);
}
s.data(Tags.SYNC_WINDOW_SIZE,
@@ -943,7 +942,7 @@
}
// Send our changes up to the server
- target.sendLocalChanges(s, this);
+ target.sendLocalChanges(s);
s.end().end().end().done();
userLog("Sync, deviceId = ", mDeviceId);
@@ -952,8 +951,8 @@
if (code == HttpStatus.SC_OK) {
InputStream is = resp.getEntity().getContent();
if (is != null) {
- moreAvailable = target.parse(is, this);
- target.cleanup(this);
+ moreAvailable = target.parse(is);
+ target.cleanup();
}
} else {
userLog("Sync response error: ", code);
diff --git a/src/com/android/exchange/adapter/AbstractSyncAdapter.java b/src/com/android/exchange/adapter/AbstractSyncAdapter.java
index 8d9fb58..d6ad165 100644
--- a/src/com/android/exchange/adapter/AbstractSyncAdapter.java
+++ b/src/com/android/exchange/adapter/AbstractSyncAdapter.java
@@ -44,15 +44,15 @@
public Account mAccount;
// Create the data for local changes that need to be sent up to the server
- public abstract boolean sendLocalChanges(Serializer s, EasSyncService service)
+ public abstract boolean sendLocalChanges(Serializer s)
throws IOException;
// Parse incoming data from the EAS server, creating, modifying, and deleting objects as
// required through the EmailProvider
- public abstract boolean parse(InputStream is, EasSyncService service)
+ public abstract boolean parse(InputStream is)
throws IOException;
// The name used to specify the collection type of the target (Email, Calendar, or Contacts)
public abstract String getCollectionName();
- public abstract void cleanup(EasSyncService service);
+ public abstract void cleanup();
public AbstractSyncAdapter(Mailbox mailbox, EasSyncService service) {
mMailbox = mailbox;
@@ -61,12 +61,29 @@
mAccount = service.mAccount;
}
- void userLog(String ...strings) {
+ public void userLog(String ...strings) {
mService.userLog(strings);
}
- void incrementChangeCount() {
+ public void incrementChangeCount() {
mService.mChangeCount++;
}
+
+ /**
+ * Returns the current SyncKey; override if the SyncKey is stored elsewhere (as for Contacts)
+ * @return the current SyncKey for the Mailbox
+ * @throws IOException
+ */
+ public String getSyncKey() throws IOException {
+ if (mMailbox.mSyncKey == null) {
+ userLog("Reset SyncKey to 0");
+ mMailbox.mSyncKey = "0";
+ }
+ return mMailbox.mSyncKey;
+ }
+
+ public void setSyncKey(String syncKey, boolean inCommands) throws IOException {
+ mMailbox.mSyncKey = syncKey;
+ }
}
diff --git a/src/com/android/exchange/adapter/AbstractSyncParser.java b/src/com/android/exchange/adapter/AbstractSyncParser.java
index d598c22..66d8aba 100644
--- a/src/com/android/exchange/adapter/AbstractSyncParser.java
+++ b/src/com/android/exchange/adapter/AbstractSyncParser.java
@@ -43,10 +43,12 @@
protected Account mAccount;
protected Context mContext;
protected ContentResolver mContentResolver;
+ protected AbstractSyncAdapter mAdapter;
- public AbstractSyncParser(InputStream in, EasSyncService _service) throws IOException {
+ public AbstractSyncParser(InputStream in, AbstractSyncAdapter adapter) throws IOException {
super(in);
- mService = _service;
+ mAdapter = adapter;
+ mService = adapter.mService;
mContext = mService.mContext;
mContentResolver = mContext.getContentResolver();
mMailbox = mService.mMailbox;
@@ -61,13 +63,15 @@
/**
* Read, parse, and act on server responses
- * Email doesn't have any, so this isn't yet implemented anywhere. It will become abstract,
- * in the near future, however.
* @throws IOException
*/
- public void responsesParser() throws IOException {
- // Placeholder until needed; will become an abstract method
- }
+ public abstract void responsesParser() throws IOException;
+
+ /**
+ * Commit any changes found during parsing
+ * @throws IOException
+ */
+ public abstract void commit() throws IOException;
/**
* Delete all records of this class in this account
@@ -101,7 +105,7 @@
// Status = 3 means invalid sync key
if (status == 3) {
// Must delete all of the data and start over with syncKey of "0"
- mMailbox.mSyncKey = "0";
+ mAdapter.setSyncKey("0", false);
// Make this a push box through the first sync
// TODO Make frequency conditional on user settings!
mMailbox.mSyncInterval = Mailbox.CHECK_INTERVAL_PUSH;
@@ -123,12 +127,12 @@
} else if (tag == Tags.SYNC_MORE_AVAILABLE) {
moreAvailable = true;
} else if (tag == Tags.SYNC_SYNC_KEY) {
- if (mMailbox.mSyncKey.equals("0")) {
+ if (mAdapter.getSyncKey().equals("0")) {
moreAvailable = true;
}
String newKey = getValue();
userLog("Parsed key for ", mMailbox.mDisplayName, ": ", newKey);
- mMailbox.mSyncKey = newKey;
+ mAdapter.setSyncKey(newKey, true);
// If we were pushing (i.e. auto-start), now we'll become ping-triggered
if (mMailbox.mSyncInterval == Mailbox.CHECK_INTERVAL_PUSH) {
mMailbox.mSyncInterval = Mailbox.CHECK_INTERVAL_PING;
@@ -138,15 +142,15 @@
}
}
+ // Commit any changes
+ commit();
+
// If the sync interval has changed, or if no commands were parsed save the change
- if (mMailbox.mSyncInterval != interval || mService.mChangeCount == 0) {
+ if (mMailbox.mSyncInterval != interval) {
synchronized (mService.getSynchronizer()) {
if (!mService.isStopped()) {
// Make sure we save away the new syncFrequency
ContentValues cv = new ContentValues();
- if (mService.mChangeCount == 0) {
- cv.put(MailboxColumns.SYNC_KEY, mMailbox.mSyncKey);
- }
cv.put(MailboxColumns.SYNC_INTERVAL, mMailbox.mSyncInterval);
mMailbox.update(mContext, cv);
}
diff --git a/src/com/android/exchange/adapter/AccountSyncAdapter.java b/src/com/android/exchange/adapter/AccountSyncAdapter.java
new file mode 100644
index 0000000..2a1c7be
--- /dev/null
+++ b/src/com/android/exchange/adapter/AccountSyncAdapter.java
@@ -0,0 +1,34 @@
+package com.android.exchange.adapter;
+
+import com.android.email.provider.EmailContent.Mailbox;
+import com.android.exchange.EasSyncService;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class AccountSyncAdapter extends AbstractSyncAdapter {
+
+ public AccountSyncAdapter(Mailbox mailbox, EasSyncService service) {
+ super(mailbox, service);
+ }
+
+ @Override
+ public void cleanup() {
+ }
+
+ @Override
+ public String getCollectionName() {
+ return null;
+ }
+
+ @Override
+ public boolean parse(InputStream is) throws IOException {
+ return false;
+ }
+
+ @Override
+ public boolean sendLocalChanges(Serializer s) throws IOException {
+ return false;
+ }
+
+}
diff --git a/src/com/android/exchange/adapter/CalendarSyncAdapter.java b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
index 2c716fb..739c9e2 100644
--- a/src/com/android/exchange/adapter/CalendarSyncAdapter.java
+++ b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
@@ -39,18 +39,18 @@
}
@Override
- public boolean sendLocalChanges(Serializer s, EasSyncService service) throws IOException {
+ public boolean sendLocalChanges(Serializer s) throws IOException {
// TODO Auto-generated method stub
return false;
}
@Override
- public void cleanup(EasSyncService service) {
+ public void cleanup() {
// TODO Auto-generated method stub
}
@Override
- public boolean parse(InputStream is, EasSyncService service) throws IOException {
+ public boolean parse(InputStream is) throws IOException {
// TODO Auto-generated method stub
return false;
}
diff --git a/src/com/android/exchange/adapter/ContactsSyncAdapter.java b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
index cb24810..f55adf0 100644
--- a/src/com/android/exchange/adapter/ContactsSyncAdapter.java
+++ b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
@@ -19,10 +19,10 @@
import com.android.email.codec.binary.Base64;
import com.android.email.provider.EmailContent.Mailbox;
-import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.exchange.Eas;
import com.android.exchange.EasSyncService;
+import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
@@ -37,9 +37,11 @@
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
+import android.provider.SyncStateContract;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.SyncState;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Im;
@@ -66,6 +68,7 @@
private static final String TAG = "EasContactsSyncAdapter";
private static final String SERVER_ID_SELECTION = RawContacts.SOURCE_ID + "=?";
+ private static final String CLIENT_ID_SELECTION = RawContacts.SYNC1 + "=?";
private static final String[] ID_PROJECTION = new String[] {RawContacts._ID};
private static final String[] GROUP_PROJECTION = new String[] {Groups.SOURCE_ID};
@@ -112,16 +115,71 @@
ArrayList<Long> mDeletedIdList = new ArrayList<Long>();
ArrayList<Long> mUpdatedIdList = new ArrayList<Long>();
+ android.accounts.Account mAccountManagerAccount;
+
public ContactsSyncAdapter(Mailbox mailbox, EasSyncService service) {
super(mailbox, service);
}
@Override
- public boolean parse(InputStream is, EasSyncService service) throws IOException {
- EasContactsSyncParser p = new EasContactsSyncParser(is, service);
+ public boolean parse(InputStream is) throws IOException {
+ EasContactsSyncParser p = new EasContactsSyncParser(is, this);
return p.parse();
}
+ /**
+ * We get our SyncKey from ContactsProvider. If there's not one, we set it to "0" (the reset
+ * state) and save that away.
+ */
+ @Override
+ public String getSyncKey() throws IOException {
+ ContentProviderClient client =
+ mService.mContentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
+ try {
+ byte[] data = SyncStateContract.Helpers.get(client,
+ ContactsContract.SyncState.CONTENT_URI, getAccountManagerAccount());
+ if (data == null || data.length == 0) {
+ setSyncKey("0", false);
+ return "0";
+ } else {
+ String syncKey = new String(data);
+ userLog("SyncKey retrieved from ContactsProvider: " + syncKey);
+ return syncKey;
+ }
+ } catch (RemoteException e) {
+ throw new IOException("Can't get SyncKey from ContactsProvider");
+ }
+ }
+
+ /**
+ * We only need to set this when we're forced to make the SyncKey "0" (a reset). In all other
+ * cases, the SyncKey is set within ContactOperations
+ */
+ @Override
+ public void setSyncKey(String syncKey, boolean inCommands) throws IOException {
+ if ("0".equals(syncKey) || !inCommands) {
+ ContentProviderClient client =
+ mService.mContentResolver
+ .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
+ try {
+ SyncStateContract.Helpers.set(client, ContactsContract.SyncState.CONTENT_URI,
+ getAccountManagerAccount(), syncKey.getBytes());
+ userLog("SyncKey set to ", syncKey, " in ContactsProvider");
+ } catch (RemoteException e) {
+ throw new IOException("Can't set SyncKey in ContactsProvider");
+ }
+ }
+ mMailbox.mSyncKey = syncKey;
+ }
+
+ public android.accounts.Account getAccountManagerAccount() {
+ if (mAccountManagerAccount == null) {
+ mAccountManagerAccount =
+ new android.accounts.Account(mAccount.mEmailAddress, Eas.ACCOUNT_MANAGER_TYPE);
+ }
+ return mAccountManagerAccount;
+ }
+
// YomiFirstName, YomiLastName, and YomiCompanyName are the names of EAS fields
// Yomi is a shortened form of yomigana, which is a Japanese phonetic rendering.
public static final class Yomi {
@@ -211,9 +269,10 @@
String[] mBindArgument = new String[1];
String mMailboxIdAsString;
Uri mAccountUri;
+ ContactOperations ops = new ContactOperations();
- public EasContactsSyncParser(InputStream in, EasSyncService service) throws IOException {
- super(in, service);
+ public EasContactsSyncParser(InputStream in, ContactsSyncAdapter adapter) throws IOException {
+ super(in, adapter);
mAccountUri = uriWithAccount(RawContacts.CONTENT_URI);
}
@@ -588,6 +647,12 @@
mBindArgument, null);
}
+ private Cursor getClientIdCursor(String clientId) {
+ mBindArgument[0] = clientId;
+ return mContentResolver.query(mAccountUri, ID_PROJECTION, CLIENT_ID_SELECTION,
+ mBindArgument, null);
+ }
+
public void deleteParser(ContactOperations ops) throws IOException {
while (nextTag(Tags.SYNC_DELETE) != END) {
switch (tag) {
@@ -663,7 +728,6 @@
@Override
public void commandsParser() throws IOException {
- ContactOperations ops = new ContactOperations();
while (nextTag(Tags.SYNC_COMMANDS) != END) {
if (tag == Tags.SYNC_ADD) {
addParser(ops);
@@ -677,6 +741,14 @@
} else
skipTag();
}
+ }
+
+ @Override
+ public void commit() throws IOException {
+ // Save the syncKey here, using the Helper provider by Contacts provider
+ userLog("Contacts SyncKey saved as: ", mMailbox.mSyncKey);
+ ops.add(SyncStateContract.Helpers.newSetOperation(SyncState.CONTENT_URI,
+ getAccountManagerAccount(), mMailbox.mSyncKey.getBytes()));
// Execute these all at once...
ops.execute();
@@ -694,12 +766,57 @@
}
}
}
+ }
- // Update the sync key in the database
- userLog("Contacts SyncKey saved as: ", mMailbox.mSyncKey);
+ public void addResponsesParser() throws IOException {
+ String serverId = null;
+ String clientId = null;
ContentValues cv = new ContentValues();
- cv.put(MailboxColumns.SYNC_KEY, mMailbox.mSyncKey);
- Mailbox.update(mContext, Mailbox.CONTENT_URI, mMailbox.mId, cv);
+ while (nextTag(Tags.SYNC_ADD) != END) {
+ switch (tag) {
+ case Tags.SYNC_SERVER_ID:
+ serverId = getValue();
+ break;
+ case Tags.SYNC_CLIENT_ID:
+ clientId = getValue();
+ break;
+ case Tags.SYNC_STATUS:
+ getValue();
+ break;
+ default:
+ skipTag();
+ }
+ }
+
+ // This is theoretically impossible, but...
+ if (clientId == null || serverId == null) return;
+
+ Cursor c = getClientIdCursor(clientId);
+ try {
+ if (c.moveToFirst()) {
+ cv.put(RawContacts.SOURCE_ID, serverId);
+ cv.put(RawContacts.DIRTY, 0);
+ ops.add(ContentProviderOperation.newUpdate(ContentUris
+ .withAppendedId(RawContacts.CONTENT_URI, c.getLong(0)))
+ .withValues(cv)
+ .build());
+ userLog("New contact " + clientId + " was given serverId: " + serverId);
+ }
+ } finally {
+ c.close();
+ }
+ }
+ @Override
+ public void responsesParser() throws IOException {
+ // Handle server responses here (for Add and Change)
+ while (nextTag(Tags.SYNC_RESPONSES) != END) {
+ if (tag == Tags.SYNC_ADD) {
+ addResponsesParser();
+ } else if (tag == Tags.SYNC_CHANGE) {
+ //changeResponsesParser();
+ } else
+ skipTag();
+ }
}
}
@@ -1142,7 +1259,7 @@
}
@Override
- public void cleanup(EasSyncService service) {
+ public void cleanup() {
// Mark the changed contacts dirty = 0
// TODO Put this in a single batch
ContactOperations ops = new ContactOperations();
@@ -1190,8 +1307,9 @@
}
private void sendIm(Serializer s, ContentValues cv) throws IOException {
- String value = cv.getAsString(Email.DATA);
- switch (cv.getAsInteger(Email.TYPE)) {
+ String value = cv.getAsString(Im.DATA);
+ if (value == null) return;
+ switch (cv.getAsInteger(Im.TYPE)) {
case TYPE_IM1:
s.data(Tags.CONTACTS2_IM_ADDRESS, value);
break;
@@ -1411,21 +1529,22 @@
}
@Override
- public boolean sendLocalChanges(Serializer s, EasSyncService service) throws IOException {
+ public boolean sendLocalChanges(Serializer s) throws IOException {
// First, let's find Contacts that have changed.
- ContentResolver cr = service.mContentResolver;
+ ContentResolver cr = mService.mContentResolver;
Uri uri = RawContacts.CONTENT_URI.buildUpon()
- .appendQueryParameter(RawContacts.ACCOUNT_NAME, service.mAccount.mEmailAddress)
+ .appendQueryParameter(RawContacts.ACCOUNT_NAME, mAccount.mEmailAddress)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, Eas.ACCOUNT_MANAGER_TYPE)
.build();
- if (service.mMailbox.mSyncKey.equals("0")) {
+ if (getSyncKey().equals("0")) {
return false;
}
try {
// Get them all atomically
EntityIterator ei = cr.queryEntities(uri, RawContacts.DIRTY + "=1", null, null);
+ ContentValues cidValues = new ContentValues();
try {
boolean first = true;
while (ei.hasNext()) {
@@ -1433,17 +1552,25 @@
// For each of these entities, create the change commands
ContentValues entityValues = entity.getEntityValues();
String serverId = entityValues.getAsString(RawContacts.SOURCE_ID);
- if (serverId == null) {
- // TODO Handle upload of new contacts
- continue;
- }
ArrayList<Integer> groupIds = new ArrayList<Integer>();
if (first) {
s.start(Tags.SYNC_COMMANDS);
first = false;
}
- s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, serverId)
- .start(Tags.SYNC_APPLICATION_DATA);
+ if (serverId == null) {
+ // This is a new contact; create a clientId
+ String clientId = "new_" + mMailbox.mId + '_' + System.currentTimeMillis();
+ s.start(Tags.SYNC_ADD).data(Tags.SYNC_CLIENT_ID, clientId);
+ // And save it in the raw contact
+ cidValues.put(ContactsContract.RawContacts.SYNC1, clientId);
+ cr.update(ContentUris.
+ withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
+ entityValues.getAsLong(ContactsContract.RawContacts._ID)),
+ cidValues, null, null);
+ } else {
+ s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, serverId);
+ }
+ s.start(Tags.SYNC_APPLICATION_DATA);
// Write out the data here
for (NamedContentValues ncv: entity.getSubValues()) {
ContentValues cv = ncv.values;
diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
index 6762d4b..2cd43c2 100644
--- a/src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -72,8 +72,8 @@
}
@Override
- public boolean parse(InputStream is, EasSyncService service) throws IOException {
- EasEmailSyncParser p = new EasEmailSyncParser(is, service);
+ public boolean parse(InputStream is) throws IOException {
+ EasEmailSyncParser p = new EasEmailSyncParser(is, this);
return p.parse();
}
@@ -84,8 +84,12 @@
private String mMailboxIdAsString;
- public EasEmailSyncParser(InputStream in, EasSyncService service) throws IOException {
- super(in, service);
+ ArrayList<Message> newEmails = new ArrayList<Message>();
+ ArrayList<Long> deletedEmails = new ArrayList<Long>();
+ ArrayList<ServerChange> changedEmails = new ArrayList<ServerChange>();
+
+ public EasEmailSyncParser(InputStream in, EmailSyncAdapter adapter) throws IOException {
+ super(in, adapter);
mMailboxIdAsString = Long.toString(mMailbox.mId);
}
@@ -399,11 +403,6 @@
*/
@Override
public void commandsParser() throws IOException {
- ArrayList<Message> newEmails = new ArrayList<Message>();
- ArrayList<Long> deletedEmails = new ArrayList<Long>();
- ArrayList<ServerChange> changedEmails = new ArrayList<ServerChange>();
- int notifyCount = 0;
-
while (nextTag(Tags.SYNC_COMMANDS) != END) {
if (tag == Tags.SYNC_ADD) {
addParser(newEmails);
@@ -417,6 +416,15 @@
} else
skipTag();
}
+ }
+
+ @Override
+ public void responsesParser() throws IOException {
+ }
+
+ @Override
+ public void commit() throws IOException {
+ int notifyCount = 0;
// Use a batch operation to handle the changes
// TODO New mail notifications? Who looks for these?
@@ -500,12 +508,12 @@
}
@Override
- public void cleanup(EasSyncService service) {
+ public void cleanup() {
if (!mDeletedIdList.isEmpty() || !mUpdatedIdList.isEmpty()) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
addCleanupOps(ops);
try {
- service.mContext.getContentResolver()
+ mContext.getContentResolver()
.applyBatch(EmailProvider.EMAIL_AUTHORITY, ops);
} catch (RemoteException e) {
// There is nothing to be done here; fail by returning null
@@ -546,7 +554,7 @@
}
@Override
- public boolean sendLocalChanges(Serializer s, EasSyncService service) throws IOException {
+ public boolean sendLocalChanges(Serializer s) throws IOException {
ContentResolver cr = mContext.getContentResolver();
// Find any of our deleted items
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index 379a80f..646c357 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -24,7 +24,6 @@
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.exchange.Eas;
-import com.android.exchange.EasSyncService;
import com.android.exchange.MockParserStream;
import com.android.exchange.SyncManager;
@@ -88,8 +87,8 @@
private MockParserStream mMock = null;
private String[] mBindArguments = new String[2];
- public FolderSyncParser(InputStream in, EasSyncService service) throws IOException {
- super(in, service);
+ public FolderSyncParser(InputStream in, AbstractSyncAdapter adapter) throws IOException {
+ super(in, adapter);
mAccountId = mAccount.mId;
mAccountIdAsString = Long.toString(mAccountId);
if (in instanceof MockParserStream) {
@@ -330,12 +329,27 @@
}
}
+ /**
+ * Not needed for FolderSync parsing; everything is done within changesParser
+ */
@Override
public void commandsParser() throws IOException {
}
+ /**
+ * We don't need to implement commit() because all operations take place atomically within
+ * changesParser
+ */
+ @Override
+ public void commit() throws IOException {
+ }
+
@Override
public void wipe() {
}
+ @Override
+ public void responsesParser() throws IOException {
+ }
+
}
diff --git a/tests/src/com/android/exchange/EasEmailSyncAdapterTests.java b/tests/src/com/android/exchange/EasEmailSyncAdapterTests.java
index 6d7ba5e..e6f7353 100644
--- a/tests/src/com/android/exchange/EasEmailSyncAdapterTests.java
+++ b/tests/src/com/android/exchange/EasEmailSyncAdapterTests.java
@@ -65,7 +65,7 @@
public void testGetMimeTypeFromFileName() throws IOException {
EasSyncService service = getTestService();
EmailSyncAdapter adapter = new EmailSyncAdapter(service.mMailbox, service);
- EasEmailSyncParser p = adapter.new EasEmailSyncParser(getTestInputStream(), service);
+ EasEmailSyncParser p = adapter.new EasEmailSyncParser(getTestInputStream(), adapter);
// Test a few known types
String mimeType = p.getMimeTypeFromFileName("foo.jpg");
assertEquals("image/jpeg", mimeType);