From bd4c3ea7ae57f43dbaca6456f9a2853d2e7d827d Mon Sep 17 00:00:00 2001 From: Shreyas Basarge Date: Thu, 16 Jun 2016 11:54:35 +0100 Subject: [PATCH] Fix for the missing sync bug Cancel a job before re-scheduling it to avoid the situation where a job could still be in JobScheduler's pending queue. Retry a sync even if it has specified the do_not_retry extra if the sync failed due to SyncAlreadyInProgress. Bug: 27532761 Change-Id: Ia5d2b31fa4e44560a3f170a2bdbf53151bff7a20 --- .../android/server/content/SyncManager.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 493fc4a4bb8ca..39ddc3a98317c 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -1355,7 +1355,11 @@ public class SyncManager { operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); } - if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)) { + if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false) + && !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. if (isLoggable) { Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified " + operation); @@ -2445,6 +2449,10 @@ public class SyncManager { if (op.isPeriodic) { scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay); } else { + // mSyncJobService.callJobFinished is async, so cancel the job to ensure we don't + // find the this job in the pending jobs list while looking for duplicates + // before scheduling it at a later time. + getJobScheduler().cancel(op.jobId); scheduleSyncOperationH(op, delay); } } @@ -2886,6 +2894,14 @@ public class SyncManager { String historyMessage; int downstreamActivity; int upstreamActivity; + + if (!syncOperation.isPeriodic) { + // mSyncJobService.jobFinidhed is async, we need to ensure that this job is + // removed from JobScheduler's pending jobs list before moving forward and + // potentially rescheduling all pending jobs to respect new backoff values. + getJobScheduler().cancel(syncOperation.jobId); + } + if (syncResult != null) { if (isLoggable) { Slog.v(TAG, "runSyncFinishedOrCanceled [finished]: "