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

Commit 9d7c4d4a authored by Matthew Williams's avatar Matthew Williams Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE. Remove service component for KLP." into klp-dev

parents 083199ef 6222288b
Loading
Loading
Loading
Loading
+2 −15
Original line number Diff line number Diff line
@@ -5736,7 +5736,6 @@ 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.SyncRequest);
    method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
    method public static deprecated android.content.SyncInfo getCurrentSync();
    method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
@@ -6716,9 +6715,7 @@ package android.content {
    field public final android.accounts.Account account;
    field public final java.lang.String authority;
    field public final android.os.Bundle extras;
    field public final boolean isService;
    field public final long period;
    field public final android.content.ComponentName service;
  }
  public class ReceiverCallNotAllowedException extends android.util.AndroidRuntimeException {
@@ -6839,7 +6836,6 @@ package android.content {
  public class SyncRequest implements android.os.Parcelable {
    method public int describeContents();
    method public boolean isExpedited();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
  }
@@ -6847,18 +6843,15 @@ package android.content {
  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);
    method public android.content.SyncRequest.Builder setIgnoreSettings(boolean);
    method public android.content.SyncRequest.Builder setManual(boolean);
    method public android.content.SyncRequest.Builder setNoRetry(boolean);
    method public android.content.SyncRequest.Builder setPriority(int);
    method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, java.lang.String);
    method public android.content.SyncRequest.Builder setSyncAdapter(android.content.ComponentName);
    method public android.content.SyncRequest.Builder setTransferSize(long, long);
    method public android.content.SyncRequest.Builder syncOnce(long, long);
    method public android.content.SyncRequest.Builder syncOnce();
    method public android.content.SyncRequest.Builder syncPeriodic(long, long);
  }
@@ -6885,12 +6878,6 @@ package android.content {
    field public boolean tooManyRetries;
  }
  public abstract class SyncService extends android.app.Service {
    ctor public SyncService();
    method public android.os.IBinder onBind(android.content.Intent);
    method public abstract void onPerformSync(android.os.Bundle, android.content.SyncResult);
  }
  public class SyncStats implements android.os.Parcelable {
    ctor public SyncStats();
    ctor public SyncStats(android.os.Parcel);
+8 −18
Original line number Diff line number Diff line
@@ -141,7 +141,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 = "disallow_metered";

    /**
     * Set by the SyncManager to request that the SyncAdapter initialize itself for
@@ -1669,7 +1669,7 @@ public abstract class ContentResolver {
            new SyncRequest.Builder()
                .setSyncAdapter(account, authority)
                .setExtras(extras)
                .syncOnce(0, 0)     // Immediate sync.
                .syncOnce()
                .build();
        requestSync(request);
    }
@@ -1677,6 +1677,9 @@ public abstract class ContentResolver {
    /**
     * Register a sync with the SyncManager. These requests are built using the
     * {@link SyncRequest.Builder}.
     *
     * @param request The immutable SyncRequest object containing the sync parameters. Use
     * {@link SyncRequest.Builder} to construct these.
     */
    public static void requestSync(SyncRequest request) {
        try {
@@ -1812,6 +1815,9 @@ public abstract class ContentResolver {
     * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE},
     * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true.
     * If any are supplied then an {@link IllegalArgumentException} will be thrown.
     * <p>As of API level 19 this function introduces a default flexibility of ~4% (up to a maximum
     * of one hour in the day) into the requested period. Use
     * {@link SyncRequest.Builder#syncPeriodic(long, long)} to set this flexibility manually.
     *
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
@@ -1874,22 +1880,6 @@ 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
     * 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.
    }

    /**
     * Get the list of information about the periodic syncs for the given account and authority.
     * <p>This method requires the caller to hold the permission
+10 −61
Original line number Diff line number Diff line
@@ -29,17 +29,13 @@ public class PeriodicSync implements Parcelable {
    public final Account account;
    /** The authority of the sync. Can be null. */
    public final String authority;
    /** The service for syncing, if this is an anonymous sync. Can be null.*/
    public final ComponentName service;
    /** Any extras that parameters that are to be passed to the sync adapter. */
    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. */
    public final boolean isService;
    /**
     * How much flexibility can be taken in scheduling the sync, in seconds.
     * {@hide}
     * How much flexibility can be taken in scheduling the sync, in seconds.
     */
    public final long flexTime;

@@ -52,76 +48,44 @@ public class PeriodicSync implements Parcelable {
    public PeriodicSync(Account account, String authority, Bundle extras, long periodInSeconds) {
        this.account = account;
        this.authority = authority;
        this.service = null;
        this.isService = false;
        if (extras == null) {
            this.extras = new Bundle();
        } else {
            this.extras = new Bundle(extras);
        }
        this.period = periodInSeconds;
        // Old API uses default flex time. No-one should be using this ctor anyway.
        // Initialise to a sane value.
        this.flexTime = 0L;
    }

    // TODO: Add copy ctor from SyncRequest?

    /**
     * Create a copy of a periodic sync.
     * {@hide}
     * Create a copy of a periodic sync.
     */
    public PeriodicSync(PeriodicSync other) {
        this.account = other.account;
        this.authority = other.authority;
        this.service = other.service;
        this.isService = other.isService;
        this.extras = new Bundle(other.extras);
        this.period = other.period;
        this.flexTime = other.flexTime;
    }

    /**
     * A PeriodicSync for a sync with a specified provider.
     * {@hide}
     * A PeriodicSync for a sync with a specified provider.
     */
    public PeriodicSync(Account account, String authority, Bundle extras,
            long period, long flexTime) {
        this.account = account;
        this.authority = authority;
        this.service = null;
        this.isService = false;
        this.extras = new Bundle(extras);
        this.period = period;
        this.flexTime = flexTime;
    }

    /**
     * A PeriodicSync for a sync with a specified SyncService.
     * {@hide}
     */
    public PeriodicSync(ComponentName service, Bundle extras,
            long period,
            long flexTime) {
        this.account = null;
        this.authority = null;
        this.service = service;
        this.isService = true;
        this.extras = new Bundle(extras);
        this.period = period;
        this.flexTime = flexTime;
    }

    private PeriodicSync(Parcel in) {
        this.isService = (in.readInt() != 0);
        if (this.isService) {
            this.service = in.readParcelable(null);
            this.account = null;
            this.authority = null;
        } else {
        this.account = in.readParcelable(null);
        this.authority = in.readString();
            this.service = null;
        }
        this.extras = in.readBundle();
        this.period = in.readLong();
        this.flexTime = in.readLong();
@@ -134,13 +98,8 @@ public class PeriodicSync implements Parcelable {

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(isService ? 1 : 0);
        if (account == null && authority == null) {
            dest.writeParcelable(service, flags);
        } else {
        dest.writeParcelable(account, flags);
        dest.writeString(authority);
        }
        dest.writeBundle(extras);
        dest.writeLong(period);
        dest.writeLong(flexTime);
@@ -167,17 +126,8 @@ public class PeriodicSync implements Parcelable {
            return false;
        }
        final PeriodicSync other = (PeriodicSync) o;
        if (this.isService != other.isService) {
            return false;
        }
        boolean equal = false;
        if (this.isService) {
            equal = service.equals(other.service);
        } else {
            equal = account.equals(other.account)
                    && authority.equals(other.authority);
        }
        return equal
        return account.equals(other.account)
            && authority.equals(other.authority)
            && period == other.period
            && syncExtrasEquals(extras, other.extras);
    }
@@ -208,7 +158,6 @@ public class PeriodicSync implements Parcelable {
    public String toString() {
        return "account: " + account +
               ", authority: " + authority +
               ", service: " + service +
               ". period: " + period + "s " +
               ", flex: " + flexTime;
    }
+85 −108

File changed.

Preview size limit exceeded, changes collapsed.

+0 −169
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content;

import android.app.Service;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.Trace;

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.
 *
 * <pre>
 * &lt;service ndroid:name=".MyAnonymousSyncService" android:permission="android.permission.SYNC" /&gt;
 * </pre>
 * Like @link android.content.AbstractThreadedSyncAdapter this service supports
 * multiple syncs at the same time. Each incoming startSync() with a unique tag
 * will spawn a thread to do the work of that sync. If startSync() is called
 * with a tag that already exists, a SyncResult.ALREADY_IN_PROGRESS is returned.
 * Remember that your service will spawn multiple threads if you schedule multiple syncs
 * at once, so if you mutate local objects you must ensure synchronization.
 */
public abstract class SyncService extends Service {

    /** SyncAdapter Instantiation that any anonymous syncs call. */
    private final AnonymousSyncAdapterImpl mSyncAdapter = new AnonymousSyncAdapterImpl();

    /** Keep track of on-going syncs, keyed by tag. */
    @GuardedBy("mLock")
    private final HashMap<Bundle, AnonymousSyncThread>
            mSyncThreads = new HashMap<Bundle, AnonymousSyncThread>();
    /** Lock object for accessing the SyncThreads HashMap. */
    private final Object mSyncThreadLock = new Object();

    @Override
    public IBinder onBind(Intent intent) {
        return mSyncAdapter.asBinder();
    }

    /** {@hide} */
    private class AnonymousSyncAdapterImpl extends IAnonymousSyncAdapter.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;
            synchronized (mSyncThreadLock) {
                if (mSyncThreads.containsKey(extras)) {
                    // 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) {
                syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
            }
        }

        /**
         * Used by the SM to cancel a specific sync using the {@link
         * com.android.server.content.SyncManager.ActiveSyncContext} as a handle.
         */
        @Override
        public void cancelSync(ISyncContext syncContext) {
            AnonymousSyncThread runningSync = null;
            synchronized (mSyncThreadLock) {
                for (AnonymousSyncThread thread : mSyncThreads.values()) {
                    if (thread.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
                        runningSync = thread;
                        break;
                    }
                }
            }
            if (runningSync != null) {
                runningSync.interrupt();
            }
        }
    }

    /**
     * {@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.
     */
    private class AnonymousSyncThread extends Thread {
        private final SyncContext mSyncContext;
        private final Bundle mExtras;

        public AnonymousSyncThread(SyncContext syncContext, Bundle extras) {
            mSyncContext = syncContext;
            mExtras = extras;
        }

        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            Trace.traceBegin(Trace.TRACE_TAG_SYNC_MANAGER, getApplication().getPackageName());

            SyncResult syncResult = new SyncResult();
            try {
                if (isCancelled()) {
                    return;
                }
                // Run the sync based off of the provided code.
                SyncService.this.onPerformSync(mExtras, syncResult);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
                if (!isCancelled()) {
                    mSyncContext.onFinished(syncResult);
                }
                // Synchronize so that the assignment will be seen by other
                // threads
                // that also synchronize accesses to mSyncThreads.
                synchronized (mSyncThreadLock) {
                    mSyncThreads.remove(mExtras);
                }
            }
        }

        private boolean isCancelled() {
            return Thread.currentThread().isInterrupted();
        }
    }

    /**
     * Initiate an anonymous sync using this service. SyncAdapter-specific
     * parameters may be specified in extras, which is guaranteed to not be
     * null.
     */
    public abstract void onPerformSync(Bundle extras, SyncResult syncResult);

}
Loading