FileDocCategorySizeDatePackage
SyncOperation.javaAPI DocAndroid 5.1 API15314Thu Mar 12 22:22:42 GMT 2015com.android.server.content

SyncOperation

public class SyncOperation extends Object implements Comparable
Value type that represents a sync operation. TODO: This is the class to flesh out with all the scheduling data - metered/unmetered, transfer-size, etc. {@hide}

Fields Summary
public static final String
TAG
public static final int
REASON_BACKGROUND_DATA_SETTINGS_CHANGED
public static final int
REASON_ACCOUNTS_UPDATED
public static final int
REASON_SERVICE_CHANGED
public static final int
REASON_PERIODIC
public static final int
REASON_IS_SYNCABLE
Sync started because it has just been set to isSyncable.
public static final int
REASON_SYNC_AUTO
Sync started because it has just been set to sync automatically.
public static final int
REASON_MASTER_SYNC_AUTO
Sync started because master sync automatically has been set to true.
public static final int
REASON_USER_START
private static String[]
REASON_NAMES
public static final int
SYNC_TARGET_UNKNOWN
public static final int
SYNC_TARGET_ADAPTER
public static final int
SYNC_TARGET_SERVICE
public final SyncStorageEngine.EndPoint
target
Identifying info for the target for this operation.
public final int
reason
Why this sync was kicked off. {@link #REASON_NAMES}
public final int
syncSource
Where this sync was initiated.
public final boolean
allowParallelSyncs
public final String
key
private final boolean
expedited
Internal boolean to avoid reading a bundle everytime we want to compare operations.
public android.os.Bundle
extras
public SyncStorageEngine.PendingOperation
pendingOperation
Bare-bones version of this operation that is persisted across reboots.
public long
latestRunTime
Elapsed real time in millis at which to run this sync.
public long
backoff
Set by the SyncManager in order to delay retries.
public long
delayUntil
Specified by the adapter to delay subsequent sync operations.
public long
effectiveRunTime
Elapsed real time in millis when this sync will be run. Depends on max(backoff, latestRunTime, and delayUntil).
public long
flexTime
Amount of time before {@link #effectiveRunTime} from which this sync can run.
public String
wakeLockName
Descriptive string key for this operation
Constructors Summary
public SyncOperation(android.accounts.Account account, int userId, int reason, int source, String provider, android.os.Bundle extras, long runTimeFromNow, long flexTime, long backoff, long delayUntil, boolean allowParallelSyncs)


              
                   
                
        this(new SyncStorageEngine.EndPoint(account, provider, userId),
                reason, source, extras, runTimeFromNow, flexTime, backoff, delayUntil,
                allowParallelSyncs);
    
public SyncOperation(android.content.ComponentName service, int userId, int reason, int source, android.os.Bundle extras, long runTimeFromNow, long flexTime, long backoff, long delayUntil)

        this(new SyncStorageEngine.EndPoint(service, userId), reason, source, extras,
                runTimeFromNow, flexTime, backoff, delayUntil, true /* allowParallelSyncs */);
    
private SyncOperation(SyncStorageEngine.EndPoint info, int reason, int source, android.os.Bundle extras, long runTimeFromNow, long flexTime, long backoff, long delayUntil, boolean allowParallelSyncs)

        this.target = info;
        this.reason = reason;
        this.syncSource = source;
        this.extras = new Bundle(extras);
        cleanBundle(this.extras);
        this.delayUntil = delayUntil;
        this.backoff = backoff;
        this.allowParallelSyncs = allowParallelSyncs;
        final long now = SystemClock.elapsedRealtime();
        // Set expedited based on runTimeFromNow. The SyncManager specifies whether the op is
        // expedited (Not done solely based on bundle).
        if (runTimeFromNow < 0) {
            this.expedited = true;
            // Sanity check: Will always be true.
            if (!this.extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
                this.extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
            }
            this.latestRunTime = now;
            this.flexTime = 0;
        } else {
            this.expedited = false;
            this.extras.remove(ContentResolver.SYNC_EXTRAS_EXPEDITED);
            this.latestRunTime = now + runTimeFromNow;
            this.flexTime = flexTime;
        }
        updateEffectiveRunTime();
        this.key = toKey(info, this.extras);
    
public SyncOperation(SyncOperation other, long newRunTimeFromNow)
Used to reschedule a sync at a new point in time.

        this(other.target, other.reason, other.syncSource, new Bundle(other.extras),
                newRunTimeFromNow,
                0L /* In back-off so no flex */,
                other.backoff,
                other.delayUntil,
                other.allowParallelSyncs);
    
Methods Summary
private voidcleanBundle(android.os.Bundle bundle)
Make sure the bundle attached to this SyncOperation doesn't have unnecessary flags set.

param
bundle to clean.

        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_UPLOAD);
        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_MANUAL);
        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS);
        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY);
        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_DISALLOW_METERED);
    
public intcompareTo(java.lang.Object o)
SyncOperations are sorted based on their earliest effective run time. This comparator is used to sort the SyncOps at a given time when deciding which to run, so earliest run time is the best criteria.

        SyncOperation other = (SyncOperation) o;
        if (expedited != other.expedited) {
            return expedited ? -1 : 1;
        }
        long thisIntervalStart = Math.max(effectiveRunTime - flexTime, 0);
        long otherIntervalStart = Math.max(
            other.effectiveRunTime - other.flexTime, 0);
        if (thisIntervalStart < otherIntervalStart) {
            return -1;
        } else if (otherIntervalStart < thisIntervalStart) {
            return 1;
        } else {
            return 0;
        }
    
public java.lang.Stringdump(android.content.pm.PackageManager pm, boolean useOneLine)

        StringBuilder sb = new StringBuilder();
        if (target.target_provider) {
            sb.append(target.account.name)
                .append(" u")
                .append(target.userId).append(" (")
                .append(target.account.type)
                .append(")")
                .append(", ")
                .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");
        }
        sb.append(", reason: ");
        sb.append(reasonToString(pm, reason));
        if (!useOneLine && !extras.keySet().isEmpty()) {
            sb.append("\n    ");
            extrasToStringBuilder(extras, sb);
        }
        return sb.toString();
    
private static voidextrasToStringBuilder(android.os.Bundle bundle, java.lang.StringBuilder sb)

        sb.append("[");
        for (String key : bundle.keySet()) {
            sb.append(key).append("=").append(bundle.get(key)).append(" ");
        }
        sb.append("]");
    
public booleanignoreBackoff()

        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
    
public booleanisConflict(com.android.server.content.SyncOperation toRun)
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.

        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;
        }
    
public booleanisExpedited()

        return expedited;
    
public booleanisIgnoreSettings()

        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
    
public booleanisInitialization()

        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
    
public booleanisManual()

        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
    
public booleanisNotAllowedOnMetered()

        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
    
public booleanmatchesAuthority(com.android.server.content.SyncOperation other)

        return this.target.matchesSpec(other.target);
    
public static java.lang.StringreasonToString(android.content.pm.PackageManager pm, int reason)

        if (reason >= 0) {
            if (pm != null) {
                final String[] packages = pm.getPackagesForUid(reason);
                if (packages != null && packages.length == 1) {
                    return packages[0];
                }
                final String name = pm.getNameForUid(reason);
                if (name != null) {
                    return name;
                }
                return String.valueOf(reason);
            } else {
                return String.valueOf(reason);
            }
        } else {
            final int index = -reason - 1;
            if (index >= REASON_NAMES.length) {
                return String.valueOf(reason);
            } else {
                return REASON_NAMES[index];
            }
        }
    
private voidremoveFalseExtra(android.os.Bundle bundle, java.lang.String extraName)

        if (!bundle.getBoolean(extraName, false)) {
            bundle.remove(extraName);
        }
    
public java.lang.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;
    
public static java.lang.StringtoKey(SyncStorageEngine.EndPoint info, android.os.Bundle extras)
Changed in V3.

        StringBuilder sb = new StringBuilder();
        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 if (info.target_service) {
            sb.append("service {package=" )
                .append(info.service.getPackageName())
                .append(" user=")
                .append(info.userId)
                .append(", class=")
                .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 java.lang.StringtoString()

        return dump(null, true);
    
public voidupdateEffectiveRunTime()
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 SyncManager on soft failures).

        // Regardless of whether we're in backoff or honouring a delayUntil, we still incorporate
        // the flex time provided by the developer.
        effectiveRunTime = ignoreBackoff() ?
                latestRunTime :
                    Math.max(Math.max(latestRunTime, delayUntil), backoff);
    
public java.lang.StringwakeLockName()

        if (wakeLockName != null) {
            return wakeLockName;
        }
        if (target.target_provider) {
            return (wakeLockName = target.provider
                    + "/" + target.account.type
                    + "/" + target.account.name);
        } else if (target.target_service) {
            return (wakeLockName = target.service.getPackageName()
                    + "/" + target.service.getClassName());
        } else {
            Log.wtf(TAG, "Invalid target getting wakelock name for operation - " + key);
            return null;
        }