Merge "Stop calendar/contacts sync in progress when sync setting is turned off"
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 410d716..a3d2587 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -1642,6 +1642,12 @@
                 return;
             }
 
+            // Every time through the loop we check to see if we're still syncable
+            if (!target.isSyncable()) {
+                mExitStatus = EXIT_DONE;
+                return;
+            }
+
             // Now, handle various requests
             while (true) {
                 Request req = null;
diff --git a/src/com/android/exchange/adapter/AbstractSyncAdapter.java b/src/com/android/exchange/adapter/AbstractSyncAdapter.java
index d6ad165..1e0aff5 100644
--- a/src/com/android/exchange/adapter/AbstractSyncAdapter.java
+++ b/src/com/android/exchange/adapter/AbstractSyncAdapter.java
@@ -17,6 +17,7 @@
 
 package com.android.exchange.adapter;
 
+import com.android.email.Email;
 import com.android.email.provider.EmailContent.Account;
 import com.android.email.provider.EmailContent.Mailbox;
 import com.android.exchange.EasSyncService;
@@ -42,6 +43,7 @@
     public EasSyncService mService;
     public Context mContext;
     public Account mAccount;
+    public final android.accounts.Account mAccountManagerAccount;
 
     // Create the data for local changes that need to be sent up to the server
     public abstract boolean sendLocalChanges(Serializer s)
@@ -53,12 +55,15 @@
     // The name used to specify the collection type of the target (Email, Calendar, or Contacts)
     public abstract String getCollectionName();
     public abstract void cleanup();
+    public abstract boolean isSyncable();
 
     public AbstractSyncAdapter(Mailbox mailbox, EasSyncService service) {
         mMailbox = mailbox;
         mService = service;
         mContext = service.mContext;
         mAccount = service.mAccount;
+        mAccountManagerAccount = new android.accounts.Account(mAccount.mEmailAddress,
+                Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
     }
 
     public void userLog(String ...strings) {
diff --git a/src/com/android/exchange/adapter/AccountSyncAdapter.java b/src/com/android/exchange/adapter/AccountSyncAdapter.java
index 2a1c7be..ed85dd7 100644
--- a/src/com/android/exchange/adapter/AccountSyncAdapter.java
+++ b/src/com/android/exchange/adapter/AccountSyncAdapter.java
@@ -31,4 +31,8 @@
         return false;
     }
 
+    @Override
+    public boolean isSyncable() {
+        return true;
+    }
 }
diff --git a/src/com/android/exchange/adapter/CalendarSyncAdapter.java b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
index 361de1e..b9fea2d 100644
--- a/src/com/android/exchange/adapter/CalendarSyncAdapter.java
+++ b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
@@ -99,7 +99,6 @@
     private static final Uri sExtendedPropertiesUri = asSyncAdapter(ExtendedProperties.CONTENT_URI);
     private static final Uri sRemindersUri = asSyncAdapter(Reminders.CONTENT_URI);
 
-    private android.accounts.Account mAccountManagerAccount;
     private long mCalendarId = -1;
 
     private ArrayList<Long> mDeletedIdList = new ArrayList<Long>();
@@ -135,6 +134,11 @@
     }
 
     @Override
+    public boolean isSyncable() {
+        return ContentResolver.getSyncAutomatically(mAccountManagerAccount, Calendar.AUTHORITY);
+    }
+
+    @Override
     public boolean parse(InputStream is) throws IOException {
         EasCalendarSyncParser p = new EasCalendarSyncParser(is, this);
         return p.parse();
@@ -165,7 +169,7 @@
             mService.mContentResolver.acquireContentProviderClient(Calendar.CONTENT_URI);
         try {
             byte[] data = SyncStateContract.Helpers.get(client,
-                    asSyncAdapter(Calendar.SyncState.CONTENT_URI), getAccountManagerAccount());
+                    asSyncAdapter(Calendar.SyncState.CONTENT_URI), mAccountManagerAccount);
             if (data == null || data.length == 0) {
                 // Initialize the SyncKey
                 setSyncKey("0", false);
@@ -190,7 +194,7 @@
                     .acquireContentProviderClient(Calendar.CONTENT_URI);
             try {
                 SyncStateContract.Helpers.set(client, asSyncAdapter(Calendar.SyncState.CONTENT_URI),
-                        getAccountManagerAccount(), syncKey.getBytes());
+                        mAccountManagerAccount, syncKey.getBytes());
                 userLog("SyncKey set to ", syncKey, " in CalendarProvider");
            } catch (RemoteException e) {
                 throw new IOException("Can't set SyncKey in CalendarProvider");
@@ -199,15 +203,6 @@
         mMailbox.mSyncKey = syncKey;
     }
 
-    public android.accounts.Account getAccountManagerAccount() {
-        if (mAccountManagerAccount == null) {
-            mAccountManagerAccount =
-                new android.accounts.Account(mAccount.mEmailAddress,
-                        Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
-        }
-        return mAccountManagerAccount;
-    }
-
     class EasCalendarSyncParser extends AbstractSyncParser {
 
         String[] mBindArgument = new String[1];
@@ -775,7 +770,7 @@
             userLog("Calendar SyncKey saved as: ", mMailbox.mSyncKey);
             // Save the syncKey here, using the Helper provider by Calendar provider
             mOps.add(SyncStateContract.Helpers.newSetOperation(SyncState.CONTENT_URI,
-                    getAccountManagerAccount(), mMailbox.mSyncKey.getBytes()));
+                    mAccountManagerAccount, mMailbox.mSyncKey.getBytes()));
 
             // Execute these all at once...
             mOps.execute();
diff --git a/src/com/android/exchange/adapter/ContactsSyncAdapter.java b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
index d471616..9d9935a 100644
--- a/src/com/android/exchange/adapter/ContactsSyncAdapter.java
+++ b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
@@ -23,19 +23,26 @@
 
 import android.content.ContentProviderClient;
 import android.content.ContentProviderOperation;
-import android.content.ContentProviderOperation.Builder;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Entity;
-import android.content.Entity.NamedContentValues;
 import android.content.EntityIterator;
 import android.content.OperationApplicationException;
+import android.content.ContentProviderOperation.Builder;
+import android.content.Entity.NamedContentValues;
 import android.database.Cursor;
 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.RawContactsEntity;
+import android.provider.ContactsContract.Settings;
+import android.provider.ContactsContract.SyncState;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Event;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -49,13 +56,6 @@
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.CommonDataKinds.Website;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Groups;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.RawContactsEntity;
-import android.provider.ContactsContract.Settings;
-import android.provider.ContactsContract.SyncState;
-import android.provider.SyncStateContract;
 import android.text.util.Rfc822Token;
 import android.text.util.Rfc822Tokenizer;
 import android.util.Log;
@@ -123,8 +123,6 @@
 
     private boolean mGroupsUsed = false;
 
-    private android.accounts.Account mAccountManagerAccount;
-
     public ContactsSyncAdapter(Mailbox mailbox, EasSyncService service) {
         super(mailbox, service);
     }
@@ -136,6 +134,12 @@
     }
 
     @Override
+    public boolean isSyncable() {
+        return ContentResolver.getSyncAutomatically(
+                mAccountManagerAccount, ContactsContract.AUTHORITY);
+    }
+
+    @Override
     public boolean parse(InputStream is) throws IOException {
         EasContactsSyncParser p = new EasContactsSyncParser(is, this);
         return p.parse();
@@ -156,7 +160,7 @@
             mService.mContentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
         try {
             byte[] data = SyncStateContract.Helpers.get(client,
-                    ContactsContract.SyncState.CONTENT_URI, getAccountManagerAccount());
+                    ContactsContract.SyncState.CONTENT_URI, mAccountManagerAccount);
             if (data == null || data.length == 0) {
                 // Initialize the SyncKey
                 setSyncKey("0", false);
@@ -187,7 +191,7 @@
                     .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
             try {
                 SyncStateContract.Helpers.set(client, ContactsContract.SyncState.CONTENT_URI,
-                        getAccountManagerAccount(), syncKey.getBytes());
+                        mAccountManagerAccount, syncKey.getBytes());
                 userLog("SyncKey set to ", syncKey, " in ContactsProvider");
            } catch (RemoteException e) {
                 throw new IOException("Can't set SyncKey in ContactsProvider");
@@ -196,14 +200,6 @@
         mMailbox.mSyncKey = syncKey;
     }
 
-    public android.accounts.Account getAccountManagerAccount() {
-        if (mAccountManagerAccount == null) {
-            mAccountManagerAccount = new android.accounts.Account(mAccount.mEmailAddress,
-                    com.android.email.Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
-        }
-        return mAccountManagerAccount;
-    }
-
     public static final class EasChildren {
         private EasChildren() {}
 
@@ -792,7 +788,7 @@
            // 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()));
+                    mAccountManagerAccount, mMailbox.mSyncKey.getBytes()));
 
             // Execute these all at once...
             ops.execute();
diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
index 49a1d99..66832ed 100644
--- a/src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -91,6 +91,11 @@
         return p.parse();
     }
 
+    @Override
+    public boolean isSyncable() {
+        return true;
+    }
+
     public class EasEmailSyncParser extends AbstractSyncParser {
 
         private static final String WHERE_SERVER_ID_AND_MAILBOX_KEY =