| Index: chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java
|
| index 913a1cb6c7eb325a26e4bc8c4bb260c35aef4a51..e8c1d5b512e4f7bd7d2ed38d8b00ed4f5ad3b16d 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java
|
| @@ -11,6 +11,7 @@ import android.content.SharedPreferences;
|
| import android.os.AsyncTask;
|
| import android.os.Bundle;
|
|
|
| +import org.chromium.base.ApiCompatibilityUtils;
|
| import org.chromium.base.ApplicationStatus;
|
| import org.chromium.base.ContextUtils;
|
| import org.chromium.base.Log;
|
| @@ -21,7 +22,9 @@ import org.chromium.components.sync.AndroidSyncSettings;
|
|
|
| import java.util.ArrayList;
|
| import java.util.Arrays;
|
| +import java.util.Collections;
|
| import java.util.HashSet;
|
| +import java.util.Iterator;
|
| import java.util.List;
|
| import java.util.Set;
|
|
|
| @@ -93,22 +96,55 @@ public class DelayedInvalidationsController {
|
| String oldAccount = prefs.getString(DELAYED_ACCOUNT_NAME, null);
|
| // Make sure to construct a new set so it can be modified safely. See crbug.com/568369.
|
| Set<String> invals = new HashSet<String>(
|
| - prefs.getStringSet(DELAYED_INVALIDATIONS, new HashSet<String>(1)));
|
| + prefs.getStringSet(DELAYED_INVALIDATIONS, Collections.<String>emptySet()));
|
| assert invals.isEmpty() || oldAccount != null;
|
| - if (oldAccount != null && !oldAccount.equals(account)) {
|
| - invals.clear();
|
| + boolean invalidateAllTypes = false;
|
| + // We invalidate all types if:
|
| + // - the account has changed
|
| + // - we were in "invalidate all types" mode already
|
| + // - new invalidation indicates to invalidate all types by setting source to 0
|
| + // - adding invalidation to the current set failed
|
| + if (oldAccount != null && !oldAccount.equals(account)) invalidateAllTypes = true;
|
| + if (oldAccount != null && invals.isEmpty()) invalidateAllTypes = true;
|
| + if (invalidation.mObjectSource == 0) invalidateAllTypes = true;
|
| + if (!invalidateAllTypes && !addInvalidationToSet(invalidation, invals)) {
|
| + invalidateAllTypes = true;
|
| }
|
| +
|
| SharedPreferences.Editor editor = prefs.edit();
|
| editor.putString(DELAYED_ACCOUNT_NAME, account);
|
| - if (invalidation.mObjectSource == 0 || (oldAccount != null && invals.isEmpty())) {
|
| - editor.putStringSet(DELAYED_INVALIDATIONS, null);
|
| + if (invalidateAllTypes) {
|
| + editor.remove(DELAYED_INVALIDATIONS);
|
| } else {
|
| - invals.add(invalidation.encodeToString());
|
| editor.putStringSet(DELAYED_INVALIDATIONS, invals);
|
| }
|
| editor.apply();
|
| }
|
|
|
| + /**
|
| + * Adds newInvalidation into set of encoded invalidations. Invalidations with the same id/source
|
| + * and lower version are removed from the set. If invalidation with same or higher version is
|
| + * is present, then new invalidation is discarded.
|
| + * @return true if update is successful, false when decoding invalidation from string fails.
|
| + */
|
| + private boolean addInvalidationToSet(
|
| + PendingInvalidation newInvalidation, Set<String> invalidations) {
|
| + for (Iterator<String> iter = invalidations.iterator(); iter.hasNext();) {
|
| + String encodedInvalidation = iter.next();
|
| + PendingInvalidation invalidation =
|
| + PendingInvalidation.decodeToPendingInvalidation(encodedInvalidation);
|
| + if (invalidation == null) return false;
|
| + if (ApiCompatibilityUtils.objectEquals(
|
| + invalidation.mObjectId, newInvalidation.mObjectId)
|
| + && invalidation.mObjectSource == newInvalidation.mObjectSource) {
|
| + if (invalidation.mVersion >= newInvalidation.mVersion) return true;
|
| + iter.remove();
|
| + }
|
| + }
|
| + invalidations.add(newInvalidation.encodeToString());
|
| + return true;
|
| + }
|
| +
|
| private List<Bundle> popPendingInvalidations(final Context context) {
|
| SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
|
| assert prefs.contains(DELAYED_ACCOUNT_NAME);
|
|
|