Loading services/core/java/com/android/server/content/SyncManager.java +20 −26 Original line number Diff line number Diff line Loading @@ -1216,7 +1216,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target)) { periodicSyncs.add(new PeriodicSync(op.target.account, op.target.provider, op.extras, op.periodMillis / 1000, op.flexMillis / 1000)); op.getClonedExtras(), op.periodMillis / 1000, op.flexMillis / 1000)); } } Loading Loading @@ -1478,7 +1478,7 @@ public class SyncManager { Slog.e(TAG, "Can't schedule null sync operation."); return; } if (!syncOperation.ignoreBackoff()) { if (!syncOperation.hasIgnoreBackoff()) { Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(syncOperation.target); if (backoff == null) { Slog.e(TAG, "Couldn't find backoff values for " Loading Loading @@ -1631,7 +1631,7 @@ public class SyncManager { getSyncStorageEngine().markPending(syncOperation.target, true); } if (syncOperation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING)) { if (syncOperation.hasRequireCharging()) { b.setRequiresCharging(true); } Loading Loading @@ -1686,7 +1686,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(info) && syncExtrasEquals(extras, op.extras, false)) { && op.areExtrasEqual(extras, /*includeSyncSettings=*/ false)) { cancelJob(op, "cancelScheduledSyncOperation"); } } Loading @@ -1704,15 +1704,9 @@ public class SyncManager { Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", " + operation); } // The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given // request. Retries of the request will always honor the backoff, so clear the // flag in case we retry this request. if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)) { operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); } operation.enableBackoff(); if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false) && !syncResult.syncAlreadyInProgress) { if (operation.hasDoNotRetry() && !syncResult.syncAlreadyInProgress) { // syncAlreadyInProgress flag is set by AbstractThreadedSyncAdapter. The sync adapter // has no way of knowing that a sync error occured. So we DO retry if the error is // syncAlreadyInProgress. Loading @@ -1720,10 +1714,9 @@ public class SyncManager { Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified " + operation); } } else if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false) && !syncResult.syncAlreadyInProgress) { } else if (operation.isUpload() && !syncResult.syncAlreadyInProgress) { // If this was an upward sync then schedule a two-way sync immediately. operation.extras.remove(ContentResolver.SYNC_EXTRAS_UPLOAD); operation.enableTwoWaySync(); if (isLoggable) { Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync " + "encountered an error: " + operation); Loading Loading @@ -3326,7 +3319,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target) && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) { && op.areExtrasEqual(extras, /*includeSyncSettings=*/ true)) { maybeUpdateSyncPeriodH(op, pollFrequencyMillis, flexMillis); return; } Loading Loading @@ -3408,7 +3401,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target) && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) { && op.areExtrasEqual(extras, /*includeSyncSettings=*/ true)) { removePeriodicSyncInternalH(op, why); } } Loading Loading @@ -3559,16 +3552,18 @@ public class SyncManager { activeSyncContext.mIsLinkedToDeath = true; syncAdapter.linkToDeath(activeSyncContext, 0); if (mLogger.enabled()) { mLogger.log("Sync start: account=" + syncOperation.target.account, " authority=", syncOperation.target.provider, " reason=", SyncOperation.reasonToString(null, syncOperation.reason), " extras=", SyncOperation.extrasToString(syncOperation.extras), " extras=", syncOperation.getExtrasAsString(), " adapter=", activeSyncContext.mSyncAdapter); } activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter); activeSyncContext.mSyncAdapter .startSync(activeSyncContext, syncOperation.target.provider, syncOperation.target.account, syncOperation.extras); syncOperation.target.account, syncOperation.getClonedExtras()); mLogger.log("Sync is running now..."); } catch (RemoteException remoteExc) { Loading Loading @@ -3602,9 +3597,8 @@ public class SyncManager { continue; } if (extras != null && !syncExtrasEquals(activeSyncContext.mSyncOperation.extras, extras, false /* no config settings */)) { !activeSyncContext.mSyncOperation.areExtrasEqual(extras, /*includeSyncSettings=*/ false)) { continue; } SyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false, Loading services/core/java/com/android/server/content/SyncOperation.java +90 −19 Original line number Diff line number Diff line Loading @@ -74,7 +74,14 @@ public class SyncOperation { /** Where this sync was initiated. */ public final int syncSource; public final boolean allowParallelSyncs; public final Bundle extras; /** * Sync extras. Note, DO NOT modify this bundle directly. When changing the content, always * create a copy, update it, set it in this field. This is to avoid concurrent modifications * when other threads are reading it. */ private volatile Bundle mImmutableExtras; public final boolean isPeriodic; /** jobId of the periodic SyncOperation that initiated this one */ public final int sourcePeriodicId; Loading Loading @@ -118,12 +125,13 @@ public class SyncOperation { public SyncOperation(SyncOperation op, long periodMillis, long flexMillis) { this(op.target, op.owningUid, op.owningPackage, op.reason, op.syncSource, new Bundle(op.extras), op.allowParallelSyncs, op.isPeriodic, op.sourcePeriodicId, op.mImmutableExtras, op.allowParallelSyncs, op.isPeriodic, op.sourcePeriodicId, periodMillis, flexMillis, ContentResolver.SYNC_EXEMPTION_NONE); } public SyncOperation(SyncStorageEngine.EndPoint info, int owningUid, String owningPackage, int reason, int source, Bundle extras, boolean allowParallelSyncs, int reason, int source, Bundle extras, boolean allowParallelSyncs, boolean isPeriodic, int sourcePeriodicId, long periodMillis, long flexMillis, @SyncExemption int syncExemptionFlag) { this.target = info; Loading @@ -131,7 +139,7 @@ public class SyncOperation { this.owningPackage = owningPackage; this.reason = reason; this.syncSource = source; this.extras = new Bundle(extras); this.mImmutableExtras = new Bundle(extras); this.allowParallelSyncs = allowParallelSyncs; this.isPeriodic = isPeriodic; this.sourcePeriodicId = sourcePeriodicId; Loading @@ -148,7 +156,7 @@ public class SyncOperation { return null; } SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, syncSource, new Bundle(extras), allowParallelSyncs, false, jobId /* sourcePeriodicId */, mImmutableExtras, allowParallelSyncs, false, jobId /* sourcePeriodicId */, periodMillis, flexMillis, ContentResolver.SYNC_EXEMPTION_NONE); return op; } Loading @@ -160,7 +168,10 @@ public class SyncOperation { reason = other.reason; syncSource = other.syncSource; allowParallelSyncs = other.allowParallelSyncs; extras = new Bundle(other.extras); // Since we treat this field as immutable, it's okay to use a shallow copy here. // No need to create a copy. mImmutableExtras = other.mImmutableExtras; wakeLockName = other.wakeLockName(); isPeriodic = other.isPeriodic; sourcePeriodicId = other.sourcePeriodicId; Loading @@ -173,7 +184,8 @@ public class SyncOperation { /** * All fields are stored in a corresponding key in the persistable bundle. * * {@link #extras} is a Bundle and can contain parcelable objects. But only the type Account * {@link #mImmutableExtras} is a Bundle and can contain parcelable objects. * But only the type Account * is allowed {@link ContentResolver#validateSyncExtrasBundle(Bundle)} that can't be stored in * a PersistableBundle. For every value of type Account with key 'key', we store a * PersistableBundle containing account information at key 'ACCOUNT:key'. The Account object Loading @@ -188,6 +200,8 @@ public class SyncOperation { PersistableBundle jobInfoExtras = new PersistableBundle(); PersistableBundle syncExtrasBundle = new PersistableBundle(); final Bundle extras = mImmutableExtras; for (String key : extras.keySet()) { Object value = extras.get(key); if (value instanceof Account) { Loading Loading @@ -327,7 +341,7 @@ public class SyncOperation { boolean matchesPeriodicOperation(SyncOperation other) { return target.matchesSpec(other.target) && SyncManager.syncExtrasEquals(extras, other.extras, true) && SyncManager.syncExtrasEquals(mImmutableExtras, other.mImmutableExtras, true) && periodMillis == other.periodMillis && flexMillis == other.flexMillis; } Loading @@ -345,6 +359,7 @@ public class SyncOperation { } private String toKey() { final Bundle extras = mImmutableExtras; StringBuilder sb = new StringBuilder(); sb.append("provider: ").append(target.provider); sb.append(" account {name=" + target.account.name Loading Loading @@ -372,6 +387,7 @@ public class SyncOperation { String dump(PackageManager pm, boolean shorter, SyncAdapterStateFetcher appStates, boolean logSafe) { final Bundle extras = mImmutableExtras; StringBuilder sb = new StringBuilder(); sb.append("JobId=").append(jobId) .append(" ") Loading Loading @@ -468,33 +484,67 @@ public class SyncOperation { } boolean isInitialization() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); } boolean isExpedited() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); } boolean isUpload() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false); } /** * Disable SYNC_EXTRAS_UPLOAD, so it will be a two-way (normal) sync. */ void enableTwoWaySync() { removeExtra(ContentResolver.SYNC_EXTRAS_UPLOAD); } boolean hasIgnoreBackoff() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); } /** * Disable SYNC_EXTRAS_IGNORE_BACKOFF. * * The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given * request. Retries of the request will always honor the backoff, so clear the * flag in case we retry this request. */ void enableBackoff() { removeExtra(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); } boolean ignoreBackoff() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); boolean hasDoNotRetry() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false); } boolean isNotAllowedOnMetered() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false); } boolean isManual() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); } boolean isIgnoreSettings() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); } boolean hasRequireCharging() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, false); } boolean isAppStandbyExempted() { return syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE; } boolean areExtrasEqual(Bundle other, boolean includeSyncSettings) { return SyncManager.syncExtrasEquals(mImmutableExtras, other, includeSyncSettings); } static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) { if (bundle == null) { sb.append("null"); Loading @@ -507,7 +557,7 @@ public class SyncOperation { sb.append("]"); } static String extrasToString(Bundle bundle) { private static String extrasToString(Bundle bundle) { final StringBuilder sb = new StringBuilder(); extrasToStringBuilder(bundle, sb); return sb.toString(); Loading @@ -531,4 +581,25 @@ public class SyncOperation { logArray[3] = target.account.name.hashCode(); return logArray; } /** * Removes a sync extra. Note do not call it from multiple threads simultaneously. */ private void removeExtra(String key) { final Bundle b = mImmutableExtras; if (!b.containsKey(key)) { return; } final Bundle clone = new Bundle(b); clone.remove(key); mImmutableExtras = clone; } public Bundle getClonedExtras() { return new Bundle(mImmutableExtras); } public String getExtrasAsString() { return extrasToString(mImmutableExtras); } } services/core/java/com/android/server/content/SyncStorageEngine.java +3 −3 Original line number Diff line number Diff line Loading @@ -137,7 +137,7 @@ public class SyncStorageEngine { /** * String names for the sync source types. * * KEEP THIS AND {@link SyncStatusInfo#SOURCE_COUNT} IN SYNC. * KEEP THIS AND {@link SyncStatusInfo}.SOURCE_COUNT IN SYNC. */ public static final String[] SOURCES = { "OTHER", Loading Loading @@ -1117,7 +1117,7 @@ public class SyncStorageEngine { Slog.v(TAG, "setActiveSync: account=" + " auth=" + activeSyncContext.mSyncOperation.target + " src=" + activeSyncContext.mSyncOperation.syncSource + " extras=" + activeSyncContext.mSyncOperation.extras); + " extras=" + activeSyncContext.mSyncOperation.getExtrasAsString()); } final EndPoint info = activeSyncContext.mSyncOperation.target; AuthorityInfo authorityInfo = getOrCreateAuthorityLocked( Loading Loading @@ -1179,7 +1179,7 @@ public class SyncStorageEngine { item.eventTime = now; item.source = op.syncSource; item.reason = op.reason; item.extras = op.extras; item.extras = op.getClonedExtras(); item.event = EVENT_START; item.syncExemptionFlag = op.syncExemptionFlag; mSyncHistory.add(0, item); Loading services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -124,8 +124,9 @@ public class SyncOperationTest extends AndroidTestCase { SyncOperation op2 = SyncOperation.maybeCreateFromJobExtras(pb); assertTrue("Account fields in extras not persisted.", account1.equals(op2.extras.get("acc"))); assertTrue("Fields in extras not persisted", "String".equals(op2.extras.getString("str"))); account1.equals(op2.getClonedExtras().get("acc"))); assertTrue("Fields in extras not persisted", "String".equals( op2.getClonedExtras().getString("str"))); } @SmallTest Loading Loading
services/core/java/com/android/server/content/SyncManager.java +20 −26 Original line number Diff line number Diff line Loading @@ -1216,7 +1216,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target)) { periodicSyncs.add(new PeriodicSync(op.target.account, op.target.provider, op.extras, op.periodMillis / 1000, op.flexMillis / 1000)); op.getClonedExtras(), op.periodMillis / 1000, op.flexMillis / 1000)); } } Loading Loading @@ -1478,7 +1478,7 @@ public class SyncManager { Slog.e(TAG, "Can't schedule null sync operation."); return; } if (!syncOperation.ignoreBackoff()) { if (!syncOperation.hasIgnoreBackoff()) { Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(syncOperation.target); if (backoff == null) { Slog.e(TAG, "Couldn't find backoff values for " Loading Loading @@ -1631,7 +1631,7 @@ public class SyncManager { getSyncStorageEngine().markPending(syncOperation.target, true); } if (syncOperation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING)) { if (syncOperation.hasRequireCharging()) { b.setRequiresCharging(true); } Loading Loading @@ -1686,7 +1686,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(info) && syncExtrasEquals(extras, op.extras, false)) { && op.areExtrasEqual(extras, /*includeSyncSettings=*/ false)) { cancelJob(op, "cancelScheduledSyncOperation"); } } Loading @@ -1704,15 +1704,9 @@ public class SyncManager { Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", " + operation); } // The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given // request. Retries of the request will always honor the backoff, so clear the // flag in case we retry this request. if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)) { operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); } operation.enableBackoff(); if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false) && !syncResult.syncAlreadyInProgress) { if (operation.hasDoNotRetry() && !syncResult.syncAlreadyInProgress) { // syncAlreadyInProgress flag is set by AbstractThreadedSyncAdapter. The sync adapter // has no way of knowing that a sync error occured. So we DO retry if the error is // syncAlreadyInProgress. Loading @@ -1720,10 +1714,9 @@ public class SyncManager { Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified " + operation); } } else if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false) && !syncResult.syncAlreadyInProgress) { } else if (operation.isUpload() && !syncResult.syncAlreadyInProgress) { // If this was an upward sync then schedule a two-way sync immediately. operation.extras.remove(ContentResolver.SYNC_EXTRAS_UPLOAD); operation.enableTwoWaySync(); if (isLoggable) { Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync " + "encountered an error: " + operation); Loading Loading @@ -3326,7 +3319,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target) && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) { && op.areExtrasEqual(extras, /*includeSyncSettings=*/ true)) { maybeUpdateSyncPeriodH(op, pollFrequencyMillis, flexMillis); return; } Loading Loading @@ -3408,7 +3401,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target) && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) { && op.areExtrasEqual(extras, /*includeSyncSettings=*/ true)) { removePeriodicSyncInternalH(op, why); } } Loading Loading @@ -3559,16 +3552,18 @@ public class SyncManager { activeSyncContext.mIsLinkedToDeath = true; syncAdapter.linkToDeath(activeSyncContext, 0); if (mLogger.enabled()) { mLogger.log("Sync start: account=" + syncOperation.target.account, " authority=", syncOperation.target.provider, " reason=", SyncOperation.reasonToString(null, syncOperation.reason), " extras=", SyncOperation.extrasToString(syncOperation.extras), " extras=", syncOperation.getExtrasAsString(), " adapter=", activeSyncContext.mSyncAdapter); } activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter); activeSyncContext.mSyncAdapter .startSync(activeSyncContext, syncOperation.target.provider, syncOperation.target.account, syncOperation.extras); syncOperation.target.account, syncOperation.getClonedExtras()); mLogger.log("Sync is running now..."); } catch (RemoteException remoteExc) { Loading Loading @@ -3602,9 +3597,8 @@ public class SyncManager { continue; } if (extras != null && !syncExtrasEquals(activeSyncContext.mSyncOperation.extras, extras, false /* no config settings */)) { !activeSyncContext.mSyncOperation.areExtrasEqual(extras, /*includeSyncSettings=*/ false)) { continue; } SyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false, Loading
services/core/java/com/android/server/content/SyncOperation.java +90 −19 Original line number Diff line number Diff line Loading @@ -74,7 +74,14 @@ public class SyncOperation { /** Where this sync was initiated. */ public final int syncSource; public final boolean allowParallelSyncs; public final Bundle extras; /** * Sync extras. Note, DO NOT modify this bundle directly. When changing the content, always * create a copy, update it, set it in this field. This is to avoid concurrent modifications * when other threads are reading it. */ private volatile Bundle mImmutableExtras; public final boolean isPeriodic; /** jobId of the periodic SyncOperation that initiated this one */ public final int sourcePeriodicId; Loading Loading @@ -118,12 +125,13 @@ public class SyncOperation { public SyncOperation(SyncOperation op, long periodMillis, long flexMillis) { this(op.target, op.owningUid, op.owningPackage, op.reason, op.syncSource, new Bundle(op.extras), op.allowParallelSyncs, op.isPeriodic, op.sourcePeriodicId, op.mImmutableExtras, op.allowParallelSyncs, op.isPeriodic, op.sourcePeriodicId, periodMillis, flexMillis, ContentResolver.SYNC_EXEMPTION_NONE); } public SyncOperation(SyncStorageEngine.EndPoint info, int owningUid, String owningPackage, int reason, int source, Bundle extras, boolean allowParallelSyncs, int reason, int source, Bundle extras, boolean allowParallelSyncs, boolean isPeriodic, int sourcePeriodicId, long periodMillis, long flexMillis, @SyncExemption int syncExemptionFlag) { this.target = info; Loading @@ -131,7 +139,7 @@ public class SyncOperation { this.owningPackage = owningPackage; this.reason = reason; this.syncSource = source; this.extras = new Bundle(extras); this.mImmutableExtras = new Bundle(extras); this.allowParallelSyncs = allowParallelSyncs; this.isPeriodic = isPeriodic; this.sourcePeriodicId = sourcePeriodicId; Loading @@ -148,7 +156,7 @@ public class SyncOperation { return null; } SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, syncSource, new Bundle(extras), allowParallelSyncs, false, jobId /* sourcePeriodicId */, mImmutableExtras, allowParallelSyncs, false, jobId /* sourcePeriodicId */, periodMillis, flexMillis, ContentResolver.SYNC_EXEMPTION_NONE); return op; } Loading @@ -160,7 +168,10 @@ public class SyncOperation { reason = other.reason; syncSource = other.syncSource; allowParallelSyncs = other.allowParallelSyncs; extras = new Bundle(other.extras); // Since we treat this field as immutable, it's okay to use a shallow copy here. // No need to create a copy. mImmutableExtras = other.mImmutableExtras; wakeLockName = other.wakeLockName(); isPeriodic = other.isPeriodic; sourcePeriodicId = other.sourcePeriodicId; Loading @@ -173,7 +184,8 @@ public class SyncOperation { /** * All fields are stored in a corresponding key in the persistable bundle. * * {@link #extras} is a Bundle and can contain parcelable objects. But only the type Account * {@link #mImmutableExtras} is a Bundle and can contain parcelable objects. * But only the type Account * is allowed {@link ContentResolver#validateSyncExtrasBundle(Bundle)} that can't be stored in * a PersistableBundle. For every value of type Account with key 'key', we store a * PersistableBundle containing account information at key 'ACCOUNT:key'. The Account object Loading @@ -188,6 +200,8 @@ public class SyncOperation { PersistableBundle jobInfoExtras = new PersistableBundle(); PersistableBundle syncExtrasBundle = new PersistableBundle(); final Bundle extras = mImmutableExtras; for (String key : extras.keySet()) { Object value = extras.get(key); if (value instanceof Account) { Loading Loading @@ -327,7 +341,7 @@ public class SyncOperation { boolean matchesPeriodicOperation(SyncOperation other) { return target.matchesSpec(other.target) && SyncManager.syncExtrasEquals(extras, other.extras, true) && SyncManager.syncExtrasEquals(mImmutableExtras, other.mImmutableExtras, true) && periodMillis == other.periodMillis && flexMillis == other.flexMillis; } Loading @@ -345,6 +359,7 @@ public class SyncOperation { } private String toKey() { final Bundle extras = mImmutableExtras; StringBuilder sb = new StringBuilder(); sb.append("provider: ").append(target.provider); sb.append(" account {name=" + target.account.name Loading Loading @@ -372,6 +387,7 @@ public class SyncOperation { String dump(PackageManager pm, boolean shorter, SyncAdapterStateFetcher appStates, boolean logSafe) { final Bundle extras = mImmutableExtras; StringBuilder sb = new StringBuilder(); sb.append("JobId=").append(jobId) .append(" ") Loading Loading @@ -468,33 +484,67 @@ public class SyncOperation { } boolean isInitialization() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); } boolean isExpedited() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); } boolean isUpload() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false); } /** * Disable SYNC_EXTRAS_UPLOAD, so it will be a two-way (normal) sync. */ void enableTwoWaySync() { removeExtra(ContentResolver.SYNC_EXTRAS_UPLOAD); } boolean hasIgnoreBackoff() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); } /** * Disable SYNC_EXTRAS_IGNORE_BACKOFF. * * The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given * request. Retries of the request will always honor the backoff, so clear the * flag in case we retry this request. */ void enableBackoff() { removeExtra(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); } boolean ignoreBackoff() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); boolean hasDoNotRetry() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false); } boolean isNotAllowedOnMetered() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false); } boolean isManual() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); } boolean isIgnoreSettings() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); } boolean hasRequireCharging() { return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, false); } boolean isAppStandbyExempted() { return syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE; } boolean areExtrasEqual(Bundle other, boolean includeSyncSettings) { return SyncManager.syncExtrasEquals(mImmutableExtras, other, includeSyncSettings); } static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) { if (bundle == null) { sb.append("null"); Loading @@ -507,7 +557,7 @@ public class SyncOperation { sb.append("]"); } static String extrasToString(Bundle bundle) { private static String extrasToString(Bundle bundle) { final StringBuilder sb = new StringBuilder(); extrasToStringBuilder(bundle, sb); return sb.toString(); Loading @@ -531,4 +581,25 @@ public class SyncOperation { logArray[3] = target.account.name.hashCode(); return logArray; } /** * Removes a sync extra. Note do not call it from multiple threads simultaneously. */ private void removeExtra(String key) { final Bundle b = mImmutableExtras; if (!b.containsKey(key)) { return; } final Bundle clone = new Bundle(b); clone.remove(key); mImmutableExtras = clone; } public Bundle getClonedExtras() { return new Bundle(mImmutableExtras); } public String getExtrasAsString() { return extrasToString(mImmutableExtras); } }
services/core/java/com/android/server/content/SyncStorageEngine.java +3 −3 Original line number Diff line number Diff line Loading @@ -137,7 +137,7 @@ public class SyncStorageEngine { /** * String names for the sync source types. * * KEEP THIS AND {@link SyncStatusInfo#SOURCE_COUNT} IN SYNC. * KEEP THIS AND {@link SyncStatusInfo}.SOURCE_COUNT IN SYNC. */ public static final String[] SOURCES = { "OTHER", Loading Loading @@ -1117,7 +1117,7 @@ public class SyncStorageEngine { Slog.v(TAG, "setActiveSync: account=" + " auth=" + activeSyncContext.mSyncOperation.target + " src=" + activeSyncContext.mSyncOperation.syncSource + " extras=" + activeSyncContext.mSyncOperation.extras); + " extras=" + activeSyncContext.mSyncOperation.getExtrasAsString()); } final EndPoint info = activeSyncContext.mSyncOperation.target; AuthorityInfo authorityInfo = getOrCreateAuthorityLocked( Loading Loading @@ -1179,7 +1179,7 @@ public class SyncStorageEngine { item.eventTime = now; item.source = op.syncSource; item.reason = op.reason; item.extras = op.extras; item.extras = op.getClonedExtras(); item.event = EVENT_START; item.syncExemptionFlag = op.syncExemptionFlag; mSyncHistory.add(0, item); Loading
services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -124,8 +124,9 @@ public class SyncOperationTest extends AndroidTestCase { SyncOperation op2 = SyncOperation.maybeCreateFromJobExtras(pb); assertTrue("Account fields in extras not persisted.", account1.equals(op2.extras.get("acc"))); assertTrue("Fields in extras not persisted", "String".equals(op2.extras.getString("str"))); account1.equals(op2.getClonedExtras().get("acc"))); assertTrue("Fields in extras not persisted", "String".equals( op2.getClonedExtras().getString("str"))); } @SmallTest Loading