| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.invalidation; | 5 package org.chromium.chrome.browser.invalidation; |
| 6 | 6 |
| 7 import android.accounts.Account; | 7 import android.accounts.Account; |
| 8 import android.content.ContentResolver; | 8 import android.content.ContentResolver; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.content.SharedPreferences; | 10 import android.content.SharedPreferences; |
| 11 import android.os.AsyncTask; | 11 import android.os.AsyncTask; |
| 12 import android.os.Bundle; | 12 import android.os.Bundle; |
| 13 | 13 |
| 14 import org.chromium.base.ApiCompatibilityUtils; |
| 14 import org.chromium.base.ApplicationStatus; | 15 import org.chromium.base.ApplicationStatus; |
| 15 import org.chromium.base.ContextUtils; | 16 import org.chromium.base.ContextUtils; |
| 16 import org.chromium.base.Log; | 17 import org.chromium.base.Log; |
| 17 import org.chromium.base.VisibleForTesting; | 18 import org.chromium.base.VisibleForTesting; |
| 18 import org.chromium.components.invalidation.PendingInvalidation; | 19 import org.chromium.components.invalidation.PendingInvalidation; |
| 19 import org.chromium.components.signin.AccountManagerHelper; | 20 import org.chromium.components.signin.AccountManagerHelper; |
| 20 import org.chromium.components.sync.AndroidSyncSettings; | 21 import org.chromium.components.sync.AndroidSyncSettings; |
| 21 | 22 |
| 22 import java.util.ArrayList; | 23 import java.util.ArrayList; |
| 23 import java.util.Arrays; | 24 import java.util.Arrays; |
| 25 import java.util.Collections; |
| 24 import java.util.HashSet; | 26 import java.util.HashSet; |
| 27 import java.util.Iterator; |
| 25 import java.util.List; | 28 import java.util.List; |
| 26 import java.util.Set; | 29 import java.util.Set; |
| 27 | 30 |
| 28 /** | 31 /** |
| 29 * A class for controlling whether an invalidation should be notified immediatel
y, or should be | 32 * A class for controlling whether an invalidation should be notified immediatel
y, or should be |
| 30 * delayed until Chrome comes to the foreground again. | 33 * delayed until Chrome comes to the foreground again. |
| 31 */ | 34 */ |
| 32 public class DelayedInvalidationsController { | 35 public class DelayedInvalidationsController { |
| 33 private static final String TAG = "invalidation"; | 36 private static final String TAG = "invalidation"; |
| 34 private static final String DELAYED_ACCOUNT_NAME = "delayed_account"; | 37 private static final String DELAYED_ACCOUNT_NAME = "delayed_account"; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 | 89 |
| 87 /** | 90 /** |
| 88 * Stores preferences to indicate that an invalidation has arrived, but drop
ped on the floor. | 91 * Stores preferences to indicate that an invalidation has arrived, but drop
ped on the floor. |
| 89 */ | 92 */ |
| 90 @VisibleForTesting | 93 @VisibleForTesting |
| 91 void addPendingInvalidation(Context context, String account, PendingInvalida
tion invalidation) { | 94 void addPendingInvalidation(Context context, String account, PendingInvalida
tion invalidation) { |
| 92 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); | 95 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); |
| 93 String oldAccount = prefs.getString(DELAYED_ACCOUNT_NAME, null); | 96 String oldAccount = prefs.getString(DELAYED_ACCOUNT_NAME, null); |
| 94 // Make sure to construct a new set so it can be modified safely. See cr
bug.com/568369. | 97 // Make sure to construct a new set so it can be modified safely. See cr
bug.com/568369. |
| 95 Set<String> invals = new HashSet<String>( | 98 Set<String> invals = new HashSet<String>( |
| 96 prefs.getStringSet(DELAYED_INVALIDATIONS, new HashSet<String>(1)
)); | 99 prefs.getStringSet(DELAYED_INVALIDATIONS, Collections.<String>em
ptySet())); |
| 97 assert invals.isEmpty() || oldAccount != null; | 100 assert invals.isEmpty() || oldAccount != null; |
| 98 if (oldAccount != null && !oldAccount.equals(account)) { | 101 boolean invalidateAllTypes = false; |
| 99 invals.clear(); | 102 // We invalidate all types if: |
| 103 // - the account has changed |
| 104 // - we were in "invalidate all types" mode already |
| 105 // - new invalidation indicates to invalidate all types by setting sourc
e to 0 |
| 106 // - adding invalidation to the current set failed |
| 107 if (oldAccount != null && !oldAccount.equals(account)) invalidateAllType
s = true; |
| 108 if (oldAccount != null && invals.isEmpty()) invalidateAllTypes = true; |
| 109 if (invalidation.mObjectSource == 0) invalidateAllTypes = true; |
| 110 if (!invalidateAllTypes && !addInvalidationToSet(invalidation, invals))
{ |
| 111 invalidateAllTypes = true; |
| 100 } | 112 } |
| 113 |
| 101 SharedPreferences.Editor editor = prefs.edit(); | 114 SharedPreferences.Editor editor = prefs.edit(); |
| 102 editor.putString(DELAYED_ACCOUNT_NAME, account); | 115 editor.putString(DELAYED_ACCOUNT_NAME, account); |
| 103 if (invalidation.mObjectSource == 0 || (oldAccount != null && invals.isE
mpty())) { | 116 if (invalidateAllTypes) { |
| 104 editor.putStringSet(DELAYED_INVALIDATIONS, null); | 117 editor.remove(DELAYED_INVALIDATIONS); |
| 105 } else { | 118 } else { |
| 106 invals.add(invalidation.encodeToString()); | |
| 107 editor.putStringSet(DELAYED_INVALIDATIONS, invals); | 119 editor.putStringSet(DELAYED_INVALIDATIONS, invals); |
| 108 } | 120 } |
| 109 editor.apply(); | 121 editor.apply(); |
| 110 } | 122 } |
| 111 | 123 |
| 124 /** |
| 125 * Adds newInvalidation into set of encoded invalidations. Invalidations wit
h the same id/source |
| 126 * and lower version are removed from the set. If invalidation with same or
higher version is |
| 127 * is present, then new invalidation is discarded. |
| 128 * @return true if update is successful, false when decoding invalidation fr
om string fails. |
| 129 */ |
| 130 private boolean addInvalidationToSet( |
| 131 PendingInvalidation newInvalidation, Set<String> invalidations) { |
| 132 for (Iterator<String> iter = invalidations.iterator(); iter.hasNext();)
{ |
| 133 String encodedInvalidation = iter.next(); |
| 134 PendingInvalidation invalidation = |
| 135 PendingInvalidation.decodeToPendingInvalidation(encodedInval
idation); |
| 136 if (invalidation == null) return false; |
| 137 if (ApiCompatibilityUtils.objectEquals( |
| 138 invalidation.mObjectId, newInvalidation.mObjectId) |
| 139 && invalidation.mObjectSource == newInvalidation.mObjectSour
ce) { |
| 140 if (invalidation.mVersion >= newInvalidation.mVersion) return tr
ue; |
| 141 iter.remove(); |
| 142 } |
| 143 } |
| 144 invalidations.add(newInvalidation.encodeToString()); |
| 145 return true; |
| 146 } |
| 147 |
| 112 private List<Bundle> popPendingInvalidations(final Context context) { | 148 private List<Bundle> popPendingInvalidations(final Context context) { |
| 113 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); | 149 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); |
| 114 assert prefs.contains(DELAYED_ACCOUNT_NAME); | 150 assert prefs.contains(DELAYED_ACCOUNT_NAME); |
| 115 Set<String> savedInvalidations = prefs.getStringSet(DELAYED_INVALIDATION
S, null); | 151 Set<String> savedInvalidations = prefs.getStringSet(DELAYED_INVALIDATION
S, null); |
| 116 clearPendingInvalidations(context); | 152 clearPendingInvalidations(context); |
| 117 // Absence of specific invalidations indicates invalidate all types. | 153 // Absence of specific invalidations indicates invalidate all types. |
| 118 if (savedInvalidations == null) return Arrays.asList(new Bundle()); | 154 if (savedInvalidations == null) return Arrays.asList(new Bundle()); |
| 119 | 155 |
| 120 List<Bundle> bundles = new ArrayList<Bundle>(savedInvalidations.size()); | 156 List<Bundle> bundles = new ArrayList<Bundle>(savedInvalidations.size()); |
| 121 for (String invalidation : savedInvalidations) { | 157 for (String invalidation : savedInvalidations) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 147 } | 183 } |
| 148 | 184 |
| 149 private static boolean isManualRequest(Bundle extras) { | 185 private static boolean isManualRequest(Bundle extras) { |
| 150 if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)) { | 186 if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)) { |
| 151 Log.d(TAG, "Manual sync requested."); | 187 Log.d(TAG, "Manual sync requested."); |
| 152 return true; | 188 return true; |
| 153 } | 189 } |
| 154 return false; | 190 return false; |
| 155 } | 191 } |
| 156 } | 192 } |
| OLD | NEW |