OLD | NEW |
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/extensions/settings/syncable_settings_storage.h" | 5 #include "chrome/browser/extensions/settings/syncable_settings_storage.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "chrome/browser/extensions/settings/settings_namespace.h" | 8 #include "chrome/browser/extensions/settings/settings_namespace.h" |
9 #include "chrome/browser/extensions/settings/settings_sync_processor.h" | 9 #include "chrome/browser/extensions/settings/settings_sync_processor.h" |
10 #include "chrome/browser/extensions/settings/settings_sync_util.h" | 10 #include "chrome/browser/extensions/settings/settings_sync_util.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 if (result->HasError()) { | 114 if (result->HasError()) { |
115 return result.Pass(); | 115 return result.Pass(); |
116 } | 116 } |
117 SyncResultIfEnabled(result); | 117 SyncResultIfEnabled(result); |
118 return result.Pass(); | 118 return result.Pass(); |
119 } | 119 } |
120 | 120 |
121 void SyncableSettingsStorage::SyncResultIfEnabled( | 121 void SyncableSettingsStorage::SyncResultIfEnabled( |
122 const ValueStore::WriteResult& result) { | 122 const ValueStore::WriteResult& result) { |
123 if (sync_processor_.get() && !result->changes().empty()) { | 123 if (sync_processor_.get() && !result->changes().empty()) { |
124 SyncError error = sync_processor_->SendChanges(result->changes()); | 124 csync::SyncError error = sync_processor_->SendChanges(result->changes()); |
125 if (error.IsSet()) | 125 if (error.IsSet()) |
126 StopSyncing(); | 126 StopSyncing(); |
127 } | 127 } |
128 } | 128 } |
129 | 129 |
130 // Sync-related methods. | 130 // Sync-related methods. |
131 | 131 |
132 SyncError SyncableSettingsStorage::StartSyncing( | 132 csync::SyncError SyncableSettingsStorage::StartSyncing( |
133 const DictionaryValue& sync_state, | 133 const DictionaryValue& sync_state, |
134 scoped_ptr<SettingsSyncProcessor> sync_processor) { | 134 scoped_ptr<SettingsSyncProcessor> sync_processor) { |
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
136 DCHECK(!sync_processor_.get()); | 136 DCHECK(!sync_processor_.get()); |
137 | 137 |
138 sync_processor_ = sync_processor.Pass(); | 138 sync_processor_ = sync_processor.Pass(); |
139 sync_processor_->Init(sync_state); | 139 sync_processor_->Init(sync_state); |
140 | 140 |
141 ReadResult maybe_settings = delegate_->Get(); | 141 ReadResult maybe_settings = delegate_->Get(); |
142 if (maybe_settings->HasError()) { | 142 if (maybe_settings->HasError()) { |
143 return SyncError( | 143 return csync::SyncError( |
144 FROM_HERE, | 144 FROM_HERE, |
145 std::string("Failed to get settings: ") + maybe_settings->error(), | 145 std::string("Failed to get settings: ") + maybe_settings->error(), |
146 sync_processor_->type()); | 146 sync_processor_->type()); |
147 } | 147 } |
148 | 148 |
149 const DictionaryValue& settings = *maybe_settings->settings().get(); | 149 const DictionaryValue& settings = *maybe_settings->settings().get(); |
150 if (sync_state.empty()) | 150 if (sync_state.empty()) |
151 return SendLocalSettingsToSync(settings); | 151 return SendLocalSettingsToSync(settings); |
152 else | 152 else |
153 return OverwriteLocalSettingsWithSync(sync_state, settings); | 153 return OverwriteLocalSettingsWithSync(sync_state, settings); |
154 } | 154 } |
155 | 155 |
156 SyncError SyncableSettingsStorage::SendLocalSettingsToSync( | 156 csync::SyncError SyncableSettingsStorage::SendLocalSettingsToSync( |
157 const DictionaryValue& settings) { | 157 const DictionaryValue& settings) { |
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
159 | 159 |
160 ValueStoreChangeList changes; | 160 ValueStoreChangeList changes; |
161 for (DictionaryValue::Iterator i(settings); i.HasNext(); i.Advance()) { | 161 for (DictionaryValue::Iterator i(settings); i.HasNext(); i.Advance()) { |
162 changes.push_back(ValueStoreChange(i.key(), NULL, i.value().DeepCopy())); | 162 changes.push_back(ValueStoreChange(i.key(), NULL, i.value().DeepCopy())); |
163 } | 163 } |
164 | 164 |
165 if (changes.empty()) | 165 if (changes.empty()) |
166 return SyncError(); | 166 return csync::SyncError(); |
167 | 167 |
168 SyncError error = sync_processor_->SendChanges(changes); | 168 csync::SyncError error = sync_processor_->SendChanges(changes); |
169 if (error.IsSet()) | 169 if (error.IsSet()) |
170 StopSyncing(); | 170 StopSyncing(); |
171 | 171 |
172 return error; | 172 return error; |
173 } | 173 } |
174 | 174 |
175 SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync( | 175 csync::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync( |
176 const DictionaryValue& sync_state, const DictionaryValue& settings) { | 176 const DictionaryValue& sync_state, const DictionaryValue& settings) { |
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
178 // Treat this as a list of changes to sync and use ProcessSyncChanges. | 178 // Treat this as a list of changes to sync and use ProcessSyncChanges. |
179 // This gives notifications etc for free. | 179 // This gives notifications etc for free. |
180 scoped_ptr<DictionaryValue> new_sync_state(sync_state.DeepCopy()); | 180 scoped_ptr<DictionaryValue> new_sync_state(sync_state.DeepCopy()); |
181 | 181 |
182 SettingSyncDataList changes; | 182 SettingSyncDataList changes; |
183 for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) { | 183 for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) { |
184 Value* orphaned_sync_value = NULL; | 184 Value* orphaned_sync_value = NULL; |
185 if (new_sync_state->RemoveWithoutPathExpansion( | 185 if (new_sync_state->RemoveWithoutPathExpansion( |
186 it.key(), &orphaned_sync_value)) { | 186 it.key(), &orphaned_sync_value)) { |
187 scoped_ptr<Value> sync_value(orphaned_sync_value); | 187 scoped_ptr<Value> sync_value(orphaned_sync_value); |
188 if (sync_value->Equals(&it.value())) { | 188 if (sync_value->Equals(&it.value())) { |
189 // Sync and local values are the same, no changes to send. | 189 // Sync and local values are the same, no changes to send. |
190 } else { | 190 } else { |
191 // Sync value is different, update local setting with new value. | 191 // Sync value is different, update local setting with new value. |
192 changes.push_back( | 192 changes.push_back( |
193 SettingSyncData( | 193 SettingSyncData( |
194 SyncChange::ACTION_UPDATE, | 194 csync::SyncChange::ACTION_UPDATE, |
195 extension_id_, | 195 extension_id_, |
196 it.key(), | 196 it.key(), |
197 sync_value.Pass())); | 197 sync_value.Pass())); |
198 } | 198 } |
199 } else { | 199 } else { |
200 // Not synced, delete local setting. | 200 // Not synced, delete local setting. |
201 changes.push_back( | 201 changes.push_back( |
202 SettingSyncData( | 202 SettingSyncData( |
203 SyncChange::ACTION_DELETE, | 203 csync::SyncChange::ACTION_DELETE, |
204 extension_id_, | 204 extension_id_, |
205 it.key(), | 205 it.key(), |
206 scoped_ptr<Value>(new DictionaryValue()))); | 206 scoped_ptr<Value>(new DictionaryValue()))); |
207 } | 207 } |
208 } | 208 } |
209 | 209 |
210 // Add all new settings to local settings. | 210 // Add all new settings to local settings. |
211 while (!new_sync_state->empty()) { | 211 while (!new_sync_state->empty()) { |
212 std::string key = *new_sync_state->begin_keys(); | 212 std::string key = *new_sync_state->begin_keys(); |
213 Value* value = NULL; | 213 Value* value = NULL; |
214 CHECK(new_sync_state->RemoveWithoutPathExpansion(key, &value)); | 214 CHECK(new_sync_state->RemoveWithoutPathExpansion(key, &value)); |
215 changes.push_back( | 215 changes.push_back( |
216 SettingSyncData( | 216 SettingSyncData( |
217 SyncChange::ACTION_ADD, | 217 csync::SyncChange::ACTION_ADD, |
218 extension_id_, | 218 extension_id_, |
219 key, | 219 key, |
220 scoped_ptr<Value>(value))); | 220 scoped_ptr<Value>(value))); |
221 } | 221 } |
222 | 222 |
223 if (changes.empty()) | 223 if (changes.empty()) |
224 return SyncError(); | 224 return csync::SyncError(); |
225 | 225 |
226 return ProcessSyncChanges(changes); | 226 return ProcessSyncChanges(changes); |
227 } | 227 } |
228 | 228 |
229 void SyncableSettingsStorage::StopSyncing() { | 229 void SyncableSettingsStorage::StopSyncing() { |
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
231 sync_processor_.reset(); | 231 sync_processor_.reset(); |
232 } | 232 } |
233 | 233 |
234 SyncError SyncableSettingsStorage::ProcessSyncChanges( | 234 csync::SyncError SyncableSettingsStorage::ProcessSyncChanges( |
235 const SettingSyncDataList& sync_changes) { | 235 const SettingSyncDataList& sync_changes) { |
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
237 DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_; | 237 DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_; |
238 | 238 |
239 if (!sync_processor_.get()) { | 239 if (!sync_processor_.get()) { |
240 return SyncError( | 240 return csync::SyncError( |
241 FROM_HERE, | 241 FROM_HERE, |
242 std::string("Sync is inactive for ") + extension_id_, | 242 std::string("Sync is inactive for ") + extension_id_, |
243 syncable::UNSPECIFIED); | 243 syncable::UNSPECIFIED); |
244 } | 244 } |
245 | 245 |
246 std::vector<SyncError> errors; | 246 std::vector<csync::SyncError> errors; |
247 ValueStoreChangeList changes; | 247 ValueStoreChangeList changes; |
248 | 248 |
249 for (SettingSyncDataList::const_iterator it = sync_changes.begin(); | 249 for (SettingSyncDataList::const_iterator it = sync_changes.begin(); |
250 it != sync_changes.end(); ++it) { | 250 it != sync_changes.end(); ++it) { |
251 DCHECK_EQ(extension_id_, it->extension_id()); | 251 DCHECK_EQ(extension_id_, it->extension_id()); |
252 | 252 |
253 const std::string& key = it->key(); | 253 const std::string& key = it->key(); |
254 const Value& value = it->value(); | 254 const Value& value = it->value(); |
255 | 255 |
256 scoped_ptr<Value> current_value; | 256 scoped_ptr<Value> current_value; |
257 { | 257 { |
258 ReadResult maybe_settings = Get(it->key()); | 258 ReadResult maybe_settings = Get(it->key()); |
259 if (maybe_settings->HasError()) { | 259 if (maybe_settings->HasError()) { |
260 errors.push_back(SyncError( | 260 errors.push_back(csync::SyncError( |
261 FROM_HERE, | 261 FROM_HERE, |
262 std::string("Error getting current sync state for ") + | 262 std::string("Error getting current sync state for ") + |
263 extension_id_ + "/" + key + ": " + maybe_settings->error(), | 263 extension_id_ + "/" + key + ": " + maybe_settings->error(), |
264 sync_processor_->type())); | 264 sync_processor_->type())); |
265 continue; | 265 continue; |
266 } | 266 } |
267 Value* value = NULL; | 267 Value* value = NULL; |
268 if (maybe_settings->settings()->GetWithoutPathExpansion(key, &value)) { | 268 if (maybe_settings->settings()->GetWithoutPathExpansion(key, &value)) { |
269 current_value.reset(value->DeepCopy()); | 269 current_value.reset(value->DeepCopy()); |
270 } | 270 } |
271 } | 271 } |
272 | 272 |
273 SyncError error; | 273 csync::SyncError error; |
274 | 274 |
275 switch (it->change_type()) { | 275 switch (it->change_type()) { |
276 case SyncChange::ACTION_ADD: | 276 case csync::SyncChange::ACTION_ADD: |
277 if (!current_value.get()) { | 277 if (!current_value.get()) { |
278 error = OnSyncAdd(key, value.DeepCopy(), &changes); | 278 error = OnSyncAdd(key, value.DeepCopy(), &changes); |
279 } else { | 279 } else { |
280 // Already a value; hopefully a local change has beaten sync in a | 280 // Already a value; hopefully a local change has beaten sync in a |
281 // race and it's not a bug, so pretend it's an update. | 281 // race and it's not a bug, so pretend it's an update. |
282 LOG(WARNING) << "Got add from sync for existing setting " << | 282 LOG(WARNING) << "Got add from sync for existing setting " << |
283 extension_id_ << "/" << key; | 283 extension_id_ << "/" << key; |
284 error = OnSyncUpdate( | 284 error = OnSyncUpdate( |
285 key, current_value.release(), value.DeepCopy(), &changes); | 285 key, current_value.release(), value.DeepCopy(), &changes); |
286 } | 286 } |
287 break; | 287 break; |
288 | 288 |
289 case SyncChange::ACTION_UPDATE: | 289 case csync::SyncChange::ACTION_UPDATE: |
290 if (current_value.get()) { | 290 if (current_value.get()) { |
291 error = OnSyncUpdate( | 291 error = OnSyncUpdate( |
292 key, current_value.release(), value.DeepCopy(), &changes); | 292 key, current_value.release(), value.DeepCopy(), &changes); |
293 } else { | 293 } else { |
294 // Similarly, pretend it's an add. | 294 // Similarly, pretend it's an add. |
295 LOG(WARNING) << "Got update from sync for nonexistent setting" << | 295 LOG(WARNING) << "Got update from sync for nonexistent setting" << |
296 extension_id_ << "/" << key; | 296 extension_id_ << "/" << key; |
297 error = OnSyncAdd(key, value.DeepCopy(), &changes); | 297 error = OnSyncAdd(key, value.DeepCopy(), &changes); |
298 } | 298 } |
299 break; | 299 break; |
300 | 300 |
301 case SyncChange::ACTION_DELETE: | 301 case csync::SyncChange::ACTION_DELETE: |
302 if (current_value.get()) { | 302 if (current_value.get()) { |
303 error = OnSyncDelete(key, current_value.release(), &changes); | 303 error = OnSyncDelete(key, current_value.release(), &changes); |
304 } else { | 304 } else { |
305 // Similarly, ignore it. | 305 // Similarly, ignore it. |
306 LOG(WARNING) << "Got delete from sync for nonexistent setting " << | 306 LOG(WARNING) << "Got delete from sync for nonexistent setting " << |
307 extension_id_ << "/" << key; | 307 extension_id_ << "/" << key; |
308 } | 308 } |
309 break; | 309 break; |
310 | 310 |
311 default: | 311 default: |
312 NOTREACHED(); | 312 NOTREACHED(); |
313 } | 313 } |
314 | 314 |
315 if (error.IsSet()) { | 315 if (error.IsSet()) { |
316 errors.push_back(error); | 316 errors.push_back(error); |
317 } | 317 } |
318 } | 318 } |
319 | 319 |
320 sync_processor_->NotifyChanges(changes); | 320 sync_processor_->NotifyChanges(changes); |
321 | 321 |
322 observers_->Notify( | 322 observers_->Notify( |
323 &SettingsObserver::OnSettingsChanged, | 323 &SettingsObserver::OnSettingsChanged, |
324 extension_id_, | 324 extension_id_, |
325 settings_namespace::SYNC, | 325 settings_namespace::SYNC, |
326 ValueStoreChange::ToJson(changes)); | 326 ValueStoreChange::ToJson(changes)); |
327 | 327 |
328 // TODO(kalman): Something sensible with multiple errors. | 328 // TODO(kalman): Something sensible with multiple errors. |
329 return errors.empty() ? SyncError() : errors[0]; | 329 return errors.empty() ? csync::SyncError() : errors[0]; |
330 } | 330 } |
331 | 331 |
332 SyncError SyncableSettingsStorage::OnSyncAdd( | 332 csync::SyncError SyncableSettingsStorage::OnSyncAdd( |
333 const std::string& key, | 333 const std::string& key, |
334 Value* new_value, | 334 Value* new_value, |
335 ValueStoreChangeList* changes) { | 335 ValueStoreChangeList* changes) { |
336 DCHECK(new_value); | 336 DCHECK(new_value); |
337 WriteResult result = delegate_->Set(IGNORE_QUOTA, key, *new_value); | 337 WriteResult result = delegate_->Set(IGNORE_QUOTA, key, *new_value); |
338 if (result->HasError()) { | 338 if (result->HasError()) { |
339 return SyncError( | 339 return csync::SyncError( |
340 FROM_HERE, | 340 FROM_HERE, |
341 std::string("Error pushing sync add to local settings: ") + | 341 std::string("Error pushing sync add to local settings: ") + |
342 result->error(), | 342 result->error(), |
343 sync_processor_->type()); | 343 sync_processor_->type()); |
344 } | 344 } |
345 changes->push_back(ValueStoreChange(key, NULL, new_value)); | 345 changes->push_back(ValueStoreChange(key, NULL, new_value)); |
346 return SyncError(); | 346 return csync::SyncError(); |
347 } | 347 } |
348 | 348 |
349 SyncError SyncableSettingsStorage::OnSyncUpdate( | 349 csync::SyncError SyncableSettingsStorage::OnSyncUpdate( |
350 const std::string& key, | 350 const std::string& key, |
351 Value* old_value, | 351 Value* old_value, |
352 Value* new_value, | 352 Value* new_value, |
353 ValueStoreChangeList* changes) { | 353 ValueStoreChangeList* changes) { |
354 DCHECK(old_value); | 354 DCHECK(old_value); |
355 DCHECK(new_value); | 355 DCHECK(new_value); |
356 WriteResult result = delegate_->Set(IGNORE_QUOTA, key, *new_value); | 356 WriteResult result = delegate_->Set(IGNORE_QUOTA, key, *new_value); |
357 if (result->HasError()) { | 357 if (result->HasError()) { |
358 return SyncError( | 358 return csync::SyncError( |
359 FROM_HERE, | 359 FROM_HERE, |
360 std::string("Error pushing sync update to local settings: ") + | 360 std::string("Error pushing sync update to local settings: ") + |
361 result->error(), | 361 result->error(), |
362 sync_processor_->type()); | 362 sync_processor_->type()); |
363 } | 363 } |
364 changes->push_back(ValueStoreChange(key, old_value, new_value)); | 364 changes->push_back(ValueStoreChange(key, old_value, new_value)); |
365 return SyncError(); | 365 return csync::SyncError(); |
366 } | 366 } |
367 | 367 |
368 SyncError SyncableSettingsStorage::OnSyncDelete( | 368 csync::SyncError SyncableSettingsStorage::OnSyncDelete( |
369 const std::string& key, | 369 const std::string& key, |
370 Value* old_value, | 370 Value* old_value, |
371 ValueStoreChangeList* changes) { | 371 ValueStoreChangeList* changes) { |
372 DCHECK(old_value); | 372 DCHECK(old_value); |
373 WriteResult result = delegate_->Remove(key); | 373 WriteResult result = delegate_->Remove(key); |
374 if (result->HasError()) { | 374 if (result->HasError()) { |
375 return SyncError( | 375 return csync::SyncError( |
376 FROM_HERE, | 376 FROM_HERE, |
377 std::string("Error pushing sync remove to local settings: ") + | 377 std::string("Error pushing sync remove to local settings: ") + |
378 result->error(), | 378 result->error(), |
379 sync_processor_->type()); | 379 sync_processor_->type()); |
380 } | 380 } |
381 changes->push_back(ValueStoreChange(key, old_value, NULL)); | 381 changes->push_back(ValueStoreChange(key, old_value, NULL)); |
382 return SyncError(); | 382 return csync::SyncError(); |
383 } | 383 } |
384 | 384 |
385 } // namespace extensions | 385 } // namespace extensions |
OLD | NEW |