Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96ca46cf authored by Matthew Williams's avatar Matthew Williams
Browse files

Fix for scheduling conflicts, address fred's comments

The last set of comments asked for a renaming. Rather than
confuse the issue now, this patch set focuses on the internals
and API changes can come later.
Renamed AnonymousSyncAdapter -> SyncServiceAdapter

Change-Id: I596ea2f7367b83b357b2f4b56e069448d5591b2a
parent 72bd0620
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -104,9 +104,9 @@ LOCAL_SRC_FILES += \
	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 \
+8 −0
Original line number Diff line number Diff line
@@ -5582,6 +5582,7 @@ package android.content {
    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();
@@ -5589,13 +5590,17 @@ package android.content {
    method public static int getIsSyncable(android.accounts.Account, java.lang.String);
    method public static boolean getMasterSyncAutomatically();
    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;
@@ -5613,6 +5618,7 @@ package android.content {
    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);
@@ -6666,6 +6672,7 @@ package android.content {
    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;
  }
@@ -6721,6 +6728,7 @@ package android.content {
    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 {
+137 −23
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ public abstract class ContentResolver {
    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
@@ -1520,11 +1520,24 @@ public abstract class ContentResolver {
     */
    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
@@ -1591,6 +1604,10 @@ public abstract class ContentResolver {
     *
     * <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
@@ -1608,13 +1625,7 @@ public abstract class ContentResolver {
        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 {
@@ -1625,6 +1636,26 @@ public abstract class ContentResolver {
        }
    }

    /**
     * {@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.
@@ -1651,19 +1682,28 @@ public abstract class ContentResolver {
    }

    /**
     * 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
        }
    }

    /**
@@ -1683,7 +1723,23 @@ public abstract class ContentResolver {
            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);
        }
@@ -1718,6 +1774,38 @@ public abstract class ContentResolver {
        }
    }

    /**
     * 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.
@@ -1752,8 +1840,8 @@ public abstract class ContentResolver {
    }

    /**
     * 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
@@ -1761,8 +1849,26 @@ public abstract class ContentResolver {
     * @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);
        }
@@ -1820,7 +1926,7 @@ public abstract class ContentResolver {
     */
    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);
        }
@@ -1836,7 +1942,15 @@ public abstract class ContentResolver {
     */
    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);
        }
+48 −16
Original line number Diff line number Diff line
@@ -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 @@ interface IContentService {
            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 @@ interface IContentService {
    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,15 +121,22 @@ interface IContentService {
     */
    void setIsSyncable(in Account account, String providerName, int syncable);

    void setMasterSyncAutomatically(boolean flag);

    boolean getMasterSyncAutomatically();
    /**
     * Corresponds roughly to setIsSyncable(String account, String provider) for syncs that bind
     * to a SyncService.
     */
    void setServiceActive(in ComponentName cname, boolean active);

    /**
     * Returns true if there is currently a sync operation for the given
     * account or authority in the pending list, or actively being processed.
     * 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 isSyncActive(in Account account, String authority);
    boolean isServiceActive(in ComponentName cname);

    void setMasterSyncAutomatically(boolean flag);

    boolean getMasterSyncAutomatically();

    List<SyncInfo> getCurrentSyncs();

@@ -130,18 +146,34 @@ interface IContentService {
     */
    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);

+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ import android.content.ISyncContext;
 * Provider specified). See {@link android.content.AbstractThreadedSyncAdapter}.
 * {@hide}
 */
oneway interface IAnonymousSyncAdapter {
oneway interface ISyncServiceAdapter {

    /**
     * Initiate a sync. SyncAdapter-specific parameters may be specified in
Loading