diff --git a/Android.mk b/Android.mk
index 1f8993c..9e06034 100644
--- a/Android.mk
+++ b/Android.mk
@@ -105,9 +105,9 @@
 	core/java/android/content/IIntentReceiver.aidl \
 	core/java/android/content/IIntentSender.aidl \
 	core/java/android/content/IOnPrimaryClipChangedListener.aidl \
-	core/java/android/content/IAnonymousSyncAdapter.aidl \
 	core/java/android/content/ISyncAdapter.aidl \
 	core/java/android/content/ISyncContext.aidl \
+	core/java/android/content/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
diff --git a/api/current.txt b/api/current.txt
index c7a68ab..2e887e5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5741,6 +5741,7 @@
     method public final android.os.Bundle call(android.net.Uri, java.lang.String, java.lang.String, android.os.Bundle);
     method public deprecated void cancelSync(android.net.Uri);
     method public static void cancelSync(android.accounts.Account, java.lang.String);
+    method public static void cancelSync(android.content.ComponentName);
     method public static void cancelSync(android.content.SyncRequest);
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public static deprecated android.content.SyncInfo getCurrentSync();
@@ -5750,13 +5751,17 @@
     method public static boolean getMasterSyncAutomatically();
     method public android.net.Uri[] getOutgoingUriPermissionGrants(int, int);
     method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
+    method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.content.ComponentName);
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
     method public static android.content.SyncAdapterType[] getSyncAdapterTypes();
     method public static boolean getSyncAutomatically(android.accounts.Account, java.lang.String);
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+    method public static boolean isServiceActive(android.content.ComponentName);
     method public static boolean isSyncActive(android.accounts.Account, java.lang.String);
+    method public static boolean isSyncActive(android.content.ComponentName);
     method public static boolean isSyncPending(android.accounts.Account, java.lang.String);
+    method public static boolean isSyncPending(android.content.ComponentName);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean);
     method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
@@ -5777,6 +5782,7 @@
     method public static void requestSync(android.content.SyncRequest);
     method public static void setIsSyncable(android.accounts.Account, java.lang.String, int);
     method public static void setMasterSyncAutomatically(boolean);
+    method public static void setServiceActive(android.content.ComponentName, boolean);
     method public static void setSyncAutomatically(android.accounts.Account, java.lang.String, boolean);
     method public deprecated void startSync(android.net.Uri, android.os.Bundle);
     method public final void unregisterContentObserver(android.database.ContentObserver);
@@ -6839,6 +6845,7 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
+    field public final android.content.ComponentName service;
     field public final long startTime;
   }
 
@@ -6852,7 +6859,7 @@
   public static class SyncRequest.Builder {
     ctor public SyncRequest.Builder();
     method public android.content.SyncRequest build();
-    method public android.content.SyncRequest.Builder setAllowMetered(boolean);
+    method public android.content.SyncRequest.Builder setDisallowMetered(boolean);
     method public android.content.SyncRequest.Builder setExpedited(boolean);
     method public android.content.SyncRequest.Builder setExtras(android.os.Bundle);
     method public android.content.SyncRequest.Builder setIgnoreBackoff(boolean);
@@ -6894,6 +6901,7 @@
     ctor public SyncService();
     method public android.os.IBinder onBind(android.content.Intent);
     method public abstract void onPerformSync(android.os.Bundle, android.content.SyncResult);
+    method protected boolean parallelSyncsEnabled();
   }
 
   public class SyncStats implements android.os.Parcelable {
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index a761a89..1fcf311 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -141,7 +141,7 @@
     public static final String SYNC_EXTRAS_PRIORITY = "sync_priority";
 
     /** {@hide} Flag to allow sync to occur on metered network. */
-    public static final String SYNC_EXTRAS_ALLOW_METERED = "allow_metered";
+    public static final String SYNC_EXTRAS_DISALLOW_METERED = "allow_metered";
 
     /**
      * Set by the SyncManager to request that the SyncAdapter initialize itself for
@@ -1744,12 +1744,25 @@
      */
     public static void cancelSync(Account account, String authority) {
         try {
-            getContentService().cancelSync(account, authority);
+            getContentService().cancelSync(account, authority, null);
         } catch (RemoteException e) {
         }
     }
 
     /**
+     * Cancel any active or pending syncs that are running on this service.
+     *
+     * @param cname the service for which to cancel all active/pending operations.
+     */
+    public static void cancelSync(ComponentName cname) {
+        try {
+            getContentService().cancelSync(null, null, cname);
+        } 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
      */
@@ -1815,6 +1828,10 @@
      *
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+     * <p>The bundle for a periodic sync can be queried by applications with the correct
+     * permissions using
+     * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
+     * sensitive data should be transferred here.
      *
      * @param account the account to specify in the sync
      * @param authority the provider to specify in the sync request
@@ -1832,13 +1849,7 @@
         if (authority == null) {
             throw new IllegalArgumentException("authority must not be null");
         }
-        if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false)
-                || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false)
-                || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false)
-                || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false)
-                || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false)
-                || extras.getBoolean(SYNC_EXTRAS_FORCE, false)
-                || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) {
+        if (invalidPeriodicExtras(extras)) {
             throw new IllegalArgumentException("illegal extras were set");
         }
         try {
@@ -1850,6 +1861,26 @@
     }
 
     /**
+     * {@hide}
+     * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
+     * extras were set for a periodic sync.
+     *
+     * @param extras bundle to validate.
+     */
+    public static boolean invalidPeriodicExtras(Bundle extras) {
+        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Remove a periodic sync. Has no affect if account, authority and extras don't match
      * an existing periodic sync.
      * <p>This method requires the caller to hold the permission
@@ -1875,19 +1906,28 @@
     }
 
     /**
-     * Remove the specified sync. This will remove any syncs that have been scheduled to run, but
-     * will not cancel any running syncs.
-     * <p>This method requires the caller to hold the permission</p>
-     * If the request is for a periodic sync this will cancel future occurrences of the sync.
-     *
-     * It is possible to cancel a sync using a SyncRequest object that is different from the object
-     * with which you requested the sync. Do so by building a SyncRequest with exactly the same
+     * Remove the specified sync. This will cancel any pending or active syncs. If the request is
+     * for a periodic sync, this call will remove any future occurrences.
+     * <p>If a periodic sync is specified, the caller must hold the permission
+     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. If this SyncRequest targets a
+     * SyncService adapter,the calling application must be signed with the same certificate as the
+     * adapter.
+     *</p>It is possible to cancel a sync using a SyncRequest object that is not the same object
+     * with which you requested the sync. Do so by building a SyncRequest with the same
      * service/adapter, frequency, <b>and</b> extras bundle.
      *
      * @param request SyncRequest object containing information about sync to cancel.
      */
     public static void cancelSync(SyncRequest request) {
-        // TODO: Finish this implementation.
+        if (request == null) {
+            throw new IllegalArgumentException("request cannot be null");
+        }
+        try {
+            getContentService().cancelRequest(request);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
     }
 
     /**
@@ -1907,7 +1947,23 @@
             throw new IllegalArgumentException("authority must not be null");
         }
         try {
-            return getContentService().getPeriodicSyncs(account, authority);
+            return getContentService().getPeriodicSyncs(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Return periodic syncs associated with the provided component.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     */
+    public static List<PeriodicSync> getPeriodicSyncs(ComponentName cname) {
+        if (cname == null) {
+            throw new IllegalArgumentException("Component must not be null");
+        }
+        try {
+            return getContentService().getPeriodicSyncs(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -1943,6 +1999,38 @@
     }
 
     /**
+     * Set whether the provided {@link SyncService} is available to process work.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     */
+    public static void setServiceActive(ComponentName cname, boolean active) {
+        try {
+            getContentService().setServiceActive(cname, active);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
+     * Query the state of this sync service.
+     * <p>Set with {@link #setServiceActive(ComponentName cname, boolean active)}.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     * @param cname ComponentName referring to a {@link SyncService}
+     * @return true if jobs will be run on this service, false otherwise.
+     */
+    public static boolean isServiceActive(ComponentName cname) {
+        try {
+            return getContentService().isServiceActive(cname);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
      * 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.
      * <p>This method requires the caller to hold the permission
@@ -1976,8 +2064,8 @@
     }
 
     /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority in the pending list, or actively being processed.
+     * Returns true if there is currently a sync operation for the given account or authority
+     * actively being processed.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#READ_SYNC_STATS}.
      * @param account the account whose setting we are querying
@@ -1985,8 +2073,26 @@
      * @return true if a sync is active for the given account or authority.
      */
     public static boolean isSyncActive(Account account, String authority) {
+        if (account == null) {
+            throw new IllegalArgumentException("account must not be null");
+        }
+        if (authority == null) {
+            throw new IllegalArgumentException("authority must not be null");
+        }
+
         try {
-            return getContentService().isSyncActive(account, authority);
+            return getContentService().isSyncActive(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static boolean isSyncActive(ComponentName cname) {
+        if (cname == null) {
+            throw new IllegalArgumentException("component name must not be null");
+        }
+        try {
+            return getContentService().isSyncActive(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -2044,7 +2150,7 @@
      */
     public static SyncStatusInfo getSyncStatus(Account account, String authority) {
         try {
-            return getContentService().getSyncStatus(account, authority);
+            return getContentService().getSyncStatus(account, authority, null);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -2060,7 +2166,15 @@
      */
     public static boolean isSyncPending(Account account, String authority) {
         try {
-            return getContentService().isSyncPending(account, authority);
+            return getContentService().isSyncPending(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static boolean isSyncPending(ComponentName cname) {
+        try {
+            return getContentService().isSyncPending(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 9ad5a19..73a76e8 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -17,6 +17,7 @@
 package android.content;
 
 import android.accounts.Account;
+import android.content.ComponentName;
 import android.content.SyncInfo;
 import android.content.ISyncStatusObserver;
 import android.content.SyncAdapterType;
@@ -55,8 +56,14 @@
             int userHandle);
 
     void requestSync(in Account account, String authority, in Bundle extras);
+    /**
+     * Start a sync given a request.
+     */
     void sync(in SyncRequest request);
-    void cancelSync(in Account account, String authority);
+    void cancelSync(in Account account, String authority, in ComponentName cname);
+
+    /** Cancel a sync, providing information about the sync to be cancelled. */
+     void cancelRequest(in SyncRequest request);
 
     /**
      * Check if the provider should be synced when a network tickle is received
@@ -74,12 +81,14 @@
     void setSyncAutomatically(in Account account, String providerName, boolean sync);
 
     /**
-     * Get the frequency of the periodic poll, if any.
-     * @param providerName the provider whose setting we are querying
-     * @return the frequency of the periodic sync in seconds. If 0 then no periodic syncs
-     * will take place.
+     * Get a list of periodic operations for a specified authority, or service.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    List<PeriodicSync> getPeriodicSyncs(in Account account, String providerName);
+    List<PeriodicSync> getPeriodicSyncs(in Account account, String providerName,
+        in ComponentName cname);
 
     /**
      * Set whether or not the provider is to be synced on a periodic basis.
@@ -112,16 +121,23 @@
      */
     void setIsSyncable(in Account account, String providerName, int syncable);
 
+    /**
+     * Corresponds roughly to setIsSyncable(String account, String provider) for syncs that bind
+     * to a SyncService.
+     */
+    void setServiceActive(in ComponentName cname, boolean active);
+
+    /**
+     * Corresponds roughly to getIsSyncable(String account, String provider) for syncs that bind
+     * to a SyncService.
+     * @return 0 if this SyncService is not enabled, 1 if enabled, <0 if unknown.
+     */
+    boolean isServiceActive(in ComponentName cname);
+
     void setMasterSyncAutomatically(boolean flag);
 
     boolean getMasterSyncAutomatically();
 
-    /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority in the pending list, or actively being processed.
-     */
-    boolean isSyncActive(in Account account, String authority);
-
     List<SyncInfo> getCurrentSyncs();
 
     /**
@@ -131,17 +147,33 @@
     SyncAdapterType[] getSyncAdapterTypes();
 
     /**
+     * Returns true if there is currently a operation for the given account/authority or service
+     * actively being processed.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
+     */
+    boolean isSyncActive(in Account account, String authority, in ComponentName cname);
+
+    /**
      * 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
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    SyncStatusInfo getSyncStatus(in Account account, String authority);
+    SyncStatusInfo getSyncStatus(in Account account, String authority, in ComponentName cname);
 
     /**
      * Return true if the pending status is true of any matching authorities.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    boolean isSyncPending(in Account account, String authority);
+    boolean isSyncPending(in Account account, String authority, in ComponentName cname);
 
     void addStatusChangeListener(int mask, ISyncStatusObserver callback);
 
diff --git a/core/java/android/content/IAnonymousSyncAdapter.aidl b/core/java/android/content/ISyncServiceAdapter.aidl
similarity index 97%
rename from core/java/android/content/IAnonymousSyncAdapter.aidl
rename to core/java/android/content/ISyncServiceAdapter.aidl
index a80cea3..d419307 100644
--- a/core/java/android/content/IAnonymousSyncAdapter.aidl
+++ b/core/java/android/content/ISyncServiceAdapter.aidl
@@ -24,7 +24,7 @@
  * Provider specified). See {@link android.content.AbstractThreadedSyncAdapter}.
  * {@hide}
  */
-oneway interface IAnonymousSyncAdapter {
+oneway interface ISyncServiceAdapter {
 
     /**
      * Initiate a sync. SyncAdapter-specific parameters may be specified in
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index 6aca151..836c6f8 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -35,7 +35,7 @@
     public final Bundle extras;
     /** How frequently the sync should be scheduled, in seconds. Kept around for API purposes. */
     public final long period;
-    /** Whether this periodic sync uses a service. */
+    /** Whether this periodic sync runs on a {@link SyncService}. */
     public final boolean isService;
     /**
      * How much flexibility can be taken in scheduling the sync, in seconds.
@@ -64,8 +64,6 @@
         this.flexTime = 0L;
     }
 
-    // TODO: Add copy ctor from SyncRequest?
-
     /**
      * Create a copy of a periodic sync.
      * {@hide}
@@ -183,7 +181,8 @@
     }
 
     /**
-     * Periodic sync extra comparison function.
+     * Periodic sync extra comparison function. Duplicated from
+     * {@link com.android.server.content.SyncManager#syncExtrasEquals(Bundle b1, Bundle b2)}
      * {@hide}
      */
     public static boolean syncExtrasEquals(Bundle b1, Bundle b2) {
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index 0284882..61b11c2 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -17,6 +17,7 @@
 package android.content;
 
 import android.accounts.Account;
+import android.content.pm.RegisteredServicesCache;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Parcelable.Creator;
@@ -29,16 +30,24 @@
     public final int authorityId;
 
     /**
-     * The {@link Account} that is currently being synced.
+     * The {@link Account} that is currently being synced. Will be null if this sync is running via
+     * a {@link SyncService}.
      */
     public final Account account;
 
     /**
-     * The authority of the provider that is currently being synced.
+     * The authority of the provider that is currently being synced. Will be null if this sync
+     * is running via a {@link SyncService}.
      */
     public final String authority;
 
     /**
+     * The {@link SyncService} that is targeted by this operation. Null if this sync is running via
+     * a {@link AbstractThreadedSyncAdapter}. 
+     */
+    public final ComponentName service;
+
+    /**
      * The start time of the current sync operation in milliseconds since boot.
      * This is represented in elapsed real time.
      * See {@link android.os.SystemClock#elapsedRealtime()}.
@@ -46,12 +55,13 @@
     public final long startTime;
 
     /** @hide */
-    public SyncInfo(int authorityId, Account account, String authority,
+    public SyncInfo(int authorityId, Account account, String authority, ComponentName service,
             long startTime) {
         this.authorityId = authorityId;
         this.account = account;
         this.authority = authority;
         this.startTime = startTime;
+        this.service = service;
     }
 
     /** @hide */
@@ -62,17 +72,20 @@
     /** @hide */
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(authorityId);
-        account.writeToParcel(parcel, 0);
+        parcel.writeParcelable(account, flags);
         parcel.writeString(authority);
         parcel.writeLong(startTime);
+        parcel.writeParcelable(service, flags);
+        
     }
 
     /** @hide */
     SyncInfo(Parcel parcel) {
         authorityId = parcel.readInt();
-        account = new Account(parcel);
+        account = parcel.readParcelable(Account.class.getClassLoader());
         authority = parcel.readString();
         startTime = parcel.readLong();
+        service = parcel.readParcelable(ComponentName.class.getClassLoader());
     }
 
     /** @hide */
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index 4474c70..201a8b3 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -32,8 +32,8 @@
     private final ComponentName mComponentInfo;
     /** Bundle containing user info as well as sync settings. */
     private final Bundle mExtras;
-    /** Allow this sync request on metered networks. */
-    private final boolean mAllowMetered;
+    /** Don't allow this sync request on metered networks. */
+    private final boolean mDisallowMetered;
     /**
      * Anticipated upload size in bytes.
      * TODO: Not yet used - we put this information into the bundle for simplicity.
@@ -85,16 +85,32 @@
 
     /**
      * {@hide}
-     * Throws a runtime IllegalArgumentException if this function is called for an
-     * anonymous sync.
      *
-     * @return (Account, Provider) for this SyncRequest.
+     * @return account object for this sync.
+     * @throws IllegalArgumentException if this function is called for a request that targets a
+     * sync service.
      */
-    public Pair<Account, String> getProviderInfo() {
+    public Account getAccount() {
         if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getProviderInfo() for an anonymous sync.");
+            throw new IllegalArgumentException("Cannot getAccount() for a sync that targets a sync"
+                    + "service.");
         }
-        return Pair.create(mAccountToSync, mAuthority);
+        return mAccountToSync;
+    }
+
+    /**
+     * {@hide}
+     *
+     * @return provider for this sync.
+     * @throws IllegalArgumentException if this function is called for a request that targets a
+     * sync service.
+     */
+    public String getProvider() {
+        if (!hasAuthority()) {
+            throw new IllegalArgumentException("Cannot getProvider() for a sync that targets a"
+                    + "sync service.");
+        }
+        return mAuthority;
     }
 
     /**
@@ -159,7 +175,7 @@
         parcel.writeLong(mSyncFlexTimeSecs);
         parcel.writeLong(mSyncRunTimeSecs);
         parcel.writeInt((mIsPeriodic ? 1 : 0));
-        parcel.writeInt((mAllowMetered ? 1 : 0));
+        parcel.writeInt((mDisallowMetered ? 1 : 0));
         parcel.writeLong(mTxBytes);
         parcel.writeLong(mRxBytes);
         parcel.writeInt((mIsAuthority ? 1 : 0));
@@ -177,7 +193,7 @@
         mSyncFlexTimeSecs = in.readLong();
         mSyncRunTimeSecs = in.readLong();
         mIsPeriodic = (in.readInt() != 0);
-        mAllowMetered = (in.readInt() != 0);
+        mDisallowMetered = (in.readInt() != 0);
         mTxBytes = in.readLong();
         mRxBytes = in.readLong();
         mIsAuthority = (in.readInt() != 0);
@@ -207,7 +223,7 @@
         // For now we merge the sync config extras & the custom extras into one bundle.
         // TODO: pass the configuration extras through separately.
         mExtras.putAll(b.mSyncConfigExtras);
-        mAllowMetered = b.mAllowMetered;
+        mDisallowMetered = b.mDisallowMetered;
         mTxBytes = b.mTxBytes;
         mRxBytes = b.mRxBytes;
     }
@@ -253,7 +269,7 @@
         /** Expected download transfer in bytes. */
         private long mRxBytes = -1L;
         /** Whether or not this sync can occur on metered networks. Default false. */
-        private boolean mAllowMetered;
+        private boolean mDisallowMetered;
         /** Priority of this sync relative to others from calling app [-2, 2]. Default 0. */
         private int mPriority = 0;
         /**
@@ -344,6 +360,10 @@
          * You cannot reuse the same builder for one-time syncs after having specified a periodic
          * sync (by calling this function). If you do, an <code>IllegalArgumentException</code>
          * will be thrown.
+         * <p>The bundle for a periodic sync can be queried by applications with the correct
+         * permissions using
+         * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
+         * sensitive data should be transferred here.
          *
          * Example usage.
          *
@@ -407,10 +427,17 @@
         }
 
         /**
-         * @param allow false to allow this transfer on metered networks. Default true.
+         * Will throw an <code>IllegalArgumentException</code> if called and
+         * {@link #setIgnoreSettings(boolean ignoreSettings)} has already been called.
+         * @param disallow true to allow this transfer on metered networks. Default false.
+         * 
          */
-        public Builder setAllowMetered(boolean allow) {
-            mAllowMetered = true;
+        public Builder setDisallowMetered(boolean disallow) {
+            if (mIgnoreSettings && disallow) {
+                throw new IllegalArgumentException("setDisallowMetered(true) after having"
+                        + "specified that settings are ignored.");
+            }
+            mDisallowMetered = disallow;
             return this;
         }
 
@@ -511,10 +538,17 @@
          *
          * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
          * {@link #build()}.
+         * <p>Throws <code>IllegalArgumentException</code> if called and
+         * {@link #setDisallowMetered(boolean)} has been set.
+         * 
          *
          * @param ignoreSettings true to ignore the sync automatically settings. Default false.
          */
         public Builder setIgnoreSettings(boolean ignoreSettings) {
+            if (mDisallowMetered && ignoreSettings) {
+                throw new IllegalArgumentException("setIgnoreSettings(true) after having specified"
+                        + " sync settings with this builder.");
+            }
             mIgnoreSettings = ignoreSettings;
             return this;
         }
@@ -591,8 +625,8 @@
             if (mIgnoreBackoff) {
                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
             }
-            if (mAllowMetered) {
-                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_ALLOW_METERED, true);
+            if (mDisallowMetered) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true);
             }
             if (mIgnoreSettings) {
                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
@@ -604,18 +638,27 @@
                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
             }
             if (mIsManual) {
-                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
             }
             mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD, mTxBytes);
             mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD, mRxBytes);
             mSyncConfigExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
             if (mSyncType == SYNC_TYPE_PERIODIC) {
                 // If this is a periodic sync ensure than invalid extras were not set.
-                validatePeriodicExtras(mCustomExtras);
-                validatePeriodicExtras(mSyncConfigExtras);
+                if (ContentResolver.invalidPeriodicExtras(mCustomExtras) || 
+                        ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
+                    throw new IllegalArgumentException("Illegal extras were set");
+                }
             } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
                 throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
             }
+            if (mSyncTarget == SYNC_TARGET_SERVICE) {
+                if (mSyncConfigExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
+                    throw new IllegalArgumentException("Cannot specify an initialisation sync"
+                            + " that targets a service.");
+                }
+            }
             // Ensure that a target for the sync has been set.
             if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
                 throw new IllegalArgumentException("Must specify an adapter with one of"
@@ -623,23 +666,5 @@
             }
             return new SyncRequest(this);
         }
-
-        /**
-         * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
-         * extras were set for a periodic sync.
-         *
-         * @param extras bundle to validate.
-         */
-        private void validatePeriodicExtras(Bundle extras) {
-            if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
-                throw new IllegalArgumentException("Illegal extras were set");
-            }
-        }
-    }
+    }   
 }
diff --git a/core/java/android/content/SyncService.java b/core/java/android/content/SyncService.java
index 100fd40..3f99ce1 100644
--- a/core/java/android/content/SyncService.java
+++ b/core/java/android/content/SyncService.java
@@ -21,24 +21,28 @@
 import android.os.IBinder;
 import android.os.Process;
 import android.os.Trace;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 
-import java.util.HashMap;
-
 /**
  * Simplified @link android.content.AbstractThreadedSyncAdapter. Folds that
  * behaviour into a service to which the system can bind when requesting an
  * anonymous (providerless/accountless) sync.
  * <p>
- * In order to perform an anonymous sync operation you must extend this service,
- * implementing the abstract methods. This service must then be declared in the
- * application's manifest as usual. You can use this service for other work, however you
- * <b> must not </b> override the onBind() method unless you know what you're doing,
- * which limits the usefulness of this service for other work.
+ * In order to perform an anonymous sync operation you must extend this service, implementing the
+ * abstract methods. This service must be declared in the application's manifest as usual. You
+ * can use this service for other work, however you <b> must not </b> override the onBind() method
+ * unless you know what you're doing, which limits the usefulness of this service for other work.
+ * <p>A {@link SyncService} can either be active or inactive. Different to an
+ * {@link AbstractThreadedSyncAdapter}, there is no
+ * {@link ContentResolver#setSyncAutomatically(android.accounts.Account account, String provider, boolean sync)},
+ * as well as no concept of initialisation (you can handle your own if needed).
  *
  * <pre>
- * &lt;service ndroid:name=".MyAnonymousSyncService" android:permission="android.permission.SYNC" /&gt;
+ * &lt;service android:name=".MySyncService"/&gt;
  * </pre>
  * Like @link android.content.AbstractThreadedSyncAdapter this service supports
  * multiple syncs at the same time. Each incoming startSync() with a unique tag
@@ -48,41 +52,50 @@
  * at once, so if you mutate local objects you must ensure synchronization.
  */
 public abstract class SyncService extends Service {
+    private static final String TAG = "SyncService";
 
-    /** SyncAdapter Instantiation that any anonymous syncs call. */
-    private final AnonymousSyncAdapterImpl mSyncAdapter = new AnonymousSyncAdapterImpl();
+    private final SyncAdapterImpl mSyncAdapter = new SyncAdapterImpl();
 
-    /** Keep track of on-going syncs, keyed by tag. */
-    @GuardedBy("mLock")
-    private final HashMap<Bundle, AnonymousSyncThread>
-            mSyncThreads = new HashMap<Bundle, AnonymousSyncThread>();
+    /** Keep track of on-going syncs, keyed by bundle. */
+    @GuardedBy("mSyncThreadLock")
+    private final SparseArray<SyncThread>
+            mSyncThreads = new SparseArray<SyncThread>();
     /** Lock object for accessing the SyncThreads HashMap. */
     private final Object mSyncThreadLock = new Object();
+    /**
+     * Default key for if this sync service does not support parallel operations. Currently not
+     * sure if null keys will make it into the ArrayMap for KLP, so keeping our default for now.
+     */
+    private static final int KEY_DEFAULT = 0;
+    /** Identifier for this sync service. */
+    private ComponentName mServiceComponent;
 
-    @Override
+    /** {@hide} */
     public IBinder onBind(Intent intent) {
+        mServiceComponent = new ComponentName(this, getClass());
         return mSyncAdapter.asBinder();
     }
 
     /** {@hide} */
-    private class AnonymousSyncAdapterImpl extends IAnonymousSyncAdapter.Stub {
-
+    private class SyncAdapterImpl extends ISyncServiceAdapter.Stub {
         @Override
         public void startSync(ISyncContext syncContext, Bundle extras) {
             // Wrap the provided Sync Context because it may go away by the time
             // we call it.
             final SyncContext syncContextClient = new SyncContext(syncContext);
             boolean alreadyInProgress = false;
+            final int extrasAsKey = extrasToKey(extras);
             synchronized (mSyncThreadLock) {
-                if (mSyncThreads.containsKey(extras)) {
+                if (mSyncThreads.get(extrasAsKey) != null) {
+                    Log.e(TAG, "starting sync for : " + mServiceComponent);
+                    // Start sync.
+                    SyncThread syncThread = new SyncThread(syncContextClient, extras);
+                    mSyncThreads.put(extrasAsKey, syncThread);
+                    syncThread.start();
+                } else {
                     // Don't want to call back to SyncManager while still
                     // holding lock.
                     alreadyInProgress = true;
-                } else {
-                    AnonymousSyncThread syncThread = new AnonymousSyncThread(
-                            syncContextClient, extras);
-                    mSyncThreads.put(extras, syncThread);
-                    syncThread.start();
                 }
             }
             if (alreadyInProgress) {
@@ -91,14 +104,15 @@
         }
 
         /**
-         * Used by the SM to cancel a specific sync using the {@link
-         * com.android.server.content.SyncManager.ActiveSyncContext} as a handle.
+         * Used by the SM to cancel a specific sync using the
+         * com.android.server.content.SyncManager.ActiveSyncContext as a handle.
          */
         @Override
         public void cancelSync(ISyncContext syncContext) {
-            AnonymousSyncThread runningSync = null;
+            SyncThread runningSync = null;
             synchronized (mSyncThreadLock) {
-                for (AnonymousSyncThread thread : mSyncThreads.values()) {
+                for (int i = 0; i < mSyncThreads.size(); i++) {
+                    SyncThread thread = mSyncThreads.valueAt(i);
                     if (thread.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
                         runningSync = thread;
                         break;
@@ -112,19 +126,39 @@
     }
 
     /**
+     * 
+     * @param extras Bundle for which to compute hash
+     * @return an integer hash that is equal to that of another bundle if they both contain the
+     * same key -> value mappings, however, not necessarily in order.
+     * Based on the toString() representation of the value mapped.
+     */
+    private int extrasToKey(Bundle extras) {
+        int hash = KEY_DEFAULT; // Empty bundle, or no parallel operations enabled.
+        if (parallelSyncsEnabled()) {
+            for (String key : extras.keySet()) {
+                String mapping = key + " " + extras.get(key).toString();
+                hash += mapping.hashCode();
+            }
+        }
+        return hash;
+    }
+
+    /**
      * {@hide}
      * Similar to {@link android.content.AbstractThreadedSyncAdapter.SyncThread}. However while
      * the ATSA considers an already in-progress sync to be if the account provided is currently
-     * syncing, this anonymous sync has no notion of account and therefore considers a sync unique
-     * if the provided bundle is different.
+     * syncing, this anonymous sync has no notion of account and considers a sync unique if the
+     * provided bundle is different.
      */
-    private class AnonymousSyncThread extends Thread {
+    private class SyncThread extends Thread {
         private final SyncContext mSyncContext;
         private final Bundle mExtras;
+        private final int mThreadsKey;
 
-        public AnonymousSyncThread(SyncContext syncContext, Bundle extras) {
+        public SyncThread(SyncContext syncContext, Bundle extras) {
             mSyncContext = syncContext;
             mExtras = extras;
+            mThreadsKey = extrasToKey(extras);
         }
 
         @Override
@@ -135,10 +169,8 @@
 
             SyncResult syncResult = new SyncResult();
             try {
-                if (isCancelled()) {
-                    return;
-                }
-                // Run the sync based off of the provided code.
+                if (isCancelled()) return;
+                // Run the sync.
                 SyncService.this.onPerformSync(mExtras, syncResult);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
@@ -146,10 +178,9 @@
                     mSyncContext.onFinished(syncResult);
                 }
                 // Synchronize so that the assignment will be seen by other
-                // threads
-                // that also synchronize accesses to mSyncThreads.
+                // threads that also synchronize accesses to mSyncThreads.
                 synchronized (mSyncThreadLock) {
-                    mSyncThreads.remove(mExtras);
+                    mSyncThreads.remove(mThreadsKey);
                 }
             }
         }
@@ -166,4 +197,14 @@
      */
     public abstract void onPerformSync(Bundle extras, SyncResult syncResult);
 
+    /**
+     * Override this function to indicated whether you want to support parallel syncs.
+     * <p>If you override and return true multiple threads will be spawned within your Service to
+     * handle each concurrent sync request.
+     *
+     * @return false to indicate that this service does not support parallel operations by default.
+     */
+    protected boolean parallelSyncsEnabled() {
+        return false;
+    }
 }
diff --git a/services/java/com/android/server/content/ContentService.java b/services/java/com/android/server/content/ContentService.java
index a56af08..ab20461 100644
--- a/services/java/com/android/server/content/ContentService.java
+++ b/services/java/com/android/server/content/ContentService.java
@@ -25,6 +25,8 @@
 import android.content.IContentService;
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.content.SyncAdapterType;
 import android.content.SyncInfo;
 import android.content.SyncRequest;
@@ -315,7 +317,6 @@
         }
     }
 
-    @Override
     public void requestSync(Account account, String authority, Bundle extras) {
         ContentResolver.validateSyncExtrasBundle(extras);
         int userId = UserHandle.getCallingUserId();
@@ -345,61 +346,56 @@
      * Depending on the request, we enqueue to suit in the SyncManager.
      * @param request
      */
-    @Override
     public void sync(SyncRequest request) {
         Bundle extras = request.getBundle();
         ContentResolver.validateSyncExtrasBundle(extras);
 
-        long flextime = request.getSyncFlexTime();
-        long runAtTime = request.getSyncRunTime();
         int userId = UserHandle.getCallingUserId();
-        int uId = Binder.getCallingUid();
-
+        int callerUid = Binder.getCallingUid();
         // 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) {
-                if (request.hasAuthority()) {
-                    // Sync Adapter registered with the system - old API.
-                    final  Account account = request.getProviderInfo().first;
-                    final String provider = request.getProviderInfo().second;
-                    if (request.isPeriodic()) {
-                        mContext.enforceCallingOrSelfPermission(
-                                Manifest.permission.WRITE_SYNC_SETTINGS,
-                                "no permission to write the sync settings");
-                        if (runAtTime < 60) {
-                            Slog.w(TAG, "Requested poll frequency of " + runAtTime
-                                    + " seconds being rounded up to 60 seconds.");
-                            runAtTime = 60;
-                        }
-                        PeriodicSync syncToAdd =
-                                new PeriodicSync(account, provider, extras, runAtTime, flextime);
-                        getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
-                    } else {
-                        long beforeRuntimeMillis = (flextime) * 1000;
-                        long runtimeMillis = runAtTime * 1000;
-                        syncManager.scheduleSync(
-                                account, userId, uId, provider, extras,
-                                beforeRuntimeMillis, runtimeMillis,
-                                false /* onlyThoseWithUnknownSyncableState */);
-                    }
+            if (syncManager == null) return;
+
+            long flextime = request.getSyncFlexTime();
+            long runAtTime = request.getSyncRunTime();
+            if (request.isPeriodic()) {
+                mContext.enforceCallingOrSelfPermission(
+                        Manifest.permission.WRITE_SYNC_SETTINGS,
+                        "no permission to write the sync settings");
+                SyncStorageEngine.EndPoint info;
+                if (!request.hasAuthority()) {
+                    // Extra permissions checking for sync service.
+                    verifySignatureForPackage(callerUid,
+                            request.getService().getPackageName(), "sync");
+                    info = new SyncStorageEngine.EndPoint(request.getService(), userId);
                 } else {
-                    // Anonymous sync - new API.
-                    final ComponentName syncService = request.getService();
-                    if (request.isPeriodic()) {
-                        throw new RuntimeException("Periodic anonymous syncs not implemented yet.");
-                    } else {
-                        long beforeRuntimeMillis = (flextime) * 1000;
-                        long runtimeMillis = runAtTime * 1000;
-                        syncManager.scheduleSync(
-                              syncService, userId, uId, extras,
-                              beforeRuntimeMillis,
-                              runtimeMillis,
-                              false /* onlyThoseWithUnknownSyncableState */); // Empty function.
-                        throw new RuntimeException("One-off anonymous syncs not implemented yet.");
-                    }
+                    info = new SyncStorageEngine.EndPoint(
+                            request.getAccount(), request.getProvider(), userId);
+                }
+                if (runAtTime < 60) {
+                    Slog.w(TAG, "Requested poll frequency of " + runAtTime
+                            + " seconds being rounded up to 60 seconds.");
+                    runAtTime = 60;
+                }
+                // Schedule periodic sync.
+                getSyncManager().getSyncStorageEngine()
+                    .updateOrAddPeriodicSync(info, runAtTime, flextime, extras);
+            } else {
+                long beforeRuntimeMillis = (flextime) * 1000;
+                long runtimeMillis = runAtTime * 1000;
+                if (request.hasAuthority()) {
+                syncManager.scheduleSync(
+                        request.getAccount(), userId, callerUid, request.getProvider(), extras,
+                        beforeRuntimeMillis, runtimeMillis,
+                        false /* onlyThoseWithUnknownSyncableState */);
+                } else {
+                    syncManager.scheduleSync(
+                            request.getService(), userId, callerUid, extras,
+                            beforeRuntimeMillis,
+                            runtimeMillis); // Empty function.
                 }
             }
         } finally {
@@ -410,11 +406,13 @@
     /**
      * Clear all scheduled sync operations that match the uri and cancel the active sync
      * 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
+     *
+     * @param account filter the pending and active syncs to cancel using this account, or null.
+     * @param authority filter the pending and active syncs to cancel using this authority, or
+     * null.
+     * @param cname cancel syncs running on this service, or null for provider/account.
      */
-    @Override
-    public void cancelSync(Account account, String authority) {
+    public void cancelSync(Account account, String authority, ComponentName cname) {
         int userId = UserHandle.getCallingUserId();
 
         // This makes it so that future permission checks will be in the context of this
@@ -423,14 +421,54 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.clearScheduledSyncOperations(account, userId, authority);
-                syncManager.cancelActiveSync(account, userId, authority);
+                SyncStorageEngine.EndPoint info;
+                if (cname == null) {
+                    info = new SyncStorageEngine.EndPoint(account, authority, userId);
+                } else {
+                    info = new SyncStorageEngine.EndPoint(cname, userId);
+                }
+                syncManager.clearScheduledSyncOperations(info);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
             }
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    public void cancelRequest(SyncRequest request) {
+        SyncManager syncManager = getSyncManager();
+        if (syncManager == null) return;
+        int userId = UserHandle.getCallingUserId();
+        int callerUid = Binder.getCallingUid();
+
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncStorageEngine.EndPoint info;
+            Bundle extras = new Bundle(request.getBundle());
+            if (request.hasAuthority()) {
+                Account account = request.getAccount();
+                String provider = request.getProvider();
+                info = new SyncStorageEngine.EndPoint(account, provider, userId);
+            } else {
+                // Only allowed to manipulate syncs for a service which you own.
+                ComponentName service = request.getService();
+                verifySignatureForPackage(callerUid, service.getPackageName(), "cancel");
+                info = new SyncStorageEngine.EndPoint(service, userId);
+            }
+            if (request.isPeriodic()) {
+                // Remove periodic sync.
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                        "no permission to write the sync settings");
+                getSyncManager().getSyncStorageEngine().removePeriodicSync(info, extras);
+            }
+            // Cancel active syncs and clear pending syncs from the queue.
+            syncManager.cancelScheduledSyncOperation(info, extras);
+            syncManager.cancelActiveSync(info, extras);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
     /**
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
@@ -459,8 +497,8 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getSyncAutomatically(
-                        account, userId, providerName);
+                return syncManager.getSyncStorageEngine()
+                        .getSyncAutomatically(account, userId, providerName);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -478,18 +516,15 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().setSyncAutomatically(
-                        account, userId, providerName, sync);
+                syncManager.getSyncStorageEngine()
+                .setSyncAutomatically(account, userId, providerName, sync);
             }
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    /**
-     * Old API. Schedule periodic sync with default flex time.
-     */
-    @Override
+    /** Old API. Schedule periodic sync with default flex time. */
     public void addPeriodicSync(Account account, String authority, Bundle extras,
             long pollFrequency) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
@@ -501,21 +536,22 @@
                     + " seconds being rounded up to 60 seconds.");
             pollFrequency = 60;
         }
+        long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
 
         long identityToken = clearCallingIdentity();
         try {
-            // Add default flex time to this sync.
-            PeriodicSync syncToAdd =
-                    new PeriodicSync(account, authority, extras,
-                            pollFrequency,
-                            SyncStorageEngine.calculateDefaultFlexTime(pollFrequency));
-            getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
+            SyncStorageEngine.EndPoint info =
+                    new SyncStorageEngine.EndPoint(account, authority, userId);
+            getSyncManager().getSyncStorageEngine()
+                .updateOrAddPeriodicSync(info,
+                        pollFrequency,
+                        defaultFlex,
+                        extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    @Override
     public void removePeriodicSync(Account account, String authority, Bundle extras) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
@@ -523,32 +559,34 @@
 
         long identityToken = clearCallingIdentity();
         try {
-            PeriodicSync syncToRemove = new PeriodicSync(account, authority, extras,
-                    0 /* Not read for removal */, 0 /* Not read for removal */);
-            getSyncManager().getSyncStorageEngine().removePeriodicSync(syncToRemove, userId);
+            getSyncManager().getSyncStorageEngine()
+                .removePeriodicSync(
+                        new SyncStorageEngine.EndPoint(account, authority, userId),
+                        extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    /**
-     * TODO: Implement.
-     * @param request Sync to remove.
-     */
-    public void removeSync(SyncRequest request) {
-
-    }
-
-    @Override
-    public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName) {
+    public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName,
+            ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
         int userId = UserHandle.getCallingUserId();
+        int callerUid = Binder.getCallingUid();
 
         long identityToken = clearCallingIdentity();
         try {
-            return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
-                    account, userId, providerName);
+            if (cname == null) {
+                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                        new SyncStorageEngine.EndPoint(account, providerName, userId));
+            } else if (account == null && providerName == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "getPeriodicSyncs");
+                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                        new SyncStorageEngine.EndPoint(cname, userId));
+            } else {
+                throw new IllegalArgumentException("Invalid authority specified");
+            }
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -572,7 +610,6 @@
         return -1;
     }
 
-    @Override
     public void setIsSyncable(Account account, String providerName, int syncable) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
@@ -590,6 +627,43 @@
         }
     }
 
+    public void setServiceActive(ComponentName cname, boolean active) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                "no permission to write the sync settings");
+        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(), "setIsEnabled");
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                int syncable = active ? 1 : 0;
+                syncManager.getSyncStorageEngine().setIsEnabled(
+                        cname, userId, syncable);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    public boolean isServiceActive(ComponentName cname) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
+                "no permission to read the sync settings");
+        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(), "getIsEnabled");
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return (syncManager.getIsTargetServiceActive(cname, userId) == 1);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+
     @Override
     public boolean getMasterSyncAutomatically() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
@@ -625,17 +699,24 @@
         }
     }
 
-    public boolean isSyncActive(Account account, String authority) {
+    public boolean isSyncActive(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         int userId = UserHandle.getCallingUserId();
-
+        int callingUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
+            if (syncManager == null) {
+                return false;
+            }
+            if (cname == null) {
                 return syncManager.getSyncStorageEngine().isSyncActive(
-                        account, userId, authority);
+                        new SyncStorageEngine.EndPoint(account, authority, userId));
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callingUid, cname.getPackageName(), "isSyncActive");
+                return syncManager.getSyncStorageEngine().isSyncActive(
+                        new SyncStorageEngine.EndPoint(cname, userId));
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -656,39 +737,55 @@
         }
     }
 
-    public SyncStatusInfo getSyncStatus(Account account, String authority) {
+    public SyncStatusInfo getSyncStatus(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         int userId = UserHandle.getCallingUserId();
-
+        int callerUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getStatusByAccountAndAuthority(
-                        account, userId, authority);
+            if (syncManager == null) {
+                return null;
             }
+            SyncStorageEngine.EndPoint info;
+            if (cname == null) {
+                info = new SyncStorageEngine.EndPoint(account, authority, userId);
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "getSyncStatus");
+                info = new SyncStorageEngine.EndPoint(cname, userId);
+            } else {
+                throw new IllegalArgumentException("Must call sync status with valid authority");
+            }
+            return syncManager.getSyncStorageEngine().getStatusByAuthority(info);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return null;
     }
 
-    public boolean isSyncPending(Account account, String authority) {
+    public boolean isSyncPending(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         int userId = UserHandle.getCallingUserId();
-
+        int callerUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
+        SyncManager syncManager = getSyncManager();
+        if (syncManager == null) return false;
+
         try {
-            SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().isSyncPending(account, userId, authority);
+            SyncStorageEngine.EndPoint info;
+            if (cname == null) {
+                info = new SyncStorageEngine.EndPoint(account, authority, userId);
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "isSyncPending");
+                info = new SyncStorageEngine.EndPoint(cname, userId);
+            } else {
+                throw new IllegalArgumentException("Invalid authority specified");
             }
+            return syncManager.getSyncStorageEngine().isSyncPending(info);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return false;
     }
 
     public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
@@ -722,6 +819,30 @@
     }
 
     /**
+     * Helper to verify that the provided package name shares the same cert as the caller.
+     * @param callerUid uid of the calling process.
+     * @param packageName package to verify against package of calling application.
+     * @param tag a tag to use when throwing an exception if the signatures don't
+     * match. Cannot be null.
+     * @return true if the calling application and the provided package are signed with the same
+     * certificate.
+     */
+    private boolean verifySignatureForPackage(int callerUid, String packageName, String tag) {
+        PackageManager pm = mContext.getPackageManager();
+        try {
+            int serviceUid = pm.getApplicationInfo(packageName, 0).uid;
+            if (pm.checkSignatures(callerUid, serviceUid) == PackageManager.SIGNATURE_MATCH) {
+                return true;
+            } else {
+                throw new SecurityException(tag + ": Caller certificate does not match that for - "
+                        + packageName);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalArgumentException(tag + ": " + packageName + " package not found.");
+        }
+    }
+
+    /**
      * Hide this class since it is not part of api,
      * but current unittest framework requires it to be public
      * @hide
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index a6b69a2..3802415 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.content.ISyncAdapter;
 import android.content.ISyncContext;
+import android.content.ISyncServiceAdapter;
 import android.content.ISyncStatusObserver;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -200,8 +201,9 @@
                             Log.v(TAG, "Internal storage is low.");
                         }
                         mStorageIsLow = true;
-                        cancelActiveSync(null /* any account */, UserHandle.USER_ALL,
-                                null /* any authority */);
+                        cancelActiveSync(
+                                SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                null /* any sync */);
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Internal storage is ok.");
@@ -219,19 +221,6 @@
         }
     };
 
-    private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (getConnectivityManager().getBackgroundDataSetting()) {
-                scheduleSync(null /* account */, UserHandle.USER_ALL,
-                        SyncOperation.REASON_BACKGROUND_DATA_SETTINGS_CHANGED,
-                        null /* authority */,
-                        new Bundle(), 0 /* delay */, 0 /* delay */,
-                        false /* onlyThoseWithUnknownSyncableState */);
-            }
-        }
-    };
-
     private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -276,16 +265,16 @@
             doDatabaseCleanup();
         }
 
+        AccountAndUser[] accounts = mRunningAccounts;
         for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
-            if (!containsAccountAndUser(mRunningAccounts,
-                    currentSyncContext.mSyncOperation.account,
-                    currentSyncContext.mSyncOperation.userId)) {
+            if (!containsAccountAndUser(accounts,
+                    currentSyncContext.mSyncOperation.target.account,
+                    currentSyncContext.mSyncOperation.target.userId)) {
                 Log.d(TAG, "canceling sync since the account is no longer running");
                 sendSyncFinishedOrCanceledMessage(currentSyncContext,
                         null /* no result since this is a cancel */);
             }
         }
-
         // we must do this since we don't bother scheduling alarms when
         // the accounts are not set yet
         sendCheckAlarmsMessage();
@@ -380,12 +369,17 @@
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
             @Override
-            public void onSyncRequest(Account account, int userId, int reason, String authority,
-                    Bundle extras) {
-                scheduleSync(account, userId, reason, authority, extras,
-                    0 /* no delay */,
-                    0 /* no delay */,
-                    false);
+            public void onSyncRequest(SyncStorageEngine.EndPoint info, int reason, Bundle extras) {
+                if (info.target_provider) {
+                    scheduleSync(info.account, info.userId, reason, info.provider, extras,
+                        0 /* no flex */,
+                        0 /* run immediately */,
+                        false);
+                } else if (info.target_service) {
+                    scheduleSync(info.service, info.userId, reason, extras,
+                            0 /* no flex */,
+                            0 /* run immediately */);
+                }
             }
         });
 
@@ -417,9 +411,6 @@
             context.registerReceiver(mBootCompletedReceiver, intentFilter);
         }
 
-        intentFilter = new IntentFilter(ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
-        context.registerReceiver(mBackgroundDataSettingChanged, intentFilter);
-
         intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
@@ -532,181 +523,106 @@
         }
     }
 
+    /**
+     * TODO: Decide if restricted users have different sync options for the sync service (as is
+     * the case with sync adapters).
+     */
+    public int getIsTargetServiceActive(ComponentName cname, int userId) {
+        return mSyncStorageEngine.getIsTargetServiceActive(cname, userId);
+    }
+
     private void ensureAlarmService() {
         if (mAlarmService == null) {
-            mAlarmService = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+            mAlarmService = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         }
     }
 
     /**
      * Initiate a sync using the new anonymous service API.
-     * TODO: Implement.
      * @param cname SyncService component bound to in order to perform the sync. 
      * @param userId the id of the user whose accounts are to be synced. If userId is USER_ALL,
      *          then all users' accounts are considered.
      * @param uid Linux uid of the application that is performing the sync. 
      * @param extras a Map of SyncAdapter-specific information to control
      *          syncs of a specific provider. Can be null.
-     * @param beforeRunTimeMillis
-     *  @param runtimeMillis
+     * @param beforeRunTimeMillis milliseconds before <code>runtimeMillis</code> that this sync may
+     * be run.
+     * @param runtimeMillis milliseconds from now by which this sync must be run.
      */
     public void scheduleSync(ComponentName cname, int userId, int uid, Bundle extras,
-            long beforeRunTimeMillis, long runtimeMillis,
-            boolean onlyThoseWithUnknownSyncableState) {
-/**
+            long beforeRunTimeMillis, long runtimeMillis) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
-
-        final boolean backgroundDataUsageAllowed = !mBootCompleted ||
-                getConnectivityManager().getBackgroundDataSetting();
-
-        if (extras == null) {
-            extras = new Bundle();
-        }
         if (isLoggable) {
-            Log.e(TAG, requestedAccount + " " + extras.toString() + " " + requestedAuthority);
+            Log.d(TAG, "one off sync for: " + cname + " " + extras.toString());
         }
+
         Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
         if (expedited) {
             runtimeMillis = -1; // this means schedule at the front of the queue
         }
 
-        AccountAndUser[] accounts;
-        if (requestedAccount != null && userId != UserHandle.USER_ALL) {
-            accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) };
-        } else {
-            // if the accounts aren't configured yet then we can't support an account-less
-            // sync request
-            accounts = mRunningAccounts;
-            if (accounts.length == 0) {
-                if (isLoggable) {
-                    Log.v(TAG, "scheduleSync: no accounts configured, dropping");
-                }
-                return;
-            }
-        }
-
-        final boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false);
-        final boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
-        if (manualSync) {
-            extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
-            extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
-        }
         final boolean ignoreSettings =
                 extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
-
-        int source;
-        if (uploadOnly) {
-            source = SyncStorageEngine.SOURCE_LOCAL;
-        } else if (manualSync) {
-            source = SyncStorageEngine.SOURCE_USER;
-        } else if (requestedAuthority == null) {
-            source = SyncStorageEngine.SOURCE_POLL;
+        int source = SyncStorageEngine.SOURCE_SERVICE;
+        int isEnabled = getIsTargetServiceActive(cname, userId);
+        // Only schedule this sync if
+        //   - we've explicitly been told to ignore settings.
+        //   - global sync is enabled for this user.
+        boolean syncAllowed =
+                ignoreSettings
+                || mSyncStorageEngine.getMasterSyncAutomatically(userId);
+        if (!syncAllowed) {
+            if (isLoggable) {
+                Log.d(TAG, "scheduleSync: sync of " + cname + " not allowed, dropping request.");
+            }
+            return;
+        }
+        if (isEnabled == 0) {
+            if (isLoggable) {
+                Log.d(TAG, "scheduleSync: " + cname + " is not enabled, dropping request");
+            }
+            return;
+        }
+        SyncStorageEngine.EndPoint info = new SyncStorageEngine.EndPoint(cname, userId);
+        Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+        long delayUntil = mSyncStorageEngine.getDelayUntilTime(info);
+        final long backoffTime = backoff != null ? backoff.first : 0;
+        if (isEnabled < 0) {
+            // Initialisation sync.
+            Bundle newExtras = new Bundle();
+            newExtras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
+            if (isLoggable) {
+                Log.v(TAG, "schedule initialisation Sync:"
+                        + ", delay until " + delayUntil
+                        + ", run now "
+                        + ", source " + source
+                        + ", sync service " + cname
+                        + ", extras " + newExtras);
+            }
+            scheduleSyncOperation(
+                    new SyncOperation(cname, userId, uid, source, newExtras,
+                            0 /* runtime */,
+                            0 /* flextime */,
+                            backoffTime,
+                            delayUntil));
         } else {
-            // this isn't strictly server, since arbitrary callers can (and do) request
-            // a non-forced two-way sync on a specific url
-            source = SyncStorageEngine.SOURCE_SERVER;
+            if (isLoggable) {
+                Log.v(TAG, "schedule Sync:"
+                        + ", delay until " + delayUntil
+                        + ", run by " + runtimeMillis
+                        + ", flex " + beforeRunTimeMillis
+                        + ", source " + source
+                        + ", sync service " + cname
+                        + ", extras " + extras);
+            }
+            scheduleSyncOperation(
+                    new SyncOperation(cname, userId, uid, source, extras,
+                            runtimeMillis /* runtime */,
+                            beforeRunTimeMillis /* flextime */,
+                            backoffTime,
+                            delayUntil));
         }
 
-        for (AccountAndUser account : accounts) {
-            // 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(account.userId)) {
-                syncableAuthorities.add(syncAdapter.type.authority);
-            }
-
-            // 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 (requestedAuthority != null) {
-                final boolean hasSyncAdapter = syncableAuthorities.contains(requestedAuthority);
-                syncableAuthorities.clear();
-                if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority);
-            }
-
-            for (String authority : syncableAuthorities) {
-                int isSyncable = getIsSyncable(account.account, account.userId,
-                        authority);
-                if (isSyncable == 0) {
-                    continue;
-                }
-                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-                syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                        SyncAdapterType.newKey(authority, account.account.type), account.userId);
-                if (syncAdapterInfo == null) {
-                    continue;
-                }
-                final boolean allowParallelSyncs = syncAdapterInfo.type.allowParallelSyncs();
-                final boolean isAlwaysSyncable = syncAdapterInfo.type.isAlwaysSyncable();
-                if (isSyncable < 0 && isAlwaysSyncable) {
-                    mSyncStorageEngine.setIsSyncable(account.account, account.userId, authority, 1);
-                    isSyncable = 1;
-                }
-                if (onlyThoseWithUnkownSyncableState && isSyncable >= 0) {
-                    continue;
-                }
-                if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) {
-                    continue;
-                }
-
-                // always allow if the isSyncable state is unknown
-                boolean syncAllowed =
-                        (isSyncable < 0)
-                        || ignoreSettings
-                        || (backgroundDataUsageAllowed
-                                && mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
-                                && mSyncStorageEngine.getSyncAutomatically(account.account,
-                                        account.userId, authority));
-                if (!syncAllowed) {
-                    if (isLoggable) {
-                        Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority
-                                + " is not allowed, dropping request");
-                    }
-                    continue;
-                }
-
-                Pair<Long, Long> backoff = mSyncStorageEngine
-                        .getBackoff(account.account, account.userId, authority);
-                long delayUntil = mSyncStorageEngine.getDelayUntilTime(account.account,
-                        account.userId, authority);
-                final long backoffTime = backoff != null ? backoff.first : 0;
-                if (isSyncable < 0) {
-                    // Initialisation sync.
-                    Bundle newExtras = new Bundle();
-                    newExtras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
-                    if (isLoggable) {
-                        Log.v(TAG, "schedule initialisation Sync:"
-                                + ", delay until " + delayUntil
-                                + ", run by " + 0
-                                + ", source " + source
-                                + ", account " + account
-                                + ", authority " + authority
-                                + ", extras " + newExtras);
-                    }
-                    scheduleSyncOperation(
-                            new SyncOperation(account.account, account.userId, reason, source,
-                                    authority, newExtras, 0 /* immediate , 0 /* No flex time,
-                                    backoffTime, delayUntil, allowParallelSyncs));
-                }
-                if (!onlyThoseWithUnkownSyncableState) {
-                    if (isLoggable) {
-                        Log.v(TAG, "scheduleSync:"
-                                + " delay until " + delayUntil
-                                + " run by " + runtimeMillis
-                                + " flex " + beforeRuntimeMillis
-                                + ", source " + source
-                                + ", account " + account
-                                + ", authority " + authority
-                                + ", extras " + extras);
-                    }
-                    scheduleSyncOperation(
-                            new SyncOperation(account.account, account.userId, reason, source,
-                                    authority, extras, runtimeMillis, beforeRuntimeMillis,
-                                    backoffTime, delayUntil, allowParallelSyncs));
-                }
-            }
-        }*/
     }
 
     /**
@@ -755,9 +671,6 @@
             long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
-        final boolean backgroundDataUsageAllowed = !mBootCompleted ||
-                getConnectivityManager().getBackgroundDataSetting();
-
         if (extras == null) {
             extras = new Bundle();
         }
@@ -774,8 +687,6 @@
         if (requestedAccount != null && userId != UserHandle.USER_ALL) {
             accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) };
         } else {
-            // if the accounts aren't configured yet then we can't support an account-less
-            // sync request
             accounts = mRunningAccounts;
             if (accounts.length == 0) {
                 if (isLoggable) {
@@ -850,12 +761,10 @@
                     continue;
                 }
 
-                // always allow if the isSyncable state is unknown
                 boolean syncAllowed =
-                        (isSyncable < 0)
+                        (isSyncable < 0) // always allow if the isSyncable state is unknown
                         || ignoreSettings
-                        || (backgroundDataUsageAllowed
-                                && mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
+                        || (mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
                                 && mSyncStorageEngine.getSyncAutomatically(account.account,
                                         account.userId, authority));
                 if (!syncAllowed) {
@@ -865,11 +774,12 @@
                     }
                     continue;
                 }
-
-                Pair<Long, Long> backoff = mSyncStorageEngine
-                        .getBackoff(account.account, account.userId, authority);
-                long delayUntil = mSyncStorageEngine.getDelayUntilTime(account.account,
-                        account.userId, authority);
+                SyncStorageEngine.EndPoint info =
+                        new SyncStorageEngine.EndPoint(
+                                account.account, authority, account.userId);
+                Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+                long delayUntil =
+                        mSyncStorageEngine.getDelayUntilTime(info);
                 final long backoffTime = backoff != null ? backoff.first : 0;
                 if (isSyncable < 0) {
                     // Initialisation sync.
@@ -879,6 +789,7 @@
                         Log.v(TAG, "schedule initialisation Sync:"
                                 + ", delay until " + delayUntil
                                 + ", run by " + 0
+                                + ", flex " + 0
                                 + ", source " + source
                                 + ", account " + account
                                 + ", authority " + authority
@@ -954,13 +865,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final Account account, final int userId,
-            final String authority) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CANCEL");
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
-        msg.obj = Pair.create(account, authority);
-        msg.arg1 = userId;
+        msg.setData(extras);
+        msg.obj = info;
         mSyncHandler.sendMessage(msg);
     }
 
@@ -983,10 +893,11 @@
     }
 
     private void clearBackoffSetting(SyncOperation op) {
-        mSyncStorageEngine.setBackoff(op.account, op.userId, op.authority,
-                SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+        mSyncStorageEngine.setBackoff(op.target,
+                SyncStorageEngine.NOT_IN_BACKOFF_MODE,
+                SyncStorageEngine.NOT_IN_BACKOFF_MODE);
         synchronized (mSyncQueue) {
-            mSyncQueue.onBackoffChanged(op.account, op.userId, op.authority, 0);
+            mSyncQueue.onBackoffChanged(op.target, 0);
         }
     }
 
@@ -996,7 +907,7 @@
         final long now = SystemClock.elapsedRealtime();
 
         final Pair<Long, Long> previousSettings =
-                mSyncStorageEngine.getBackoff(op.account, op.userId, op.authority);
+                mSyncStorageEngine.getBackoff(op.target);
         long newDelayInMs = -1;
         if (previousSettings != null) {
             // don't increase backoff before current backoff is expired. This will happen for op's
@@ -1027,14 +938,12 @@
 
         final long backoff = now + newDelayInMs;
 
-        mSyncStorageEngine.setBackoff(op.account, op.userId, op.authority,
-                backoff, newDelayInMs);
-
+        mSyncStorageEngine.setBackoff(op.target, backoff, newDelayInMs);
         op.backoff = backoff;
         op.updateEffectiveRunTime();
 
         synchronized (mSyncQueue) {
-            mSyncQueue.onBackoffChanged(op.account, op.userId, op.authority, backoff);
+            mSyncQueue.onBackoffChanged(op.target, backoff);
         }
     }
 
@@ -1047,20 +956,20 @@
         } else {
             newDelayUntilTime = 0;
         }
-        mSyncStorageEngine
-                .setDelayUntilTime(op.account, op.userId, op.authority, newDelayUntilTime);
+        mSyncStorageEngine.setDelayUntilTime(op.target, newDelayUntilTime);
         synchronized (mSyncQueue) {
-            mSyncQueue.onDelayUntilTimeChanged(op.account, op.authority, newDelayUntilTime);
+            mSyncQueue.onDelayUntilTimeChanged(op.target, newDelayUntilTime);
         }
     }
 
     /**
      * 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
+     * @param info object containing info about which syncs to cancel. The authority can
+     * have null account/provider info to specify all accounts/providers.
+     * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(Account account, int userId, String authority) {
-        sendCancelSyncsMessage(account, userId, authority);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
+        sendCancelSyncsMessage(info, extras);
     }
 
     /**
@@ -1089,24 +998,40 @@
 
     /**
      * 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
+     * @param info limit the removals to operations that match this authority. The authority can
+     * have null account/provider info to specify all accounts/providers.
      */
-    public void clearScheduledSyncOperations(Account account, int userId, String authority) {
+    public void clearScheduledSyncOperations(SyncStorageEngine.EndPoint info) {
         synchronized (mSyncQueue) {
-            mSyncQueue.remove(account, userId, authority);
+            mSyncQueue.remove(info, null /* all operations */);
         }
-        mSyncStorageEngine.setBackoff(account, userId, authority,
+        mSyncStorageEngine.setBackoff(info,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
     }
 
+    /**
+     * Remove a specified sync, if it exists.
+     * @param info Authority for which the sync is to be removed.
+     * @param extras extras bundle to uniquely identify sync.
+     */
+    public void cancelScheduledSyncOperation(SyncStorageEngine.EndPoint info, Bundle extras) {
+        synchronized (mSyncQueue) {
+            mSyncQueue.remove(info, extras);
+        }
+        // Reset the back-off if there are no more syncs pending.
+        if (!mSyncStorageEngine.isSyncPending(info)) {
+            mSyncStorageEngine.setBackoff(info,
+                    SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+        }
+    }
+
     void maybeRescheduleSync(SyncResult syncResult, SyncOperation operation) {
         boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG);
         if (isLoggable) {
             Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", " + operation);
         }
 
-        operation = new SyncOperation(operation);
+        operation = new SyncOperation(operation, 0L /* newRunTimeFromNow */);
 
         // The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given
         // request. Retries of the request will always honor the backoff, so clear the
@@ -1115,25 +1040,29 @@
             operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
         }
 
-        // If this sync aborted because the internal sync loop retried too many times then
-        //   don't reschedule. Otherwise we risk getting into a retry loop.
-        // If the operation succeeded to some extent then retry immediately.
-        // If this was a two-way sync then retry soft errors with an exponential backoff.
-        // If this was an upward sync then schedule a two-way sync immediately.
-        // Otherwise do not reschedule.
         if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)) {
-            Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified "
-                    + operation);
+            if (isLoggable) {
+                Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified "
+                        + operation);
+            }
         } else if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false)
                 && !syncResult.syncAlreadyInProgress) {
+            // If this was an upward sync then schedule a two-way sync immediately.
             operation.extras.remove(ContentResolver.SYNC_EXTRAS_UPLOAD);
-            Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
-                    + "encountered an error: " + operation);
+            if (isLoggable) {
+                Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
+                        + "encountered an error: " + operation);
+            }
             scheduleSyncOperation(operation);
         } else if (syncResult.tooManyRetries) {
-            Log.d(TAG, "not retrying sync operation because it retried too many times: "
-                    + operation);
+            // If this sync aborted because the internal sync loop retried too many times then
+            //   don't reschedule. Otherwise we risk getting into a retry loop.
+            if (isLoggable) {
+                Log.d(TAG, "not retrying sync operation because it retried too many times: "
+                        + operation);
+            }
         } else if (syncResult.madeSomeProgress()) {
+            // If the operation succeeded to some extent then retry immediately.
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation because even though it had an error "
                         + "it achieved some success");
@@ -1146,19 +1075,18 @@
             }
             scheduleSyncOperation(
                 new SyncOperation(
-                    operation.account, operation.userId,
-                    operation.reason,
-                    operation.syncSource,
-                    operation.authority, operation.extras,
-                    DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000, operation.flexTime,
-                    operation.backoff, operation.delayUntil, operation.allowParallelSyncs));
+                        operation,
+                        DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000 /* newRunTimeFromNow */)
+                );
         } else if (syncResult.hasSoftError()) {
+            // If this was a two-way sync then retry soft errors with an exponential backoff.
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation because it encountered a soft error: "
                         + operation);
             }
             scheduleSyncOperation(operation);
         } else {
+            // Otherwise do not reschedule.
             Log.d(TAG, "not retrying sync operation because the error is a hard error: "
                     + operation);
         }
@@ -1191,9 +1119,12 @@
         updateRunningAccounts();
 
         cancelActiveSync(
-                null /* any account */,
-                userId,
-                null /* any authority */);
+                new SyncStorageEngine.EndPoint(
+                        null /* any account */,
+                        null /* any authority */,
+                        userId),
+                        null /* any sync. */
+                );
     }
 
     private void onUserRemoved(int userId) {
@@ -1202,7 +1133,7 @@
         // Clean up the storage engine database
         mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId);
         synchronized (mSyncQueue) {
-            mSyncQueue.removeUser(userId);
+            mSyncQueue.removeUserLocked(userId);
         }
     }
 
@@ -1214,6 +1145,7 @@
         final SyncOperation mSyncOperation;
         final long mHistoryRowId;
         ISyncAdapter mSyncAdapter;
+        ISyncServiceAdapter mSyncServiceAdapter;
         final long mStartTime;
         long mTimeoutStartTime;
         boolean mBound;
@@ -1239,10 +1171,10 @@
             mSyncOperation = syncOperation;
             mHistoryRowId = historyRowId;
             mSyncAdapter = null;
+            mSyncServiceAdapter = null;
             mStartTime = SystemClock.elapsedRealtime();
             mTimeoutStartTime = mStartTime;
-            mSyncWakeLock = mSyncHandler.getSyncWakeLock(
-                    mSyncOperation.account, mSyncOperation.authority);
+            mSyncWakeLock = mSyncHandler.getSyncWakeLock(mSyncOperation);
             mSyncWakeLock.setWorkSource(new WorkSource(syncAdapterUid));
             mSyncWakeLock.acquire();
         }
@@ -1269,7 +1201,12 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             Message msg = mSyncHandler.obtainMessage();
             msg.what = SyncHandler.MESSAGE_SERVICE_CONNECTED;
-            msg.obj = new ServiceConnectionData(this, ISyncAdapter.Stub.asInterface(service));
+            if (mSyncOperation.target.target_provider) {
+                msg.arg1 = SyncOperation.SYNC_TARGET_ADAPTER;
+            } else {
+                msg.arg1 = SyncOperation.SYNC_TARGET_SERVICE;
+            }
+            msg.obj = new ServiceConnectionData(this, service);
             mSyncHandler.sendMessage(msg);
         }
 
@@ -1280,13 +1217,13 @@
             mSyncHandler.sendMessage(msg);
         }
 
-        boolean bindToSyncAdapter(RegisteredServicesCache.ServiceInfo info, int userId) {
+        boolean bindToSyncAdapter(ComponentName serviceComponent, int userId) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.d(TAG, "bindToSyncAdapter: " + info.componentName + ", connection " + this);
+                Log.d(TAG, "bindToSyncAdapter: " + serviceComponent + ", connection " + this);
             }
             Intent intent = new Intent();
             intent.setAction("android.content.SyncAdapter");
-            intent.setComponent(info.componentName);
+            intent.setComponent(serviceComponent);
             intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                     com.android.internal.R.string.sync_binding_label);
             intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
@@ -1296,7 +1233,7 @@
             final boolean bindResult = mContext.bindServiceAsUser(intent, this,
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
                     | Context.BIND_ALLOW_OOM_MANAGEMENT,
-                    new UserHandle(mSyncOperation.userId));
+                    new UserHandle(mSyncOperation.target.userId));
             if (!bindResult) {
                 mBound = false;
             }
@@ -1319,7 +1256,6 @@
             mSyncWakeLock.setWorkSource(null);
         }
 
-        @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
             toString(sb);
@@ -1458,11 +1394,14 @@
                 int row = table.getNumRows();
                 Pair<AuthorityInfo, SyncStatusInfo> syncAuthoritySyncStatus = 
                         mSyncStorageEngine.getCopyOfAuthorityWithSyncStatus(
-                                account.account, account.userId, syncAdapterType.type.authority);
+                                new SyncStorageEngine.EndPoint(
+                                        account.account,
+                                        syncAdapterType.type.authority,
+                                        account.userId));
                 SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first;
                 SyncStatusInfo status = syncAuthoritySyncStatus.second;
 
-                String authority = settings.authority;
+                String authority = settings.base.provider;
                 if (authority.length() > 50) {
                     authority = authority.substring(authority.length() - 50);
                 }
@@ -1583,14 +1522,25 @@
             int maxAuthority = 0;
             int maxAccount = 0;
             for (SyncStorageEngine.SyncHistoryItem item : items) {
-                SyncStorageEngine.AuthorityInfo authority
+                SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.base.target_provider) {
+                        authorityName = authorityInfo.base.provider;
+                        accountKey = authorityInfo.base.account.name + "/"
+                                + authorityInfo.base.account.type
+                                + " u" + authorityInfo.base.userId;
+                    } else if (authorityInfo.base.target_service) {
+                        authorityName = authorityInfo.base.service.getPackageName() + "/"
+                                + authorityInfo.base.service.getClassName()
+                                + " u" + authorityInfo.base.userId;
+                        accountKey = "no account";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1711,14 +1661,25 @@
             final PackageManager pm = mContext.getPackageManager();
             for (int i = 0; i < N; i++) {
                 SyncStorageEngine.SyncHistoryItem item = items.get(i);
-                SyncStorageEngine.AuthorityInfo authority
+                SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.base.target_provider) {
+                        authorityName = authorityInfo.base.provider;
+                        accountKey = authorityInfo.base.account.name + "/"
+                                + authorityInfo.base.account.type
+                                + " u" + authorityInfo.base.userId;
+                    } else if (authorityInfo.base.target_service) {
+                        authorityName = authorityInfo.base.service.getPackageName() + "/"
+                                + authorityInfo.base.service.getClassName()
+                                + " u" + authorityInfo.base.userId;
+                        accountKey = "none";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1777,14 +1738,25 @@
                 if (extras == null || extras.size() == 0) {
                     continue;
                 }
-                final SyncStorageEngine.AuthorityInfo authority
+                final SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.base.target_provider) {
+                        authorityName = authorityInfo.base.provider;
+                        accountKey = authorityInfo.base.account.name + "/"
+                                + authorityInfo.base.account.type
+                                + " u" + authorityInfo.base.userId;
+                    } else if (authorityInfo.base.target_service) {
+                        authorityName = authorityInfo.base.service.getPackageName() + "/"
+                                + authorityInfo.base.service.getClassName()
+                                + " u" + authorityInfo.base.userId;
+                        accountKey = "none";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1928,10 +1900,11 @@
 
     class ServiceConnectionData {
         public final ActiveSyncContext activeSyncContext;
-        public final ISyncAdapter syncAdapter;
-        ServiceConnectionData(ActiveSyncContext activeSyncContext, ISyncAdapter syncAdapter) {
+        public final IBinder adapter;
+
+        ServiceConnectionData(ActiveSyncContext activeSyncContext, IBinder adapter) {
             this.activeSyncContext = activeSyncContext;
-            this.syncAdapter = syncAdapter;
+            this.adapter = adapter;
         }
     }
 
@@ -1951,8 +1924,7 @@
         public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
         private Long mAlarmScheduleTime = null;
         public final SyncTimeTracker mSyncTimeTracker = new SyncTimeTracker();
-        private final HashMap<Pair<Account, String>, PowerManager.WakeLock> mWakeLocks =
-                Maps.newHashMap();
+        private final HashMap<String, PowerManager.WakeLock> mWakeLocks = Maps.newHashMap();
 
         private volatile CountDownLatch mReadyToRunLatch = new CountDownLatch(1);
 
@@ -1966,12 +1938,11 @@
             }
         }
 
-        private PowerManager.WakeLock getSyncWakeLock(Account account, String authority) {
-            final Pair<Account, String> wakeLockKey = Pair.create(account, authority);
+        private PowerManager.WakeLock getSyncWakeLock(SyncOperation operation) {
+            final String wakeLockKey = operation.wakeLockKey();
             PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey);
             if (wakeLock == null) {
-                final String name = SYNC_WAKE_LOCK_PREFIX + "/" + authority + "/" + account.type
-                        + "/" + account.name;
+                final String name = SYNC_WAKE_LOCK_PREFIX + operation.wakeLockName();
                 wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name);
                 wakeLock.setReferenceCounted(false);
                 mWakeLocks.put(wakeLockKey, wakeLock);
@@ -2020,7 +1991,6 @@
             super(looper);
         }
 
-        @Override
         public void handleMessage(Message msg) {
             long earliestFuturePollTime = Long.MAX_VALUE;
             long nextPendingSyncTime = Long.MAX_VALUE;
@@ -2038,12 +2008,13 @@
                 earliestFuturePollTime = scheduleReadyPeriodicSyncs();
                 switch (msg.what) {
                     case SyncHandler.MESSAGE_CANCEL: {
-                        Pair<Account, String> payload = (Pair<Account, String>) msg.obj;
+                        SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj;
+                        Bundle extras = msg.peekData();
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: "
-                                    + payload.first + ", " + payload.second);
+                                    + payload + " bundle: " + extras);
                         }
-                        cancelActiveSyncLocked(payload.first, msg.arg1, payload.second);
+                        cancelActiveSyncLocked(payload, extras);
                         nextPendingSyncTime = maybeStartNextSyncLocked();
                         break;
                     }
@@ -2052,35 +2023,39 @@
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_FINISHED");
                         }
-                        SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload)msg.obj;
+                        SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload) msg.obj;
                         if (!isSyncStillActive(payload.activeSyncContext)) {
                             Log.d(TAG, "handleSyncHandlerMessage: dropping since the "
                                     + "sync is no longer active: "
                                     + payload.activeSyncContext);
                             break;
                         }
-                        runSyncFinishedOrCanceledLocked(payload.syncResult, payload.activeSyncContext);
+                        runSyncFinishedOrCanceledLocked(payload.syncResult,
+                                payload.activeSyncContext);
 
                         // since a sync just finished check if it is time to start a new sync
                         nextPendingSyncTime = maybeStartNextSyncLocked();
                         break;
 
                     case SyncHandler.MESSAGE_SERVICE_CONNECTED: {
-                        ServiceConnectionData msgData = (ServiceConnectionData)msg.obj;
+                        ServiceConnectionData msgData = (ServiceConnectionData) msg.obj;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CONNECTED: "
                                     + msgData.activeSyncContext);
                         }
                         // check that this isn't an old message
                         if (isSyncStillActive(msgData.activeSyncContext)) {
-                            runBoundToSyncAdapter(msgData.activeSyncContext, msgData.syncAdapter);
+                            runBoundToAdapter(
+                                    msgData.activeSyncContext,
+                                    msgData.adapter,
+                                    msg.arg1 /* target */);
                         }
                         break;
                     }
 
                     case SyncHandler.MESSAGE_SERVICE_DISCONNECTED: {
                         final ActiveSyncContext currentSyncContext =
-                                ((ServiceConnectionData)msg.obj).activeSyncContext;
+                                ((ServiceConnectionData) msg.obj).activeSyncContext;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_DISCONNECTED: "
                                     + currentSyncContext);
@@ -2089,12 +2064,15 @@
                         if (isSyncStillActive(currentSyncContext)) {
                             // cancel the sync if we have a syncadapter, which means one is
                             // outstanding
-                            if (currentSyncContext.mSyncAdapter != null) {
-                                try {
+                            try {
+                                if (currentSyncContext.mSyncAdapter != null) {
                                     currentSyncContext.mSyncAdapter.cancelSync(currentSyncContext);
-                                } catch (RemoteException e) {
-                                    // we don't need to retry this in this case
+                                } else if (currentSyncContext.mSyncServiceAdapter != null) {
+                                    currentSyncContext.mSyncServiceAdapter
+                                        .cancelSync(currentSyncContext);
                                 }
+                            } catch (RemoteException e) {
+                                // We don't need to retry this in this case.
                             }
 
                             // pretend that the sync failed with an IOException,
@@ -2139,9 +2117,46 @@
             }
         }
 
+        private boolean isDispatchable(SyncStorageEngine.EndPoint target) {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            if (target.target_provider) {
+                // skip the sync if the account of this operation no longer exists
+                AccountAndUser[] accounts = mRunningAccounts;
+                if (!containsAccountAndUser(
+                        accounts, target.account, target.userId)) {
+                    return false;
+                }
+                if (!mSyncStorageEngine.getMasterSyncAutomatically(target.userId)
+                        || !mSyncStorageEngine.getSyncAutomatically(
+                                target.account,
+                                target.userId,
+                                target.provider)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Not scheduling periodic operation: sync turned off.");
+                    }
+                    return false;
+                }
+                if (getIsSyncable(target.account, target.userId, target.provider)
+                        == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Not scheduling periodic operation: isSyncable == 0.");
+                    }
+                    return false;
+                }
+            } else if (target.target_service) {
+                if (getIsTargetServiceActive(target.service, target.userId) == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "   Not scheduling periodic operation: isEnabled == 0.");
+                    }
+                    return false;
+                }
+            }
+            return true;
+        }
+
         /**
          * Turn any periodic sync operations that are ready to run into pending sync operations.
-         * @return the desired start time of the earliest future  periodic sync operation,
+         * @return the desired start time of the earliest future periodic sync operation,
          * in milliseconds since boot
          */
         private long scheduleReadyPeriodicSyncs() {
@@ -2149,14 +2164,7 @@
             if (isLoggable) {
                 Log.v(TAG, "scheduleReadyPeriodicSyncs");
             }
-            final boolean backgroundDataUsageAllowed =
-                    getConnectivityManager().getBackgroundDataSetting();
             long earliestFuturePollTime = Long.MAX_VALUE;
-            if (!backgroundDataUsageAllowed) {
-                return earliestFuturePollTime;
-            }
-
-            AccountAndUser[] accounts = mRunningAccounts;
 
             final long nowAbsolute = System.currentTimeMillis();
             final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis)
@@ -2167,23 +2175,8 @@
             for (Pair<AuthorityInfo, SyncStatusInfo> info : infos) {
                 final AuthorityInfo authorityInfo = info.first;
                 final SyncStatusInfo status = info.second;
-                // skip the sync if the account of this operation no longer
-                // exists
-                if (!containsAccountAndUser(
-                        accounts, authorityInfo.account, authorityInfo.userId)) {
-                    continue;
-                }
-
-                if (!mSyncStorageEngine.getMasterSyncAutomatically(authorityInfo.userId)
-                        || !mSyncStorageEngine.getSyncAutomatically(
-                                authorityInfo.account, authorityInfo.userId,
-                                authorityInfo.authority)) {
-                    continue;
-                }
-
-                if (getIsSyncable(
-                        authorityInfo.account, authorityInfo.userId, authorityInfo.authority)
-                        == 0) {
+                
+                if (!isDispatchable(authorityInfo.base)) {
                     continue;
                 }
 
@@ -2211,7 +2204,7 @@
                     boolean runEarly = remainingMillis <= flexInMillis
                             && timeSinceLastRunMillis > periodInMillis - flexInMillis;
                     if (isLoggable) {
-                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.authority + "."
+                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.base + "."
                         + " period: " + (periodInMillis)
                         + " flex: " + (flexInMillis)
                         + " remaining: " + (remainingMillis)
@@ -2231,41 +2224,49 @@
                      * future, sync now and reinitialize. This can happen for
                      * example if the user changed the time, synced and changed
                      * back.
-                     * Case 3: If we failed to sync at the last scheduled
-                     * time.
+                     * Case 3: If we failed to sync at the last scheduled time.
                      * Case 4: This sync is close enough to the time that we can schedule it.
                      */
-                    if (runEarly // Case 4
-                            || remainingMillis == periodInMillis // Case 1
+                    if (remainingMillis == periodInMillis // Case 1
                             || lastPollTimeAbsolute > nowAbsolute // Case 2
-                            || timeSinceLastRunMillis >= periodInMillis) { // Case 3
+                            || timeSinceLastRunMillis >= periodInMillis // Case 3
+                            || runEarly) { // Case 4
                         // Sync now
-                        
-                        final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                                authorityInfo.account, authorityInfo.userId,
-                                authorityInfo.authority);
-                        final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-                        syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                                SyncAdapterType.newKey(
-                                        authorityInfo.authority, authorityInfo.account.type),
-                                authorityInfo.userId);
-                        if (syncAdapterInfo == null) {
-                            continue;
-                        }
+                        SyncStorageEngine.EndPoint target = authorityInfo.base;
+                        final Pair<Long, Long> backoff =
+                                mSyncStorageEngine.getBackoff(target);
                         mSyncStorageEngine.setPeriodicSyncTime(authorityInfo.ident,
                                 authorityInfo.periodicSyncs.get(i), nowAbsolute);
-                        scheduleSyncOperation(
-                                new SyncOperation(authorityInfo.account, authorityInfo.userId,
-                                        SyncOperation.REASON_PERIODIC,
-                                        SyncStorageEngine.SOURCE_PERIODIC,
-                                        authorityInfo.authority, extras,
-                                        0 /* runtime */, 0 /* flex */,
-                                                backoff != null ? backoff.first : 0,
-                                        mSyncStorageEngine.getDelayUntilTime(
-                                                authorityInfo.account, authorityInfo.userId,
-                                                authorityInfo.authority),
-                                        syncAdapterInfo.type.allowParallelSyncs()));
-                        
+
+                        if (target.target_provider) {
+                            final RegisteredServicesCache.ServiceInfo<SyncAdapterType>
+                                syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                                    SyncAdapterType.newKey(
+                                            target.provider, target.account.type),
+                                    target.userId);
+                            if (syncAdapterInfo == null) {
+                                continue;
+                            }
+                            scheduleSyncOperation(
+                                    new SyncOperation(target.account, target.userId,
+                                            SyncOperation.REASON_PERIODIC,
+                                            SyncStorageEngine.SOURCE_PERIODIC,
+                                            target.provider, extras,
+                                            0 /* runtime */, 0 /* flex */,
+                                            backoff != null ? backoff.first : 0,
+                                            mSyncStorageEngine.getDelayUntilTime(target),
+                                            syncAdapterInfo.type.allowParallelSyncs()));
+                        } else if (target.target_service) {
+                            scheduleSyncOperation(
+                                    new SyncOperation(target.service, target.userId,
+                                            SyncOperation.REASON_PERIODIC,
+                                            SyncStorageEngine.SOURCE_PERIODIC,
+                                            extras,
+                                            0 /* runtime */,
+                                            0 /* flex */,
+                                            backoff != null ? backoff.first : 0,
+                                            mSyncStorageEngine.getDelayUntilTime(target)));
+                        }
                     }
                     // Compute when this periodic sync should next run.
                     long nextPollTimeAbsolute;
@@ -2312,8 +2313,7 @@
 
             // If the accounts aren't known yet then we aren't ready to run. We will be kicked
             // when the account lookup request does complete.
-            AccountAndUser[] accounts = mRunningAccounts;
-            if (accounts == INITIAL_ACCOUNTS_ARRAY) {
+            if (mRunningAccounts == INITIAL_ACCOUNTS_ARRAY) {
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: accounts not known, skipping");
                 }
@@ -2323,9 +2323,6 @@
             // 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.
-            final boolean backgroundDataUsageAllowed =
-                    getConnectivityManager().getBackgroundDataSetting();
-
             final long now = SystemClock.elapsedRealtime();
 
             // will be set to the next time that a sync should be considered for running
@@ -2347,40 +2344,23 @@
                 while (operationIterator.hasNext()) {
                     final SyncOperation op = operationIterator.next();
 
-                    // Drop the sync if the account of this operation no longer exists.
-                    if (!containsAccountAndUser(accounts, op.account, op.userId)) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: account doesn't exist.");
-                        }
-                        continue;
-                    }
-
-                    // Drop this sync request if it isn't syncable.
-                    int syncableState = getIsSyncable(
-                            op.account, op.userId, op.authority);
-                    if (syncableState == 0) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: isSyncable == 0.");
-                        }
-                        continue;
-                    }
-
-                    // If the user is not running, drop the request.
-                    if (!activityManager.isUserRunning(op.userId)) {
-                        final UserInfo userInfo = mUserManager.getUserInfo(op.userId);
+                    // If the user is not running, skip the request.
+                    if (!activityManager.isUserRunning(op.target.userId)) {
+                        final UserInfo userInfo = mUserManager.getUserInfo(op.target.userId);
                         if (userInfo == null) {
-                            removedUsers.add(op.userId);
+                            removedUsers.add(op.target.userId);
                         }
                         if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: user not running.");
+                            Log.v(TAG, "    Dropping all sync operations for + "
+                                    + op.target.userId + ": user not running.");
                         }
                         continue;
                     }
-
+                    if (!isOperationValidLocked(op)) {
+                        operationIterator.remove();
+                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                        continue;
+                    }
                     // If the next run time is in the future, even given the flexible scheduling,
                     // return the time.
                     if (op.effectiveRunTime - op.flexTime > now) {
@@ -2388,42 +2368,16 @@
                             nextReadyToRunTime = op.effectiveRunTime;
                         }
                         if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: Sync too far in future.");
+                            Log.v(TAG, "    Not running sync operation: Sync too far in future."
+                                    + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime
+                                    + " now: " + now);
                         }
                         continue;
                     }
-                    // TODO: change this behaviour for non-registered syncs.
-                    final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-                    syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                            SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
-
-                    // only proceed if network is connected for requesting UID
-                    final boolean uidNetworkConnected;
-                    if (syncAdapterInfo != null) {
-                        final NetworkInfo networkInfo = getConnectivityManager()
-                                .getActiveNetworkInfoForUid(syncAdapterInfo.uid);
-                        uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
-                    } else {
-                        uidNetworkConnected = false;
-                    }
-
-                    // skip the sync if it isn't manual, and auto sync or
-                    // background data usage is disabled or network is
-                    // disconnected for the target UID.
-                    if (!op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
-                            && (syncableState > 0)
-                            && (!mSyncStorageEngine.getMasterSyncAutomatically(op.userId)
-                                || !backgroundDataUsageAllowed
-                                || !uidNetworkConnected
-                                || !mSyncStorageEngine.getSyncAutomatically(
-                                       op.account, op.userId, op.authority))) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        continue;
-                    }
-
+                    // Add this sync to be run.
                     operations.add(op);
                 }
+
                 for (Integer user : removedUsers) {
                     // if it's still removed
                     if (mUserManager.getUserInfo(user) == null) {
@@ -2465,13 +2419,9 @@
                             }
                         }
                     }
-                    if (activeOp.account.type.equals(candidate.account.type)
-                            && activeOp.authority.equals(candidate.authority)
-                            && activeOp.userId == candidate.userId
-                            && (!activeOp.allowParallelSyncs
-                                || activeOp.account.name.equals(candidate.account.name))) {
+                    if (activeOp.isConflict(candidate)) {
                         conflict = activeSyncContext;
-                        // don't break out since we want to do a full count of the varieties
+                        // don't break out since we want to do a full count of the varieties.
                     } else {
                         if (candidateIsInitialization == activeOp.isInitialization()
                                 && activeSyncContext.mStartTime + MAX_TIME_PER_SYNC < now) {
@@ -2521,8 +2471,8 @@
                     // is null. Reschedule the active sync and start the candidate.
                     toReschedule = oldestNonExpeditedRegular;
                     if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to run, "
-                                + oldestNonExpeditedRegular);
+                        Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to"
+                                + " run, " + oldestNonExpeditedRegular);
                     }
                 } else if (longRunning != null
                         && (candidateIsInitialization
@@ -2551,7 +2501,113 @@
             }
 
             return nextReadyToRunTime;
-     }
+        }
+
+        /**
+         * Determine if a sync is no longer valid and should be dropped from the sync queue and its
+         * pending op deleted.
+         * @param op operation for which the sync is to be scheduled.
+         */
+        private boolean isOperationValidLocked(SyncOperation op) {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            int targetUid;
+            int state;
+            final SyncStorageEngine.EndPoint target = op.target;
+            boolean syncEnabled = mSyncStorageEngine.getMasterSyncAutomatically(target.userId);
+            if (target.target_provider) {
+                // Drop the sync if the account of this operation no longer exists.
+                AccountAndUser[] accounts = mRunningAccounts;
+                if (!containsAccountAndUser(accounts, target.account, target.userId)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: account doesn't exist.");
+                    }
+                    return false;
+                }
+                // Drop this sync request if it isn't syncable.
+                state = getIsSyncable(target.account, target.userId, target.provider);
+                if (state == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: isSyncable == 0.");
+                    }
+                    return false;
+                }
+                syncEnabled = syncEnabled && mSyncStorageEngine.getSyncAutomatically(
+                        target.account, target.userId, target.provider);
+
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+                syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(
+                                target.provider, target.account.type), target.userId);
+                if (syncAdapterInfo != null) {
+                    targetUid = syncAdapterInfo.uid;
+                } else {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: No sync adapter registered"
+                                + "for: " + target);
+                    }
+                    return false;
+                }
+            } else if (target.target_service) {
+                state = getIsTargetServiceActive(target.service, target.userId);
+                if (state == 0) {
+                    // TODO: Change this to not drop disabled syncs - keep them in the pending queue.
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: isActive == 0.");
+                    }
+                    return false;
+                }
+                try {
+                    targetUid = mContext.getPackageManager()
+                            .getServiceInfo(target.service, 0)
+                            .applicationInfo
+                            .uid;
+                } catch (PackageManager.NameNotFoundException e) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: No service registered for: "
+                                + target.service);
+                    }
+                    return false;
+                }
+            } else {
+                Log.e(TAG, "Unknown target for Sync Op: " + target);
+                return false;
+            }
+
+            // We ignore system settings that specify the sync is invalid if:
+            // 1) It's manual - we try it anyway. When/if it fails it will be rescheduled.
+            //      or
+            // 2) it's an initialisation sync - we just need to connect to it.
+            final boolean ignoreSystemConfiguration =
+                    op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
+                    || (state < 0);
+
+            // Sync not enabled.
+            if (!syncEnabled && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: disallowed by settings/network.");
+                }
+                return false;
+            }
+            // Network down.
+            final NetworkInfo networkInfo = getConnectivityManager()
+                    .getActiveNetworkInfoForUid(targetUid);
+            final boolean uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
+            if (!uidNetworkConnected && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: disallowed by settings/network.");
+                }
+                return false;
+            }
+            // Metered network.
+            if (op.isNotAllowedOnMetered() && getConnectivityManager().isActiveNetworkMetered()
+                    && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: not allowed on metered network.");
+                }
+                return false;
+            }
+            return true;
+        }
 
         private boolean dispatchSyncOperation(SyncOperation op) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2561,27 +2617,48 @@
                     Log.v(TAG, syncContext.toString());
                 }
             }
-
-            // connect to the sync adapter
-            SyncAdapterType syncAdapterType = SyncAdapterType.newKey(op.authority, op.account.type);
-            final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-            syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, op.userId);
-            if (syncAdapterInfo == null) {
-                Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
-                        + ", removing settings for it");
-                mSyncStorageEngine.removeAuthority(op.account, op.userId, op.authority);
-                return false;
+            // Connect to the sync adapter.
+            int targetUid;
+            ComponentName targetComponent;
+            final SyncStorageEngine.EndPoint info = op.target;
+            if (info.target_provider) {
+                SyncAdapterType syncAdapterType =
+                        SyncAdapterType.newKey(info.provider, info.account.type);
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+                syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
+                if (syncAdapterInfo == null) {
+                    Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
+                            + ", removing settings for it");
+                    mSyncStorageEngine.removeAuthority(info);
+                    return false;
+                }
+                targetUid = syncAdapterInfo.uid;
+                targetComponent = syncAdapterInfo.componentName;
+            } else {
+                // TODO: Store the uid of the service as part of the authority info in order to
+                // avoid this call?
+                try {
+                    targetUid = mContext.getPackageManager()
+                            .getServiceInfo(info.service, 0)
+                            .applicationInfo
+                            .uid;
+                    targetComponent = info.service;
+                } catch(PackageManager.NameNotFoundException e) {
+                    Log.d(TAG, "Can't find a service for " + info.service
+                            + ", removing settings for it");
+                    mSyncStorageEngine.removeAuthority(info);
+                    return false;
+                }
             }
-
             ActiveSyncContext activeSyncContext =
-                    new ActiveSyncContext(op, insertStartSyncEvent(op), syncAdapterInfo.uid);
+                    new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid);
             activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext);
             mActiveSyncContexts.add(activeSyncContext);
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext);
             }
-            if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo, op.userId)) {
-                Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);
+            if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                Log.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
             }
@@ -2589,47 +2666,54 @@
             return true;
         }
 
-        private void runBoundToSyncAdapter(final ActiveSyncContext activeSyncContext,
-              ISyncAdapter syncAdapter) {
-            activeSyncContext.mSyncAdapter = syncAdapter;
+        private void runBoundToAdapter(final ActiveSyncContext activeSyncContext,
+                IBinder syncAdapter, int target) {
             final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
             try {
                 activeSyncContext.mIsLinkedToDeath = true;
-                syncAdapter.asBinder().linkToDeath(activeSyncContext, 0);
+                syncAdapter.linkToDeath(activeSyncContext, 0);
 
-                syncAdapter.startSync(activeSyncContext, syncOperation.authority,
-                        syncOperation.account, syncOperation.extras);
+                if (syncOperation.target.target_provider) {
+                    activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
+                    activeSyncContext.mSyncAdapter
+                        .startSync(activeSyncContext, syncOperation.target.provider,
+                                syncOperation.target.account, syncOperation.extras);
+                } else if (syncOperation.target.target_service) {
+                    activeSyncContext.mSyncServiceAdapter =
+                            ISyncServiceAdapter.Stub.asInterface(syncAdapter);
+                    activeSyncContext.mSyncServiceAdapter
+                        .startSync(activeSyncContext, syncOperation.extras);
+                }
             } catch (RemoteException remoteExc) {
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation);
-                scheduleSyncOperation(new SyncOperation(syncOperation));
+                scheduleSyncOperation(
+                        new SyncOperation(syncOperation, 0L /* newRunTimeFromNow */));
             } catch (RuntimeException exc) {
                 closeActiveSyncContext(activeSyncContext);
                 Log.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
         }
 
-        private void cancelActiveSyncLocked(Account account, int userId, String authority) {
+        /**
+         * Cancel the sync for the provided authority that matches the given bundle. Info here
+         * can have null fields to indicate all the active syncs for that field.
+         */
+        private void cancelActiveSyncLocked(SyncStorageEngine.EndPoint info, Bundle extras) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
                 if (activeSyncContext != null) {
-                    // if an account was specified then only cancel the sync if it matches
-                    if (account != null) {
-                        if (!account.equals(activeSyncContext.mSyncOperation.account)) {
-                            continue;
-                        }
+                    final SyncStorageEngine.EndPoint opInfo =
+                            activeSyncContext.mSyncOperation.target;
+                    if (!opInfo.matches(info)) {
+                        continue;
                     }
-                    // if an authority was specified then only cancel the sync if it matches
-                    if (authority != null) {
-                        if (!authority.equals(activeSyncContext.mSyncOperation.authority)) {
-                            continue;
-                        }
-                    }
-                    // check if the userid matches
-                    if (userId != UserHandle.USER_ALL
-                            && userId != activeSyncContext.mSyncOperation.userId) {
+                    if (extras != null &&
+                            !syncExtrasEquals(activeSyncContext.mSyncOperation.extras,
+                                    extras,
+                                    false /* no config settings */)) {
                         continue;
                     }
                     runSyncFinishedOrCanceledLocked(null /* no result since this is a cancel */,
@@ -2642,16 +2726,19 @@
                 ActiveSyncContext activeSyncContext) {
             boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
+            final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
+            final SyncStorageEngine.EndPoint info = syncOperation.target;
+
             if (activeSyncContext.mIsLinkedToDeath) {
-                activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                if (info.target_provider) {
+                    activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                } else {
+                    activeSyncContext.mSyncServiceAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                }
                 activeSyncContext.mIsLinkedToDeath = false;
             }
             closeActiveSyncContext(activeSyncContext);
-
-            final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
-
             final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
-
             String historyMessage;
             int downstreamActivity;
             int upstreamActivity;
@@ -2693,6 +2780,12 @@
                     } catch (RemoteException e) {
                         // we don't need to retry this in this case
                     }
+                } else if (activeSyncContext.mSyncServiceAdapter != null) {
+                    try {
+                        activeSyncContext.mSyncServiceAdapter.cancelSync(activeSyncContext);
+                    } catch (RemoteException e) {
+                        // we don't need to retry this in this case
+                    }
                 }
                 historyMessage = SyncStorageEngine.MESG_CANCELED;
                 downstreamActivity = 0;
@@ -2702,24 +2795,35 @@
             stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
                     upstreamActivity, downstreamActivity, elapsedTime);
 
-            if (syncResult != null && syncResult.tooManyDeletions) {
-                installHandleTooManyDeletesNotification(syncOperation.account,
-                        syncOperation.authority, syncResult.stats.numDeletes,
-                        syncOperation.userId);
+            // Check for full-resync and schedule it after closing off the last sync.
+            if (info.target_provider) {
+                if (syncResult != null && syncResult.tooManyDeletions) {
+                    installHandleTooManyDeletesNotification(info.account,
+                            info.provider, syncResult.stats.numDeletes,
+                            info.userId);
+                } else {
+                    mNotificationMgr.cancelAsUser(null,
+                            info.account.hashCode() ^ info.provider.hashCode(),
+                            new UserHandle(info.userId));
+                }
+                if (syncResult != null && syncResult.fullSyncRequested) {
+                    scheduleSyncOperation(
+                            new SyncOperation(info.account, info.userId,
+                                syncOperation.reason,
+                                syncOperation.syncSource, info.provider, new Bundle(),
+                                0 /* delay */, 0 /* flex */,
+                                syncOperation.backoff, syncOperation.delayUntil,
+                                syncOperation.allowParallelSyncs));
+                }
             } else {
-                mNotificationMgr.cancelAsUser(null,
-                        syncOperation.account.hashCode() ^ syncOperation.authority.hashCode(),
-                        new UserHandle(syncOperation.userId));
-            }
-
-            if (syncResult != null && syncResult.fullSyncRequested) {
-                scheduleSyncOperation(
-                        new SyncOperation(syncOperation.account, syncOperation.userId,
-                            syncOperation.reason,
-                            syncOperation.syncSource, syncOperation.authority, new Bundle(),
-                            0 /* delay */, 0 /* flex */,
-                            syncOperation.backoff, syncOperation.delayUntil,
-                            syncOperation.allowParallelSyncs));
+                if (syncResult != null && syncResult.fullSyncRequested) {
+                    scheduleSyncOperation(
+                            new SyncOperation(info.service, info.userId,
+                                syncOperation.reason,
+                                syncOperation.syncSource, new Bundle(),
+                                0 /* delay */, 0 /* flex */,
+                                syncOperation.backoff, syncOperation.delayUntil));
+                }
             }
             // no need to schedule an alarm, as that will be done by our caller.
         }
@@ -2728,7 +2832,7 @@
             activeSyncContext.close();
             mActiveSyncContexts.remove(activeSyncContext);
             mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo,
-                    activeSyncContext.mSyncOperation.userId);
+                    activeSyncContext.mSyncOperation.target.userId);
         }
 
         /**
@@ -2991,26 +3095,16 @@
         }
 
         public long insertStartSyncEvent(SyncOperation syncOperation) {
-            final int source = syncOperation.syncSource;
             final long now = System.currentTimeMillis();
-
-            EventLog.writeEvent(2720, syncOperation.authority,
-                                SyncStorageEngine.EVENT_START, source,
-                                syncOperation.account.name.hashCode());
-
-            return mSyncStorageEngine.insertStartSyncEvent(
-                    syncOperation.account, syncOperation.userId, syncOperation.reason,
-                    syncOperation.authority,
-                    now, source, syncOperation.isInitialization(), syncOperation.extras
-            );
+            EventLog.writeEvent(2720,
+                    syncOperation.toEventLog(SyncStorageEngine.EVENT_START));
+            return mSyncStorageEngine.insertStartSyncEvent(syncOperation, now);
         }
 
         public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
                 int upstreamActivity, int downstreamActivity, long elapsedTime) {
-            EventLog.writeEvent(2720, syncOperation.authority,
-                                SyncStorageEngine.EVENT_STOP, syncOperation.syncSource,
-                                syncOperation.account.name.hashCode());
-
+            EventLog.writeEvent(2720,
+                    syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP));
             mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime,
                     resultMessage, downstreamActivity, upstreamActivity);
         }
@@ -3025,6 +3119,79 @@
         return false;
     }
 
+    /**
+     * Sync extra comparison function.
+     * @param b1 bundle to compare
+     * @param b2 other bundle to compare
+     * @param includeSyncSettings if false, ignore system settings in bundle.
+     */
+    public static boolean syncExtrasEquals(Bundle b1, Bundle b2, boolean includeSyncSettings) {
+        if (b1 == b2) {
+            return true;
+        }
+        if (includeSyncSettings && b1.size() != b2.size()) {
+            return false;
+        }
+        for (String key : b1.keySet()) {
+            if (!includeSyncSettings && isSyncSetting(key)) {
+                continue;
+            }
+            if (!b2.containsKey(key)) {
+                return false;
+            }
+            if (!b1.get(key).equals(b2.get(key))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @return true if the provided key is used by the SyncManager in scheduling the sync.
+     */
+    private static boolean isSyncSetting(String key) {
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_MANUAL)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_PRIORITY)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_INITIALIZE)) {
+            return true;
+        }
+        return false;
+    }
+
     static class PrintTable {
         private ArrayList<Object[]> mTable = Lists.newArrayList();
         private final int mCols;
diff --git a/services/java/com/android/server/content/SyncOperation.java b/services/java/com/android/server/content/SyncOperation.java
index ce1dde4..eef20b2 100644
--- a/services/java/com/android/server/content/SyncOperation.java
+++ b/services/java/com/android/server/content/SyncOperation.java
@@ -20,10 +20,9 @@
 import android.content.pm.PackageManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
-import android.content.SyncRequest;
 import android.os.Bundle;
 import android.os.SystemClock;
-import android.util.Pair;
+import android.util.Log;
 
 /**
  * Value type that represents a sync operation.
@@ -32,10 +31,13 @@
  * {@hide}
  */
 public class SyncOperation implements Comparable {
+    public static final String TAG = "SyncManager";
+
     public static final int REASON_BACKGROUND_DATA_SETTINGS_CHANGED = -1;
     public static final int REASON_ACCOUNTS_UPDATED = -2;
     public static final int REASON_SERVICE_CHANGED = -3;
     public static final int REASON_PERIODIC = -4;
+    /** Sync started because it has just been set to isSyncable. */
     public static final int REASON_IS_SYNCABLE = -5;
     /** Sync started because it has just been set to sync automatically. */
     public static final int REASON_SYNC_AUTO = -6;
@@ -54,19 +56,21 @@
             "UserStart",
     };
 
-    /** Account info to identify a SyncAdapter registered with the system. */
-    public final Account account;
-    /** Authority info to identify a SyncAdapter registered with the system. */
-    public final String authority;
-    /** Service to which this operation will bind to perform the sync. */
-    public final ComponentName service;
-    public final int userId;
+    public static final int SYNC_TARGET_UNKNOWN = 0;
+    public static final int SYNC_TARGET_ADAPTER = 1;
+    public static final int SYNC_TARGET_SERVICE = 2;
+
+    /** Identifying info for the authority for this operation. */
+    public final SyncStorageEngine.EndPoint target;
+    /** Why this sync was kicked off. {@link #REASON_NAMES} */
     public final int reason;
+    /** Where this sync was initiated. */
     public int syncSource;
     public final boolean allowParallelSyncs;
     public Bundle extras;
     public final String key;
     public boolean expedited;
+    /** Bare-bones version of this operation that is persisted across reboots. */
     public SyncStorageEngine.PendingOperation pendingOperation;
     /** Elapsed real time in millis at which to run this sync. */
     public long latestRunTime;
@@ -79,25 +83,56 @@
      * Depends on max(backoff, latestRunTime, and delayUntil).
      */
     public long effectiveRunTime;
-    /** Amount of time before {@link effectiveRunTime} from which this sync can run. */
+    /** Amount of time before {@link #effectiveRunTime} from which this sync can run. */
     public long flexTime;
 
-    public SyncOperation(Account account, int userId, int reason, int source, String authority,
+    public SyncOperation(Account account, int userId, int reason, int source, String provider,
             Bundle extras, long runTimeFromNow, long flexTime, long backoff,
             long delayUntil, boolean allowParallelSyncs) {
-        this.service = null;
-        this.account = account;
-        this.authority = authority;
-        this.userId = userId;
+        this.target = new SyncStorageEngine.EndPoint(account, provider, userId);
         this.reason = reason;
-        this.syncSource = source;
         this.allowParallelSyncs = allowParallelSyncs;
+        this.key = initialiseOperation(this.target, source, extras, runTimeFromNow, flexTime,
+                backoff, delayUntil);
+    }
+
+    public SyncOperation(ComponentName service, int userId, int reason, int source,
+            Bundle extras, long runTimeFromNow, long flexTime, long backoff,
+            long delayUntil) {
+        this.target = new SyncStorageEngine.EndPoint(service, userId);
+        // Default to true for sync service. The service itself decides how to handle this.
+        this.allowParallelSyncs = true;
+        this.reason = reason;
+        this.key =
+                initialiseOperation(this.target,
+                        source, extras, runTimeFromNow, flexTime, backoff, delayUntil);
+    }
+
+    /** Used to reschedule a sync at a new point in time. */
+    SyncOperation(SyncOperation other, long newRunTimeFromNow) {
+        this.target = other.target;
+        this.reason = other.reason;
+        this.expedited = other.expedited;
+        this.allowParallelSyncs = other.allowParallelSyncs;
+        // re-use old flex, but only 
+        long newFlexTime = Math.min(other.flexTime, newRunTimeFromNow);
+        this.key =
+                initialiseOperation(this.target,
+                    other.syncSource, other.extras,
+                    newRunTimeFromNow /* runTimeFromNow*/,
+                    newFlexTime /* flexTime */,
+                    other.backoff,
+                    0L /* delayUntil */);
+    }
+
+    private String initialiseOperation(SyncStorageEngine.EndPoint info, int source, Bundle extras,
+            long runTimeFromNow, long flexTime, long backoff, long delayUntil) {
+        this.syncSource = source;
         this.extras = new Bundle(extras);
         cleanBundle(this.extras);
         this.delayUntil = delayUntil;
         this.backoff = backoff;
         final long now = SystemClock.elapsedRealtime();
-        // Checks the extras bundle. Must occur after we set the internal bundle.
         if (runTimeFromNow < 0 || isExpedited()) {
             this.expedited = true;
             this.latestRunTime = now;
@@ -108,41 +143,11 @@
             this.flexTime = flexTime;
         }
         updateEffectiveRunTime();
-        this.key = toKey();
+        return toKey(info, extras);
     }
 
-    public SyncOperation(SyncRequest request, int userId, int reason, int source, long backoff,
-            long delayUntil, boolean allowParallelSyncs) {
-        if (request.hasAuthority()) {
-            Pair<Account, String> providerInfo = request.getProviderInfo();
-            this.account = providerInfo.first;
-            this.authority = providerInfo.second;
-            this.service = null;
-        } else {
-            this.service = request.getService();
-            this.account = null;
-            this.authority = null;
-        }
-        this.userId = userId;
-        this.reason = reason;
-        this.syncSource = source;
-        this.allowParallelSyncs = allowParallelSyncs;
-        this.extras = new Bundle(extras);
-        cleanBundle(this.extras);
-        this.delayUntil = delayUntil;
-        this.backoff = backoff;
-        final long now = SystemClock.elapsedRealtime();
-        if (request.isExpedited()) {
-            this.expedited = true;
-            this.latestRunTime = now;
-            this.flexTime = 0;
-        } else {
-            this.expedited = false;
-            this.latestRunTime = now + (request.getSyncRunTime() * 1000);
-            this.flexTime = request.getSyncFlexTime() * 1000;
-        }
-        updateEffectiveRunTime();
-        this.key = toKey();
+    public boolean matchesAuthority(SyncOperation other) {
+        return this.target.matches(other.target);
     }
 
     /**
@@ -159,11 +164,7 @@
         removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS);
         removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_EXPEDITED);
         removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_ALLOW_METERED);
-
-        // Remove Config data.
-        bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD);
-        bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISALLOW_METERED);
     }
 
     private void removeFalseExtra(Bundle bundle, String extraName) {
@@ -172,22 +173,24 @@
         }
     }
 
-    /** Only used to immediately reschedule a sync. */
-    SyncOperation(SyncOperation other) {
-        this.service = other.service;
-        this.account = other.account;
-        this.authority = other.authority;
-        this.userId = other.userId;
-        this.reason = other.reason;
-        this.syncSource = other.syncSource;
-        this.extras = new Bundle(other.extras);
-        this.expedited = other.expedited;
-        this.latestRunTime = SystemClock.elapsedRealtime();
-        this.flexTime = 0L;
-        this.backoff = other.backoff;
-        this.allowParallelSyncs = other.allowParallelSyncs;
-        this.updateEffectiveRunTime();
-        this.key = toKey();
+    /**
+     * Determine whether if this sync operation is running, the provided operation would conflict
+     * with it.
+     * Parallel syncs allow multiple accounts to be synced at the same time. 
+     */
+    public boolean isConflict(SyncOperation toRun) {
+        final SyncStorageEngine.EndPoint other = toRun.target;
+        if (target.target_provider) {
+            return target.account.type.equals(other.account.type)
+                    && target.provider.equals(other.provider)
+                    && target.userId == other.userId
+                    && (!allowParallelSyncs
+                            || target.account.name.equals(other.account.name));
+        } else {
+            // Ops that target a service default to allow parallel syncs, which is handled by the
+            // service returning SYNC_IN_PROGRESS if they don't.
+            return target.service.equals(other.service) && !allowParallelSyncs;
+        }
     }
 
     @Override
@@ -196,18 +199,26 @@
     }
 
     public String dump(PackageManager pm, boolean useOneLine) {
-        StringBuilder sb = new StringBuilder()
-                .append(account.name)
+        StringBuilder sb = new StringBuilder();
+        if (target.target_provider) {
+            sb.append(target.account.name)
                 .append(" u")
-                .append(userId).append(" (")
-                .append(account.type)
+                .append(target.userId).append(" (")
+                .append(target.account.type)
                 .append(")")
                 .append(", ")
-                .append(authority)
-                .append(", ")
-                .append(SyncStorageEngine.SOURCES[syncSource])
-                .append(", latestRunTime ")
-                .append(latestRunTime);
+                .append(target.provider)
+                .append(", ");
+        } else if (target.target_service) {
+            sb.append(target.service.getPackageName())
+                .append(" u")
+                .append(target.userId).append(" (")
+                .append(target.service.getClassName()).append(")")
+                .append(", ");
+        }
+        sb.append(SyncStorageEngine.SOURCES[syncSource])
+            .append(", currentRunTime ")
+            .append(effectiveRunTime);
         if (expedited) {
             sb.append(", EXPEDITED");
         }
@@ -245,10 +256,6 @@
         }
     }
 
-    public boolean isMetered() {
-        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_ALLOW_METERED, false);
-    }
-
     public boolean isInitialization() {
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
     }
@@ -261,28 +268,39 @@
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
     }
 
+    public boolean isNotAllowedOnMetered() {
+        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
+    }
+
     /** Changed in V3. */
-    private String toKey() {
+    public static String toKey(SyncStorageEngine.EndPoint info, Bundle extras) {
         StringBuilder sb = new StringBuilder();
-        if (service == null) {
-            sb.append("authority: ").append(authority);
-            sb.append(" account {name=" + account.name + ", user=" + userId + ", type=" + account.type
+        if (info.target_provider) {
+            sb.append("provider: ").append(info.provider);
+            sb.append(" account {name=" + info.account.name
+                    + ", user="
+                    + info.userId
+                    + ", type="
+                    + info.account.type
                     + "}");
-        } else {
+        } else if (info.target_service) {
             sb.append("service {package=" )
-                .append(service.getPackageName())
+                .append(info.service.getPackageName())
                 .append(" user=")
-                .append(userId)
+                .append(info.userId)
                 .append(", class=")
-                .append(service.getClassName())
+                .append(info.service.getClassName())
                 .append("}");
+        } else {
+            Log.v(TAG, "Converting SyncOperaton to key, invalid target: " + info.toString());
+            return "";
         }
         sb.append(" extras: ");
         extrasToStringBuilder(extras, sb);
         return sb.toString();
     }
 
-    public static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+    private static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -290,6 +308,31 @@
         sb.append("]");
     }
 
+    public String wakeLockKey() {
+        if (target.target_provider) {
+            return target.account.name + "/" + target.account.type + ":" + target.provider;
+        } else if (target.target_service) {
+            return target.service.getPackageName() + "/" + target.service.getClassName();
+        } else {
+            Log.wtf(TAG, "Invalid target getting wakelock for operation - " + key);
+            return null;
+        }
+    }
+
+    public String wakeLockName() {
+        if (target.target_provider) {
+            return "/" + target.provider
+                    + "/" + target.account.type
+                    + "/" + target.account.name;
+        } else if (target.target_service) {
+            return "/" + target.service.getPackageName()
+                    + "/" + target.service.getClassName();
+        } else {
+            Log.wtf(TAG, "Invalid target getting wakelock name for operation - " + key);
+            return null;
+        }
+    }
+
     /**
      * Update the effective run time of this Operation based on latestRunTime (specified at
      * creation time of sync), delayUntil (specified by SyncAdapter), or backoff (specified by
@@ -325,4 +368,21 @@
             return 0;
         }
     }
+
+    // TODO: Test this to make sure that casting to object doesn't lose the type info for EventLog.
+    public Object[] toEventLog(int event) {
+        Object[] logArray = new Object[4];
+        logArray[1] = event;
+        logArray[2] = syncSource;
+        if (target.target_provider) {
+            logArray[0] = target.provider;
+            logArray[3] = target.account.name.hashCode();
+        } else if (target.target_service) {
+            logArray[0] = target.service.getPackageName();
+            logArray[3] = target.service.hashCode();
+        } else {
+            Log.wtf(TAG, "sync op with invalid target: " + key);
+        }
+        return logArray;
+    }
 }
diff --git a/services/java/com/android/server/content/SyncQueue.java b/services/java/com/android/server/content/SyncQueue.java
index 6f3fe6e..da7efba 100644
--- a/services/java/com/android/server/content/SyncQueue.java
+++ b/services/java/com/android/server/content/SyncQueue.java
@@ -16,12 +16,11 @@
 
 package com.android.server.content;
 
-import android.accounts.Account;
 import android.content.pm.PackageManager;
-import android.content.pm.RegisteredServicesCache;
 import android.content.SyncAdapterType;
 import android.content.SyncAdaptersCache;
 import android.content.pm.RegisteredServicesCache.ServiceInfo;
+import android.os.Bundle;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -60,25 +59,51 @@
 
     public void addPendingOperations(int userId) {
         for (SyncStorageEngine.PendingOperation op : mSyncStorageEngine.getPendingOperations()) {
-            if (op.userId != userId) continue;
+            final SyncStorageEngine.EndPoint info = op.authority;
+            if (info.userId != userId) continue;
 
-            final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                    op.account, op.userId, op.authority);
-            final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                    SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
-            if (syncAdapterInfo == null) {
-                Log.w(TAG, "Missing sync adapter info for authority " + op.authority + ", userId "
-                        + op.userId);
-                continue;
+            final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+            SyncOperation operationToAdd;
+            if (info.target_provider) {
+                final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(info.provider, info.account.type), info.userId);
+                if (syncAdapterInfo == null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.w(TAG, "Missing sync adapter info for authority " + op.authority);
+                    }
+                    continue;
+                }
+                operationToAdd = new SyncOperation(
+                        info.account, info.userId, op.reason, op.syncSource, info.provider,
+                        op.extras,
+                        0 /* delay */,
+                        0 /* flex */,
+                        backoff != null ? backoff.first : 0,
+                        mSyncStorageEngine.getDelayUntilTime(info),
+                        syncAdapterInfo.type.allowParallelSyncs());
+                operationToAdd.expedited = op.expedited;
+                operationToAdd.pendingOperation = op;
+                add(operationToAdd, op);
+            } else if (info.target_service) {
+                try {
+                    mPackageManager.getServiceInfo(info.service, 0);
+                } catch (PackageManager.NameNotFoundException e) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.w(TAG, "Missing sync servce for authority " + op.authority);
+                    }
+                    continue;
+                }
+                operationToAdd = new SyncOperation(
+                        info.service, info.userId, op.reason, op.syncSource,
+                        op.extras,
+                        0 /* delay */,
+                        0 /* flex */,
+                        backoff != null ? backoff.first : 0,
+                        mSyncStorageEngine.getDelayUntilTime(info));
+                operationToAdd.expedited = op.expedited;
+                operationToAdd.pendingOperation = op;
+                add(operationToAdd, op);
             }
-            SyncOperation syncOperation = new SyncOperation(
-                    op.account, op.userId, op.reason, op.syncSource, op.authority, op.extras,
-                    0 /* delay */, 0 /* flex */, backoff != null ? backoff.first : 0,
-                    mSyncStorageEngine.getDelayUntilTime(op.account, op.userId, op.authority),
-                    syncAdapterInfo.type.allowParallelSyncs());
-            syncOperation.expedited = op.expedited;
-            syncOperation.pendingOperation = op;
-            add(syncOperation, op);
         }
     }
 
@@ -119,12 +144,8 @@
         operation.pendingOperation = pop;
         // Don't update the PendingOp if one already exists. This really is just a placeholder,
         // no actual scheduling info is placed here.
-        // TODO: Change this to support service components.
         if (operation.pendingOperation == null) {
-            pop = new SyncStorageEngine.PendingOperation(
-                    operation.account, operation.userId, operation.reason, operation.syncSource,
-                    operation.authority, operation.extras, operation.expedited);
-            pop = mSyncStorageEngine.insertIntoPending(pop);
+            pop = mSyncStorageEngine.insertIntoPending(operation);
             if (pop == null) {
                 throw new IllegalStateException("error adding pending sync operation "
                         + operation);
@@ -136,17 +157,16 @@
         return true;
     }
 
-    public void removeUser(int userId) {
+    public void removeUserLocked(int userId) {
         ArrayList<SyncOperation> opsToRemove = new ArrayList<SyncOperation>();
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.userId == userId) {
+            if (op.target.userId == userId) {
                 opsToRemove.add(op);
             }
         }
-
-        for (SyncOperation op : opsToRemove) {
-            remove(op);
-        }
+            for (SyncOperation op : opsToRemove) {
+                remove(op);
+            }
     }
 
     /**
@@ -154,8 +174,15 @@
      * @param operation the operation to remove
      */
     public void remove(SyncOperation operation) {
+        boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG);
         SyncOperation operationToRemove = mOperationsMap.remove(operation.key);
+        if (isLoggable) {
+            Log.d(TAG, "Attempting to remove: " + operation.key);
+        }
         if (operationToRemove == null) {
+            if (isLoggable) {
+                Log.d(TAG, "Could not find: " + operation.key);
+            }
             return;
         }
         if (!mSyncStorageEngine.deleteFromPending(operationToRemove.pendingOperation)) {
@@ -164,41 +191,58 @@
         }
     }
 
-    public void onBackoffChanged(Account account, int userId, String providerName, long backoff) {
-        // for each op that matches the account and provider update its
+    /** Reset backoffs for all operations in the queue. */
+    public void clearBackoffs() {
+        for (SyncOperation op : mOperationsMap.values()) {
+            op.backoff = 0L;
+            op.updateEffectiveRunTime();
+        }
+    }
+
+    public void onBackoffChanged(SyncStorageEngine.EndPoint target, long backoff) {
+        // For each op that matches the authority of the changed op, update its
         // backoff and effectiveStartTime
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.account.equals(account) && op.authority.equals(providerName)
-                    && op.userId == userId) {
+            if (op.target.matches(target)) {
                 op.backoff = backoff;
                 op.updateEffectiveRunTime();
             }
         }
     }
 
-    public void onDelayUntilTimeChanged(Account account, String providerName, long delayUntil) {
-        // for each op that matches the account and provider update its
-        // delayUntilTime and effectiveStartTime
+    public void onDelayUntilTimeChanged(SyncStorageEngine.EndPoint target, long delayUntil) {
+        // for each op that matches the authority info of the provided op, change the delay time.
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.account.equals(account) && op.authority.equals(providerName)) {
+            if (op.target.matches(target)) {
                 op.delayUntil = delayUntil;
                 op.updateEffectiveRunTime();
             }
         }
     }
 
-    public void remove(Account account, int userId, String authority) {
+    /**
+     * Remove all of the SyncOperations associated with a given target.
+     *
+     * @param info target object provided here can have null Account/provider. This is the case
+     * where you want to remove all ops associated with a provider (null Account) or all ops
+     * associated with an account (null provider).
+     * @param extras option bundle to include to further specify which operation to remove. If this
+     * bundle contains sync settings flags, they are ignored.
+     */
+    public void remove(final SyncStorageEngine.EndPoint info, Bundle extras) {
         Iterator<Map.Entry<String, SyncOperation>> entries = mOperationsMap.entrySet().iterator();
         while (entries.hasNext()) {
             Map.Entry<String, SyncOperation> entry = entries.next();
             SyncOperation syncOperation = entry.getValue();
-            if (account != null && !syncOperation.account.equals(account)) {
+            final SyncStorageEngine.EndPoint opInfo = syncOperation.target;
+            if (!opInfo.matches(info)) {
                 continue;
             }
-            if (authority != null && !syncOperation.authority.equals(authority)) {
-                continue;
-            }
-            if (userId != syncOperation.userId) {
+            if (extras != null
+                    && !SyncManager.syncExtrasEquals(
+                        syncOperation.extras,
+                        extras,
+                        false /* no config flags*/)) {
                 continue;
             }
             entries.remove();
diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
index 1b9ed98..6cc3d8a 100644
--- a/services/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -24,6 +24,7 @@
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
 import android.content.SyncInfo;
+import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
@@ -36,10 +37,12 @@
 import android.os.Parcel;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.util.ArrayMap;
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -71,7 +74,6 @@
 public class SyncStorageEngine extends Handler {
 
     private static final String TAG = "SyncManager";
-    private static final boolean DEBUG = false;
     private static final String TAG_FILE = "SyncManagerFile";
 
     private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
@@ -108,10 +110,7 @@
 
     /** 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)
-     */
+    /** 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. */
@@ -119,6 +118,9 @@
 
     /** Enum value for a periodic sync. */
     public static final int SOURCE_PERIODIC = 4;
+    
+    /** Enum value for a sync started for a service. */
+    public static final int SOURCE_SERVICE = 5;
 
     public static final long NOT_IN_BACKOFF_MODE = -1;
 
@@ -128,7 +130,8 @@
                                              "LOCAL",
                                              "POLL",
                                              "USER",
-                                             "PERIODIC" };
+                                             "PERIODIC",
+                                             "SERVICE"};
 
     // The MESG column will contain one of these or one of the Error types.
     public static final String MESG_SUCCESS = "success";
@@ -156,41 +159,53 @@
     }
 
     public static class PendingOperation {
-        final Account account;
-        final int userId;
+        final EndPoint authority;
         final int reason;
         final int syncSource;
-        final String authority;
         final Bundle extras;        // note: read-only.
-        final ComponentName serviceName;
         final boolean expedited;
 
-        int authorityId;
+        final int authorityId;
+        // No longer used.
+        // Keep around for sake up updating from pending.bin to pending.xml
         byte[] flatExtras;
 
-        PendingOperation(Account account, int userId, int reason, int source,
-                String authority, Bundle extras, boolean expedited) {
-            this.account = account;
-            this.userId = userId;
+        PendingOperation(AuthorityInfo authority, int reason, int source,
+                 Bundle extras, boolean expedited) {
+            this.authority = authority.base;
             this.syncSource = source;
             this.reason = reason;
-            this.authority = authority;
             this.extras = extras != null ? new Bundle(extras) : extras;
             this.expedited = expedited;
-            this.authorityId = -1;
-            this.serviceName = null;
+            this.authorityId = authority.ident;
         }
 
         PendingOperation(PendingOperation other) {
-            this.account = other.account;
-            this.userId = other.userId;
             this.reason = other.reason;
             this.syncSource = other.syncSource;
             this.authority = other.authority;
             this.extras = other.extras;
             this.authorityId = other.authorityId;
             this.expedited = other.expedited;
-            this.serviceName = other.serviceName;
+        }
+
+        /**
+         * Considered equal if they target the same sync adapter (A {@link android.content.SyncService}
+         * is considered an adapter), for the same userId.
+         * @param other PendingOperation to compare.
+         * @return true if the two pending ops are the same.
+         */
+        public boolean equals(PendingOperation other) {
+            return authority.matches(other.authority);
+        }
+
+        public String toString() {
+            return "service=" + authority.service
+                        + " user=" + authority.userId
+                        + " auth=" + authority
+                        + " account=" + authority.account
+                        + " src=" + syncSource
+                        + " extras=" + extras;
         }
     }
 
@@ -204,17 +219,93 @@
         }
     }
 
-    public static class AuthorityInfo {
+    /**  Bare bones representation of a sync target. */
+    public static class EndPoint {
+        public final static EndPoint USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL =
+                new EndPoint(null, null, UserHandle.USER_ALL);
         final ComponentName service;
         final Account account;
         final int userId;
-        final String authority;
+        final String provider;
+        final boolean target_service;
+        final boolean target_provider;
+
+        public EndPoint(ComponentName service, int userId) {
+            this.service = service;
+            this.userId = userId;
+            this.account = null;
+            this.provider = null;
+            this.target_service = true;
+            this.target_provider = false;
+        }
+
+        public EndPoint(Account account, String provider, int userId) {
+            this.account = account;
+            this.provider = provider;
+            this.userId = userId;
+            this.service = null;
+            this.target_service = false;
+            this.target_provider = true;
+        }
+
+        /**
+         * An Authority for a sync matches if it targets the same sync adapter for the same user.
+         * If the authority is for a provider/account pair and the account or provider is null, it
+         * matches by default.
+         */
+        public boolean matches(EndPoint other) {
+            if (userId != other.userId
+                    && userId != UserHandle.USER_ALL
+                    && other.userId != UserHandle.USER_ALL) {
+                return false;
+            }
+            if (target_service && other.target_service) {
+                return service.equals(other.service);
+            } else if (target_provider && other.target_provider) {
+                boolean accountsMatch;
+                if (account == null || other.account == null) {
+                    accountsMatch = true;
+                } else {
+                    accountsMatch = account.equals(other.account);
+                }
+                boolean providersMatch;
+                if (provider == null || other.provider == null) {
+                    providersMatch = true;
+                } else {
+                    providersMatch = provider.equals(other.provider);
+                }
+                return accountsMatch && providersMatch;
+            }
+            return false;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            if (target_provider) {
+                sb.append(account == null ? "ALL ACCS" : account.name)
+                    .append("/")
+                    .append(provider == null ? "ALL PDRS" : provider);
+            } else if (target_service) {
+                sb.append(service.getPackageName());
+            } else {
+                sb.append("invalid target");
+            }
+            return sb.toString();
+        }
+    }
+
+    public static class AuthorityInfo {
+        final EndPoint base;
         final int ident;
         boolean enabled;
         int syncable;
+        /** Time at which this sync will run, taking into account backoff. */
         long backoffTime;
+        /** Amount of delay due to backoff. */
         long backoffDelay;
+        /** Offset to add to any requests coming to this authority. */
         long delayUntil;
+
         final ArrayList<PeriodicSync> periodicSyncs;
 
         /**
@@ -224,10 +315,7 @@
          * @param toCopy AuthorityInfo to be copied.
          */
         AuthorityInfo(AuthorityInfo toCopy) {
-            account = toCopy.account;
-            userId = toCopy.userId;
-            authority = toCopy.authority;
-            service = toCopy.service;
+            base = toCopy.base;
             ident = toCopy.ident;
             enabled = toCopy.enabled;
             syncable = toCopy.syncable;
@@ -241,56 +329,42 @@
             }
         }
 
-        /**
-         * Create an authority with one periodic sync scheduled with an empty bundle and syncing
-         * every day. An empty bundle is considered equal to any other bundle see
-         * {@link PeriodicSync.syncExtrasEquals}.
-         * @param account Account that this authority syncs.
-         * @param userId which user this sync is registered for.
-         * @param userId user for which this authority is registered.
-         * @param ident id of this authority.
-         */
-        AuthorityInfo(Account account, int userId, String authority, int ident) {
-            this.account = account;
-            this.userId = userId;
-            this.authority = authority;
-            this.service = null;
-            this.ident = ident;
-            enabled = SYNC_ENABLED_DEFAULT;
+        AuthorityInfo(EndPoint info, int id) {
+            base = info;
+            ident = id;
+            enabled = info.target_provider ?
+                    SYNC_ENABLED_DEFAULT : true;
+            // Service is active by default,
+            if (info.target_service) {
+                this.syncable = 1;
+            }
+            periodicSyncs = new ArrayList<PeriodicSync>();
+            defaultInitialisation();
+        }
+
+        private void defaultInitialisation() {
             syncable = -1; // default to "unknown"
             backoffTime = -1; // if < 0 then we aren't in backoff mode
             backoffDelay = -1; // if < 0 then we aren't in backoff mode
-            periodicSyncs = new ArrayList<PeriodicSync>();
-            // Old version adds one periodic sync a day.
-            periodicSyncs.add(new PeriodicSync(account, authority,
-                                new Bundle(),
-                                DEFAULT_POLL_FREQUENCY_SECONDS,
-                                calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)));
+            PeriodicSync defaultSync;
+            // Old version is one sync a day. Empty bundle gets replaced by any addPeriodicSync()
+            // call.
+            if (base.target_provider) {
+                defaultSync =
+                        new PeriodicSync(base.account, base.provider,
+                            new Bundle(),
+                            DEFAULT_POLL_FREQUENCY_SECONDS,
+                            calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS));
+                periodicSyncs.add(defaultSync);
+            }
+            
         }
 
         /**
-         * Create an authority with one periodic sync scheduled with an empty bundle and syncing
-         * every day using a sync service.
-         * @param cname sync service identifier.
-         * @param userId user for which this authority is registered.
-         * @param ident id of this authority.
+         * Two AuthorityInfos are considered equal if they have the same authority.
          */
-        AuthorityInfo(ComponentName cname, int userId, int ident) {
-            this.account = null;
-            this.userId = userId;
-            this.authority = null;
-            this.service = cname;
-            this.ident = ident;
-            // Sync service is always enabled.
-            enabled = true;
-            syncable = -1; // default to "unknown"
-            backoffTime = -1; // if < 0 then we aren't in backoff mode
-            backoffDelay = -1; // if < 0 then we aren't in backoff mode
-            periodicSyncs = new ArrayList<PeriodicSync>();
-            periodicSyncs.add(new PeriodicSync(account, authority,
-                                new Bundle(),
-                                DEFAULT_POLL_FREQUENCY_SECONDS,
-                                calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)));
+        public boolean equals(EndPoint other) {
+            return base.matches(other);
         }
     }
 
@@ -322,16 +396,9 @@
     }
 
     interface OnSyncRequestListener {
-        /**
-         * Called when a sync is needed on an account(s) due to some change in state.
-         * @param account
-         * @param userId
-         * @param reason
-         * @param authority
-         * @param extras
-         */
-        public void onSyncRequest(Account account, int userId, int reason, String authority,
-                Bundle extras);
+
+        /** Called when a sync is needed on an account(s) due to some change in state. */
+        public void onSyncRequest(EndPoint info, int reason, Bundle extras);
     }
 
     // Primary list of all syncable authorities.  Also our global lock.
@@ -357,8 +424,8 @@
             = new RemoteCallbackList<ISyncStatusObserver>();
 
     /** Reverse mapping for component name -> <userid -> authority id>. */
-    private final HashMap<ComponentName, SparseArray<AuthorityInfo>> mServices =
-            new HashMap<ComponentName, SparseArray<AuthorityInfo>>();
+    private final ArrayMap<ComponentName, SparseArray<AuthorityInfo>> mServices =
+            new ArrayMap<ComponentName, SparseArray<AuthorityInfo>>();
 
     private int mNextAuthorityId = 0;
 
@@ -501,7 +568,7 @@
      * @return amount of seconds before syncTimeSeconds that the sync can occur.
      *      I.e.
      *      earliest_sync_time = syncTimeSeconds - calculateDefaultFlexTime(syncTimeSeconds)
-     * The flex time is capped at a percentage of the {@link DEFAULT_POLL_FREQUENCY_SECONDS}.
+     * The flex time is capped at a percentage of the {@link #DEFAULT_POLL_FREQUENCY_SECONDS}.
      */
     public static long calculateDefaultFlexTime(long syncTimeSeconds) {
         if (syncTimeSeconds < DEFAULT_MIN_FLEX_ALLOWED_SECS) {
@@ -535,7 +602,7 @@
             mChangeListeners.finishBroadcast();
         }
 
-        if (DEBUG) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "reportChange " + which + " to: " + reports);
         }
 
@@ -555,7 +622,8 @@
     public boolean getSyncAutomatically(Account account, int userId, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(account, providerName, userId),
                         "getSyncAutomatically");
                 return authority != null && authority.enabled;
             }
@@ -563,10 +631,9 @@
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
-                AuthorityInfo authority = mAuthorities.valueAt(i);
-                if (authority.authority.equals(providerName)
-                        && authority.userId == userId
-                        && authority.enabled) {
+                AuthorityInfo authorityInfo = mAuthorities.valueAt(i);
+                if (authorityInfo.base.matches(new EndPoint(account, providerName, userId))
+                        && authorityInfo.enabled) {
                     return true;
                 }
             }
@@ -576,15 +643,18 @@
 
     public void setSyncAutomatically(Account account, int userId, String providerName,
             boolean sync) {
-        if (DEBUG) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.d(TAG, "setSyncAutomatically: " + /* account + */" provider " + providerName
                     + ", user " + userId + " -> " + sync);
         }
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(account, userId, providerName, -1,
-                    false);
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(
+                            new EndPoint(account, providerName, userId),
+                            -1 /* ident */,
+                            false);
             if (authority.enabled == sync) {
-                if (DEBUG) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.d(TAG, "setSyncAutomatically: already set to " + sync + ", doing nothing");
                 }
                 return;
@@ -603,8 +673,9 @@
     public int getIsSyncable(Account account, int userId, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                        "getIsSyncable");
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(account, providerName, userId),
+                        "get authority syncable");
                 if (authority == null) {
                     return -1;
                 }
@@ -614,9 +685,10 @@
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
-                AuthorityInfo authority = mAuthorities.valueAt(i);
-                if (authority.authority.equals(providerName)) {
-                    return authority.syncable;
+                AuthorityInfo authorityInfo = mAuthorities.valueAt(i);
+                if (authorityInfo.base != null
+                        && authorityInfo.base.provider.equals(providerName)) {
+                    return authorityInfo.syncable;
                 }
             }
             return -1;
@@ -624,103 +696,163 @@
     }
 
     public void setIsSyncable(Account account, int userId, String providerName, int syncable) {
+        synchronized (mAuthorities) {
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(
+                            new EndPoint(account, providerName, userId),
+                            -1 /* ident */,
+                            false);
+            setSyncableLocked(authority, syncable);
+        }
+    }
+
+    public int getIsTargetServiceActive(ComponentName cname, int userId) {
+        synchronized (mAuthorities) {
+            if (cname != null) {
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(cname, userId),
+                        "get service enabled");
+                if (authority == null) {
+                    return -1;
+                }
+                return authority.syncable;
+            }
+            return -1;
+        }
+    }
+
+    public void setIsEnabled(ComponentName cname, int userId, int syncable) {
+        synchronized (mAuthorities) {
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(
+                            new EndPoint(cname, userId), -1, false);
+            setSyncableLocked(authority, syncable);
+        }
+    }
+
+    /**
+     * An enabled sync service and a syncable provider's adapter both get resolved to the same
+     * persisted variable - namely the "syncable" attribute for an AuthorityInfo in accounts.xml.
+     * @param aInfo
+     * @param syncable
+     */
+    private void setSyncableLocked(AuthorityInfo aInfo, int syncable) {
         if (syncable > 1) {
             syncable = 1;
         } else if (syncable < -1) {
             syncable = -1;
         }
-        if (DEBUG) {
-            Log.d(TAG, "setIsSyncable: " + account + ", provider " + providerName
-                    + ", user " + userId + " -> " + syncable);
-        }
-        synchronized (mAuthorities) {
-            AuthorityInfo authority =
-                    getOrCreateAuthorityLocked(account, userId, providerName, -1, false);
-            if (authority.syncable == syncable) {
-                if (DEBUG) {
-                    Log.d(TAG, "setIsSyncable: already set to " + syncable + ", doing nothing");
-                }
-                return;
-            }
-            authority.syncable = syncable;
-            writeAccountInfoLocked();
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.d(TAG, "setIsSyncable: " + aInfo.toString() + " -> " + syncable);
         }
 
+        if (aInfo.syncable == syncable) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.d(TAG, "setIsSyncable: already set to " + syncable + ", doing nothing");
+            }
+            return;
+        }
+        aInfo.syncable = syncable;
+        writeAccountInfoLocked();
+
         if (syncable > 0) {
-            requestSync(account, userId, SyncOperation.REASON_IS_SYNCABLE,  providerName,
-                    new Bundle());
+            requestSync(aInfo, SyncOperation.REASON_IS_SYNCABLE, new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public Pair<Long, Long> getBackoff(Account account, int userId, String providerName) {
+    public Pair<Long, Long> getBackoff(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getBackoff");
-            if (authority == null || authority.backoffTime < 0) {
-                return null;
+            AuthorityInfo authority = getAuthorityLocked(info, "getBackoff");
+            if (authority != null) {
+                return Pair.create(authority.backoffTime, authority.backoffDelay);
             }
-            return Pair.create(authority.backoffTime, authority.backoffDelay);
+            return null;
         }
     }
 
-    public void setBackoff(Account account, int userId, String providerName,
-            long nextSyncTime, long nextDelay) {
-        if (DEBUG) {
-            Log.v(TAG, "setBackoff: " + account + ", provider " + providerName
-                    + ", user " + userId
+    /**
+     * Update the backoff for the given endpoint. The endpoint may be for a provider/account and
+     * the account or provider info be null, which signifies all accounts or providers.
+     */
+    public void setBackoff(EndPoint info, long nextSyncTime, long nextDelay) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "setBackoff: " + info
                     + " -> nextSyncTime " + nextSyncTime + ", nextDelay " + nextDelay);
         }
-        boolean changed = false;
+        boolean changed;
         synchronized (mAuthorities) {
-            if (account == null || providerName == null) {
-                for (AccountInfo accountInfo : mAccounts.values()) {
-                    if (account != null && !account.equals(accountInfo.accountAndUser.account)
-                            && userId != accountInfo.accountAndUser.userId) {
-                        continue;
-                    }
-                    for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                        if (providerName != null
-                                && !providerName.equals(authorityInfo.authority)) {
-                            continue;
-                        }
-                        if (authorityInfo.backoffTime != nextSyncTime
-                                || authorityInfo.backoffDelay != nextDelay) {
-                            authorityInfo.backoffTime = nextSyncTime;
-                            authorityInfo.backoffDelay = nextDelay;
-                            changed = true;
-                        }
-                    }
-                }
+            if (info.target_provider
+                    && (info.account == null || info.provider == null)) {
+                // Do more work for a provider sync if the provided info has specified all
+                // accounts/providers. 
+                changed = setBackoffLocked(
+                        info.account /* may be null */,
+                        info.userId,
+                        info.provider /* may be null */,
+                        nextSyncTime, nextDelay);
             } else {
-                AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(account, userId, providerName, -1 /* ident */,
-                                true);
-                if (authority.backoffTime == nextSyncTime && authority.backoffDelay == nextDelay) {
-                    return;
+                AuthorityInfo authorityInfo =
+                        getOrCreateAuthorityLocked(info, -1 /* ident */, true);
+                if (authorityInfo.backoffTime == nextSyncTime
+                        && authorityInfo.backoffDelay == nextDelay) {
+                    changed = false;
+                } else {
+                    authorityInfo.backoffTime = nextSyncTime;
+                    authorityInfo.backoffDelay = nextDelay;
+                    changed = true;
                 }
-                authority.backoffTime = nextSyncTime;
-                authority.backoffDelay = nextDelay;
-                changed = true;
             }
         }
-
         if (changed) {
             reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
         }
     }
 
+    /**
+     * Either set backoff for a specific authority, or set backoff for all the
+     * accounts on a specific adapter/all adapters.
+     *
+     * @param account account for which to set backoff. Null to specify all accounts.
+     * @param userId id of the user making this request.
+     * @param providerName provider for which to set backoff. Null to specify all providers.
+     */
+    private boolean setBackoffLocked(Account account, int userId, String providerName,
+            long nextSyncTime, long nextDelay) {
+        boolean changed = false;
+        for (AccountInfo accountInfo : mAccounts.values()) {
+            if (account != null && !account.equals(accountInfo.accountAndUser.account)
+                    && userId != accountInfo.accountAndUser.userId) {
+                continue;
+            }
+            for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+                if (providerName != null
+                        && !providerName.equals(authorityInfo.base.provider)) {
+                    continue;
+                }
+                if (authorityInfo.backoffTime != nextSyncTime
+                        || authorityInfo.backoffDelay != nextDelay) {
+                    authorityInfo.backoffTime = nextSyncTime;
+                    authorityInfo.backoffDelay = nextDelay;
+                    changed = true;
+                }
+            }
+        }
+        return changed;
+    }
+
     public void clearAllBackoffs(SyncQueue syncQueue) {
         boolean changed = false;
         synchronized (mAuthorities) {
             synchronized (syncQueue) {
+                // Clear backoff for all sync adapters.
                 for (AccountInfo accountInfo : mAccounts.values()) {
                     for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
                         if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
                                 || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
-                            if (DEBUG) {
+                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Log.v(TAG, "clearAllBackoffs:"
-                                        + " authority:" + authorityInfo.authority
+                                        + " authority:" + authorityInfo.base
                                         + " account:" + accountInfo.accountAndUser.account.name
                                         + " user:" + accountInfo.accountAndUser.userId
                                         + " backoffTime was: " + authorityInfo.backoffTime
@@ -728,12 +860,23 @@
                             }
                             authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
                             authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
-                            syncQueue.onBackoffChanged(accountInfo.accountAndUser.account,
-                                    accountInfo.accountAndUser.userId, authorityInfo.authority, 0);
                             changed = true;
                         }
                     }
                 }
+                // Clear backoff for all sync services.
+                for (ComponentName service : mServices.keySet()) {
+                    SparseArray<AuthorityInfo> aInfos = mServices.get(service);
+                    for (int i = 0; i < aInfos.size(); i++) {
+                        AuthorityInfo authorityInfo = aInfos.valueAt(i);
+                        if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+                                || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+                            authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+                            authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+                        }
+                    }
+                }
+                syncQueue.clearBackoffs();
             }
         }
 
@@ -742,28 +885,9 @@
         }
     }
 
-    public void setDelayUntilTime(Account account, int userId, String providerName,
-            long delayUntil) {
-        if (DEBUG) {
-            Log.v(TAG, "setDelayUntil: " + account + ", provider " + providerName
-                    + ", user " + userId + " -> delayUntil " + delayUntil);
-        }
+    public long getDelayUntilTime(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(
-                    account, userId, providerName, -1 /* ident */, true);
-            if (authority.delayUntil == delayUntil) {
-                return;
-            }
-            authority.delayUntil = delayUntil;
-        }
-
-        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
-    }
-
-    public long getDelayUntilTime(Account account, int userId, String providerName) {
-        synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getDelayUntil");
+            AuthorityInfo authority = getAuthorityLocked(info, "getDelayUntil");
             if (authority == null) {
                 return 0;
             }
@@ -771,113 +895,148 @@
         }
     }
 
-    private void updateOrRemovePeriodicSync(PeriodicSync toUpdate, int userId, boolean add) {
-        if (DEBUG) {
-            Log.v(TAG, "addOrRemovePeriodicSync: " + toUpdate.account + ", user " + userId
-                    + ", provider " + toUpdate.authority
-                    + " -> period " + toUpdate.period + ", extras " + toUpdate.extras);
+    public void setDelayUntilTime(EndPoint info, long delayUntil) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "setDelayUntil: " + info
+                    + " -> delayUntil " + delayUntil);
         }
         synchronized (mAuthorities) {
-            if (toUpdate.period <= 0 && add) {
-                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-"
-                        + add);
+            AuthorityInfo authority = getOrCreateAuthorityLocked(info, -1, true);
+            if (authority.delayUntil == delayUntil) {
+                return;
             }
-            if (toUpdate.extras == null) {
-                Log.e(TAG, "null extras, should never happen in updateOrRemovePeriodicSync: add-"
-                        + add);
+            authority.delayUntil = delayUntil;
+        }
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+    }
+
+    public void updateOrAddPeriodicSync(EndPoint info, long period, long flextime, Bundle extras) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "addPeriodicSync: " + info
+                    + " -> period " + period + ", flex " + flextime + ", extras "
+                    + extras.toString());
+        }
+        synchronized (mAuthorities) {
+            if (period <= 0) {
+                Log.e(TAG, "period < 0, should never happen in updateOrAddPeriodicSync");
+            }
+            if (extras == null) {
+                Log.e(TAG, "null extras, should never happen in updateOrAddPeriodicSync:");
             }
             try {
-                AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(toUpdate.account, userId, toUpdate.authority,
-                                -1, false);
-                if (add) {
-                    // add this periodic sync if an equivalent periodic doesn't already exist.
-                    boolean alreadyPresent = false;
-                    for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) {
-                        PeriodicSync syncInfo = authority.periodicSyncs.get(i);
-                        if (PeriodicSync.syncExtrasEquals(
-                                toUpdate.extras,
-                                syncInfo.extras)) {
-                            if (toUpdate.period == syncInfo.period &&
-                                    toUpdate.flexTime == syncInfo.flexTime) {
-                                // Absolutely the same.
-                                return;
-                            }
-                            authority.periodicSyncs.set(i, new PeriodicSync(toUpdate));
-                            alreadyPresent = true;
-                            break;
-                        }
-                    }
-                    // If we added an entry to the periodicSyncs array also add an entry to
-                    // the periodic syncs status to correspond to it.
-                    if (!alreadyPresent) {
-                        authority.periodicSyncs.add(new PeriodicSync(toUpdate));
-                        SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
-                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0L);
-                    }
+                PeriodicSync toUpdate;
+                if (info.target_provider) {
+                    toUpdate = new PeriodicSync(info.account,
+                            info.provider,
+                            extras,
+                            period,
+                            flextime);
                 } else {
-                    // Remove any periodic syncs that match the authority and extras.
-                    SyncStatusInfo status = mSyncStatus.get(authority.ident);
-                    boolean changed = false;
-                    Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
-                    int i = 0;
-                    while (iterator.hasNext()) {
-                        PeriodicSync syncInfo = iterator.next();
-                        if (PeriodicSync.syncExtrasEquals(syncInfo.extras, toUpdate.extras)) {
-                            iterator.remove();
-                            changed = true;
-                            // If we removed an entry from the periodicSyncs array also
-                            // remove the corresponding entry from the status
-                            if (status != null) {
-                                status.removePeriodicSyncTime(i);
-                            } else {
-                                Log.e(TAG, "Tried removing sync status on remove periodic sync but"
-                                        + "did not find it.");
-                            }
-                        } else {
-                            i++;
+                    toUpdate = new PeriodicSync(info.service,
+                            extras,
+                            period,
+                            flextime);
+                }
+                AuthorityInfo authority =
+                        getOrCreateAuthorityLocked(info, -1, false);
+                // add this periodic sync if an equivalent periodic doesn't already exist.
+                boolean alreadyPresent = false;
+                for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) {
+                    PeriodicSync syncInfo = authority.periodicSyncs.get(i);
+                    if (SyncManager.syncExtrasEquals(syncInfo.extras,
+                            extras,
+                            true /* includeSyncSettings*/)) {
+                        if (period == syncInfo.period &&
+                                flextime == syncInfo.flexTime) {
+                            // Absolutely the same.
+                            Log.e(TAG, "update psync: exactly the same.");
+                            return;
                         }
+                        authority.periodicSyncs.set(i, toUpdate);
+                        alreadyPresent = true;
+                        break;
                     }
-                    if (!changed) {
-                        return;
-                    }
+                }
+                // If we added an entry to the periodicSyncs array also add an entry to
+                // the periodic syncs status to correspond to it.
+                if (!alreadyPresent) {
+                    authority.periodicSyncs.add(toUpdate);
+                    SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
+                    // A new periodic sync is initialised as already having been run.
+                    status.setPeriodicSyncTime(
+                            authority.periodicSyncs.size() - 1,
+                            System.currentTimeMillis());
                 }
             } finally {
                 writeAccountInfoLocked();
                 writeStatusLocked();
             }
         }
-
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void addPeriodicSync(PeriodicSync toAdd, int userId) {
-        updateOrRemovePeriodicSync(toAdd, userId, true /* add */);
+    public void removePeriodicSync(EndPoint info, Bundle extras) {
+        synchronized(mAuthorities) {
+            try {
+                AuthorityInfo authority =
+                        getOrCreateAuthorityLocked(info, -1, false);
+                // Remove any periodic syncs that match the authority and extras.
+                SyncStatusInfo status = mSyncStatus.get(authority.ident);
+                boolean changed = false;
+                Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
+                int i = 0;
+                while (iterator.hasNext()) {
+                    PeriodicSync syncInfo = iterator.next();
+                    if (SyncManager.syncExtrasEquals(syncInfo.extras,
+                            extras,
+                            true /* includeSyncSettings */)) {
+                        iterator.remove();
+                        changed = true;
+                        // If we removed an entry from the periodicSyncs array also
+                        // remove the corresponding entry from the status
+                        if (status != null) {
+                            status.removePeriodicSyncTime(i);
+                        } else {
+                            Log.e(TAG, "Tried removing sync status on remove periodic sync but"
+                                    + " did not find it.");
+                        }
+                    } else {
+                        i++;
+                    }
+                }
+                if (!changed) {
+                    return;
+                }
+            } finally {
+                writeAccountInfoLocked();
+                writeStatusLocked();
+            }
+        }
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void removePeriodicSync(PeriodicSync toRemove, int userId) {
-        updateOrRemovePeriodicSync(toRemove, userId, false /* remove */);
-    }
-
-    public List<PeriodicSync> getPeriodicSyncs(Account account, int userId, String providerName) {
-        ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>();
+    /**
+     * @return list of periodic syncs for an authority. Never returns null - if no such syncs
+     * exist, returns an empty list.
+     */
+    public List<PeriodicSync> getPeriodicSyncs(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getPeriodicSyncs");
-            if (authority != null) {
-                for (PeriodicSync item : authority.periodicSyncs) {
+            AuthorityInfo authorityInfo = getAuthorityLocked(info, "getPeriodicSyncs");
+            ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>();
+            if (authorityInfo != null) {
+                for (PeriodicSync item : authorityInfo.periodicSyncs) {
                     // Copy and send out. Necessary for thread-safety although it's parceled.
                     syncs.add(new PeriodicSync(item));
                 }
             }
+            return syncs;
         }
-        return syncs;
     }
 
     public void setMasterSyncAutomatically(boolean flag, int userId) {
         synchronized (mAuthorities) {
             Boolean auto = mMasterSyncAutomatically.get(userId);
-            if (auto != null && (boolean) auto == flag) {
+            if (auto != null && auto == flag) {
                 return;
             }
             mMasterSyncAutomatically.put(userId, flag);
@@ -898,12 +1057,6 @@
         }
     }
 
-    public void removeAuthority(Account account, int userId, String authority) {
-        synchronized (mAuthorities) {
-            removeAuthorityLocked(account, userId, authority, true /* doWrite */);
-        }
-    }
-
     public AuthorityInfo getAuthority(int authorityId) {
         synchronized (mAuthorities) {
             return mAuthorities.get(authorityId);
@@ -911,53 +1064,47 @@
     }
 
     /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority actively being processed.
+     * Returns true if there is currently a sync operation being actively processed for the given
+     * authority.
      */
-    public boolean isSyncActive(Account account, int userId, String authority) {
+    public boolean isSyncActive(EndPoint info) {
         synchronized (mAuthorities) {
-            for (SyncInfo syncInfo : getCurrentSyncs(userId)) {
+            for (SyncInfo syncInfo : getCurrentSyncs(info.userId)) {
                 AuthorityInfo ainfo = getAuthority(syncInfo.authorityId);
-                if (ainfo != null && ainfo.account.equals(account)
-                        && ainfo.authority.equals(authority)
-                        && ainfo.userId == userId) {
+                if (ainfo != null && ainfo.base.matches(info)) {
                     return true;
                 }
             }
         }
-
         return false;
     }
 
-    public PendingOperation insertIntoPending(PendingOperation op) {
+    public PendingOperation insertIntoPending(SyncOperation op) {
+        PendingOperation pop;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "insertIntoPending: account=" + op.account
-                        + " user=" + op.userId
-                        + " auth=" + op.authority
-                        + " src=" + op.syncSource
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "insertIntoPending: authority=" + op.target
                         + " extras=" + op.extras);
             }
-
-            AuthorityInfo authority = getOrCreateAuthorityLocked(op.account, op.userId,
-                    op.authority,
-                    -1 /* desired identifier */,
-                    true /* write accounts to storage */);
+            final EndPoint info = op.target;
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(info,
+                            -1 /* desired identifier */,
+                            true /* write accounts to storage */);
             if (authority == null) {
                 return null;
             }
 
-            op = new PendingOperation(op);
-            op.authorityId = authority.ident;
-            mPendingOperations.add(op);
-            appendPendingOperationLocked(op);
+            pop = new PendingOperation(authority, op.reason, op.syncSource, op.extras,
+                    op.expedited);
+            mPendingOperations.add(pop);
+            writePendingOperationsLocked();
 
             SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
             status.pending = true;
         }
-
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
-        return op;
+        return pop;
     }
 
     /**
@@ -965,18 +1112,13 @@
      * authorities. If there are no more pending syncs for the same authority/account/userid,
      * update the SyncStatusInfo for that authority(authority here is the internal representation
      * of a 'sync operation'.
-     * @param op
-     * @return
+     * @param op Pending op to delete.
      */
     public boolean deleteFromPending(PendingOperation op) {
         boolean res = false;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "deleteFromPending: account=" + op.account
-                    + " user=" + op.userId
-                    + " auth=" + op.authority
-                    + " src=" + op.syncSource
-                    + " extras=" + op.extras);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "deleteFromPending: account=" + op.toString());
             }
             if (mPendingOperations.remove(op)) {
                 if (mPendingOperations.size() == 0
@@ -986,30 +1128,27 @@
                 } else {
                     mNumPendingFinished++;
                 }
-
-                AuthorityInfo authority = getAuthorityLocked(op.account, op.userId, op.authority,
-                        "deleteFromPending");
+                AuthorityInfo authority = getAuthorityLocked(op.authority, "deleteFromPending");
                 if (authority != null) {
-                    if (DEBUG) Log.v(TAG, "removing - " + authority.toString());
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "removing - " + authority.toString());
+                    }
                     final int N = mPendingOperations.size();
                     boolean morePending = false;
-                    for (int i=0; i<N; i++) {
+                    for (int i = 0; i < N; i++) {
                         PendingOperation cur = mPendingOperations.get(i);
-                        if (cur.account.equals(op.account)
-                                && cur.authority.equals(op.authority)
-                                && cur.userId == op.userId) {
+                        if (cur.equals(op)) {
                             morePending = true;
                             break;
                         }
                     }
 
                     if (!morePending) {
-                        if (DEBUG) Log.v(TAG, "no more pending!");
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "no more pending!");
                         SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
                         status.pending = false;
                     }
                 }
-
                 res = true;
             }
         }
@@ -1044,7 +1183,7 @@
      */
     public void doDatabaseCleanup(Account[] accounts, int userId) {
         synchronized (mAuthorities) {
-            if (DEBUG) Log.v(TAG, "Updating for new accounts...");
+            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Updating for new accounts...");
             SparseArray<AuthorityInfo> removing = new SparseArray<AuthorityInfo>();
             Iterator<AccountInfo> accIt = mAccounts.values().iterator();
             while (accIt.hasNext()) {
@@ -1052,7 +1191,7 @@
                 if (!ArrayUtils.contains(accounts, acc.accountAndUser.account)
                         && acc.accountAndUser.userId == userId) {
                     // This account no longer exists...
-                    if (DEBUG) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Account removed: " + acc.accountAndUser);
                     }
                     for (AuthorityInfo auth : acc.authorities.values()) {
@@ -1099,25 +1238,25 @@
     public SyncInfo addActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
         final SyncInfo syncInfo;
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "setActiveSync: account="
-                    + activeSyncContext.mSyncOperation.account
-                    + " auth=" + activeSyncContext.mSyncOperation.authority
+                    + " auth=" + activeSyncContext.mSyncOperation.target
                     + " src=" + activeSyncContext.mSyncOperation.syncSource
                     + " extras=" + activeSyncContext.mSyncOperation.extras);
             }
-            AuthorityInfo authority = getOrCreateAuthorityLocked(
-                    activeSyncContext.mSyncOperation.account,
-                    activeSyncContext.mSyncOperation.userId,
-                    activeSyncContext.mSyncOperation.authority,
+            final EndPoint info = activeSyncContext.mSyncOperation.target;
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(
+                    info,
                     -1 /* assign a new identifier if creating a new authority */,
                     true /* write to storage if this results in a change */);
-            syncInfo = new SyncInfo(authority.ident,
-                    authority.account, authority.authority,
+            syncInfo = new SyncInfo(
+                    authorityInfo.ident,
+                    authorityInfo.base.account,
+                    authorityInfo.base.provider,
+                    authorityInfo.base.service,
                     activeSyncContext.mStartTime);
-            getCurrentSyncs(authority.userId).add(syncInfo);
+            getCurrentSyncs(authorityInfo.base.userId).add(syncInfo);
         }
-
         reportActiveChange();
         return syncInfo;
     }
@@ -1127,10 +1266,11 @@
      */
     public void removeActiveSync(SyncInfo syncInfo, int userId) {
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "removeActiveSync: account=" + syncInfo.account
                         + " user=" + userId
-                        + " auth=" + syncInfo.authority);
+                        + " auth=" + syncInfo.authority
+                        + " service=" + syncInfo.service);
             }
             getCurrentSyncs(userId).remove(syncInfo);
         }
@@ -1147,36 +1287,37 @@
 
     /**
      * Note that sync has started for the given account and authority.
+     *
+       syncOperation.account, syncOperation.userId, syncOperation.reason,
+                    syncOperation.authority,
+                    now, source, syncOperation.isInitialization(), syncOperation.extras
      */
-    public long insertStartSyncEvent(Account accountName, int userId, int reason,
-            String authorityName, long now, int source, boolean initialization, Bundle extras) {
+    public long insertStartSyncEvent(SyncOperation op, long now) {
         long id;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "insertStartSyncEvent: account=" + accountName + "user=" + userId
-                    + " auth=" + authorityName + " source=" + source);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "insertStartSyncEvent: " + op);
             }
-            AuthorityInfo authority = getAuthorityLocked(accountName, userId, authorityName,
-                    "insertStartSyncEvent");
+            AuthorityInfo authority = getAuthorityLocked(op.target, "insertStartSyncEvent");
             if (authority == null) {
                 return -1;
             }
             SyncHistoryItem item = new SyncHistoryItem();
-            item.initialization = initialization;
+            item.initialization = op.isInitialization();
             item.authorityId = authority.ident;
             item.historyId = mNextHistoryId++;
             if (mNextHistoryId < 0) mNextHistoryId = 0;
             item.eventTime = now;
-            item.source = source;
-            item.reason = reason;
-            item.extras = extras;
+            item.source = op.syncSource;
+            item.reason = op.reason;
+            item.extras = op.extras;
             item.event = EVENT_START;
             mSyncHistory.add(0, item);
             while (mSyncHistory.size() > MAX_HISTORY) {
                 mSyncHistory.remove(mSyncHistory.size()-1);
             }
             id = item.historyId;
-            if (DEBUG) Log.v(TAG, "returning historyId " + id);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "returning historyId " + id);
         }
 
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
@@ -1186,7 +1327,7 @@
     public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
             long downstreamActivity, long upstreamActivity) {
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "stopSyncEvent: historyId=" + historyId);
             }
             SyncHistoryItem item = null;
@@ -1325,10 +1466,9 @@
     /**
      * Return a copy of the specified authority with the corresponding sync status
      */
-    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(
-            Account account, int userId, String authority) {
+    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(account, userId, authority,
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(info,
                     -1 /* assign a new identifier if creating a new authority */,
                     true /* write to storage if this results in a change */);
             return createCopyPairOfAuthorityWithSyncStatusLocked(authorityInfo);
@@ -1352,24 +1492,22 @@
     /**
      * Returns the status that matches the authority and account.
      *
-     * @param account the account we want to check
-     * @param authority the authority whose row should be selected
-     * @return the SyncStatusInfo for the authority
+     * @param info the target we want to check
+     * @return the SyncStatusInfo for the target
      */
-    public SyncStatusInfo getStatusByAccountAndAuthority(Account account, int userId,
-            String authority) {
-        if (account == null || authority == null) {
+    public SyncStatusInfo getStatusByAuthority(EndPoint info) {
+        if (info.target_provider && (info.account == null || info.provider == null)) {
           throw new IllegalArgumentException();
+        } else if (info.target_service && info.service == null) {
+            throw new IllegalArgumentException();
         }
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 SyncStatusInfo cur = mSyncStatus.valueAt(i);
                 AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
-
-                if (ainfo != null && ainfo.authority.equals(authority)
-                        && ainfo.userId == userId
-                        && account.equals(ainfo.account)) {
+                if (ainfo != null
+                        && ainfo.base.matches(info)) {
                   return cur;
                 }
             }
@@ -1377,25 +1515,20 @@
         }
     }
 
-    /**
-     * Return true if the pending status is true of any matching authorities.
-     */
-    public boolean isSyncPending(Account account, int userId, String authority) {
+    /** Return true if the pending status is true of any matching authorities. */
+    public boolean isSyncPending(EndPoint info) {
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 SyncStatusInfo cur = mSyncStatus.valueAt(i);
                 AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
                 if (ainfo == null) {
                     continue;
                 }
-                if (userId != ainfo.userId) {
+                if (!ainfo.base.matches(info)) {
                     continue;
                 }
-                if (account != null && !ainfo.account.equals(account)) {
-                    continue;
-                }
-                if (ainfo.authority.equals(authority) && cur.pending) {
+                if (cur.pending) {
                     return true;
                 }
             }
@@ -1453,126 +1586,131 @@
     /**
      * Retrieve an authority, returning null if one does not exist.
      *
-     * @param accountName The name of the account for the authority.
-     * @param authorityName The name of the authority itself.
+     * @param info container for the info of the authority to look up.
      * @param tag If non-null, this will be used in a log message if the
      * requested authority does not exist.
      */
-    private AuthorityInfo getAuthorityLocked(Account accountName, int userId, String authorityName,
-            String tag) {
-        AccountAndUser au = new AccountAndUser(accountName, userId);
-        AccountInfo accountInfo = mAccounts.get(au);
-        if (accountInfo == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + ": unknown account " + au);
-                }
+    private AuthorityInfo getAuthorityLocked(EndPoint info, String tag) {
+        if (info.target_service) {
+            SparseArray<AuthorityInfo> aInfo = mServices.get(info.service);
+            AuthorityInfo authority = null;
+            if (aInfo != null) {
+                authority = aInfo.get(info.userId);
             }
+            if (authority == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + " No authority info found for " + info.service + " for user "
+                                + info.userId);
+                    }
+                }
+                return null;
+            }
+            return authority;
+        } else if (info.target_provider){
+            AccountAndUser au = new AccountAndUser(info.account, info.userId);
+            AccountInfo accountInfo = mAccounts.get(au);
+            if (accountInfo == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + ": unknown account " + au);
+                    }
+                }
+                return null;
+            }
+            AuthorityInfo authority = accountInfo.authorities.get(info.provider);
+            if (authority == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + ": unknown provider " + info.provider);
+                    }
+                }
+                return null;
+            }
+            return authority;
+        } else {
+            Log.e(TAG, tag + " Authority : " + info + ", invalid target");
             return null;
         }
-        AuthorityInfo authority = accountInfo.authorities.get(authorityName);
-        if (authority == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + ": unknown authority " + authorityName);
-                }
-            }
-            return null;
-        }
-
-        return authority;
     }
 
     /**
-     * Retrieve an authority, returning null if one does not exist.
-     *
-     * @param service The service name used for this sync.
-     * @param userId The user for whom this sync is scheduled.
-     * @param tag If non-null, this will be used in a log message if the
-     * requested authority does not exist.
-     */
-    private AuthorityInfo getAuthorityLocked(ComponentName service, int userId, String tag) {
-        AuthorityInfo authority = mServices.get(service).get(userId);
-        if (authority == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + " No authority info found for " + service + " for user "
-                            + userId);
-                }
-            }
-            return null;
-        }
-        return authority;
-    }
-
-    /**
-     * @param cname identifier for the service.
-     * @param userId for the syncs corresponding to this authority.
+     * @param info info identifying authority.
      * @param ident unique identifier for authority. -1 for none.
      * @param doWrite if true, update the accounts.xml file on the disk.
-     * @return the authority that corresponds to the provided sync service, creating it if none
+     * @return the authority that corresponds to the provided sync authority, creating it if none
      * exists.
      */
-    private AuthorityInfo getOrCreateAuthorityLocked(ComponentName cname, int userId, int ident,
-            boolean doWrite) {
-        SparseArray<AuthorityInfo> aInfo = mServices.get(cname);
-        if (aInfo == null) {
-            aInfo = new SparseArray<AuthorityInfo>();
-            mServices.put(cname, aInfo);
-        }
-        AuthorityInfo authority = aInfo.get(userId);
-        if (authority == null) {
-            if (ident < 0) {
-                ident = mNextAuthorityId;
-                mNextAuthorityId++;
-                doWrite = true;
+    private AuthorityInfo getOrCreateAuthorityLocked(EndPoint info, int ident, boolean doWrite) {
+        AuthorityInfo authority = null;
+        if (info.target_service) {
+            SparseArray<AuthorityInfo> aInfo = mServices.get(info.service);
+            if (aInfo == null) {
+                aInfo = new SparseArray<AuthorityInfo>();
+                mServices.put(info.service, aInfo);
             }
-            if (DEBUG) {
-                Log.v(TAG, "created a new AuthorityInfo for " + cname.getPackageName()
-                        + ", " + cname.getClassName()
-                        + ", user: " + userId);
+            authority = aInfo.get(info.userId);
+            if (authority == null) {
+                authority = createAuthorityLocked(info, ident, doWrite);
+                aInfo.put(info.userId, authority);
             }
-            authority = new AuthorityInfo(cname, userId, ident);
-            aInfo.put(userId, authority);
-            mAuthorities.put(ident, authority);
-            if (doWrite) {
-                writeAccountInfoLocked();
+        } else if (info.target_provider) {
+            AccountAndUser au = new AccountAndUser(info.account, info.userId);
+            AccountInfo account = mAccounts.get(au);
+            if (account == null) {
+                account = new AccountInfo(au);
+                mAccounts.put(au, account);
+            }
+            authority = account.authorities.get(info.provider);
+            if (authority == null) {
+                authority = createAuthorityLocked(info, ident, doWrite);
+                account.authorities.put(info.provider, authority);
             }
         }
         return authority;
     }
 
-    private AuthorityInfo getOrCreateAuthorityLocked(Account accountName, int userId,
-            String authorityName, int ident, boolean doWrite) {
-        AccountAndUser au = new AccountAndUser(accountName, userId);
-        AccountInfo account = mAccounts.get(au);
-        if (account == null) {
-            account = new AccountInfo(au);
-            mAccounts.put(au, account);
+    private AuthorityInfo createAuthorityLocked(EndPoint info, int ident, boolean doWrite) {
+        AuthorityInfo authority;
+        if (ident < 0) {
+            ident = mNextAuthorityId;
+            mNextAuthorityId++;
+            doWrite = true;
         }
-        AuthorityInfo authority = account.authorities.get(authorityName);
-        if (authority == null) {
-            if (ident < 0) {
-                ident = mNextAuthorityId;
-                mNextAuthorityId++;
-                doWrite = true;
-            }
-            if (DEBUG) {
-                Log.v(TAG, "created a new AuthorityInfo for " + accountName
-                        + ", user " + userId
-                        + ", provider " + authorityName);
-            }
-            authority = new AuthorityInfo(accountName, userId, authorityName, ident);
-            account.authorities.put(authorityName, authority);
-            mAuthorities.put(ident, authority);
-            if (doWrite) {
-                writeAccountInfoLocked();
-            }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "created a new AuthorityInfo for " + info);
         }
-
+        authority = new AuthorityInfo(info, ident);
+        mAuthorities.put(ident, authority);
+        if (doWrite) {
+            writeAccountInfoLocked();
+        }
         return authority;
     }
 
+    public void removeAuthority(EndPoint info) {
+        synchronized (mAuthorities) {
+            if (info.target_provider) {
+                removeAuthorityLocked(info.account, info.userId, info.provider, true /* doWrite */);
+            } else {
+                SparseArray<AuthorityInfo> aInfos = mServices.get(info.service);
+                if (aInfos != null) {
+                    AuthorityInfo authorityInfo = aInfos.get(info.userId);
+                    if (authorityInfo != null) {
+                        mAuthorities.remove(authorityInfo.ident);
+                        aInfos.delete(info.userId);
+                        writeAccountInfoLocked();
+                    }
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Remove an authority associated with a provider. Needs to be a standalone function for
+     * backward compatibility.
+     */
     private void removeAuthorityLocked(Account account, int userId, String authorityName,
             boolean doWrite) {
         AccountInfo accountInfo = mAccounts.get(new AccountAndUser(account, userId));
@@ -1591,8 +1729,7 @@
      * Updates (in a synchronized way) the periodic sync time of the specified
      * authority id and target periodic sync
      */
-    public void setPeriodicSyncTime(
-            int authorityId, PeriodicSync targetPeriodicSync, long when) {
+    public void setPeriodicSyncTime(int authorityId, PeriodicSync targetPeriodicSync, long when) {
         boolean found = false;
         final AuthorityInfo authorityInfo;
         synchronized (mAuthorities) {
@@ -1608,7 +1745,7 @@
         }
         if (!found) {
             Log.w(TAG, "Ignoring setPeriodicSyncTime request for a sync that does not exist. " +
-                    "Authority: " + authorityInfo.authority);
+                    "Authority: " + authorityInfo.base);
         }
     }
 
@@ -1777,10 +1914,10 @@
 
         ArrayList<AuthorityInfo> authoritiesToRemove = new ArrayList<AuthorityInfo>();
         final int N = mAuthorities.size();
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             AuthorityInfo authority = mAuthorities.valueAt(i);
             // skip this authority if it isn't one of the renamed ones
-            final String newAuthorityName = sAuthorityRenames.get(authority.authority);
+            final String newAuthorityName = sAuthorityRenames.get(authority.base);
             if (newAuthorityName == null) {
                 continue;
             }
@@ -1796,20 +1933,26 @@
             }
 
             // if we already have a record of this new authority then don't copy over the settings
-            if (getAuthorityLocked(authority.account, authority.userId, newAuthorityName, "cleanup")
-                    != null) {
+            EndPoint newInfo =
+                    new EndPoint(authority.base.account,
+                            newAuthorityName,
+                            authority.base.userId);
+            if (getAuthorityLocked(newInfo, "cleanup") != null) {
                 continue;
             }
 
-            AuthorityInfo newAuthority = getOrCreateAuthorityLocked(authority.account,
-                    authority.userId, newAuthorityName, -1 /* ident */, false /* doWrite */);
+            AuthorityInfo newAuthority =
+                    getOrCreateAuthorityLocked(newInfo, -1 /* ident */, false /* doWrite */);
             newAuthority.enabled = true;
             writeNeeded = true;
         }
 
         for (AuthorityInfo authorityInfo : authoritiesToRemove) {
-            removeAuthorityLocked(authorityInfo.account, authorityInfo.userId,
-                    authorityInfo.authority, false /* doWrite */);
+            removeAuthorityLocked(
+                    authorityInfo.base.account,
+                    authorityInfo.base.userId,
+                    authorityInfo.base.provider,
+                    false /* doWrite */);
             writeNeeded = true;
         }
 
@@ -1865,15 +2008,18 @@
             }
             if (authority == null) {
                 if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                    Log.v(TAG, "Creating entry");
+                    Log.v(TAG_FILE, "Creating authority entry");
                 }
                 if (accountName != null && accountType != null) {
-                    authority = getOrCreateAuthorityLocked(
-                            new Account(accountName, accountType), userId, authorityName, id,
-                                false);
+                    EndPoint info =
+                            new EndPoint(
+                                    new Account(accountName, accountType),
+                                    authorityName, userId);
+                    authority = getOrCreateAuthorityLocked(info, id, false);
                 } else {
-                    authority = getOrCreateAuthorityLocked(
-                            new ComponentName(packageName, className), userId, id, false);
+                    EndPoint info =
+                            new EndPoint(new ComponentName(packageName, className), userId);
+                    authority = getOrCreateAuthorityLocked(info, id, false);
                 }
                 // If the version is 0 then we are upgrading from a file format that did not
                 // know about periodic syncs. In that case don't clear the list since we
@@ -1905,7 +2051,7 @@
     /**
      * Parse a periodic sync from accounts.xml. Sets the bundle to be empty.
      */
-    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authority) {
+    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authorityInfo) {
         Bundle extras = new Bundle(); // Gets filled in later.
         String periodValue = parser.getAttributeValue(null, "period");
         String flexValue = parser.getAttributeValue(null, "flex");
@@ -1930,10 +2076,22 @@
             Log.d(TAG, "No flex time specified for this sync, using a default. period: "
             + period + " flex: " + flextime);
         }
-        final PeriodicSync periodicSync =
-                new PeriodicSync(authority.account, authority.authority, extras,
+        PeriodicSync periodicSync;
+        if (authorityInfo.base.target_provider) {
+            periodicSync =
+                new PeriodicSync(authorityInfo.base.account,
+                        authorityInfo.base.provider,
+                        extras,
                         period, flextime);
-        authority.periodicSyncs.add(periodicSync);
+        } else {
+            periodicSync =
+                    new PeriodicSync(
+                            authorityInfo.base.service,
+                            extras,
+                            period,
+                            flextime);
+        }
+        authorityInfo.periodicSyncs.add(periodicSync);
         return periodicSync;
     }
 
@@ -2001,17 +2159,18 @@
             final int N = mAuthorities.size();
             for (int i = 0; i < N; i++) {
                 AuthorityInfo authority = mAuthorities.valueAt(i);
+                EndPoint info = authority.base;
                 out.startTag(null, "authority");
                 out.attribute(null, "id", Integer.toString(authority.ident));
-                out.attribute(null, XML_ATTR_USER, Integer.toString(authority.userId));
+                out.attribute(null, XML_ATTR_USER, Integer.toString(info.userId));
                 out.attribute(null, XML_ATTR_ENABLED, Boolean.toString(authority.enabled));
-                if (authority.service == null) {
-                    out.attribute(null, "account", authority.account.name);
-                    out.attribute(null, "type", authority.account.type);
-                    out.attribute(null, "authority", authority.authority);
+                if (info.service == null) {
+                    out.attribute(null, "account", info.account.name);
+                    out.attribute(null, "type", info.account.type);
+                    out.attribute(null, "authority", info.provider);
                 } else {
-                    out.attribute(null, "package", authority.service.getPackageName());
-                    out.attribute(null, "class", authority.service.getClassName());
+                    out.attribute(null, "package", info.service.getPackageName());
+                    out.attribute(null, "class", info.service.getClassName());
                 }
                 if (authority.syncable < 0) {
                     out.attribute(null, "syncable", "unknown");
@@ -2105,9 +2264,13 @@
                     accountType = "com.google";
                 }
                 String authorityName = c.getString(c.getColumnIndex("authority"));
-                AuthorityInfo authority = this.getOrCreateAuthorityLocked(
-                        new Account(accountName, accountType), 0 /* legacy is single-user */,
-                        authorityName, -1, false);
+                AuthorityInfo authority =
+                        this.getOrCreateAuthorityLocked(
+                                new EndPoint(new Account(accountName, accountType),
+                                        authorityName,
+                                        0 /* legacy is single-user */)
+                                , -1,
+                                false);
                 if (authority != null) {
                     int i = mSyncStatus.size();
                     boolean found = false;
@@ -2159,7 +2322,7 @@
                     while (i > 0) {
                         i--;
                         AuthorityInfo authority = mAuthorities.valueAt(i);
-                        if (authority.authority.equals(provider)) {
+                        if (authority.base.equals(provider)) {
                             authority.enabled = value == null || Boolean.parseBoolean(value);
                             authority.syncable = 1;
                         }
@@ -2275,62 +2438,52 @@
             String tagName = parser.getName();
             do {
                 PendingOperation pop = null;
-                if (eventType == XmlPullParser.START_TAG) {
-                    try {
-                        tagName = parser.getName();
-                        if (parser.getDepth() == 1 && "op".equals(tagName)) {
-                            // Verify version.
-                            String versionString =
-                                    parser.getAttributeValue(null, XML_ATTR_VERSION);
-                            if (versionString == null ||
-                                    Integer.parseInt(versionString) != PENDING_OPERATION_VERSION) {
-                                Log.w(TAG, "Unknown pending operation version " + versionString);
-                                throw new java.io.IOException("Unknown version.");
-                            }
-                            int authorityId = Integer.valueOf(parser.getAttributeValue(
-                                    null, XML_ATTR_AUTHORITYID));
-                            boolean expedited = Boolean.valueOf(parser.getAttributeValue(
-                                    null, XML_ATTR_EXPEDITED));
-                            int syncSource = Integer.valueOf(parser.getAttributeValue(
-                                    null, XML_ATTR_SOURCE));
-                            int reason = Integer.valueOf(parser.getAttributeValue(
-                                    null, XML_ATTR_REASON));
-                            AuthorityInfo authority = mAuthorities.get(authorityId);
-                            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                                Log.v(TAG_FILE, authorityId + " " + expedited + " " + syncSource + " "
-                                        + reason);
-                            }
-                            if (authority != null) {
-                                pop = new PendingOperation(
-                                        authority.account, authority.userId, reason,
-                                        syncSource, authority.authority, new Bundle(),
-                                        expedited);
-                                pop.flatExtras = null; // No longer used.
-                                mPendingOperations.add(pop);
+                    if (eventType == XmlPullParser.START_TAG) {
+                        try {
+                            tagName = parser.getName();
+                            if (parser.getDepth() == 2 && "op".equals(tagName)) {
+                                int authorityId = Integer.valueOf(parser.getAttributeValue(
+                                        null, XML_ATTR_AUTHORITYID));
+                                boolean expedited = Boolean.valueOf(parser.getAttributeValue(
+                                        null, XML_ATTR_EXPEDITED));
+                                int syncSource = Integer.valueOf(parser.getAttributeValue(
+                                        null, XML_ATTR_SOURCE));
+                                int reason = Integer.valueOf(parser.getAttributeValue(
+                                        null, XML_ATTR_REASON));
+                                AuthorityInfo authority = mAuthorities.get(authorityId);
                                 if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                                    Log.v(TAG_FILE, "Adding pending op: "
+                                    Log.v(TAG_FILE, authorityId + " " + expedited + " " +
+                                            syncSource + " " + reason);
+                                }
+                                if (authority != null) {
+                                    pop = new PendingOperation(
+                                            authority, reason, syncSource, new Bundle(), expedited);
+                                    pop.flatExtras = null; // No longer used.
+                                    mPendingOperations.add(pop);
+                                    if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                        Log.v(TAG_FILE, "Adding pending op: "
                                             + pop.authority
                                             + " src=" + pop.syncSource
                                             + " reason=" + pop.reason
                                             + " expedited=" + pop.expedited);
+                                    }
+                                } else {
+                                    // Skip non-existent authority.
+                                    pop = null;
+                                    if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                        Log.v(TAG_FILE, "No authority found for " + authorityId
+                                                + ", skipping");
+                                    }
                                 }
-                            } else {
-                                // Skip non-existent authority.
-                                pop = null;
-                                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                                    Log.v(TAG_FILE, "No authority found for " + authorityId
-                                            + ", skipping");
-                                }
+                            } else if (parser.getDepth() == 2 &&
+                                    pop != null &&
+                                    "extra".equals(tagName)) {
+                                parseExtra(parser, pop.extras);
                             }
-                        } else if (parser.getDepth() == 2 &&
-                                pop != null &&
-                                "extra".equals(tagName)) {
-                            parseExtra(parser, pop.extras);
+                        } catch (NumberFormatException e) {
+                            Log.d(TAG, "Invalid data in xml file.", e);
                         }
-                    } catch (NumberFormatException e) {
-                        Log.d(TAG, "Invalid data in xml file.", e);
                     }
-                }
                 eventType = parser.next();
             } while(eventType != XmlPullParser.END_DOCUMENT);
         } catch (java.io.IOException e) {
@@ -2348,98 +2501,6 @@
         }
     }
 
-    private static final String XML_ATTR_AUTHORITYID = "authority_id";
-    private static final String XML_ATTR_SOURCE = "source";
-    private static final String XML_ATTR_EXPEDITED = "expedited";
-    private static final String XML_ATTR_REASON = "reason";
-    private static final String XML_ATTR_VERSION = "version";
-
-    /**
-     * Write all currently pending ops to the pending ops file.
-     */
-    private void writePendingOperationsLocked() {
-        final int N = mPendingOperations.size();
-        FileOutputStream fos = null;
-        try {
-            if (N == 0) {
-                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                    Log.v(TAG_FILE, "Truncating " + mPendingFile.getBaseFile());
-                }
-                mPendingFile.truncate();
-                return;
-            }
-            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG_FILE, "Writing new " + mPendingFile.getBaseFile());
-            }
-            fos = mPendingFile.startWrite();
-            XmlSerializer out = new FastXmlSerializer();
-            out.setOutput(fos, "utf-8");
-
-            for (int i = 0; i < N; i++) {
-                PendingOperation pop = mPendingOperations.get(i);
-                writePendingOperationLocked(pop, out);
-            }
-            out.endDocument();
-            mPendingFile.finishWrite(fos);
-        } catch (java.io.IOException e1) {
-            Log.w(TAG, "Error writing pending operations", e1);
-            if (fos != null) {
-                mPendingFile.failWrite(fos);
-            }
-        }
-    }
-
-    /** Write all currently pending ops to the pending ops file. */
-     private void writePendingOperationLocked(PendingOperation pop, XmlSerializer out)
-             throws IOException {
-         // Pending operation.
-         out.startTag(null, "op");
-
-         out.attribute(null, XML_ATTR_VERSION, Integer.toString(PENDING_OPERATION_VERSION));
-         out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
-         out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
-         out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
-         out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
-         extrasToXml(out, pop.extras);
-
-         out.endTag(null, "op");
-     }
-
-    /**
-     * Append the given operation to the pending ops file; if unable to,
-     * write all pending ops.
-     */
-    private void appendPendingOperationLocked(PendingOperation op) {
-        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
-        }
-        FileOutputStream fos = null;
-        try {
-            fos = mPendingFile.openAppend();
-        } catch (java.io.IOException e) {
-            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Failed append; writing full file");
-            }
-            writePendingOperationsLocked();
-            return;
-        }
-
-        try {
-            XmlSerializer out = new FastXmlSerializer();
-            out.setOutput(fos, "utf-8");
-            writePendingOperationLocked(op, out);
-            out.endDocument();
-            mPendingFile.finishWrite(fos);
-        } catch (java.io.IOException e1) {
-            Log.w(TAG, "Error writing appending operation", e1);
-            mPendingFile.failWrite(fos);
-        } finally {
-            try {
-                fos.close();
-            } catch (IOException e) {}
-        }
-    }
-
     static private byte[] flattenBundle(Bundle bundle) {
         byte[] flatData = null;
         Parcel parcel = Parcel.obtain();
@@ -2469,6 +2530,60 @@
         return bundle;
     }
 
+    private static final String XML_ATTR_AUTHORITYID = "authority_id";
+    private static final String XML_ATTR_SOURCE = "source";
+    private static final String XML_ATTR_EXPEDITED = "expedited";
+    private static final String XML_ATTR_REASON = "reason";
+
+    /**
+     * Write all currently pending ops to the pending ops file.
+     * TODO: Change this from xml so that we can append to this file as before.
+     */
+    private void writePendingOperationsLocked() {
+        final int N = mPendingOperations.size();
+        FileOutputStream fos = null;
+        try {
+            if (N == 0) {
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)){
+                    Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
+                }
+                mPendingFile.truncate();
+                return;
+            }
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
+            }
+            fos = mPendingFile.startWrite();
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
+            out.startDocument(null, true);
+            out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+            out.startTag(null, "pending");
+            out.attribute(null, "version", Integer.toString(PENDING_OPERATION_VERSION));
+
+            for (int i = 0; i < N; i++) {
+                PendingOperation pop = mPendingOperations.get(i);
+                out.startTag(null, "op");
+                out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
+                out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
+                out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
+                out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
+                extrasToXml(out, pop.extras);
+                out.endTag(null, "op");
+             }
+             out.endTag(null, "pending");
+             out.endDocument();
+             mPendingFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing pending operations", e1);
+            if (fos != null) {
+                mPendingFile.failWrite(fos);
+            }
+        }
+    }
+
+
     private void extrasToXml(XmlSerializer out, Bundle extras) throws java.io.IOException {
         for (String key : extras.keySet()) {
             out.startTag(null, "extra");
@@ -2501,6 +2616,26 @@
         }
     }
 
+    private void requestSync(AuthorityInfo authorityInfo, int reason, Bundle extras) {
+        if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
+                && mSyncRequestListener != null) {
+            mSyncRequestListener.onSyncRequest(authorityInfo.base, reason, extras);
+        } else {
+            SyncRequest.Builder req =
+                    new SyncRequest.Builder()
+                        .syncOnce(0, 0)
+                        .setExtras(extras);
+            if (authorityInfo.base.target_provider) {
+                req.setSyncAdapter(
+                        authorityInfo.base.account,
+                        authorityInfo.base.provider);
+            } else {
+                req.setSyncAdapter(authorityInfo.base.service);
+            }
+            ContentResolver.requestSync(req.build());
+        }
+    }
+
     private void requestSync(Account account, int userId, int reason, String authority,
             Bundle extras) {
         // If this is happening in the system process, then call the syncrequest listener
@@ -2509,7 +2644,10 @@
         // which will know which userId to apply based on the Binder id.
         if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
                 && mSyncRequestListener != null) {
-            mSyncRequestListener.onSyncRequest(account, userId, reason, authority, extras);
+            mSyncRequestListener.onSyncRequest(
+                    new EndPoint(account, authority, userId),
+                    reason,
+                    extras);
         } else {
             ContentResolver.requestSync(account, authority, extras);
         }
@@ -2605,10 +2743,8 @@
     public void dumpPendingOperations(StringBuilder sb) {
         sb.append("Pending Ops: ").append(mPendingOperations.size()).append(" operation(s)\n");
         for (PendingOperation pop : mPendingOperations) {
-            sb.append("(" + pop.account)
-                .append(", u" + pop.userId)
-                .append(", " + pop.authority)
-                .append(", " + pop.extras)
+            sb.append("(info: " + pop.authority.toString())
+                .append(", extras: " + pop.extras)
                 .append(")\n");
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index e44652f..853d2a2 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -17,6 +17,7 @@
 package com.android.server.content;
 
 import android.accounts.Account;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -32,22 +33,33 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.server.content.SyncStorageEngine.EndPoint;
+
 import com.android.internal.os.AtomicFile;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.util.List;
 
+import com.android.server.content.SyncStorageEngine.EndPoint;
+
 public class SyncStorageEngineTest extends AndroidTestCase {
 
     protected Account account1;
+    protected ComponentName syncService1;
     protected String authority1 = "testprovider";
     protected Bundle defaultBundle;
     protected final int DEFAULT_USER = 0;
-    
+
+    /* Some default poll frequencies. */
+    final long dayPoll = (60 * 60 * 24);
+    final long dayFuzz = 60;
+    final long thousandSecs = 1000;
+    final long thousandSecsFuzz = 100;
+
     MockContentResolver mockResolver;
     SyncStorageEngine engine;
-    
+
     private File getSyncDir() {
         return new File(new File(getContext().getFilesDir(), "system"), "sync");
     }
@@ -55,6 +67,7 @@
     @Override
     public void setUp() {
         account1 = new Account("a@example.com", "example.type");
+        syncService1 = new ComponentName("com.example", "SyncService");
         // Default bundle.
         defaultBundle = new Bundle();
         defaultBundle.putInt("int_key", 0);
@@ -80,11 +93,13 @@
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
                 new TestContext(mockResolver, getContext()));
-
         long time0 = 1000;
-        long historyId = engine.insertStartSyncEvent(
-                account, 0, SyncOperation.REASON_PERIODIC, authority, time0,
-                SyncStorageEngine.SOURCE_LOCAL, false /* initialization */, null /* extras */);
+        SyncOperation op = new SyncOperation(account, 0,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL,
+                authority,
+                null, time0, 0 /* flex*/, 0, 0, true);
+        long historyId = engine.insertStartSyncEvent(op, time0);
         long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
         engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
     }
@@ -94,27 +109,28 @@
      */
     @MediumTest
     public void testPending() throws Exception {
-        SyncStorageEngine.PendingOperation pop =
-                new SyncStorageEngine.PendingOperation(account1, DEFAULT_USER,
-                        SyncOperation.REASON_PERIODIC, SyncStorageEngine.SOURCE_LOCAL,
-                        authority1, defaultBundle, false);
-        
-        engine.insertIntoPending(pop);
+        SyncOperation sop = new SyncOperation(account1,
+                DEFAULT_USER,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, null,
+                0 /* runtime */, 0 /* flex */, 0 /* backoff */, 0 /* delayuntil */,
+                true /* expedited */);
+        engine.insertIntoPending(sop);
+
         // Force engine to read from disk.
         engine.clearAndReadState();
 
         assert(engine.getPendingOperationCount() == 1);
         List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
         SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
-        assertEquals(pop.account, popRetrieved.account);
-        assertEquals(pop.reason, popRetrieved.reason);
-        assertEquals(pop.userId, popRetrieved.userId);
-        assertEquals(pop.syncSource, popRetrieved.syncSource);
-        assertEquals(pop.authority, popRetrieved.authority);
-        assertEquals(pop.expedited, popRetrieved.expedited);
-        assertEquals(pop.serviceName, popRetrieved.serviceName);
-        assert(android.content.PeriodicSync.syncExtrasEquals(pop.extras, popRetrieved.extras));
-
+        assertEquals(sop.target.account, popRetrieved.authority.account);
+        assertEquals(sop.target.provider, popRetrieved.authority.provider);
+        assertEquals(sop.target.service, popRetrieved.authority.service);
+        assertEquals(sop.target.userId, popRetrieved.authority.userId);
+        assertEquals(sop.reason, popRetrieved.reason);
+        assertEquals(sop.syncSource, popRetrieved.syncSource);
+        assertEquals(sop.expedited, popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras));
     }
 
     /**
@@ -134,42 +150,44 @@
         final int period2 = 1000;
 
         PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1);
+        EndPoint end1 = new EndPoint(account1, authority, 0);
+
         PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2);
         PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2);
 
-        
+
 
         removePeriodicSyncs(engine, account1, 0, authority);
         removePeriodicSyncs(engine, account2, 0, authority);
         removePeriodicSyncs(engine, account1, 1, authority);
 
         // this should add two distinct periodic syncs for account1 and one for account2
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0);
-        engine.addPeriodicSync(sync4, 0);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras1);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras2);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period2, 0, extras2);
+        engine.updateOrAddPeriodicSync(new EndPoint(account2, authority, 0), period2, 0, extras2);
         // add a second user
-        engine.addPeriodicSync(sync2, 1);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 1), period1, 0, extras2);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0));
 
         assertEquals(2, syncs.size());
 
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1, 0);
+        engine.removePeriodicSync(new EndPoint(account1, authority, 0), extras1);
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0));
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(account2, authority, 0));
         assertEquals(1, syncs.size());
         assertEquals(sync4, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(sync2.account, sync2.authority, 1));
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
     }
@@ -190,12 +208,19 @@
         final int period2 = 1000;
         final int flex1 = 10;
         final int flex2 = 100;
+        EndPoint point1 = new EndPoint(account1, authority, 0);
+        EndPoint point2 = new EndPoint(account2, authority, 0);
+        EndPoint point1User2 = new EndPoint(account1, authority, 1);
 
         PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1, flex1);
         PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1, flex1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2, flex2);
         PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2, flex2);
 
+        EndPoint target1 = new EndPoint(account1, authority, 0);
+        EndPoint target2 = new EndPoint(account2, authority, 0);
+        EndPoint target1UserB = new EndPoint(account1, authority, 1);
+
         MockContentResolver mockResolver = new MockContentResolver();
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
@@ -206,40 +231,42 @@
         removePeriodicSyncs(engine, account1, 1, authority);
 
         // This should add two distinct periodic syncs for account1 and one for account2
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0); // Should edit sync2 and update the period.
-        engine.addPeriodicSync(sync4, 0);
-        // add a second user
-        engine.addPeriodicSync(sync2, 1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2);
+        // Edit existing sync and update the period and flex.
+        engine.updateOrAddPeriodicSync(target1, period2, flex2, extras2);
+        engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2);
+        // add a target for a second user.
+        engine.updateOrAddPeriodicSync(target1UserB, period1, flex1, extras2);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
 
         assertEquals(2, syncs.size());
 
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1, 0);
+        engine.removePeriodicSync(target1, extras1);
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync4, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        syncs = engine.getPeriodicSyncs(target1UserB);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
     }
 
     private void removePeriodicSyncs(SyncStorageEngine engine, Account account, int userId, String authority) {
-        engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, 0, authority));
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, userId, authority);
+        EndPoint target = new EndPoint(account, authority, userId);
+        engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, userId, authority));
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target);
         for (PeriodicSync sync : syncs) {
-            engine.removePeriodicSync(sync, userId);
+            engine.removePeriodicSync(target, sync.extras);
         }
     }
 
@@ -264,16 +291,19 @@
         final int flex1 = 10;
         final int flex2 = 100;
 
+        EndPoint point1 = new EndPoint(account1, authority1, 0);
+        EndPoint point2 = new EndPoint(account1, authority2, 0);
+        EndPoint point3 = new EndPoint(account2, authority1, 0);
+
         PeriodicSync sync1 = new PeriodicSync(account1, authority1, extras1, period1, flex1);
         PeriodicSync sync2 = new PeriodicSync(account1, authority1, extras2, period1, flex1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority2, extras1, period1, flex1);
         PeriodicSync sync4 = new PeriodicSync(account1, authority2, extras2, period2, flex2);
         PeriodicSync sync5 = new PeriodicSync(account2, authority1, extras1, period1, flex1);
 
-        MockContentResolver mockResolver = new MockContentResolver();
-
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
-                new TestContext(mockResolver, getContext()));
+        EndPoint target1 = new EndPoint(account1, authority1, 0);
+        EndPoint target2 = new EndPoint(account1, authority2, 0);
+        EndPoint target3 = new EndPoint(account2, authority1, 0);
 
         removePeriodicSyncs(engine, account1, 0, authority1);
         removePeriodicSyncs(engine, account2, 0, authority1);
@@ -294,26 +324,26 @@
         engine.setIsSyncable(account2, 0, authority2, 0);
         engine.setSyncAutomatically(account2, 0, authority2, true);
 
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0);
-        engine.addPeriodicSync(sync4, 0);
-        engine.addPeriodicSync(sync5, 0);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2);
+        engine.updateOrAddPeriodicSync(target2, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2);
+        engine.updateOrAddPeriodicSync(target3, period1, flex1, extras1);
 
         engine.writeAllState();
         engine.clearAndReadState();
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals(2, syncs.size());
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync2, syncs.get(1));
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(2, syncs.size());
         assertEquals(sync3, syncs.get(0));
         assertEquals(sync4, syncs.get(1));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync5, syncs.get(0));
 
@@ -328,6 +358,35 @@
         assertEquals(0, engine.getIsSyncable(account2, 0, authority2));
     }
 
+    @SmallTest
+    public void testComponentParsing() throws Exception {
+        // Sync Service component.
+        PeriodicSync sync1 = new PeriodicSync(syncService1, Bundle.EMPTY, dayPoll, dayFuzz);
+
+        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"2\" >\n"
+                + "<authority id=\"0\" user=\"0\" package=\"" + syncService1.getPackageName() + "\""
+                + " class=\"" + syncService1.getClassName() + "\" syncable=\"true\">"
+                + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>"
+                + "\n</authority>"
+                + "</accounts>").getBytes();
+
+        File syncDir = getSyncDir();
+        syncDir.mkdirs();
+        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        FileOutputStream fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        // Test service component read
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(
+                new SyncStorageEngine.EndPoint(syncService1, 0));
+        assertEquals(1, syncs.size());
+        assertEquals(1, engine.getIsTargetServiceActive(syncService1, 0));
+    }
+
     @MediumTest
     /**
      * V2 introduces flex time as well as service components.
@@ -339,20 +398,20 @@
         final String authority2 = "auth2";
         final String authority3 = "auth3";
 
-        final long dayPoll = (60 * 60 * 24);
-        final long dayFuzz = 60;
-        final long thousandSecs = 1000;
-        final long thousandSecsFuzz = 100;
-        final Bundle extras = new Bundle();
-        PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, dayPoll, dayFuzz);
-        PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, dayPoll, dayFuzz);
-        PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, dayPoll, dayFuzz);
-        PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, thousandSecs, thousandSecsFuzz);
-        PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, thousandSecs, thousandSecsFuzz);
-        PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, thousandSecs, thousandSecsFuzz);
-        MockContentResolver mockResolver = new MockContentResolver();
+        EndPoint target1 = new EndPoint(account, authority1, 0);
+        EndPoint target2 = new EndPoint(account, authority2, 0);
+        EndPoint target3 = new EndPoint(account, authority3, 0);
+        EndPoint target4 = new EndPoint(account, authority3, 1);
 
-        final TestContext testContext = new TestContext(mockResolver, getContext());
+        PeriodicSync sync1 = new PeriodicSync(account, authority1, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync2 = new PeriodicSync(account, authority2, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync3 = new PeriodicSync(account, authority3, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync1s = new PeriodicSync(account, authority1, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
+        PeriodicSync sync2s = new PeriodicSync(account, authority2, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
+        PeriodicSync sync3s = new PeriodicSync(account, authority3, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
 
         byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                 + "<accounts version=\"2\" >\n"
@@ -378,21 +437,22 @@
         fos.write(accountsFileData);
         accountInfoFile.finishWrite(fos);
 
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
+        engine.clearAndReadState();
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals("Got incorrect # of syncs", 1, syncs.size());
         assertEquals(sync1, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+        syncs = engine.getPeriodicSyncs(target4);
+
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
@@ -411,13 +471,13 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(0, syncs.size());
 
         accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
@@ -440,15 +500,15 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync1s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3s, syncs.get(0));
     }
@@ -460,6 +520,12 @@
         final String authority2 = "auth2";
         final String authority3 = "auth3";
         final Bundle extras = new Bundle();
+
+        EndPoint target1 = new EndPoint(account, authority1, 0);
+        EndPoint target2 = new EndPoint(account, authority2, 0);
+        EndPoint target3 = new EndPoint(account, authority3, 0);
+        EndPoint target4 = new EndPoint(account, authority3, 1);
+
         PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24));
         PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24));
         PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24));
@@ -488,19 +554,20 @@
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals("expected sync1: " + sync1.toString() + " == sync 2" + syncs.get(0).toString(), sync1, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
+        syncs = engine.getPeriodicSyncs(target4);
 
-        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
@@ -518,13 +585,13 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(0, syncs.size());
 
         accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
@@ -547,15 +614,15 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync1s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3s, syncs.get(0));
     }
