- clean up the sync settings names to:
   (get|set)SyncAutomatically
   (get|set)MasterSyncAutomatically
- change SYNC_EXTRAS_FORCE to SYNC_EXTRAS_MANUAL to mace clear that
  this overrides the .*SyncAutomatically settings
- make ContentResolver methods that call the sync controls methods
  in IContentService so that SDK users can use them
- rename startSync to requestSync to reinforce the fact that a sync
  is not immediately or always started when this method is called
- add an Account parameter to all the sync settings and control methods
- change the sync control methods to take a String authority rather than a Uri uri
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
index e628dcd..db73dd5 100644
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ b/core/java/android/content/AbstractSyncableContentProvider.java
@@ -141,7 +141,8 @@
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
             if (!upgradeDatabase(db, oldVersion, newVersion)) {
                 mSyncState.discardSyncData(db, null /* all accounts */);
-                getContext().getContentResolver().startSync(mContentUri, new Bundle());
+                ContentResolver.requestSync(null /* all accounts */,
+                        mContentUri.getAuthority(), new Bundle());
             }
         }
 
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index a01c5d1..98ed098 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -48,9 +48,18 @@
  * This class provides applications access to the content model.
  */
 public abstract class ContentResolver {
-    public final static String SYNC_EXTRAS_ACCOUNT = "account";
+    /**
+     * @deprecated instead use
+     * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)}
+     */
+    public static final String SYNC_EXTRAS_ACCOUNT = "account";
     public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
+    /**
+     * @deprecated instead use
+     * {@link #SYNC_EXTRAS_MANUAL}
+     */
     public static final String SYNC_EXTRAS_FORCE = "force";
+    public static final String SYNC_EXTRAS_MANUAL = "force";
     public static final String SYNC_EXTRAS_UPLOAD = "upload";
     public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
     public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions";
@@ -90,7 +99,35 @@
      * in the cursor is the same.
      */
     public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
-    
+
+    /** @hide */
+    public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
+    /** @hide */
+    public static final int SYNC_ERROR_AUTHENTICATION = 2;
+    /** @hide */
+    public static final int SYNC_ERROR_IO = 3;
+    /** @hide */
+    public static final int SYNC_ERROR_PARSE = 4;
+    /** @hide */
+    public static final int SYNC_ERROR_CONFLICT = 5;
+    /** @hide */
+    public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6;
+    /** @hide */
+    public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7;
+    /** @hide */
+    public static final int SYNC_ERROR_INTERNAL = 8;
+
+    /** @hide */
+    public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0;
+    /** @hide */
+    public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1;
+    /** @hide */
+    public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2;
+    /** @hide */
+    public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3;
+    /** @hide */
+    public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff;
+
     public ContentResolver(Context context) {
         mContext = context;
     }
@@ -829,11 +866,42 @@
      *
      * @param uri the uri of the provider to sync or null to sync all providers.
      * @param extras any extras to pass to the SyncAdapter.
+     * @deprecated instead use
+     * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)}
      */
     public void startSync(Uri uri, Bundle extras) {
+        Account account = null;
+        if (extras != null) {
+            String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT);
+            if (!TextUtils.isEmpty(accountName)) {
+                account = new Account(accountName, "com.google.GAIA");
+            }
+            extras.remove(SYNC_EXTRAS_ACCOUNT);
+        }
+        requestSync(account, uri != null ? uri.getAuthority() : null, extras);
+    }
+
+    /**
+     * Start an asynchronous sync operation. If you want to monitor the progress
+     * of the sync you may register a SyncObserver. Only values of the following
+     * types may be used in the extras bundle:
+     * <ul>
+     * <li>Integer</li>
+     * <li>Long</li>
+     * <li>Boolean</li>
+     * <li>Float</li>
+     * <li>Double</li>
+     * <li>String</li>
+     * </ul>
+     *
+     * @param account which account should be synced
+     * @param authority which authority should be synced
+     * @param extras any extras to pass to the SyncAdapter.
+     */
+    public static void requestSync(Account account, String authority, Bundle extras) {
         validateSyncExtrasBundle(extras);
         try {
-            getContentService().startSync(uri, extras);
+            getContentService().requestSync(account, authority, extras);
         } catch (RemoteException e) {
         }
     }
@@ -874,13 +942,186 @@
         }
     }
 
+    /**
+     * Cancel any active or pending syncs that match the Uri. If the uri is null then
+     * all syncs will be canceled.
+     *
+     * @param uri the uri of the provider to sync or null to sync all providers.
+     * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)}
+     */
     public void cancelSync(Uri uri) {
+        cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null);
+    }
+
+    /**
+     * Cancel any active or pending syncs that match account and authority. The account and
+     * authority can each independently be set to null, which means that syncs with any account
+     * or authority, respectively, will match.
+     *
+     * @param account filters the syncs that match by this account
+     * @param authority filters the syncs that match by this authority
+     */
+    public static void cancelSync(Account account, String authority) {
         try {
-            getContentService().cancelSync(uri);
+            getContentService().cancelSync(account, authority);
         } catch (RemoteException e) {
         }
     }
 
+    /**
+     * Get information about the SyncAdapters that are known to the system.
+     * @return an array of SyncAdapters that have registered with the system
+     */
+    public static SyncAdapterType[] getSyncAdapterTypes() {
+        try {
+            return getContentService().getSyncAdapterTypes();
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Check if the provider should be synced when a network tickle is received
+     *
+     * @param account the account whose setting we are querying
+     * @param authority the provider whose setting we are querying
+     * @return true if the provider should be synced when a network tickle is received
+     */
+    public static boolean getSyncAutomatically(Account account, String authority) {
+        try {
+            return getContentService().getSyncAutomatically(account, authority);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Set whether or not the provider is synced when it receives a network tickle.
+     *
+     * @param account the account whose setting we are querying
+     * @param authority the provider whose behavior is being controlled
+     * @param sync true if the provider should be synced when tickles are received for it
+     */
+    public static void setSyncAutomatically(Account account, String authority, boolean sync) {
+        try {
+            getContentService().setSyncAutomatically(account, authority, sync);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
+     * Gets the master auto-sync setting that applies to all the providers and accounts.
+     * If this is false then the per-provider auto-sync setting is ignored.
+     *
+     * @return the master auto-sync setting that applies to all the providers and accounts
+     */
+    public static boolean getMasterSyncAutomatically() {
+        try {
+            return getContentService().getMasterSyncAutomatically();
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Sets the master auto-sync setting that applies to all the providers and accounts.
+     * If this is false then the per-provider auto-sync setting is ignored.
+     *
+     * @param sync the master auto-sync setting that applies to all the providers and accounts
+     */
+    public static void setMasterSyncAutomatically(boolean sync) {
+        try {
+            getContentService().setMasterSyncAutomatically(sync);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
+     * Returns true if there is currently a sync operation for the given
+     * account or authority in the pending list, or actively being processed.
+     * @param account the account whose setting we are querying
+     * @param authority the provider whose behavior is being queried
+     * @return true if a sync is active for the given account or authority.
+     */
+    public static boolean isSyncActive(Account account, String authority) {
+        try {
+            return getContentService().isSyncActive(account, authority);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * If a sync is active returns the information about it, otherwise returns false.
+     * @return the ActiveSyncInfo for the currently active sync or null if one is not active.
+     * @hide
+     */
+    public static ActiveSyncInfo getActiveSync() {
+        try {
+            return getContentService().getActiveSync();
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Returns the status that matches the authority. If there are multiples accounts for
+     * the authority, the one with the latest "lastSuccessTime" status is returned.
+     * @param account the account whose setting we are querying
+     * @param authority the provider whose behavior is being queried
+     * @return the SyncStatusInfo for the authority, or null if none exists
+     * @hide
+     */
+    public static SyncStatusInfo getSyncStatus(Account account, String authority) {
+        try {
+            return getContentService().getSyncStatus(account, authority);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Return true if the pending status is true of any matching authorities.
+     * @param account the account whose setting we are querying
+     * @param authority the provider whose behavior is being queried
+     * @return true if there is a pending sync with the matching account and authority
+     */
+    public static boolean isSyncPending(Account account, String authority) {
+        try {
+            return getContentService().isSyncPending(account, authority);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) {
+        try {
+            ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() {
+                public void onStatusChanged(int which) throws RemoteException {
+                    callback.onStatusChanged(which);
+                }
+            };
+            getContentService().addStatusChangeListener(mask, observer);
+            return observer;
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static void removeStatusChangeListener(Object handle) {
+        try {
+            getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+
     private final class CursorWrapperInner extends CursorWrapper {
         private IContentProvider mContentProvider;
         public static final String TAG="CursorWrapperInner";
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index c768ffa..7a1ad2b 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -161,7 +161,9 @@
             }
             if (syncToNetwork) {
                 SyncManager syncManager = getSyncManager();
-                if (syncManager != null) syncManager.scheduleLocalSync(uri);
+                if (syncManager != null) {
+                    syncManager.scheduleLocalSync(null /* all accounts */, uri.getAuthority());
+                }
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -187,14 +189,16 @@
         }
     }
 
-    public void startSync(Uri url, Bundle extras) {
+    public void requestSync(Account account, String authority, Bundle extras) {
         ContentResolver.validateSyncExtrasBundle(extras);
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) syncManager.startSync(url, extras);
+            if (syncManager != null) {
+                syncManager.scheduleSync(account, authority, extras, 0 /* no delay */);
+            }
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -202,34 +206,50 @@
 
     /**
      * Clear all scheduled sync operations that match the uri and cancel the active sync
-     * if it matches the uri. If the uri is null, clear all scheduled syncs and cancel
-     * the active one, if there is one.
-     * @param uri Filter on the sync operations to cancel, or all if null.
+     * if they match the authority and account, if they are present.
+     * @param account filter the pending and active syncs to cancel using this account
+     * @param authority filter the pending and active syncs to cancel using this authority
      */
-    public void cancelSync(Uri uri) {
+    public void cancelSync(Account account, String authority) {
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.clearScheduledSyncOperations(uri);
-                syncManager.cancelActiveSync(uri);
+                syncManager.clearScheduledSyncOperations(account, authority);
+                syncManager.cancelActiveSync(account, authority);
             }
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    public boolean getSyncProviderAutomatically(String providerName) {
+    /**
+     * Get information about the SyncAdapters that are known to the system.
+     * @return an array of SyncAdapters that have registered with the system
+     */
+    public SyncAdapterType[] getSyncAdapterTypes() {
+        // This makes it so that future permission checks will be in the context of this
+        // process rather than the caller's process. We will restore this before returning.
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            return syncManager.getSyncAdapterTypes();
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+    
+    public boolean getSyncAutomatically(Account account, String providerName) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getSyncProviderAutomatically(
-                        null, providerName);
+                return syncManager.getSyncStorageEngine().getSyncAutomatically(
+                        account, providerName);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -237,29 +257,29 @@
         return false;
     }
 
-    public void setSyncProviderAutomatically(String providerName, boolean sync) {
+    public void setSyncAutomatically(Account account, String providerName, boolean sync) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().setSyncProviderAutomatically(
-                        null, providerName, sync);
+                syncManager.getSyncStorageEngine().setSyncAutomatically(
+                        account, providerName, sync);
             }
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    public boolean getListenForNetworkTickles() {
+    public boolean getMasterSyncAutomatically() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getListenForNetworkTickles();
+                return syncManager.getSyncStorageEngine().getMasterSyncAutomatically();
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -267,14 +287,14 @@
         return false;
     }
     
-    public void setListenForNetworkTickles(boolean flag) {
+    public void setMasterSyncAutomatically(boolean flag) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().setListenForNetworkTickles(flag);
+                syncManager.getSyncStorageEngine().setMasterSyncAutomatically(flag);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -312,7 +332,7 @@
         return null;
     }
     
-    public SyncStatusInfo getStatusByAuthority(String authority) {
+    public SyncStatusInfo getSyncStatus(Account account, String authority) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         long identityToken = clearCallingIdentity();
@@ -328,15 +348,14 @@
         return null;
     }
     
-    public boolean isAuthorityPending(Account account, String authority) {
+    public boolean isSyncPending(Account account, String authority) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().isAuthorityPending(
-                        account, authority);
+                return syncManager.getSyncStorageEngine().isSyncPending(account, authority);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -349,8 +368,7 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().addStatusChangeListener(
-                        mask, callback);
+                syncManager.getSyncStorageEngine().addStatusChangeListener(mask, callback);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -362,8 +380,7 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().removeStatusChangeListener(
-                        callback);
+                syncManager.getSyncStorageEngine().removeStatusChangeListener(callback);
             }
         } finally {
             restoreCallingIdentity(identityToken);
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 4352227..658a5bc 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -19,6 +19,7 @@
 import android.accounts.Account;
 import android.content.ActiveSyncInfo;
 import android.content.ISyncStatusObserver;
+import android.content.SyncAdapterType;
 import android.content.SyncStatusInfo;
 import android.net.Uri;
 import android.os.Bundle;
@@ -35,15 +36,15 @@
     void notifyChange(in Uri uri, IContentObserver observer,
             boolean observerWantsSelfNotifications, boolean syncToNetwork);
 
-    void startSync(in Uri url, in Bundle extras);
-    void cancelSync(in Uri uri);
+    void requestSync(in Account account, String authority, in Bundle extras);
+    void cancelSync(in Account account, String authority);
     
     /**
      * Check if the provider should be synced when a network tickle is received
      * @param providerName the provider whose setting we are querying
      * @return true of the provider should be synced when a network tickle is received
      */
-    boolean getSyncProviderAutomatically(String providerName);
+    boolean getSyncAutomatically(in Account account, String providerName);
 
     /**
      * Set whether or not the provider is synced when it receives a network tickle.
@@ -51,11 +52,11 @@
      * @param providerName the provider whose behavior is being controlled
      * @param sync true if the provider should be synced when tickles are received for it
      */
-    void setSyncProviderAutomatically(String providerName, boolean sync);
+    void setSyncAutomatically(in Account account, String providerName, boolean sync);
 
-    void setListenForNetworkTickles(boolean flag);
+    void setMasterSyncAutomatically(boolean flag);
 
-    boolean getListenForNetworkTickles();
+    boolean getMasterSyncAutomatically();
     
     /**
      * Returns true if there is currently a sync operation for the given
@@ -66,17 +67,23 @@
     ActiveSyncInfo getActiveSync();
     
     /**
+     * Returns the types of the SyncAdapters that are registered with the system.
+     * @return Returns the types of the SyncAdapters that are registered with the system.
+     */
+    SyncAdapterType[] getSyncAdapterTypes();
+
+    /**
      * Returns the status that matches the authority. If there are multiples accounts for
      * the authority, the one with the latest "lastSuccessTime" status is returned.
      * @param authority the authority whose row should be selected
      * @return the SyncStatusInfo for the authority, or null if none exists
      */
-    SyncStatusInfo getStatusByAuthority(String authority);
+    SyncStatusInfo getSyncStatus(in Account account, String authority);
 
     /**
      * Return true if the pending status is true of any matching authorities.
      */
-    boolean isAuthorityPending(in Account account, String authority);
+    boolean isSyncPending(in Account account, String authority);
     
     void addStatusChangeListener(int mask, ISyncStatusObserver callback);
     
diff --git a/core/java/android/content/SyncAdapterType.aidl b/core/java/android/content/SyncAdapterType.aidl
new file mode 100644
index 0000000..e67841f
--- /dev/null
+++ b/core/java/android/content/SyncAdapterType.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+parcelable SyncAdapterType;
+
diff --git a/core/java/android/content/SyncAdapterType.java b/core/java/android/content/SyncAdapterType.java
index 368a879..5a96003 100644
--- a/core/java/android/content/SyncAdapterType.java
+++ b/core/java/android/content/SyncAdapterType.java
@@ -17,12 +17,14 @@
 package android.content;
 
 import android.text.TextUtils;
+import android.os.Parcelable;
+import android.os.Parcel;
 
 /**
  * Value type that represents a SyncAdapterType. This object overrides {@link #equals} and
  * {@link #hashCode}, making it suitable for use as the key of a {@link java.util.Map}
  */
-public class SyncAdapterType {
+public class SyncAdapterType implements Parcelable {
     public final String authority;
     public final String accountType;
 
@@ -54,4 +56,27 @@
     public String toString() {
         return "SyncAdapterType {name=" + authority + ", type=" + accountType + "}";
     }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(authority);
+        dest.writeString(accountType);
+    }
+
+    public SyncAdapterType(Parcel source) {
+        this(source.readString(), source.readString());
+    }
+
+    public static final Creator<SyncAdapterType> CREATOR = new Creator<SyncAdapterType>() {
+        public SyncAdapterType createFromParcel(Parcel source) {
+            return new SyncAdapterType(source);
+        }
+
+        public SyncAdapterType[] newArray(int size) {
+            return new SyncAdapterType[size];
+        }
+    };
 }
\ No newline at end of file
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index c7954a5..f73b394 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -35,7 +35,6 @@
 import android.content.pm.RegisteredServicesCache;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -72,7 +71,7 @@
 import java.util.Map;
 import java.util.PriorityQueue;
 import java.util.Random;
-import java.util.Set;
+import java.util.Collection;
 
 /**
  * @hide
@@ -160,7 +159,7 @@
                             Log.v(TAG, "Internal storage is low.");
                         }
                         mStorageIsLow = true;
-                        cancelActiveSync(null /* no url */);
+                        cancelActiveSync(null /* any account */, null /* any authority */);
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Internal storage is ok.");
@@ -204,7 +203,7 @@
         if (hadAccountsAlready && accounts.length > 0) {
             // request a sync so that if the password was changed we will
             // retry any sync that failed when it was wrong
-            startSync(null /* all providers */, null /* no extras */);
+            scheduleSync(null, null, null, 0 /* no delay */);
         }
     }
 
@@ -327,7 +326,7 @@
         mHandleAlarmWakeLock.setReferenceCounted(false);
 
         mSyncStorageEngine.addStatusChangeListener(
-                SyncStorageEngine.CHANGE_SETTINGS, new ISyncStatusObserver.Stub() {
+                ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, new ISyncStatusObserver.Stub() {
             public void onStatusChanged(int which) {
                 // force the sync loop to run if the settings change
                 sendCheckAlarmsMessage();
@@ -406,7 +405,8 @@
         scheduleSyncPollAlarm(nextRelativePollTimeMs);
 
         // perform a poll
-        scheduleSync(null /* sync all syncable providers */, new Bundle(), 0 /* no delay */);
+        scheduleSync(null /* sync all syncable accounts */, null /* sync all syncable providers */,
+                new Bundle(), 0 /* no delay */);
     }
 
     private void writeSyncPollTime(long when) {
@@ -502,20 +502,21 @@
      *
      * <p>You'll start getting callbacks after this.
      *
-     * @param url The Uri of a specific provider to be synced, or
-     *          null to sync all providers.
+     * @param requestedAccount the account to sync, may be null to signify all accounts
+     * @param requestedAuthority the authority to sync, may be null to indicate all authorities
      * @param extras a Map of SyncAdapter-specific information to control
 *          syncs of a specific provider. Can be null. Is ignored
 *          if the url is null.
      * @param delay how many milliseconds in the future to wait before performing this
-     *   sync. -1 means to make this the next sync to perform.
      */
-    public void scheduleSync(Uri url, Bundle extras, long delay) {
+    public void scheduleSync(Account requestedAccount, String requestedAuthority,
+            Bundle extras, long delay) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         if (isLoggable) {
             Log.v(TAG, "scheduleSync:"
                     + " delay " + delay
-                    + ", url " + ((url == null) ? "(null)" : url)
+                    + ", account " + requestedAccount
+                    + ", authority " + requestedAuthority
                     + ", extras " + ((extras == null) ? "(null)" : extras));
         }
 
@@ -539,9 +540,8 @@
         }
 
         Account[] accounts;
-        Account accountFromExtras = extras.getParcelable(ContentResolver.SYNC_EXTRAS_ACCOUNT);
-        if (accountFromExtras != null) {
-            accounts = new Account[]{accountFromExtras};
+        if (requestedAccount != null) {
+            accounts = new Account[]{requestedAccount};
         } else {
             // if the accounts aren't configured yet then we can't support an account-less
             // sync request
@@ -563,14 +563,14 @@
         }
 
         final boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false);
-        final boolean force = extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false);
+        final boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
 
         int source;
         if (uploadOnly) {
             source = SyncStorageEngine.SOURCE_LOCAL;
-        } else if (force) {
+        } else if (manualSync) {
             source = SyncStorageEngine.SOURCE_USER;
-        } else if (url == null) {
+        } else if (requestedAuthority == null) {
             source = SyncStorageEngine.SOURCE_POLL;
         } else {
             // this isn't strictly server, since arbitrary callers can (and do) request
@@ -578,9 +578,9 @@
             source = SyncStorageEngine.SOURCE_SERVER;
         }
 
-        // compile a list of authorities that have sync adapters
-        // for each authority sync each account that matches a sync adapter
-        Set<String> syncableAuthorities = new HashSet<String>();
+        // Compile a list of authorities that have sync adapters.
+        // For each authority sync each account that matches a sync adapter.
+        final HashSet<String> syncableAuthorities = new HashSet<String>();
         for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter :
                 mSyncAdapters.getAllServices()) {
             syncableAuthorities.add(syncAdapter.type.authority);
@@ -588,10 +588,10 @@
 
         // if the url was specified then replace the list of authorities with just this authority
         // or clear it if this authority isn't syncable
-        if (url != null) {
-            boolean isSyncable = syncableAuthorities.contains(url.getAuthority());
+        if (requestedAuthority != null) {
+            final boolean isSyncable = syncableAuthorities.contains(requestedAuthority);
             syncableAuthorities.clear();
-            if (isSyncable) syncableAuthorities.add(url.getAuthority());
+            if (isSyncable) syncableAuthorities.add(requestedAuthority);
         }
 
         for (String authority : syncableAuthorities) {
@@ -614,10 +614,10 @@
         mStatusText = message;
     }
 
-    public void scheduleLocalSync(Uri url) {
+    public void scheduleLocalSync(Account account, String authority) {
         final Bundle extras = new Bundle();
         extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
-        scheduleSync(url, extras, LOCAL_SYNC_DELAY);
+        scheduleSync(account, authority, extras, LOCAL_SYNC_DELAY);
     }
 
     private IPackageManager getPackageManager() {
@@ -631,18 +631,16 @@
         return mPackageManager;
     }
 
-    /**
-     * Initiate a sync for this given URL, or pass null for a full sync.
-     *
-     * <p>You'll start getting callbacks after this.
-     *
-     * @param url The Uri of a specific provider to be synced, or
-     *          null to sync all providers.
-     * @param extras a Map of SyncAdapter specific information to control
-     *          syncs of a specific provider. Can be null. Is ignored
-     */
-    public void startSync(Uri url, Bundle extras) {
-        scheduleSync(url, extras, 0 /* no delay */);
+    public SyncAdapterType[] getSyncAdapterTypes() {
+        final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos =
+                mSyncAdapters.getAllServices();
+        SyncAdapterType[] types = new SyncAdapterType[serviceInfos.size()];
+        int i = 0;
+        for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) {
+            types[i] = serviceInfo.type;
+            ++i;
+        }
+        return types;
     }
 
     public void updateHeartbeatTime() {
@@ -725,17 +723,22 @@
     }
 
     /**
-     * Cancel the active sync if it matches the uri. The uri corresponds to the one passed
-     * in to startSync().
-     * @param uri If non-null, the active sync is only canceled if it matches the uri.
-     *   If null, any active sync is canceled.
+     * Cancel the active sync if it matches the authority and account.
+     * @param account limit the cancelations to syncs with this account, if non-null
+     * @param authority limit the cancelations to syncs with this authority, if non-null
      */
-    public void cancelActiveSync(Uri uri) {
+    public void cancelActiveSync(Account account, String authority) {
         ActiveSyncContext activeSyncContext = mActiveSyncContext;
         if (activeSyncContext != null) {
-            // if a Uri was specified then only cancel the sync if it matches the the uri
-            if (uri != null) {
-                if (!uri.getAuthority().equals(activeSyncContext.mSyncOperation.authority)) {
+            // if an authority was specified then only cancel the sync if it matches
+            if (account != null) {
+                if (!account.equals(activeSyncContext.mSyncOperation.account)) {
+                    return;
+                }
+            }
+            // if an account was specified then only cancel the sync if it matches
+            if (authority != null) {
+                if (!authority.equals(activeSyncContext.mSyncOperation.authority)) {
                     return;
                 }
             }
@@ -787,14 +790,13 @@
     }
 
     /**
-     * Remove any scheduled sync operations that match uri. The uri corresponds to the one passed
-     * in to startSync().
-     * @param uri If non-null, only operations that match the uri are cleared.
-     *   If null, all operations are cleared.
+     * Remove scheduled sync operations.
+     * @param account limit the removals to operations with this account, if non-null
+     * @param authority limit the removals to operations with this authority, if non-null
      */
-    public void clearScheduledSyncOperations(Uri uri) {
+    public void clearScheduledSyncOperations(Account account, String authority) {
         synchronized (mSyncQueue) {
-            mSyncQueue.clear(null, uri != null ? uri.getAuthority() : null);
+            mSyncQueue.clear(account, authority);
         }
     }
 
@@ -1558,14 +1560,14 @@
             // Otherwise consume SyncOperations from the head of the SyncQueue until one is
             // found that is runnable (not disabled, etc). If that one is ready to run then
             // start it, otherwise just get out.
-            SyncOperation syncOperation;
+            SyncOperation op;
             final ConnectivityManager connManager = (ConnectivityManager)
                     mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-            final boolean backgroundDataSetting = connManager.getBackgroundDataSetting();
+            final boolean backgroundDataUsageAllowed = connManager.getBackgroundDataSetting();
             synchronized (mSyncQueue) {
                 while (true) {
-                    syncOperation = mSyncQueue.head();
-                    if (syncOperation == null) {
+                    op = mSyncQueue.head();
+                    if (op == null) {
                         if (isLoggable) {
                             Log.v(TAG, "runStateIdle: no more sync operations, returning");
                         }
@@ -1575,39 +1577,40 @@
                     // Sync is disabled, drop this operation.
                     if (!isSyncEnabled()) {
                         if (isLoggable) {
-                            Log.v(TAG, "runStateIdle: sync disabled, dropping " + syncOperation);
+                            Log.v(TAG, "runStateIdle: sync disabled, dropping " + op);
                         }
                         mSyncQueue.popHead();
                         continue;
                     }
 
-                    // skip the sync if it isn't a force and the settings are off for this provider
-                    final boolean force = syncOperation.extras.getBoolean(
-                            ContentResolver.SYNC_EXTRAS_FORCE, false);
-                    if (!force && (!backgroundDataSetting
-                            || !mSyncStorageEngine.getListenForNetworkTickles()
-                            || !mSyncStorageEngine.getSyncProviderAutomatically(
-                                    null, syncOperation.authority))) {
+                    // skip the sync if it isn't manual and auto sync is disabled
+                    final boolean manualSync = op.extras.getBoolean(
+                            ContentResolver.SYNC_EXTRAS_MANUAL, false);
+                    final boolean syncAutomatically =
+                            mSyncStorageEngine.getSyncAutomatically(op.account, op.authority)
+                                    || mSyncStorageEngine.getMasterSyncAutomatically();
+                    boolean syncAllowed =
+                            manualSync || (backgroundDataUsageAllowed && syncAutomatically);
+                    if (!syncAllowed) {
                         if (isLoggable) {
-                            Log.v(TAG, "runStateIdle: sync off, dropping " + syncOperation);
+                            Log.v(TAG, "runStateIdle: sync off, dropping " + op);
                         }
                         mSyncQueue.popHead();
                         continue;
                     }
 
                     // skip the sync if the account of this operation no longer exists
-                    if (!ArrayUtils.contains(accounts, syncOperation.account)) {
+                    if (!ArrayUtils.contains(accounts, op.account)) {
                         mSyncQueue.popHead();
                         if (isLoggable) {
-                            Log.v(TAG, "runStateIdle: account not present, dropping "
-                                    + syncOperation);
+                            Log.v(TAG, "runStateIdle: account not present, dropping " + op);
                         }
                         continue;
                     }
 
                     // go ahead and try to sync this syncOperation
                     if (isLoggable) {
-                        Log.v(TAG, "runStateIdle: found sync candidate: " + syncOperation);
+                        Log.v(TAG, "runStateIdle: found sync candidate: " + op);
                     }
                     break;
                 }
@@ -1615,11 +1618,10 @@
                 // If the first SyncOperation isn't ready to run schedule a wakeup and
                 // get out.
                 final long now = SystemClock.elapsedRealtime();
-                if (syncOperation.earliestRunTime > now) {
+                if (op.earliestRunTime > now) {
                     if (Log.isLoggable(TAG, Log.DEBUG)) {
                         Log.d(TAG, "runStateIdle: the time is " + now + " yet the next "
-                                + "sync operation is for " + syncOperation.earliestRunTime
-                                + ": " + syncOperation);
+                                + "sync operation is for " + op.earliestRunTime + ": " + op);
                     }
                     return;
                 }
@@ -1627,14 +1629,14 @@
                 // We will do this sync. Remove it from the queue and run it outside of the
                 // synchronized block.
                 if (isLoggable) {
-                    Log.v(TAG, "runStateIdle: we are going to sync " + syncOperation);
+                    Log.v(TAG, "runStateIdle: we are going to sync " + op);
                 }
                 mSyncQueue.popHead();
             }
 
             // connect to the sync adapter
-            SyncAdapterType syncAdapterType = new SyncAdapterType(syncOperation.authority,
-                    syncOperation.account.mType);
+            SyncAdapterType syncAdapterType = new SyncAdapterType(op.authority,
+                    op.account.mType);
             RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
                     mSyncAdapters.getServiceInfo(syncAdapterType);
             if (syncAdapterInfo == null) {
@@ -1646,7 +1648,7 @@
             }
 
             ActiveSyncContext activeSyncContext =
-                    new ActiveSyncContext(syncOperation, insertStartSyncEvent(syncOperation));
+                    new ActiveSyncContext(op, insertStartSyncEvent(op));
             mActiveSyncContext = activeSyncContext;
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "runStateIdle: setting mActiveSyncContext to " + mActiveSyncContext);
@@ -1776,21 +1778,21 @@
          */
         private int syncResultToErrorNumber(SyncResult syncResult) {
             if (syncResult.syncAlreadyInProgress)
-                return SyncStorageEngine.ERROR_SYNC_ALREADY_IN_PROGRESS;
+                return ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS;
             if (syncResult.stats.numAuthExceptions > 0)
-                return SyncStorageEngine.ERROR_AUTHENTICATION;
+                return ContentResolver.SYNC_ERROR_AUTHENTICATION;
             if (syncResult.stats.numIoExceptions > 0)
-                return SyncStorageEngine.ERROR_IO;
+                return ContentResolver.SYNC_ERROR_IO;
             if (syncResult.stats.numParseExceptions > 0)
-                return SyncStorageEngine.ERROR_PARSE;
+                return ContentResolver.SYNC_ERROR_PARSE;
             if (syncResult.stats.numConflictDetectedExceptions > 0)
-                return SyncStorageEngine.ERROR_CONFLICT;
+                return ContentResolver.SYNC_ERROR_CONFLICT;
             if (syncResult.tooManyDeletions)
-                return SyncStorageEngine.ERROR_TOO_MANY_DELETIONS;
+                return ContentResolver.SYNC_ERROR_TOO_MANY_DELETIONS;
             if (syncResult.tooManyRetries)
-                return SyncStorageEngine.ERROR_TOO_MANY_RETRIES;
+                return ContentResolver.SYNC_ERROR_TOO_MANY_RETRIES;
             if (syncResult.databaseError)
-                return SyncStorageEngine.ERROR_INTERNAL;
+                return ContentResolver.SYNC_ERROR_INTERNAL;
             throw new IllegalStateException("we are not in an error state, " + syncResult);
         }
 
@@ -1831,9 +1833,10 @@
                 } else {
                     final boolean timeToShowNotification =
                             now > mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY;
-                    final boolean syncIsForced = syncOperation.extras
-                            .getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false);
-                    shouldInstall = timeToShowNotification || syncIsForced;
+                    // show the notification immediately if this is a manual sync
+                    final boolean manualSync = syncOperation.extras
+                            .getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
+                    shouldInstall = timeToShowNotification || manualSync;
                 }
             }
 
@@ -2088,9 +2091,9 @@
             SyncOperation existingOperation = mOpsByKey.get(operationKey);
 
             // if this operation matches an existing operation that is being retried (delay > 0)
-            // and this operation isn't forced, ignore this operation
+            // and this isn't a manual sync operation, ignore this operation
             if (existingOperation != null && existingOperation.delay > 0) {
-                if (!operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)) {
+                if (!operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)) {
                     return false;
                 }
             }
diff --git a/core/java/android/content/SyncStatusObserver.java b/core/java/android/content/SyncStatusObserver.java
new file mode 100644
index 0000000..663378a
--- /dev/null
+++ b/core/java/android/content/SyncStatusObserver.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+public interface SyncStatusObserver {
+    void onStatusChanged(int which);
+}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index aaa763d..aaba7c7 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -49,8 +49,6 @@
 import java.util.Iterator;
 import java.util.TimeZone;
 
-import com.google.android.collect.Sets;
-
 /**
  * Singleton that tracks the sync data and overall sync
  * history on the device.
@@ -89,6 +87,9 @@
     /** Enum value for a user-initiated sync. */
     public static final int SOURCE_USER = 3;
 
+    private static final Intent SYNC_CONNECTION_SETTING_CHANGED_INTENT =
+            new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED");
+
     // TODO: i18n -- grab these out of resources.
     /** String names for the sync source types. */
     public static final String[] SOURCES = { "SERVER",
@@ -96,26 +97,10 @@
                                              "POLL",
                                              "USER" };
 
-    // Error types
-    public static final int ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
-    public static final int ERROR_AUTHENTICATION = 2;
-    public static final int ERROR_IO = 3;
-    public static final int ERROR_PARSE = 4;
-    public static final int ERROR_CONFLICT = 5;
-    public static final int ERROR_TOO_MANY_DELETIONS = 6;
-    public static final int ERROR_TOO_MANY_RETRIES = 7;
-    public static final int ERROR_INTERNAL = 8;
-
     // The MESG column will contain one of these or one of the Error types.
     public static final String MESG_SUCCESS = "success";
     public static final String MESG_CANCELED = "canceled";
 
-    public static final int CHANGE_SETTINGS = 1<<0;
-    public static final int CHANGE_PENDING = 1<<1;
-    public static final int CHANGE_ACTIVE = 1<<2;
-    public static final int CHANGE_STATUS = 1<<3;
-    public static final int CHANGE_ALL = 0x7fffffff;
-    
     public static final int MAX_HISTORY = 15;
     
     private static final int MSG_WRITE_STATUS = 1;
@@ -166,7 +151,7 @@
         final String authority;
         final int ident;
         boolean enabled;
-        
+
         AuthorityInfo(Account account, String authority, int ident) {
             this.account = account;
             this.authority = authority;
@@ -259,7 +244,7 @@
     private int mNumPendingFinished = 0;
     
     private int mNextHistoryId = 0;
-    private boolean mListenForTickles = true;
+    private boolean mMasterSyncAutomatically = true;
     
     private SyncStorageEngine(Context context) {
         mContext = context;
@@ -356,14 +341,14 @@
         }
     }
     
-    public boolean getSyncProviderAutomatically(Account account, String providerName) {
+    public boolean getSyncAutomatically(Account account, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
                 AuthorityInfo authority = getAuthorityLocked(account, providerName,
-                        "getSyncProviderAutomatically");
-                return authority != null ? authority.enabled : false;
+                        "getSyncAutomatically");
+                return authority != null && authority.enabled;
             }
-            
+
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
@@ -377,42 +362,31 @@
         }
     }
 
-    public void setSyncProviderAutomatically(Account account, String providerName,
-            boolean sync) {
+    public void setSyncAutomatically(Account account, String providerName, boolean sync) {
         synchronized (mAuthorities) {
-            if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, providerName,
-                        "setSyncProviderAutomatically");
-                if (authority != null) {
-                    authority.enabled = sync;
-                }
-            } else {
-                int i = mAuthorities.size();
-                while (i > 0) {
-                    i--;
-                    AuthorityInfo authority = mAuthorities.get(i);
-                    if (authority.authority.equals(providerName)) {
-                        authority.enabled = sync;
-                    }
-                }
+            AuthorityInfo authority = getAuthorityLocked(account, providerName,
+                    "setSyncAutomatically");
+            if (authority != null) {
+                authority.enabled = sync;
             }
             writeAccountInfoLocked();
         }
         
-        reportChange(CHANGE_SETTINGS);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void setListenForNetworkTickles(boolean flag) {
+    public void setMasterSyncAutomatically(boolean flag) {
         synchronized (mAuthorities) {
-            mListenForTickles = flag;
+            mMasterSyncAutomatically = flag;
             writeAccountInfoLocked();
         }
-        reportChange(CHANGE_SETTINGS);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+        mContext.sendBroadcast(SYNC_CONNECTION_SETTING_CHANGED_INTENT);
     }
 
-    public boolean getListenForNetworkTickles() {
+    public boolean getMasterSyncAutomatically() {
         synchronized (mAuthorities) {
-            return mListenForTickles;
+            return mMasterSyncAutomatically;
         }
     }
     
@@ -481,7 +455,7 @@
             status.pending = true;
         }
         
-        reportChange(CHANGE_PENDING);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
         return op;
     }
 
@@ -527,7 +501,7 @@
             }
         }
         
-        reportChange(CHANGE_PENDING);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
         return res;
     }
 
@@ -543,7 +517,7 @@
             }
             writePendingOperationsLocked();
         }
-        reportChange(CHANGE_PENDING);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
         return num;
     }
 
@@ -650,14 +624,14 @@
             }
         }
         
-        reportChange(CHANGE_ACTIVE);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE);
     }
 
     /**
      * To allow others to send active change reports, to poke clients.
      */
     public void reportActiveChange() {
-        reportChange(CHANGE_ACTIVE);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE);
     }
     
     /**
@@ -689,7 +663,7 @@
             if (DEBUG) Log.v(TAG, "returning historyId " + id);
         }
         
-        reportChange(CHANGE_STATUS);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
         return id;
     }
 
@@ -793,7 +767,7 @@
             }            
         }
         
-        reportChange(CHANGE_STATUS);
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
     }
 
     /**
@@ -851,7 +825,7 @@
     /**
      * Return true if the pending status is true of any matching authorities.
      */
-    public boolean isAuthorityPending(Account account, String authority) {
+    public boolean isSyncPending(Account account, String authority) {
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
             for (int i=0; i<N; i++) {
@@ -907,7 +881,7 @@
      */
     public long getInitialSyncFailureTime() {
         synchronized (mAuthorities) {
-            if (!mListenForTickles) {
+            if (!mMasterSyncAutomatically) {
                 return 0;
             }
             
@@ -1041,7 +1015,7 @@
             if ("accounts".equals(tagName)) {
                 String listen = parser.getAttributeValue(
                         null, "listen-for-tickles");
-                mListenForTickles = listen == null
+                mMasterSyncAutomatically = listen == null
                             || Boolean.parseBoolean(listen);
                 eventType = parser.next();
                 do {
@@ -1122,7 +1096,7 @@
             out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
             
             out.startTag(null, "accounts");
-            if (!mListenForTickles) {
+            if (!mMasterSyncAutomatically) {
                 out.attribute(null, "listen-for-tickles", "false");
             }
             
@@ -1262,13 +1236,18 @@
                 String value = c.getString(c.getColumnIndex("value"));
                 if (name == null) continue;
                 if (name.equals("listen_for_tickles")) {
-                    setListenForNetworkTickles(value == null
-                            || Boolean.parseBoolean(value));
+                    setMasterSyncAutomatically(value == null || Boolean.parseBoolean(value));
                 } else if (name.startsWith("sync_provider_")) {
                     String provider = name.substring("sync_provider_".length(),
                             name.length());
-                    setSyncProviderAutomatically(null, provider,
-                            value == null || Boolean.parseBoolean(value));
+                    int i = mAuthorities.size();
+                    while (i > 0) {
+                        i--;
+                        AuthorityInfo authority = mAuthorities.get(i);
+                        if (authority.authority.equals(provider)) {
+                            authority.enabled = value == null || Boolean.parseBoolean(value);
+                        }
+                    }
                 }
             }
             
diff --git a/core/java/android/content/TempProviderSyncAdapter.java b/core/java/android/content/TempProviderSyncAdapter.java
index 0cbe01e..fb05fe7 100644
--- a/core/java/android/content/TempProviderSyncAdapter.java
+++ b/core/java/android/content/TempProviderSyncAdapter.java
@@ -63,12 +63,10 @@
      *
      * @param context allows you to publish status and interact with the
      * @param account the account to sync
-     * @param forced if true then the sync was forced
+     * @param manualSync true if this sync was requested manually by the user
      * @param result information to track what happened during this sync attempt
-     * @return true, if the sync was successfully started. One reason it can
-     *   fail to start is if there is no user configured on the device.
      */
-    public abstract void onSyncStarting(SyncContext context, Account account, boolean forced,
+    public abstract void onSyncStarting(SyncContext context, Account account, boolean manualSync,
             SyncResult result);
 
     /**
@@ -229,12 +227,12 @@
             mAdapterSyncStarted = false;
             String message = null;
 
-            boolean syncForced = extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false);
+            boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
 
             try {
                 mProvider.onSyncStart(syncContext, account);
                 mProviderSyncStarted = true;
-                onSyncStarting(syncContext, account, syncForced, mResult);
+                onSyncStarting(syncContext, account, manualSync, mResult);
                 if (mResult.hasError()) {
                     message = "SyncAdapter failed while trying to start sync";
                     return;
diff --git a/core/java/android/provider/Sync.java b/core/java/android/provider/Sync.java
deleted file mode 100644
index c9bde0e..0000000
--- a/core/java/android/provider/Sync.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.provider;
-
-import android.content.ContentQueryMap;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.accounts.Account;
-import android.text.TextUtils;
-
-import java.util.Map;
-
-/**
- * The Sync provider stores information used in managing the syncing of the device,
- * including the history and pending syncs.
- * 
- * @hide
- */
-public final class Sync {
-    // utility class
-    private Sync() {}
-
-    /**
-     * The content url for this provider.
-     */
-    public static final Uri CONTENT_URI = Uri.parse("content://sync");
-
-    /**
-     * Columns from the stats table.
-     */
-    public interface StatsColumns {
-        /**
-         * The sync account.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ACCOUNT = "account";
-
-        /**
-         * The sync account type.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ACCOUNT_TYPE = "account_type";
-
-        /**
-         * The content authority (contacts, calendar, etc.).
-         * <P>Type: TEXT</P>
-         */
-        public static final String AUTHORITY = "authority";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the stats table.
-     */
-    public static final class Stats implements BaseColumns, StatsColumns {
-
-        // utility class
-        private Stats() {}
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI =
-                Uri.parse("content://sync/stats");
-
-        /** Projection for the _id column in the stats table. */
-        public static final String[] SYNC_STATS_PROJECTION = {_ID};
-    }
-
-    /**
-     * Columns from the history table.
-     */
-    public interface HistoryColumns {
-        /**
-         * The ID of the stats row corresponding to this event.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String STATS_ID = "stats_id";
-
-        /**
-         * The source of the sync event (LOCAL, POLL, USER, SERVER).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SOURCE = "source";
-
-        /**
-         * The type of sync event (START, STOP).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String EVENT = "event";
-
-        /**
-         * The time of the event.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String EVENT_TIME = "eventTime";
-
-        /**
-         * How long this event took. This is only valid if the EVENT is EVENT_STOP.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String ELAPSED_TIME = "elapsedTime";
-
-        /**
-         * Any additional message associated with this event.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MESG = "mesg";
-
-        /**
-         * How much activity was performed sending data to the server. This is sync adapter
-         * specific, but usually is something like how many record update/insert/delete attempts
-         * were carried out. This is only valid if the EVENT is EVENT_STOP.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String UPSTREAM_ACTIVITY = "upstreamActivity";
-
-        /**
-         * How much activity was performed while receiving data from the server.
-         * This is sync adapter specific, but usually is something like how many
-         * records were received from the server. This is only valid if the
-         * EVENT is EVENT_STOP.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String DOWNSTREAM_ACTIVITY = "downstreamActivity";
-    }
-
-    /**
-     * Columns from the history table.
-     */
-    public interface StatusColumns {
-        /**
-         * How many syncs were completed for this account and authority.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SYNCS = "numSyncs";
-
-        /**
-         * How long all the events for this account and authority took.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String TOTAL_ELAPSED_TIME = "totalElapsedTime";
-
-        /**
-         * The number of syncs with SOURCE_POLL.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_POLL = "numSourcePoll";
-
-        /**
-         * The number of syncs with SOURCE_SERVER.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_SERVER = "numSourceServer";
-
-        /**
-         * The number of syncs with SOURCE_LOCAL.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_LOCAL = "numSourceLocal";
-
-        /**
-         * The number of syncs with SOURCE_USER.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_USER = "numSourceUser";
-
-        /**
-         * The time in ms that the last successful sync ended. Will be null if
-         * there are no successful syncs. A successful sync is defined as one having
-         * MESG=MESG_SUCCESS.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_SUCCESS_TIME = "lastSuccessTime";
-
-        /**
-         * The SOURCE of the last successful sync. Will be null if
-         * there are no successful syncs. A successful sync is defined
-         * as one having MESG=MESG_SUCCESS.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_SUCCESS_SOURCE = "lastSuccessSource";
-
-        /**
-         * The end time in ms of the last sync that failed since the last successful sync.
-         * Will be null if there are no syncs or if the last one succeeded. A failed
-         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_FAILURE_TIME = "lastFailureTime";
-
-        /**
-         * The SOURCE of the last sync that failed since the last successful sync.
-         * Will be null if there are no syncs or if the last one succeeded. A failed
-         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_FAILURE_SOURCE = "lastFailureSource";
-
-        /**
-         * The MESG of the last sync that failed since the last successful sync.
-         * Will be null if there are no syncs or if the last one succeeded. A failed
-         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
-         * <P>Type: STRING</P>
-         */
-        public static final String LAST_FAILURE_MESG = "lastFailureMesg";
-
-        /**
-         * Is set to 1 if a sync is pending, 0 if not.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String PENDING = "pending";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the history
-     * table.
-     */
-    public static class History implements BaseColumns,
-                                                 StatsColumns,
-                                                 HistoryColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI =
-                Uri.parse("content://sync/history");
-
-        /** Enum value for a sync start event. */
-        public static final int EVENT_START = 0;
-
-        /** Enum value for a sync stop event. */
-        public static final int EVENT_STOP = 1;
-
-        // TODO: i18n -- grab these out of resources.
-        /** String names for the sync event types. */
-        public static final String[] EVENTS = { "START", "STOP" };
-
-        /** Enum value for a server-initiated sync. */
-        public static final int SOURCE_SERVER = 0;
-
-        /** Enum value for a local-initiated sync. */
-        public static final int SOURCE_LOCAL = 1;
-        /**
-         * Enum value for a poll-based sync (e.g., upon connection to
-         * network)
-         */
-        public static final int SOURCE_POLL = 2;
-
-        /** Enum value for a user-initiated sync. */
-        public static final int SOURCE_USER = 3;
-
-        // TODO: i18n -- grab these out of resources.
-        /** String names for the sync source types. */
-        public static final String[] SOURCES = { "SERVER",
-                                                 "LOCAL",
-                                                 "POLL",
-                                                 "USER" };
-
-        // Error types
-        public static final int ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
-        public static final int ERROR_AUTHENTICATION = 2;
-        public static final int ERROR_IO = 3;
-        public static final int ERROR_PARSE = 4;
-        public static final int ERROR_CONFLICT = 5;
-        public static final int ERROR_TOO_MANY_DELETIONS = 6;
-        public static final int ERROR_TOO_MANY_RETRIES = 7;
-        public static final int ERROR_INTERNAL = 8;
-
-        // The MESG column will contain one of these or one of the Error types.
-        public static final String MESG_SUCCESS = "success";
-        public static final String MESG_CANCELED = "canceled";
-
-        private static final String FINISHED_SINCE_WHERE_CLAUSE = EVENT + "=" + EVENT_STOP
-                + " AND " + EVENT_TIME + ">? AND " + ACCOUNT + "=? AND " + ACCOUNT_TYPE + "=?"
-                + " AND " + AUTHORITY + "=?";
-
-        public static String mesgToString(String mesg) {
-            if (MESG_SUCCESS.equals(mesg)) return mesg;
-            if (MESG_CANCELED.equals(mesg)) return mesg;
-            switch (Integer.parseInt(mesg)) {
-                case ERROR_SYNC_ALREADY_IN_PROGRESS: return "already in progress";
-                case ERROR_AUTHENTICATION: return "bad authentication";
-                case ERROR_IO: return "network error";
-                case ERROR_PARSE: return "parse error";
-                case ERROR_CONFLICT: return "conflict detected";
-                case ERROR_TOO_MANY_DELETIONS: return "too many deletions";
-                case ERROR_TOO_MANY_RETRIES: return "too many retries";
-                case ERROR_INTERNAL: return "internal error";
-                default: return "unknown error";
-            }
-        }
-
-        // utility class
-        private History() {}
-
-        /**
-         * returns a cursor that queries the sync history in descending event time order
-         * @param contentResolver the ContentResolver to use for the query
-         * @return the cursor on the History table
-         */
-        public static Cursor query(ContentResolver contentResolver) {
-            return contentResolver.query(CONTENT_URI, null, null, null, EVENT_TIME + " desc");
-        }
-
-        public static boolean hasNewerSyncFinished(ContentResolver contentResolver,
-                Account account, String authority, long when) {
-            Cursor c = contentResolver.query(CONTENT_URI, new String[]{_ID},
-                    FINISHED_SINCE_WHERE_CLAUSE,
-                    new String[]{Long.toString(when), account.mName, account.mType, authority},
-                    null);
-            try {
-              return c.getCount() > 0;
-            } finally {
-                c.close();
-            }
-        }
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the authority history
-     * table, which contains information about syncs aggregated by account and authority.
-     * All the HistoryColumns except for EVENT are present, plus the AuthorityHistoryColumns.
-     */
-    public static class Status extends History implements StatusColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/status");
-
-        // utility class
-        private Status() {}
-
-        /**
-         * returns a cursor that queries the authority sync history in descending event order of
-         * ACCOUNT, AUTHORITY
-         * @param contentResolver the ContentResolver to use for the query
-         * @return the cursor on the AuthorityHistory table
-         */
-        public static Cursor query(ContentResolver contentResolver) {
-            return contentResolver.query(CONTENT_URI, null, null, null,
-                    ACCOUNT_TYPE + "," + ACCOUNT + "," + AUTHORITY);
-        }
-
-        public static class QueryMap extends ContentQueryMap {
-            public QueryMap(ContentResolver contentResolver,
-                    boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null),
-                        _ID, keepUpdated, handlerForUpdateNotifications);
-            }
-
-            public ContentValues get(Account account, String authority) {
-                Map<String, ContentValues> rows = getRows();
-                for (ContentValues values : rows.values()) {
-                    if (values.getAsString(ACCOUNT).equals(account.mName)
-                            && values.getAsString(ACCOUNT_TYPE).equals(account.mType)
-                            && values.getAsString(AUTHORITY).equals(authority)) {
-                        return values;
-                    }
-                }
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the pending syncs table
-     */
-    public static final class Pending implements BaseColumns,
-                                                 StatsColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/pending");
-
-        // utility class
-        private Pending() {}
-
-        public static class QueryMap extends ContentQueryMap {
-            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null), _ID, keepUpdated,
-                        handlerForUpdateNotifications);
-            }
-
-            public boolean isPending(Account account, String authority) {
-                Map<String, ContentValues> rows = getRows();
-                for (ContentValues values : rows.values()) {
-                    if (values.getAsString(ACCOUNT).equals(account.mName)
-                            && values.getAsString(ACCOUNT_TYPE).equals(account.mType)
-                            && values.getAsString(AUTHORITY).equals(authority)) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Columns from the history table.
-     */
-    public interface ActiveColumns {
-        /**
-         * The wallclock time of when the active sync started.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String START_TIME = "startTime";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the pending syncs table
-     */
-    public static final class Active implements BaseColumns,
-                                                StatsColumns,
-                                                ActiveColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/active");
-
-        // utility class
-        private Active() {}
-
-        public static class QueryMap extends ContentQueryMap {
-            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null), _ID, keepUpdated,
-                        handlerForUpdateNotifications);
-            }
-
-            public ContentValues getActiveSyncInfo() {
-                Map<String, ContentValues> rows = getRows();
-                for (ContentValues values : rows.values()) {
-                    return values;
-                }
-                return null;
-            }
-
-            public Account getSyncingAccount() {
-                ContentValues values = getActiveSyncInfo();
-                if (values == null || TextUtils.isEmpty(values.getAsString(ACCOUNT))) {
-                    return null;
-                }
-                return new Account(values.getAsString(ACCOUNT), values.getAsString(ACCOUNT_TYPE));
-            }
-
-            public String getSyncingAuthority() {
-                ContentValues values = getActiveSyncInfo();
-                return (values == null) ? null : values.getAsString(AUTHORITY);
-            }
-
-            public long getSyncStartTime() {
-                ContentValues values = getActiveSyncInfo();
-                return (values == null) ? -1 : values.getAsLong(START_TIME);
-            }
-        }
-    }
-
-    /**
-     * Columns in the settings table, which holds key/value pairs of settings.
-     */
-    public interface SettingsColumns {
-        /**
-         * The key of the setting
-         * <P>Type: TEXT</P>
-         */
-        public static final String KEY = "name";
-
-        /**
-         * The value of the settings
-         * <P>Type: TEXT</P>
-         */
-        public static final String VALUE = "value";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the settings
-     * table.
-     */
-    public static final class Settings implements BaseColumns, SettingsColumns {
-        /**
-         * The Uri of the settings table. This table behaves a little differently than
-         * normal tables. Updates are not allowed, only inserts, and inserts cause a replace
-         * to be performed, which first deletes the row if it is already present.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/settings");
-
-        /** controls whether or not the device listens for sync tickles */
-        public static final String SETTING_LISTEN_FOR_TICKLES = "listen_for_tickles";
-
-        /** controls whether or not the individual provider is synced when tickles are received */
-        public static final String SETTING_SYNC_PROVIDER_PREFIX = "sync_provider_";
-
-        /** query column project */
-        private static final String[] PROJECTION = { KEY, VALUE };
-
-        /**
-         * Convenience function for updating a single settings value as a
-         * boolean. This will either create a new entry in the table if the
-         * given name does not exist, or modify the value of the existing row
-         * with that name.  Note that internally setting values are always
-         * stored as strings, so this function converts the given value to a
-         * string before storing it.
-         *
-         * @param contentResolver the ContentResolver to use to access the settings table
-         * @param name The name of the setting to modify.
-         * @param val The new value for the setting.
-         */
-        static private void putBoolean(ContentResolver contentResolver, String name, boolean val) {
-            ContentValues values = new ContentValues();
-            values.put(KEY, name);
-            values.put(VALUE, Boolean.toString(val));
-            // this insert is translated into an update by the underlying Sync provider
-            contentResolver.insert(CONTENT_URI, values);
-        }
-
-        /**
-         * Convenience function for getting a setting value as a boolean without using the
-         * QueryMap for light-weight setting querying.
-         * @param contentResolver The ContentResolver for querying the setting.
-         * @param name The name of the setting to query
-         * @param def The default value for the setting.
-         * @return The value of the setting.
-         */
-        static public boolean getBoolean(ContentResolver contentResolver,
-                String name, boolean def) {
-            Cursor cursor = contentResolver.query(
-                    CONTENT_URI,
-                    PROJECTION,
-                    KEY + "=?",
-                    new String[] { name },
-                    null);
-            try {
-                if (cursor != null && cursor.moveToFirst()) {
-                    return Boolean.parseBoolean(cursor.getString(1));
-                }
-            } finally {
-                if (cursor != null) cursor.close();
-            }
-            return def;
-        }
-
-        /**
-         * A convenience method to set whether or not the provider is synced when
-         * it receives a network tickle.
-         *
-         * @param contentResolver the ContentResolver to use to access the settings table
-         * @param providerName the provider whose behavior is being controlled
-         * @param sync true if the provider should be synced when tickles are received for it
-         */
-        static public void setSyncProviderAutomatically(ContentResolver contentResolver,
-                String providerName, boolean sync) {
-            putBoolean(contentResolver, SETTING_SYNC_PROVIDER_PREFIX + providerName, sync);
-        }
-
-        /**
-         * A convenience method to set whether or not the device should listen to tickles.
-         *
-         * @param contentResolver the ContentResolver to use to access the settings table
-         * @param flag true if it should listen.
-         */
-        static public void setListenForNetworkTickles(ContentResolver contentResolver,
-                boolean flag) {
-            putBoolean(contentResolver, SETTING_LISTEN_FOR_TICKLES, flag);
-        }
-
-        public static class QueryMap extends ContentQueryMap {
-            private ContentResolver mContentResolver;
-
-            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null), KEY, keepUpdated,
-                        handlerForUpdateNotifications);
-                mContentResolver = contentResolver;
-            }
-
-            /**
-             * Check if the provider should be synced when a network tickle is received
-             * @param providerName the provider whose setting we are querying
-             * @return true of the provider should be synced when a network tickle is received
-             */
-            public boolean getSyncProviderAutomatically(String providerName) {
-                return getBoolean(SETTING_SYNC_PROVIDER_PREFIX + providerName, true);
-            }
-
-            /**
-             * Set whether or not the provider is synced when it receives a network tickle.
-             *
-             * @param providerName the provider whose behavior is being controlled
-             * @param sync true if the provider should be synced when tickles are received for it
-             */
-            public void setSyncProviderAutomatically(String providerName, boolean sync) {
-                Settings.setSyncProviderAutomatically(mContentResolver, providerName, sync);
-            }
-
-            /**
-             * Set whether or not the device should listen for tickles.
-             *
-             * @param flag true if it should listen.
-             */
-            public void setListenForNetworkTickles(boolean flag) {
-                Settings.setListenForNetworkTickles(mContentResolver, flag);
-            }
-
-            /**
-             * Check if the device should listen to tickles.
-
-             * @return true if it should
-             */
-            public boolean getListenForNetworkTickles() {
-                return getBoolean(SETTING_LISTEN_FOR_TICKLES, true);
-            }
-
-            /**
-             * Convenience function for retrieving a single settings value
-             * as a boolean.
-             *
-             * @param name The name of the setting to retrieve.
-             * @param def Value to return if the setting is not defined.
-             * @return The setting's current value, or 'def' if it is not defined.
-             */
-            private boolean getBoolean(String name, boolean def) {
-                ContentValues values = getValues(name);
-                return values != null ? values.getAsBoolean(VALUE) : def;
-            }
-        }
-    }
-}