Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/sync/DelayedSyncController.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/DelayedSyncController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/DelayedSyncController.java |
| index 8b896444047bbe081606c8300425a0f0536acd75..840c19c197170d57baba46404fa90283199ea7c6 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/DelayedSyncController.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/DelayedSyncController.java |
| @@ -11,20 +11,28 @@ import android.content.SharedPreferences; |
| import android.os.AsyncTask; |
| import android.os.Bundle; |
| import android.preference.PreferenceManager; |
| -import android.util.Log; |
| import org.chromium.base.ApplicationStatus; |
| +import org.chromium.base.Log; |
| import org.chromium.base.VisibleForTesting; |
| +import org.chromium.components.invalidation.PendingInvalidation; |
| import org.chromium.sync.AndroidSyncSettings; |
| import org.chromium.sync.signin.AccountManagerHelper; |
| +import java.util.ArrayList; |
| +import java.util.Arrays; |
| +import java.util.HashSet; |
| +import java.util.List; |
| +import java.util.Set; |
| + |
| /** |
| - * A class for controlling when a sync should be performed immediately, and when it should be |
| + * A class for controlling whether an invalidation should be notified immediately, or should be |
| * delayed until Chrome comes to the foreground again. |
| */ |
| public class DelayedSyncController { |
|
nyquist
2015/06/05 19:49:39
Now with your new awesomeness this class name seem
knn
2015/06/08 11:09:01
I wanted to defer any churn until the cl is review
|
| - private static final String TAG = "DelayedSyncController"; |
| + private static final String TAG = Log.makeTag("invalidation"); |
| private static final String DELAYED_ACCOUNT_NAME = "delayed_account"; |
| + private static final String DELAYED_INVALIDATIONS = "delayed_invalidations"; |
| private static class LazyHolder { |
| private static final DelayedSyncController INSTANCE = new DelayedSyncController(); |
| @@ -38,18 +46,20 @@ public class DelayedSyncController { |
| DelayedSyncController() {} |
| /** |
| - * Resume any syncs that were delayed while Chromium was backgrounded. |
| + * Notify any invalidations that were delayed while Chromium was backgrounded. |
| + * @return whether there were any invalidations pending to be notified. |
| */ |
| - public boolean resumeDelayedSyncs(final Context context) { |
| + public boolean notifyPendingInvalidations(final Context context) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| String accountName = prefs.getString(DELAYED_ACCOUNT_NAME, null); |
| if (accountName == null) { |
| - Log.d(TAG, "No delayed sync."); |
| + Log.d(TAG, "No pending invalidations."); |
| return false; |
| } else { |
| - Log.d(TAG, "Handling delayed sync."); |
| + Log.d(TAG, "Handling pending invalidations."); |
| Account account = AccountManagerHelper.createAccountFromName(accountName); |
| - requestSyncOnBackgroundThread(context, account); |
| + List<Bundle> bundles = popPendingInvalidations(context); |
| + notifyInvalidationsOnBackgroundThread(context, account, bundles); |
| return true; |
| } |
| } |
| @@ -59,12 +69,15 @@ public class DelayedSyncController { |
| * IO operations. |
| */ |
| @VisibleForTesting |
| - void requestSyncOnBackgroundThread(final Context context, final Account account) { |
| + void notifyInvalidationsOnBackgroundThread( |
| + final Context context, final Account account, final List<Bundle> bundles) { |
| new AsyncTask<Void, Void, Void>() { |
| @Override |
| protected Void doInBackground(Void... unused) { |
| String contractAuthority = AndroidSyncSettings.getContractAuthority(context); |
| - ContentResolver.requestSync(account, contractAuthority, new Bundle()); |
| + for (Bundle bundle : bundles) { |
| + ContentResolver.requestSync(account, contractAuthority, bundle); |
| + } |
| return null; |
| } |
| }.execute(); |
| @@ -73,40 +86,68 @@ public class DelayedSyncController { |
| /** |
| * Stores preferences to indicate that an invalidation has arrived, but dropped on the floor. |
| */ |
| - void setDelayedSync(Context ctx, String accountName) { |
| - SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(ctx).edit(); |
| - editor.putString(DELAYED_ACCOUNT_NAME, accountName); |
| + @VisibleForTesting |
| + void addPendingInvalidation(Context context, String account, PendingInvalidation invalidation) { |
| + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| + String oldAccount = prefs.getString(DELAYED_ACCOUNT_NAME, null); |
| + Set<String> invals = prefs.getStringSet(DELAYED_INVALIDATIONS, new HashSet<String>(1)); |
| + assert invals.isEmpty() || oldAccount != null; |
| + if (oldAccount != null && !oldAccount.equals(account)) { |
| + invals.clear(); |
| + } |
| + SharedPreferences.Editor editor = prefs.edit(); |
| + editor.putString(DELAYED_ACCOUNT_NAME, account); |
| + if (invalidation.mObjectSource == 0 || (oldAccount != null && invals.isEmpty())) { |
| + editor.putStringSet(DELAYED_INVALIDATIONS, null); |
| + } else { |
| + invals.add(invalidation.encodeToString()); |
| + editor.putStringSet(DELAYED_INVALIDATIONS, invals); |
| + } |
| editor.apply(); |
| } |
| + private List<Bundle> popPendingInvalidations(final Context context) { |
| + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| + assert prefs.contains(DELAYED_ACCOUNT_NAME); |
| + Set<String> savedInvalidations = prefs.getStringSet(DELAYED_INVALIDATIONS, null); |
| + clearPendingInvalidations(context); |
| + // Absence of specific invalidations indicates invalidate all types. |
| + if (savedInvalidations == null) return Arrays.asList(new Bundle()); |
| + |
| + List<Bundle> bundles = new ArrayList<Bundle>(savedInvalidations.size()); |
| + for (String invalidation : savedInvalidations) { |
| + Bundle bundle = PendingInvalidation.decodeToBundle(invalidation); |
| + if (bundle == null) { |
| + Log.e(TAG, "Error parsing saved invalidation. Invalidating all."); |
| + return Arrays.asList(new Bundle()); |
| + } |
| + bundles.add(bundle); |
| + } |
| + return bundles; |
| + } |
| + |
| /** |
| - * If there is a delayed sync, it will be cleared. |
| + * If there are any pending invalidations, they will be cleared. |
| */ |
| @VisibleForTesting |
| - void clearDelayedSyncs(Context context) { |
| - setDelayedSync(context, null); |
| + public void clearPendingInvalidations(Context context) { |
| + SharedPreferences.Editor editor = |
| + PreferenceManager.getDefaultSharedPreferences(context).edit(); |
| + editor.putString(DELAYED_ACCOUNT_NAME, null); |
| + editor.putStringSet(DELAYED_INVALIDATIONS, null); |
| + editor.apply(); |
| } |
| @VisibleForTesting |
| - boolean shouldPerformSync(Context ctx, Bundle extras, Account account) { |
| - boolean manualSync = isManualSync(extras); |
| - |
| - if (manualSync || ApplicationStatus.hasVisibleActivities()) { |
| - clearDelayedSyncs(ctx); |
| - return true; |
| - } else { |
| - Log.d(TAG, "Delaying sync."); |
| - setDelayedSync(ctx, account.name); |
| - return false; |
| - } |
| + boolean shouldNotifyInvalidation(Bundle extras) { |
| + return isManualRequest(extras) || ApplicationStatus.hasVisibleActivities(); |
| } |
| - private static boolean isManualSync(Bundle extras) { |
| - boolean manualSync = false; |
| + private static boolean isManualRequest(Bundle extras) { |
| if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)) { |
| - manualSync = true; |
| Log.d(TAG, "Manual sync requested."); |
| + return true; |
| } |
| - return manualSync; |
| + return false; |
| } |
| } |