Pending op fix didn't merge properly from KLP-dev.
Manually merge in Cl c/342668. Add another test to ensure that it
WAI.
Change-Id: Iae603328d525cc71e4e31ad30a13384efc50f823
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index 713e599..1722f76 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -547,6 +547,7 @@
if (isLoggable) {
Log.d(TAG, "one off sync for: " + cname + " " + extras.toString());
}
+
Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
if (expedited) {
runtimeMillis = -1; // this means schedule at the front of the queue
diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
index f843a62..1d8ca5a 100644
--- a/services/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -362,6 +362,12 @@
periodicSyncs.add(defaultSync);
}
}
+
+ @Override
+ public String toString() {
+ return target + ", enabled=" + enabled + ", syncable=" + syncable + ", backoff="
+ + backoffTime + ", delay=" + delayUntil;
+ }
}
public static class SyncHistoryItem {
@@ -1084,7 +1090,7 @@
pop = new PendingOperation(authority, op.reason, op.syncSource, op.extras,
op.expedited);
mPendingOperations.add(pop);
- writePendingOperationsLocked();
+ appendPendingOperationLocked(pop);
SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
status.pending = true;
@@ -2416,6 +2422,9 @@
}
try {
fis = mPendingFile.openRead();
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, "Reading " + mPendingFile.getBaseFile());
+ }
XmlPullParser parser;
parser = Xml.newPullParser();
parser.setInput(fis, null);
@@ -2427,12 +2436,11 @@
}
if (eventType == XmlPullParser.END_DOCUMENT) return; // Nothing to read.
- String tagName = parser.getName();
do {
PendingOperation pop = null;
if (eventType == XmlPullParser.START_TAG) {
try {
- tagName = parser.getName();
+ String tagName = parser.getName();
if (parser.getDepth() == 1 && "op".equals(tagName)) {
// Verify version.
String versionString =
@@ -2556,17 +2564,11 @@
fos = mPendingFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
out.setOutput(fos, "utf-8");
- out.startDocument(null, true);
- out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
- out.startTag(null, "pending");
- out.attribute(null, "version", Integer.toString(PENDING_OPERATION_VERSION));
for (int i = 0; i < N; i++) {
PendingOperation pop = mPendingOperations.get(i);
writePendingOperationLocked(pop, out);
}
- out.endTag(null, "pending");
out.endDocument();
mPendingFile.finishWrite(fos);
} catch (java.io.IOException e1) {
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index d328a30..0354ffd 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -46,6 +46,7 @@
public class SyncStorageEngineTest extends AndroidTestCase {
protected Account account1;
+ protected Account account2;
protected ComponentName syncService1;
protected String authority1 = "testprovider";
protected Bundle defaultBundle;
@@ -67,6 +68,7 @@
@Override
public void setUp() {
account1 = new Account("a@example.com", "example.type");
+ account2 = new Account("b@example.com", "example.type");
syncService1 = new ComponentName("com.example", "SyncService");
// Default bundle.
defaultBundle = new Bundle();
@@ -98,7 +100,7 @@
SyncOperation.REASON_PERIODIC,
SyncStorageEngine.SOURCE_LOCAL,
authority,
- null, time0, 0 /* flex*/, 0, 0, true);
+ Bundle.EMPTY, time0, 0 /* flex*/, 0, 0, true);
long historyId = engine.insertStartSyncEvent(op, time0);
long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
@@ -108,11 +110,11 @@
* Test persistence of pending operations.
*/
@MediumTest
- public void testPending() throws Exception {
+ public void testAppendPending() throws Exception {
SyncOperation sop = new SyncOperation(account1,
DEFAULT_USER,
SyncOperation.REASON_PERIODIC,
- SyncStorageEngine.SOURCE_LOCAL, authority1, null,
+ SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
0 /* runtime */, 0 /* flex */, 0 /* backoff */, 0 /* delayuntil */,
true /* expedited */);
engine.insertIntoPending(sop);
@@ -134,6 +136,77 @@
}
/**
+ * Verify {@link com.android.server.content.SyncStorageEngine#writePendingOperationsLocked()}
+ */
+ public void testWritePendingOperationsLocked() throws Exception {
+ SyncOperation sop = new SyncOperation(account1,
+ DEFAULT_USER,
+ SyncOperation.REASON_IS_SYNCABLE,
+ SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+ 1000L /* runtime */, 57L /* flex */, 0 /* backoff */, 0 /* delayuntil */,
+ true /* expedited */);
+ SyncOperation sop1 = new SyncOperation(account2,
+ DEFAULT_USER,
+ SyncOperation.REASON_PERIODIC,
+ SyncStorageEngine.SOURCE_LOCAL, authority1, defaultBundle,
+ 0 /* runtime */, 0 /* flex */, 20L /* backoff */, 100L /* delayuntil */,
+ false /* expedited */);
+ SyncOperation deleted = new SyncOperation(account2,
+ DEFAULT_USER,
+ SyncOperation.REASON_SYNC_AUTO,
+ SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+ 0 /* runtime */, 0 /* flex */, 20L /* backoff */, 100L /* delayuntil */,
+ false /* expedited */);
+ engine.insertIntoPending(sop);
+ engine.insertIntoPending(sop1);
+ engine.insertIntoPending(deleted);
+
+ SyncStorageEngine.PendingOperation popDeleted = engine.getPendingOperations().get(2);
+ // Free verifying, going to delete it anyway.
+ assertEquals(deleted.target.account, popDeleted.target.account);
+ assertEquals(deleted.target.provider, popDeleted.target.provider);
+ assertEquals(deleted.target.service, popDeleted.target.service);
+ assertEquals(deleted.target.userId, popDeleted.target.userId);
+ assertEquals(deleted.reason, popDeleted.reason);
+ assertEquals(deleted.syncSource, popDeleted.syncSource);
+ assertEquals(deleted.expedited, popDeleted.expedited);
+ assert(android.content.PeriodicSync.syncExtrasEquals(deleted.extras, popDeleted.extras));
+ // Delete one to force write-all
+ engine.deleteFromPending(popDeleted);
+ assertEquals("Delete of pending op failed.", 2, engine.getPendingOperationCount());
+ // If there's dirty pending data (which there is because we deleted a pending op) this
+ // re-writes the entire file.
+ engine.writeAllState();
+
+ engine.clearAndReadState();
+
+ // Validate state read back out.
+ assertEquals("Delete of pending op failed.", 2, engine.getPendingOperationCount());
+
+ List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
+
+ SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
+ assertEquals(sop.target.account, popRetrieved.target.account);
+ assertEquals(sop.target.provider, popRetrieved.target.provider);
+ assertEquals(sop.target.service, popRetrieved.target.service);
+ assertEquals(sop.target.userId, popRetrieved.target.userId);
+ assertEquals(sop.reason, popRetrieved.reason);
+ assertEquals(sop.syncSource, popRetrieved.syncSource);
+ assertEquals(sop.expedited, popRetrieved.expedited);
+ assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras));
+
+ popRetrieved = pops.get(1);
+ assertEquals(sop1.target.account, popRetrieved.target.account);
+ assertEquals(sop1.target.provider, popRetrieved.target.provider);
+ assertEquals(sop1.target.service, popRetrieved.target.service);
+ assertEquals(sop1.target.userId, popRetrieved.target.userId);
+ assertEquals(sop1.reason, popRetrieved.reason);
+ assertEquals(sop1.syncSource, popRetrieved.syncSource);
+ assertEquals(sop1.expedited, popRetrieved.expedited);
+ assert(android.content.PeriodicSync.syncExtrasEquals(sop1.extras, popRetrieved.extras));
+ }
+
+ /**
* Test that we can create, remove and retrieve periodic syncs. Backwards compatibility -
* periodic syncs with no flex time are no longer used.
*/