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

Side by Side Diff: chrome/browser/extensions/syncable_extension_settings_storage.cc

Issue 8361027: Re-commit 106660 with the crashing test disabled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 9 years, 2 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/syncable_extension_settings_storage.h" 5 #include "chrome/browser/extensions/syncable_extension_settings_storage.h"
6 6
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "chrome/browser/extensions/extension_settings_sync_util.h" 8 #include "chrome/browser/extensions/extension_settings_sync_util.h"
9 #include "chrome/browser/sync/api/sync_data.h" 9 #include "chrome/browser/sync/api/sync_data.h"
10 #include "chrome/browser/sync/protocol/extension_setting_specifics.pb.h" 10 #include "chrome/browser/sync/protocol/extension_setting_specifics.pb.h"
11 #include "content/browser/browser_thread.h" 11 #include "content/browser/browser_thread.h"
12 12
13 SyncableExtensionSettingsStorage::SyncableExtensionSettingsStorage( 13 SyncableExtensionSettingsStorage::SyncableExtensionSettingsStorage(
14 std::string extension_id, ExtensionSettingsStorage* delegate) 14 const scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> >&
15 : extension_id_(extension_id), delegate_(delegate), sync_processor_(NULL) { 15 observers,
16 const std::string& extension_id,
17 ExtensionSettingsStorage* delegate)
18 : observers_(observers),
19 extension_id_(extension_id),
20 delegate_(delegate),
21 sync_processor_(NULL) {
16 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 22 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
17 } 23 }
18 24
19 SyncableExtensionSettingsStorage::~SyncableExtensionSettingsStorage() { 25 SyncableExtensionSettingsStorage::~SyncableExtensionSettingsStorage() {
20 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
21 } 27 }
22 28
23 ExtensionSettingsStorage::Result SyncableExtensionSettingsStorage::Get( 29 ExtensionSettingsStorage::Result SyncableExtensionSettingsStorage::Get(
24 const std::string& key) { 30 const std::string& key) {
25 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 31 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 sync_processor_ = sync_processor; 117 sync_processor_ = sync_processor;
112 118
113 Result maybe_settings = delegate_->Get(); 119 Result maybe_settings = delegate_->Get();
114 if (maybe_settings.HasError()) { 120 if (maybe_settings.HasError()) {
115 return SyncError( 121 return SyncError(
116 FROM_HERE, 122 FROM_HERE,
117 std::string("Failed to get settings: ") + maybe_settings.GetError(), 123 std::string("Failed to get settings: ") + maybe_settings.GetError(),
118 syncable::EXTENSION_SETTINGS); 124 syncable::EXTENSION_SETTINGS);
119 } 125 }
120 126
121 DictionaryValue* settings = maybe_settings.GetSettings(); 127 const DictionaryValue* settings = maybe_settings.GetSettings();
122 if (sync_state.empty()) { 128 if (sync_state.empty()) {
123 return SendLocalSettingsToSync(*settings); 129 return SendLocalSettingsToSync(*settings);
124 } 130 }
125 return OverwriteLocalSettingsWithSync(sync_state, *settings); 131 return OverwriteLocalSettingsWithSync(sync_state, *settings);
126 } 132 }
127 133
128 SyncError SyncableExtensionSettingsStorage::SendLocalSettingsToSync( 134 SyncError SyncableExtensionSettingsStorage::SendLocalSettingsToSync(
129 const DictionaryValue& settings) { 135 const DictionaryValue& settings) {
130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
131 SyncChangeList changes; 137 SyncChangeList changes;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 synced_keys_.clear(); 223 synced_keys_.clear();
218 } 224 }
219 225
220 std::vector<SyncError> SyncableExtensionSettingsStorage::ProcessSyncChanges( 226 std::vector<SyncError> SyncableExtensionSettingsStorage::ProcessSyncChanges(
221 const ExtensionSettingSyncDataList& sync_changes) { 227 const ExtensionSettingSyncDataList& sync_changes) {
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
223 DCHECK(sync_processor_); 229 DCHECK(sync_processor_);
224 DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_; 230 DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_;
225 231
226 std::vector<SyncError> errors; 232 std::vector<SyncError> errors;
233 ExtensionSettingChanges::Builder changes;
227 234
228 for (ExtensionSettingSyncDataList::const_iterator it = sync_changes.begin(); 235 for (ExtensionSettingSyncDataList::const_iterator it = sync_changes.begin();
229 it != sync_changes.end(); ++it) { 236 it != sync_changes.end(); ++it) {
230 DCHECK_EQ(extension_id_, it->extension_id()); 237 DCHECK_EQ(extension_id_, it->extension_id());
238
239 const std::string& key = it->key();
240 const Value& value = it->value();
241
242 scoped_ptr<Value> current_value;
243 {
244 Result maybe_settings = Get(it->key());
245 if (maybe_settings.HasError()) {
246 errors.push_back(SyncError(
247 FROM_HERE,
248 std::string("Error getting current sync state for ") +
249 extension_id_ + "/" + key + ": " + maybe_settings.GetError(),
250 syncable::EXTENSION_SETTINGS));
251 continue;
252 }
253 const DictionaryValue* settings = maybe_settings.GetSettings();
254 if (settings) {
255 Value* value = NULL;
256 if (settings->GetWithoutPathExpansion(key, &value)) {
257 current_value.reset(value->DeepCopy());
258 }
259 }
260 }
261
262 SyncError error;
263
231 switch (it->change_type()) { 264 switch (it->change_type()) {
232 case SyncChange::ACTION_ADD: 265 case SyncChange::ACTION_ADD:
233 case SyncChange::ACTION_UPDATE: { 266 if (!current_value.get()) {
234 synced_keys_.insert(it->key()); 267 error = OnSyncAdd(key, value.DeepCopy(), &changes);
235 Result result = delegate_->Set(it->key(), it->value()); 268 } else {
236 if (result.HasError()) { 269 // Already a value; hopefully a local change has beaten sync in a
237 errors.push_back(SyncError( 270 // race and it's not a bug, so pretend it's an update.
238 FROM_HERE, 271 LOG(WARNING) << "Got add from sync for existing setting " <<
239 std::string("Error pushing sync change to local settings: ") + 272 extension_id_ << "/" << key;
240 result.GetError(), 273 error = OnSyncUpdate(
241 syncable::EXTENSION_SETTINGS)); 274 key, current_value.release(), value.DeepCopy(), &changes);
242 } 275 }
243 break; 276 break;
244 }
245 277
246 case SyncChange::ACTION_DELETE: { 278 case SyncChange::ACTION_UPDATE:
247 synced_keys_.erase(it->key()); 279 if (current_value.get()) {
248 Result result = delegate_->Remove(it->key()); 280 error = OnSyncUpdate(
249 if (result.HasError()) { 281 key, current_value.release(), value.DeepCopy(), &changes);
250 errors.push_back(SyncError( 282 } else {
251 FROM_HERE, 283 // Similarly, pretend it's an add.
252 std::string("Error removing sync change from local settings: ") + 284 LOG(WARNING) << "Got update from sync for nonexistent setting" <<
253 result.GetError(), 285 extension_id_ << "/" << key;
254 syncable::EXTENSION_SETTINGS)); 286 error = OnSyncAdd(key, value.DeepCopy(), &changes);
255 } 287 }
256 break; 288 break;
257 } 289
290 case SyncChange::ACTION_DELETE:
291 if (current_value.get()) {
292 error = OnSyncDelete(key, current_value.release(), &changes);
293 } else {
294 // Similarly, ignore it.
295 LOG(WARNING) << "Got delete from sync for nonexistent setting " <<
296 extension_id_ << "/" << key;
297 }
298 break;
258 299
259 default: 300 default:
260 NOTREACHED(); 301 NOTREACHED();
261 } 302 }
303
304 if (error.IsSet()) {
305 errors.push_back(error);
306 }
262 } 307 }
263 308
309 observers_->Notify(
310 &ExtensionSettingsObserver::OnSettingsChanged,
311 static_cast<Profile*>(NULL),
312 extension_id_,
313 changes.Build());
314
264 return errors; 315 return errors;
265 } 316 }
266 317
267 void SyncableExtensionSettingsStorage::SendAddsOrUpdatesToSync( 318 void SyncableExtensionSettingsStorage::SendAddsOrUpdatesToSync(
268 const std::set<std::string>& changed_keys, 319 const std::set<std::string>& changed_keys,
269 const DictionaryValue& settings) { 320 const DictionaryValue& settings) {
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
271 DCHECK(sync_processor_); 322 DCHECK(sync_processor_);
272 DCHECK(!changed_keys.empty()); 323 DCHECK(!changed_keys.empty());
273 324
(...skipping 26 matching lines...) Expand all
300 351
301 void SyncableExtensionSettingsStorage::SendDeletesToSync( 352 void SyncableExtensionSettingsStorage::SendDeletesToSync(
302 const std::set<std::string>& keys) { 353 const std::set<std::string>& keys) {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
304 DCHECK(sync_processor_); 355 DCHECK(sync_processor_);
305 DCHECK(!keys.empty()); 356 DCHECK(!keys.empty());
306 357
307 SyncChangeList changes; 358 SyncChangeList changes;
308 for (std::set<std::string>::const_iterator it = keys.begin(); 359 for (std::set<std::string>::const_iterator it = keys.begin();
309 it != keys.end(); ++it) { 360 it != keys.end(); ++it) {
310 DCHECK(synced_keys_.count(*it)); 361 if (!synced_keys_.count(*it)) {
362 LOG(WARNING) << "Deleted " << *it << " but no entry in synced_keys";
363 continue;
364 }
311 changes.push_back( 365 changes.push_back(
312 extension_settings_sync_util::CreateDelete(extension_id_, *it)); 366 extension_settings_sync_util::CreateDelete(extension_id_, *it));
313 } 367 }
314 368
369 if (changes.empty()) {
370 return;
371 }
372
315 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 373 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
316 if (error.IsSet()) { 374 if (error.IsSet()) {
317 LOG(WARNING) << "Failed to send changes to sync: " << error.message(); 375 LOG(WARNING) << "Failed to send changes to sync: " << error.message();
318 return; 376 return;
319 } 377 }
320 378
321 for (std::set<std::string>::const_iterator it = keys.begin(); 379 for (std::set<std::string>::const_iterator it = keys.begin();
322 it != keys.end(); ++it) { 380 it != keys.end(); ++it) {
323 synced_keys_.erase(*it); 381 synced_keys_.erase(*it);
324 } 382 }
325 } 383 }
384
385 SyncError SyncableExtensionSettingsStorage::OnSyncAdd(
386 const std::string& key,
387 Value* new_value,
388 ExtensionSettingChanges::Builder* changes) {
389 DCHECK(new_value);
390 synced_keys_.insert(key);
391 Result result = delegate_->Set(key, *new_value);
392 if (result.HasError()) {
393 return SyncError(
394 FROM_HERE,
395 std::string("Error pushing sync add to local settings: ") +
396 result.GetError(),
397 syncable::EXTENSION_SETTINGS);
398 }
399 changes->AppendChange(key, NULL, new_value);
400 return SyncError();
401 }
402
403 SyncError SyncableExtensionSettingsStorage::OnSyncUpdate(
404 const std::string& key,
405 Value* old_value,
406 Value* new_value,
407 ExtensionSettingChanges::Builder* changes) {
408 DCHECK(old_value);
409 DCHECK(new_value);
410 Result result = delegate_->Set(key, *new_value);
411 if (result.HasError()) {
412 return SyncError(
413 FROM_HERE,
414 std::string("Error pushing sync update to local settings: ") +
415 result.GetError(),
416 syncable::EXTENSION_SETTINGS);
417 }
418 changes->AppendChange(key, old_value, new_value);
419 return SyncError();
420 }
421
422 SyncError SyncableExtensionSettingsStorage::OnSyncDelete(
423 const std::string& key,
424 Value* old_value,
425 ExtensionSettingChanges::Builder* changes) {
426 DCHECK(old_value);
427 synced_keys_.erase(key);
428 Result result = delegate_->Remove(key);
429 if (result.HasError()) {
430 return SyncError(
431 FROM_HERE,
432 std::string("Error pushing sync remove to local settings: ") +
433 result.GetError(),
434 syncable::EXTENSION_SETTINGS);
435 }
436 changes->AppendChange(key, old_value, NULL);
437 return SyncError();
438 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/syncable_extension_settings_storage.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698