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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" 6 #include "chrome/browser/extensions/api/storage/settings_sync_util.h" 7 #include "content/public/browser/browser_thread.h" 8 #include "extensions/browser/api/storage/settings_namespace.h" 9 #include "sync/api/sync_change_processor.h" 10 #include "sync/api/sync_data.h" 11 #include "sync/protocol/extension_setting_specifics.pb.h" 12 13 using content::BrowserThread; 14 15 namespace extensions { 16 17 SettingsSyncProcessor::SettingsSyncProcessor( 18 const std::string& extension_id, 19 syncer::ModelType type, 20 syncer::SyncChangeProcessor* sync_processor) 21 : extension_id_(extension_id), 22 type_(type), 23 sync_processor_(sync_processor), 24 initialized_(false) { 25 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 26 CHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS); 27 CHECK(sync_processor); 28 } 29 30 SettingsSyncProcessor::~SettingsSyncProcessor() { 31 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 32 } 33 34 void SettingsSyncProcessor::Init(const base::DictionaryValue& initial_state) { 35 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 36 CHECK(!initialized_) << "Init called multiple times"; 37 38 for (base::DictionaryValue::Iterator i(initial_state); !i.IsAtEnd(); 39 i.Advance()) 40 synced_keys_.insert(i.key()); 41 42 initialized_ = true; 43 } 44 45 syncer::SyncError SettingsSyncProcessor::SendChanges( 46 const ValueStoreChangeList& changes) { 47 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 48 CHECK(initialized_) << "Init not called"; 49 50 syncer::SyncChangeList sync_changes; 51 std::set<std::string> added_keys; 52 std::set<std::string> deleted_keys; 53 54 for (ValueStoreChangeList::const_iterator i = changes.begin(); 55 i != changes.end(); ++i) { 56 const std::string& key = i->key(); 57 const base::Value* value = i->new_value(); 58 if (value) { 59 if (synced_keys_.count(key)) { 60 // New value, key is synced; send ACTION_UPDATE. 61 sync_changes.push_back(settings_sync_util::CreateUpdate( 62 extension_id_, key, *value, type_)); 63 } else { 64 // New value, key is not synced; send ACTION_ADD. 65 sync_changes.push_back(settings_sync_util::CreateAdd( 66 extension_id_, key, *value, type_)); 67 added_keys.insert(key); 68 } 69 } else { 70 if (synced_keys_.count(key)) { 71 // Clearing value, key is synced; send ACTION_DELETE. 72 sync_changes.push_back(settings_sync_util::CreateDelete( 73 extension_id_, key, type_)); 74 deleted_keys.insert(key); 75 } else { 76 LOG(WARNING) << "Deleted " << key << " but not in synced_keys_"; 77 } 78 } 79 } 80 81 if (sync_changes.empty()) 82 return syncer::SyncError(); 83 84 syncer::SyncError error = 85 sync_processor_->ProcessSyncChanges(FROM_HERE, sync_changes); 86 if (error.IsSet()) 87 return error; 88 89 synced_keys_.insert(added_keys.begin(), added_keys.end()); 90 for (std::set<std::string>::iterator i = deleted_keys.begin(); 91 i != deleted_keys.end(); ++i) { 92 synced_keys_.erase(*i); 93 } 94 95 return syncer::SyncError(); 96 } 97 98 void SettingsSyncProcessor::NotifyChanges(const ValueStoreChangeList& changes) { 99 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 100 CHECK(initialized_) << "Init not called"; 101 102 for (ValueStoreChangeList::const_iterator i = changes.begin(); 103 i != changes.end(); ++i) { 104 if (i->new_value()) 105 synced_keys_.insert(i->key()); 106 else 107 synced_keys_.erase(i->key()); 108 } 109 } 110 111 } // namespace extensions 112