diff options
| author | 2012-05-06 15:25:47 -0700 | |
|---|---|---|
| committer | 2012-05-06 15:25:47 -0700 | |
| commit | 989c753281fcb689ea163530096ac589c9e5a44f (patch) | |
| tree | e3bc8acfa35b787a6ea1f9cec3e431910076db83 | |
| parent | 2551e5a1d9990514d8116e352b8e5c2f10a9d303 (diff) | |
| parent | dc47556cb37b6f25faceb5eb97cef60d384b55fb (diff) | |
Merge "fix expedited syncs. there were times when an expedited sync wouldn't correctly preempt non-expedited syncs" into jb-dev
4 files changed, 48 insertions, 22 deletions
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 34c40a0be54d..badcb03a0e4a 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -17,7 +17,6 @@ package android.content; import com.android.internal.R; -import com.android.internal.util.ArrayUtils; import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -32,7 +31,6 @@ import android.app.AppGlobals; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; -import android.app.DownloadManager.Request; import android.content.SyncStorageEngine.OnSyncRequestListener; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -1998,6 +1996,7 @@ public class SyncManager implements OnAccountsUpdateListener { ActiveSyncContext conflict = null; ActiveSyncContext longRunning = null; ActiveSyncContext toReschedule = null; + ActiveSyncContext oldestNonExpeditedRegular = null; for (ActiveSyncContext activeSyncContext : mActiveSyncContexts) { final SyncOperation activeOp = activeSyncContext.mSyncOperation; @@ -2005,6 +2004,13 @@ public class SyncManager implements OnAccountsUpdateListener { numInit++; } else { numRegular++; + if (!activeOp.isExpedited()) { + if (oldestNonExpeditedRegular == null + || (oldestNonExpeditedRegular.mStartTime + > activeSyncContext.mStartTime)) { + oldestNonExpeditedRegular = activeSyncContext; + } + } } if (activeOp.account.type.equals(candidate.account.type) && activeOp.authority.equals(candidate.authority) @@ -2027,8 +2033,13 @@ public class SyncManager implements OnAccountsUpdateListener { Log.v(TAG, " numActiveInit=" + numInit + ", numActiveRegular=" + numRegular); Log.v(TAG, " longRunning: " + longRunning); Log.v(TAG, " conflict: " + conflict); + Log.v(TAG, " oldestNonExpeditedRegular: " + oldestNonExpeditedRegular); } + final boolean roomAvailable = candidateIsInitialization + ? numInit < MAX_SIMULTANEOUS_INITIALIZATION_SYNCS + : numRegular < MAX_SIMULTANEOUS_REGULAR_SYNCS; + if (conflict != null) { if (candidateIsInitialization && !conflict.mSyncOperation.isInitialization() && numInit < MAX_SIMULTANEOUS_INITIALIZATION_SYNCS) { @@ -2048,23 +2059,32 @@ public class SyncManager implements OnAccountsUpdateListener { } else { continue; } - } else { - final boolean roomAvailable = candidateIsInitialization - ? numInit < MAX_SIMULTANEOUS_INITIALIZATION_SYNCS - : numRegular < MAX_SIMULTANEOUS_REGULAR_SYNCS; - if (roomAvailable) { - // dispatch candidate - } else if (longRunning != null - && (candidateIsInitialization - == longRunning.mSyncOperation.isInitialization())) { - toReschedule = longRunning; - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "canceling and rescheduling sync since it ran roo long, " - + longRunning); - } - } else { - continue; + } else if (roomAvailable) { + // dispatch candidate + } else if (candidate.isExpedited() && oldestNonExpeditedRegular != null + && !candidateIsInitialization) { + // We found an active, non-expedited regular sync. We also know that the + // candidate doesn't conflict with this active sync since conflict + // is null. Reschedule the active sync and start the candidate. + toReschedule = oldestNonExpeditedRegular; + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to run, " + + oldestNonExpeditedRegular); } + } else if (longRunning != null + && (candidateIsInitialization + == longRunning.mSyncOperation.isInitialization())) { + // We found an active, long-running sync. Reschedule the active + // sync and start the candidate. + toReschedule = longRunning; + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "canceling and rescheduling sync since it ran roo long, " + + longRunning); + } + } else { + // we were unable to find or make space to run this candidate, go on to + // the next one + continue; } if (toReschedule != null) { @@ -2516,7 +2536,7 @@ public class SyncManager implements OnAccountsUpdateListener { return mSyncStorageEngine.insertStartSyncEvent( syncOperation.account, syncOperation.userId, syncOperation.authority, - now, source); + now, source, syncOperation.isInitialization()); } public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage, diff --git a/core/java/android/content/SyncOperation.java b/core/java/android/content/SyncOperation.java index 4e86ef8a2eb2..9fcc22d3f942 100644 --- a/core/java/android/content/SyncOperation.java +++ b/core/java/android/content/SyncOperation.java @@ -116,6 +116,10 @@ public class SyncOperation implements Comparable { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); } + public boolean isExpedited() { + return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); + } + public boolean ignoreBackoff() { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); } diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java index d821918766ba..6c7e9404901a 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/core/java/android/content/SyncStorageEngine.java @@ -221,6 +221,7 @@ public class SyncStorageEngine extends Handler { long upstreamActivity; long downstreamActivity; String mesg; + boolean initialization; } public static class DayStats { @@ -1012,7 +1013,7 @@ public class SyncStorageEngine extends Handler { * Note that sync has started for the given account and authority. */ public long insertStartSyncEvent(Account accountName, int userId, String authorityName, - long now, int source) { + long now, int source, boolean initialization) { long id; synchronized (mAuthorities) { if (Log.isLoggable(TAG, Log.VERBOSE)) { @@ -1025,6 +1026,7 @@ public class SyncStorageEngine extends Handler { return -1; } SyncHistoryItem item = new SyncHistoryItem(); + item.initialization = initialization; item.authorityId = authority.ident; item.historyId = mNextHistoryId++; if (mNextHistoryId < 0) mNextHistoryId = 0; diff --git a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java b/core/tests/coretests/src/android/content/SyncStorageEngineTest.java index 96f313a1e29f..2add623970c6 100644 --- a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java +++ b/core/tests/coretests/src/android/content/SyncStorageEngineTest.java @@ -20,7 +20,6 @@ import com.android.internal.os.AtomicFile; import android.accounts.Account; import android.os.Bundle; -import android.os.Debug; import android.test.AndroidTestCase; import android.test.RenamingDelegatingContext; import android.test.mock.MockContentResolver; @@ -57,7 +56,8 @@ public class SyncStorageEngineTest extends AndroidTestCase { long time0 = 1000; long historyId = engine.insertStartSyncEvent( - account, 0, authority, time0, SyncStorageEngine.SOURCE_LOCAL); + account, 0, authority, time0, SyncStorageEngine.SOURCE_LOCAL, + false /* initialization */); long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2; engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0); } |