Merge "Split Apply Ops Into Chuncks" into jb-ub-mail-ur10
diff --git a/src/com/android/exchange/ExchangeService.java b/src/com/android/exchange/ExchangeService.java
index cd391c3..8733b5c 100644
--- a/src/com/android/exchange/ExchangeService.java
+++ b/src/com/android/exchange/ExchangeService.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -32,6 +33,8 @@
import android.provider.CalendarContract;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.RawContacts;
import com.android.emailcommon.Api;
import com.android.emailcommon.provider.Account;
@@ -363,34 +366,6 @@
return accounts;
}
- public static void deleteAccountPIMData(final Context context, final long accountId) {
- /*Mailbox mailbox =
- Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_CONTACTS);
- if (mailbox != null) {
- EasSyncService service = EasSyncService.getServiceForMailbox(context, mailbox);
- // ContactsSyncAdapter is gone now, and this class is deprecated.
- // Just leaving this commented out code here for reference.
- ContactsSyncAdapter adapter = new ContactsSyncAdapter(service);
- adapter.wipe();
- }*/
- final Mailbox mailbox =
- Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_CALENDAR);
-
- if (mailbox != null) {
- final EasSyncService service = EasSyncService.getServiceForMailbox(context, mailbox);
- final Uri eventsAsSyncAdapter = eventsAsSyncAdapter(Events.CONTENT_URI,
- service.mAccount.mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
- // CalenderSyncAdapter is gone now, and this class is deprecated.
- // Just leaving this commented out code here for reference.
-// CalendarSyncAdapter adapter = new CalendarSyncAdapter(service);
-// adapter.wipe();
- // Need to have a selection since we don't specify an id in the url
- context.getContentResolver().delete(eventsAsSyncAdapter, "TRUE", new String[0]);
- unregisterCalendarObservers();
-
- }
- }
-
public static boolean onSecurityHold(Account account) {
return (account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0;
}
@@ -399,10 +374,12 @@
return (account.mFlags & Account.FLAGS_SYNC_DISABLED) != 0;
}
- private static Uri eventsAsSyncAdapter(Uri uri, String account, String accountType) {
- return uri.buildUpon().appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
- .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
- .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
+ private static Uri eventsAsSyncAdapter(final Uri uri, final String account,
+ final String accountType) {
+ return uri.buildUpon()
+ .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
+ .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
+ .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
}
/**
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index 2826533..49f88b3 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -40,6 +40,8 @@
import com.android.exchange.CommandStatusException.CommandStatus;
import com.android.exchange.Eas;
import com.android.exchange.ExchangeService;
+import com.android.exchange.service.EasCalendarSyncHandler;
+import com.android.exchange.service.EasContactsSyncHandler;
import com.android.mail.utils.LogUtils;
import com.google.common.annotations.VisibleForTesting;
@@ -149,15 +151,15 @@
@VisibleForTesting
boolean mInUnitTest = false;
- private String[] mBindArguments = new String[2];
+ private final String[] mBindArguments = new String[2];
/** List of pending operations to send as a batch to the content provider. */
- private ArrayList<ContentProviderOperation> mOperations =
+ private final ArrayList<ContentProviderOperation> mOperations =
new ArrayList<ContentProviderOperation>();
/** Indicates whether this sync is an initial FolderSync. */
private boolean mInitialSync;
/** List of folder server ids whose children changed with this sync. */
- private ArrayList<String> mParentFixupsNeeded = new ArrayList<String>();
+ private final ArrayList<String> mParentFixupsNeeded = new ArrayList<String>();
/** Indicates whether the sync response provided a different sync key than we had. */
private boolean mSyncKeyChanged = false;
@@ -237,8 +239,11 @@
// and EAS 14 style command status
} else if (status == Eas.FOLDER_STATUS_INVALID_KEY ||
CommandStatus.isBadSyncKey(status)) {
- // Delete PIM data
- ExchangeService.deleteAccountPIMData(mContext, mAccountId);
+ EasCalendarSyncHandler.wipeAccountFromContentProvider(mContext,
+ mAccount.mEmailAddress);
+ EasContactsSyncHandler.wipeAccountFromContentProvider(mContext,
+ mAccount.mEmailAddress);
+
// Save away any mailbox sync information that is NOT default
saveMailboxSyncOptions();
// And only then, delete mailboxes
diff --git a/src/com/android/exchange/provider/ExchangeDirectoryProvider.java b/src/com/android/exchange/provider/ExchangeDirectoryProvider.java
index 75740bd..2b94271 100644
--- a/src/com/android/exchange/provider/ExchangeDirectoryProvider.java
+++ b/src/com/android/exchange/provider/ExchangeDirectoryProvider.java
@@ -84,6 +84,7 @@
@Override
public boolean onCreate() {
+ EmailContent.init(getContext());
return true;
}
diff --git a/src/com/android/exchange/service/AbstractSyncAdapterService.java b/src/com/android/exchange/service/AbstractSyncAdapterService.java
index eb56083..bb1e7e2 100644
--- a/src/com/android/exchange/service/AbstractSyncAdapterService.java
+++ b/src/com/android/exchange/service/AbstractSyncAdapterService.java
@@ -26,11 +26,9 @@
/**
* Base class for services that handle sync requests from the system SyncManager.
* This class covers the boilerplate for using an {@link AbstractThreadedSyncAdapter}. Subclasses
- * should just implement their sync adapter, and override {@link #newSyncAdapter}.
+ * should just implement their sync adapter, and override {@link #getSyncAdapter}.
*/
public abstract class AbstractSyncAdapterService extends Service {
- private AbstractThreadedSyncAdapter mSyncAdapter = null;
-
public AbstractSyncAdapterService() {
super();
}
@@ -40,17 +38,17 @@
super.onCreate();
// Make sure EmailContent is initialized in Exchange app
EmailContent.init(this);
- mSyncAdapter = newSyncAdapter();
}
@Override
public IBinder onBind(Intent intent) {
- return mSyncAdapter.getSyncAdapterBinder();
+ return getSyncAdapter().getSyncAdapterBinder();
}
/**
- * Subclasses should override this to supply a new instance of its sync adapter.
- * @return A new instance of the sync adapter.
+ * Subclasses should override this to supply an instance of its sync adapter. Best practice is
+ * to create a singleton and return that.
+ * @return An instance of the sync adapter.
*/
- protected abstract AbstractThreadedSyncAdapter newSyncAdapter();
+ protected abstract AbstractThreadedSyncAdapter getSyncAdapter();
}
diff --git a/src/com/android/exchange/service/CalendarSyncAdapterService.java b/src/com/android/exchange/service/CalendarSyncAdapterService.java
index 876b1c4..0297847 100644
--- a/src/com/android/exchange/service/CalendarSyncAdapterService.java
+++ b/src/com/android/exchange/service/CalendarSyncAdapterService.java
@@ -40,13 +40,21 @@
private static final String DIRTY_IN_ACCOUNT =
Events.DIRTY + "=1 AND " + Events.ACCOUNT_NAME + "=?";
+ private static final Object sSyncAdapterLock = new Object();
+ private static AbstractThreadedSyncAdapter sSyncAdapter = null;
+
public CalendarSyncAdapterService() {
super();
}
@Override
- protected AbstractThreadedSyncAdapter newSyncAdapter() {
- return new SyncAdapterImpl(this);
+ protected AbstractThreadedSyncAdapter getSyncAdapter() {
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new SyncAdapterImpl(this);
+ }
+ return sSyncAdapter;
+ }
}
private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
diff --git a/src/com/android/exchange/service/ContactsSyncAdapterService.java b/src/com/android/exchange/service/ContactsSyncAdapterService.java
index 54ef2e0..d99cfcd 100644
--- a/src/com/android/exchange/service/ContactsSyncAdapterService.java
+++ b/src/com/android/exchange/service/ContactsSyncAdapterService.java
@@ -40,13 +40,21 @@
private static final String ACCOUNT_AND_TYPE_CONTACTS =
MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_CONTACTS;
+ private static final Object sSyncAdapterLock = new Object();
+ private static AbstractThreadedSyncAdapter sSyncAdapter = null;
+
public ContactsSyncAdapterService() {
super();
}
@Override
- protected AbstractThreadedSyncAdapter newSyncAdapter() {
- return new SyncAdapterImpl(this);
+ protected AbstractThreadedSyncAdapter getSyncAdapter() {
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new SyncAdapterImpl(this);
+ }
+ return sSyncAdapter;
+ }
}
private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
diff --git a/src/com/android/exchange/service/EmailSyncAdapterService.java b/src/com/android/exchange/service/EmailSyncAdapterService.java
index 07ed718..964755c 100644
--- a/src/com/android/exchange/service/EmailSyncAdapterService.java
+++ b/src/com/android/exchange/service/EmailSyncAdapterService.java
@@ -73,6 +73,9 @@
/** Projection used for getting email address for an account. */
private static final String[] ACCOUNT_EMAIL_PROJECTION = { AccountColumns.EMAIL_ADDRESS };
+ private static final Object sSyncAdapterLock = new Object();
+ private static AbstractThreadedSyncAdapter sSyncAdapter = null;
+
/**
* Bookkeeping for handling synchronization between pings and syncs.
* "Ping" refers to a hanging POST or GET that is used to receive push notifications. Ping is
@@ -496,8 +499,13 @@
}
@Override
- protected AbstractThreadedSyncAdapter newSyncAdapter() {
- return new SyncAdapterImpl(this);
+ protected AbstractThreadedSyncAdapter getSyncAdapter() {
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new SyncAdapterImpl(this);
+ }
+ return sSyncAdapter;
+ }
}
// TODO: Handle cancelSync() appropriately.