Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Side by Side Diff: chrome/browser/sync/invalidations/invalidator_storage.cc

Issue 10911084: Implement Invalidator::Acknowledge (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/sync/invalidations/invalidator_storage.h" 5 #include "chrome/browser/sync/invalidations/invalidator_storage.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "chrome/browser/prefs/pref_service.h" 12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
14 #include "sync/internal_api/public/base/model_type.h" 14 #include "sync/internal_api/public/base/model_type.h"
15 #include "sync/notifier/invalidation_util.h"
15 16
16 using syncer::InvalidationVersionMap; 17 using syncer::InvalidationStateMap;
17 18
18 namespace browser_sync { 19 namespace browser_sync {
19 20
20 namespace { 21 namespace {
21 22
22 const char kSourceKey[] = "source"; 23 const char kSourceKey[] = "source";
23 const char kNameKey[] = "name"; 24 const char kNameKey[] = "name";
24 const char kMaxVersionKey[] = "max-version"; 25 const char kMaxVersionKey[] = "max-version";
26 const char kCurrentAckHandleKey[] = "current-ack";
27 const char kExpectedAckHandleKey[] = "expected-ack";
25 28
29 // TODO(dcheng): Rename.
26 bool ValueToObjectIdAndVersion(const DictionaryValue& value, 30 bool ValueToObjectIdAndVersion(const DictionaryValue& value,
27 invalidation::ObjectId* id, 31 invalidation::ObjectId* id,
28 int64* max_version) { 32 syncer::LocalState* state) {
29 std::string source_str; 33 std::string source_str;
30 int source = 0; 34 int source = 0;
31 std::string name; 35 std::string name;
32 std::string max_version_str; 36 std::string max_version_str;
33 if (!value.GetString(kSourceKey, &source_str)) { 37 if (!value.GetString(kSourceKey, &source_str)) {
34 DLOG(WARNING) << "Unable to deserialize source"; 38 DLOG(WARNING) << "Unable to deserialize source";
35 return false; 39 return false;
36 } 40 }
37 if (!value.GetString(kNameKey, &name)) { 41 if (!value.GetString(kNameKey, &name)) {
38 DLOG(WARNING) << "Unable to deserialize name"; 42 DLOG(WARNING) << "Unable to deserialize name";
39 return false; 43 return false;
40 } 44 }
41 if (!value.GetString(kMaxVersionKey, &max_version_str)) { 45 if (!value.GetString(kMaxVersionKey, &max_version_str)) {
42 DLOG(WARNING) << "Unable to deserialize max version"; 46 DLOG(WARNING) << "Unable to deserialize max version";
43 return false; 47 return false;
44 } 48 }
45 if (!base::StringToInt(source_str, &source)) { 49 if (!base::StringToInt(source_str, &source)) {
46 DLOG(WARNING) << "Invalid source: " << source_str; 50 DLOG(WARNING) << "Invalid source: " << source_str;
47 return false; 51 return false;
48 } 52 }
49 if (!base::StringToInt64(max_version_str, max_version)) { 53 if (!base::StringToInt64(max_version_str, &state->version)) {
50 DLOG(WARNING) << "Invalid max invalidation version: " << max_version_str; 54 DLOG(WARNING) << "Invalid max invalidation version: " << max_version_str;
51 return false; 55 return false;
52 } 56 }
53 *id = invalidation::ObjectId(source, name); 57 *id = invalidation::ObjectId(source, name);
58 // The following field is optional, as it may not always be set (for
59 // example, when upgrading from previous versions of Chrome).
60 const base::Value* current_ack_handle_value = NULL;
61 if (value.Get(kCurrentAckHandleKey, &current_ack_handle_value)) {
62 state->current.ResetFromValue(*current_ack_handle_value);
63 }
64 // TODO(dcheng): Consider regenerating the latest ack handle value on Chrome
65 // startup to allow for format changes?
66 const base::Value* expected_ack_handle_value = NULL;
67 if (value.Get(kExpectedAckHandleKey, &expected_ack_handle_value)) {
68 state->expected.ResetFromValue(*expected_ack_handle_value);
69 }
54 return true; 70 return true;
55 } 71 }
56 72
57 // The caller owns the returned value. 73 // The caller owns the returned value.
58 DictionaryValue* ObjectIdAndVersionToValue(const invalidation::ObjectId& id, 74 DictionaryValue* ObjectIdAndStateToValue(const invalidation::ObjectId& id,
59 int64 max_version) { 75 const syncer::LocalState& state) {
60 DictionaryValue* value = new DictionaryValue; 76 DictionaryValue* value = new DictionaryValue;
61 value->SetString(kSourceKey, base::IntToString(id.source())); 77 value->SetString(kSourceKey, base::IntToString(id.source()));
62 value->SetString(kNameKey, id.name()); 78 value->SetString(kNameKey, id.name());
63 value->SetString(kMaxVersionKey, base::Int64ToString(max_version)); 79 value->SetString(kMaxVersionKey, base::Int64ToString(state.version));
80 value->Set(kCurrentAckHandleKey, state.current.ToValue().release());
81 value->Set(kExpectedAckHandleKey, state.expected.ToValue().release());
64 return value; 82 return value;
65 } 83 }
66 84
67 } // namespace 85 } // namespace
68 86
69 InvalidatorStorage::InvalidatorStorage(PrefService* pref_service) 87 InvalidatorStorage::InvalidatorStorage(PrefService* pref_service)
70 : pref_service_(pref_service) { 88 : pref_service_(pref_service) {
71 // TODO(tim): Create a Mock instead of maintaining the if(!pref_service_) case 89 // TODO(tim): Create a Mock instead of maintaining the if(!pref_service_) case
72 // throughout this file. This is a problem now due to lack of injection at 90 // throughout this file. This is a problem now due to lack of injection at
73 // ProfileSyncService. Bug 130176. 91 // ProfileSyncService. Bug 130176.
74 if (pref_service_) { 92 if (pref_service_) {
75 pref_service_->RegisterListPref(prefs::kInvalidatorMaxInvalidationVersions, 93 pref_service_->RegisterListPref(prefs::kInvalidatorMaxInvalidationVersions,
76 PrefService::UNSYNCABLE_PREF); 94 PrefService::UNSYNCABLE_PREF);
77 pref_service_->RegisterStringPref(prefs::kInvalidatorInvalidationState, 95 pref_service_->RegisterStringPref(prefs::kInvalidatorInvalidationState,
78 std::string(), 96 std::string(),
79 PrefService::UNSYNCABLE_PREF); 97 PrefService::UNSYNCABLE_PREF);
80 98
81 MigrateMaxInvalidationVersionsPref(); 99 MigrateMaxInvalidationVersionsPref();
82 } 100 }
83 } 101 }
84 102
85 InvalidatorStorage::~InvalidatorStorage() { 103 InvalidatorStorage::~InvalidatorStorage() {
86 } 104 }
87 105
88 InvalidationVersionMap InvalidatorStorage::GetAllMaxVersions() const { 106 InvalidationStateMap InvalidatorStorage::GetStateMap() const {
89 DCHECK(thread_checker_.CalledOnValidThread()); 107 DCHECK(thread_checker_.CalledOnValidThread());
90 InvalidationVersionMap max_versions; 108 InvalidationStateMap state;
91 if (!pref_service_) { 109 if (!pref_service_) {
92 return max_versions; 110 return state;
93 } 111 }
94 const base::ListValue* max_versions_list = 112 const base::ListValue* state_map_list =
95 pref_service_->GetList(prefs::kInvalidatorMaxInvalidationVersions); 113 pref_service_->GetList(prefs::kInvalidatorMaxInvalidationVersions);
96 CHECK(max_versions_list); 114 CHECK(state_map_list);
97 DeserializeFromList(*max_versions_list, &max_versions); 115 DeserializeFromList(*state_map_list, &state);
98 return max_versions; 116 return state;
99 } 117 }
100 118
101 void InvalidatorStorage::SetMaxVersion(const invalidation::ObjectId& id, 119 void InvalidatorStorage::SetMaxVersion(const invalidation::ObjectId& id,
102 int64 max_version) { 120 int64 max_version) {
103 DCHECK(thread_checker_.CalledOnValidThread()); 121 DCHECK(thread_checker_.CalledOnValidThread());
104 CHECK(pref_service_); 122 CHECK(pref_service_);
105 InvalidationVersionMap max_versions = GetAllMaxVersions(); 123 InvalidationStateMap state_map = GetStateMap();
106 InvalidationVersionMap::iterator it = max_versions.find(id); 124 InvalidationStateMap::iterator it = state_map.find(id);
107 if ((it != max_versions.end()) && (max_version <= it->second)) { 125 if ((it != state_map.end()) && (max_version <= it->second.version)) {
108 NOTREACHED(); 126 NOTREACHED();
109 return; 127 return;
110 } 128 }
111 max_versions[id] = max_version; 129 state_map[id].version = max_version;
112 130
113 base::ListValue max_versions_list; 131 base::ListValue state_map_list;
114 SerializeToList(max_versions, &max_versions_list); 132 SerializeToList(state_map, &state_map_list);
115 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions, 133 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions,
116 max_versions_list); 134 state_map_list);
117 } 135 }
118 136
119 void InvalidatorStorage::Forget(const syncer::ObjectIdSet& ids) { 137 void InvalidatorStorage::Forget(const syncer::ObjectIdSet& ids) {
120 DCHECK(thread_checker_.CalledOnValidThread()); 138 DCHECK(thread_checker_.CalledOnValidThread());
121 CHECK(pref_service_); 139 CHECK(pref_service_);
122 InvalidationVersionMap max_versions = GetAllMaxVersions(); 140 InvalidationStateMap state_map = GetStateMap();
123 for (syncer::ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); 141 for (syncer::ObjectIdSet::const_iterator it = ids.begin(); it != ids.end();
124 ++it) { 142 ++it) {
125 max_versions.erase(*it); 143 state_map.erase(*it);
126 } 144 }
127 145
128 base::ListValue max_versions_list; 146 base::ListValue state_map_list;
129 SerializeToList(max_versions, &max_versions_list); 147 SerializeToList(state_map, &state_map_list);
130 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions, 148 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions,
131 max_versions_list); 149 state_map_list);
132 } 150 }
133 151
134 // static 152 // static
135 void InvalidatorStorage::DeserializeFromList( 153 void InvalidatorStorage::DeserializeFromList(
136 const base::ListValue& max_versions_list, 154 const base::ListValue& state_map_list,
137 InvalidationVersionMap* max_versions_map) { 155 InvalidationStateMap* state_map) {
138 max_versions_map->clear(); 156 state_map->clear();
139 for (size_t i = 0; i < max_versions_list.GetSize(); ++i) { 157 for (size_t i = 0; i < state_map_list.GetSize(); ++i) {
140 const DictionaryValue* value = NULL; 158 const DictionaryValue* value = NULL;
141 if (!max_versions_list.GetDictionary(i, &value)) { 159 if (!state_map_list.GetDictionary(i, &value)) {
142 DLOG(WARNING) << "Unable to deserialize entry " << i; 160 DLOG(WARNING) << "Unable to deserialize entry " << i;
143 continue; 161 continue;
144 } 162 }
145 invalidation::ObjectId id; 163 invalidation::ObjectId id;
146 int64 max_version = 0; 164 syncer::LocalState state;
147 if (!ValueToObjectIdAndVersion(*value, &id, &max_version)) { 165 if (!ValueToObjectIdAndVersion(*value, &id, &state)) {
148 DLOG(WARNING) << "Error while deserializing entry " << i; 166 DLOG(WARNING) << "Error while deserializing entry " << i;
149 continue; 167 continue;
150 } 168 }
151 (*max_versions_map)[id] = max_version; 169 (*state_map)[id] = state;
152 } 170 }
153 } 171 }
154 172
155 // static 173 // static
156 void InvalidatorStorage::SerializeToList( 174 void InvalidatorStorage::SerializeToList(
157 const InvalidationVersionMap& max_versions_map, 175 const InvalidationStateMap& state_map,
158 base::ListValue* max_versions_list) { 176 base::ListValue* state_map_list) {
159 for (InvalidationVersionMap::const_iterator it = max_versions_map.begin(); 177 for (InvalidationStateMap::const_iterator it = state_map.begin();
160 it != max_versions_map.end(); ++it) { 178 it != state_map.end(); ++it) {
161 max_versions_list->Append(ObjectIdAndVersionToValue(it->first, it->second)); 179 state_map_list->Append(ObjectIdAndStateToValue(it->first, it->second));
162 } 180 }
163 } 181 }
164 182
165 // Legacy migration code. 183 // Legacy migration code.
166 void InvalidatorStorage::MigrateMaxInvalidationVersionsPref() { 184 void InvalidatorStorage::MigrateMaxInvalidationVersionsPref() {
167 pref_service_->RegisterDictionaryPref(prefs::kSyncMaxInvalidationVersions, 185 pref_service_->RegisterDictionaryPref(prefs::kSyncMaxInvalidationVersions,
168 PrefService::UNSYNCABLE_PREF); 186 PrefService::UNSYNCABLE_PREF);
169 const base::DictionaryValue* max_versions_dict = 187 const base::DictionaryValue* max_versions_dict =
170 pref_service_->GetDictionary(prefs::kSyncMaxInvalidationVersions); 188 pref_service_->GetDictionary(prefs::kSyncMaxInvalidationVersions);
171 CHECK(max_versions_dict); 189 CHECK(max_versions_dict);
172 if (!max_versions_dict->empty()) { 190 if (!max_versions_dict->empty()) {
173 InvalidationVersionMap max_versions; 191 InvalidationStateMap state_map;
174 DeserializeMap(max_versions_dict, &max_versions); 192 DeserializeMap(max_versions_dict, &state_map);
175 base::ListValue max_versions_list; 193 base::ListValue state_map_list;
176 SerializeToList(max_versions, &max_versions_list); 194 SerializeToList(state_map, &state_map_list);
177 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions, 195 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions,
178 max_versions_list); 196 state_map_list);
179 UMA_HISTOGRAM_BOOLEAN("InvalidatorStorage.MigrateInvalidationVersionsPref", 197 UMA_HISTOGRAM_BOOLEAN("InvalidatorStorage.MigrateInvalidationVersionsPref",
180 true); 198 true);
181 } else { 199 } else {
182 UMA_HISTOGRAM_BOOLEAN("InvalidatorStorage.MigrateInvalidationVersionsPref", 200 UMA_HISTOGRAM_BOOLEAN("InvalidatorStorage.MigrateInvalidationVersionsPref",
183 false); 201 false);
184 } 202 }
185 pref_service_->ClearPref(prefs::kSyncMaxInvalidationVersions); 203 pref_service_->ClearPref(prefs::kSyncMaxInvalidationVersions);
186 } 204 }
187 205
188 // Legacy migration code. 206 // Legacy migration code.
189 // static 207 // static
190 void InvalidatorStorage::DeserializeMap( 208 void InvalidatorStorage::DeserializeMap(
191 const base::DictionaryValue* max_versions_dict, 209 const base::DictionaryValue* max_versions_dict,
192 InvalidationVersionMap* map) { 210 InvalidationStateMap* map) {
193 map->clear(); 211 map->clear();
194 // Convert from a string -> string DictionaryValue to a 212 // Convert from a string -> string DictionaryValue to a
195 // ModelType -> int64 map. 213 // ModelType -> int64 map.
196 for (base::DictionaryValue::key_iterator it = 214 for (base::DictionaryValue::key_iterator it =
197 max_versions_dict->begin_keys(); 215 max_versions_dict->begin_keys();
198 it != max_versions_dict->end_keys(); ++it) { 216 it != max_versions_dict->end_keys(); ++it) {
199 int model_type_int = 0; 217 int model_type_int = 0;
200 if (!base::StringToInt(*it, &model_type_int)) { 218 if (!base::StringToInt(*it, &model_type_int)) {
201 LOG(WARNING) << "Invalid model type key: " << *it; 219 LOG(WARNING) << "Invalid model type key: " << *it;
202 continue; 220 continue;
(...skipping 12 matching lines...) Expand all
215 LOG(WARNING) << "Invalid max invalidation version for " 233 LOG(WARNING) << "Invalid max invalidation version for "
216 << syncer::ModelTypeToString(model_type) << ": " 234 << syncer::ModelTypeToString(model_type) << ": "
217 << max_version_str; 235 << max_version_str;
218 continue; 236 continue;
219 } 237 }
220 invalidation::ObjectId id; 238 invalidation::ObjectId id;
221 if (!syncer::RealModelTypeToObjectId(model_type, &id)) { 239 if (!syncer::RealModelTypeToObjectId(model_type, &id)) {
222 DLOG(WARNING) << "Invalid model type: " << model_type; 240 DLOG(WARNING) << "Invalid model type: " << model_type;
223 continue; 241 continue;
224 } 242 }
225 (*map)[id] = max_version; 243 (*map)[id].version = max_version;
226 } 244 }
227 } 245 }
228 246
229 std::string InvalidatorStorage::GetInvalidationState() const { 247 std::string InvalidatorStorage::GetInvalidationState() const {
230 std::string utf8_state(pref_service_ ? 248 std::string utf8_state(pref_service_ ?
231 pref_service_->GetString(prefs::kInvalidatorInvalidationState) : ""); 249 pref_service_->GetString(prefs::kInvalidatorInvalidationState) : "");
232 std::string state_data; 250 std::string state_data;
233 base::Base64Decode(utf8_state, &state_data); 251 base::Base64Decode(utf8_state, &state_data);
234 return state_data; 252 return state_data;
235 } 253 }
236 254
237 void InvalidatorStorage::SetInvalidationState(const std::string& state) { 255 void InvalidatorStorage::SetInvalidationState(const std::string& state) {
238 DCHECK(thread_checker_.CalledOnValidThread()); 256 DCHECK(thread_checker_.CalledOnValidThread());
239 std::string utf8_state; 257 std::string utf8_state;
240 base::Base64Encode(state, &utf8_state); 258 base::Base64Encode(state, &utf8_state);
241 pref_service_->SetString(prefs::kInvalidatorInvalidationState, 259 pref_service_->SetString(prefs::kInvalidatorInvalidationState,
242 utf8_state); 260 utf8_state);
243 } 261 }
244 262
245 void InvalidatorStorage::Clear() { 263 void InvalidatorStorage::Clear() {
246 DCHECK(thread_checker_.CalledOnValidThread()); 264 DCHECK(thread_checker_.CalledOnValidThread());
247 pref_service_->ClearPref(prefs::kInvalidatorMaxInvalidationVersions); 265 pref_service_->ClearPref(prefs::kInvalidatorMaxInvalidationVersions);
248 pref_service_->ClearPref(prefs::kInvalidatorInvalidationState); 266 pref_service_->ClearPref(prefs::kInvalidatorInvalidationState);
249 } 267 }
250 268
269 void InvalidatorStorage::GenerateAckHandles(const syncer::ObjectIdSet& ids,
270 syncer::AckHandleMap* ack_handles) {
271 DCHECK(thread_checker_.CalledOnValidThread());
272 CHECK(pref_service_);
273 InvalidationStateMap state_map = GetStateMap();
274
275 for (syncer::ObjectIdSet::const_iterator it = ids.begin(); it != ids.end();
276 ++it) {
277 // TODO(dcheng): Do we need to set the default max version value to
278 // something other than zero?
279 state_map[*it].expected = syncer::AckHandle::CreateUnique();
280 ack_handles->insert(std::make_pair(*it, state_map[*it].expected));
281 }
282
283 base::ListValue state_map_list;
284 SerializeToList(state_map, &state_map_list);
285 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions,
Pete Williamson 2012/09/14 18:28:22 Is the preference service the right place for this
dcheng 2012/09/14 19:08:49 It seemed logical to group it here, since it's whe
286 state_map_list);
287 }
288
289 void InvalidatorStorage::Acknowledge(const invalidation::ObjectId& id,
290 const syncer::AckHandle& ack_handle) {
291 DCHECK(thread_checker_.CalledOnValidThread());
292 CHECK(pref_service_);
293 InvalidationStateMap state_map = GetStateMap();
294
295 InvalidationStateMap::iterator it = state_map.find(id);
296 // This could happen if the acknowledgement is delayed and Forget() has
297 // already been called.
298 if (it == state_map.end())
299 return;
300 it->second.current = ack_handle;
301
302 base::ListValue state_map_list;
303 SerializeToList(state_map, &state_map_list);
304 pref_service_->Set(prefs::kInvalidatorMaxInvalidationVersions,
305 state_map_list);
306 }
307
251 } // namespace browser_sync 308 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698