SyncOperationpublic class SyncOperation extends Object implements ComparableValue 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_SYNCABLESync started because it has just been set to isSyncable. | public static final int | REASON_SYNC_AUTOSync started because it has just been set to sync automatically. | public static final int | REASON_MASTER_SYNC_AUTOSync 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 | targetIdentifying info for the target for this operation. | public final int | reasonWhy this sync was kicked off. {@link #REASON_NAMES} | public final int | syncSourceWhere this sync was initiated. | public final boolean | allowParallelSyncs | public final String | key | private final boolean | expeditedInternal boolean to avoid reading a bundle everytime we want to compare operations. | public android.os.Bundle | extras | public SyncStorageEngine.PendingOperation | pendingOperationBare-bones version of this operation that is persisted across reboots. | public long | latestRunTimeElapsed real time in millis at which to run this sync. | public long | backoffSet by the SyncManager in order to delay retries. | public long | delayUntilSpecified by the adapter to delay subsequent sync operations. | public long | effectiveRunTimeElapsed real time in millis when this sync will be run.
Depends on max(backoff, latestRunTime, and delayUntil). | public long | flexTimeAmount of time before {@link #effectiveRunTime} from which this sync can run. | public String | wakeLockNameDescriptive 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 void | cleanBundle(android.os.Bundle bundle)Make sure the bundle attached to this SyncOperation doesn't have unnecessary
flags set.
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 int | compareTo(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.String | dump(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 void | extrasToStringBuilder(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 boolean | ignoreBackoff()
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
| public boolean | isConflict(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 boolean | isExpedited()
return expedited;
| public boolean | isIgnoreSettings()
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
| public boolean | isInitialization()
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
| public boolean | isManual()
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
| public boolean | isNotAllowedOnMetered()
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
| public boolean | matchesAuthority(com.android.server.content.SyncOperation other)
return this.target.matchesSpec(other.target);
| public static java.lang.String | reasonToString(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 void | removeFalseExtra(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.String | toKey(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.String | toString()
return dump(null, true);
| public void | updateEffectiveRunTime()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.String | wakeLockName()
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;
}
|
|