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

Commit eea358a7 authored by Matthew Williams's avatar Matthew Williams Committed by Android Git Automerger
Browse files

am 9d7c4d4a: Merge "DO NOT MERGE. Remove service component for KLP." into klp-dev

* commit '9d7c4d4a':
  DO NOT MERGE. Remove service component for KLP.
parents 3e09c1a3 9d7c4d4a
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