| 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/api/storage/settings_backend.h" | 5 #include "chrome/browser/extensions/api/storage/sync_storage_backend.h" |
| 6 | 6 |
| 7 #include "base/files/file_enumerator.h" | 7 #include "base/files/file_enumerator.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" | 9 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" |
| 10 #include "chrome/browser/extensions/api/storage/settings_sync_util.h" | 10 #include "chrome/browser/extensions/api/storage/settings_sync_util.h" |
| 11 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h" | 11 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h" |
| 12 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "sync/api/sync_error_factory.h" | 13 #include "sync/api/sync_error_factory.h" |
| 14 | 14 |
| 15 using content::BrowserThread; | 15 using content::BrowserThread; |
| 16 | 16 |
| 17 namespace extensions { | 17 namespace extensions { |
| 18 | 18 |
| 19 SettingsBackend::SettingsBackend( | 19 namespace { |
| 20 |
| 21 void AddAllSyncData(const std::string& extension_id, |
| 22 const base::DictionaryValue& src, |
| 23 syncer::ModelType type, |
| 24 syncer::SyncDataList* dst) { |
| 25 for (base::DictionaryValue::Iterator it(src); !it.IsAtEnd(); it.Advance()) { |
| 26 dst->push_back(settings_sync_util::CreateData( |
| 27 extension_id, it.key(), it.value(), type)); |
| 28 } |
| 29 } |
| 30 |
| 31 } // namespace |
| 32 |
| 33 SyncStorageBackend::SyncStorageBackend( |
| 20 const scoped_refptr<SettingsStorageFactory>& storage_factory, | 34 const scoped_refptr<SettingsStorageFactory>& storage_factory, |
| 21 const base::FilePath& base_path, | 35 const base::FilePath& base_path, |
| 36 const SettingsStorageQuotaEnforcer::Limits& quota, |
| 37 const scoped_refptr<SettingsObserverList>& observers, |
| 22 syncer::ModelType sync_type, | 38 syncer::ModelType sync_type, |
| 23 const syncer::SyncableService::StartSyncFlare& flare, | 39 const syncer::SyncableService::StartSyncFlare& flare) |
| 24 const SettingsStorageQuotaEnforcer::Limits& quota, | 40 : SettingsBackend(storage_factory, base_path, quota), |
| 25 const scoped_refptr<SettingsObserverList>& observers) | |
| 26 : storage_factory_(storage_factory), | |
| 27 base_path_(base_path), | |
| 28 quota_(quota), | |
| 29 observers_(observers), | 41 observers_(observers), |
| 30 sync_type_(sync_type), | 42 sync_type_(sync_type), |
| 31 flare_(flare) { | 43 flare_(flare) { |
| 32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 33 DCHECK(sync_type_ == syncer::EXTENSION_SETTINGS || | 45 DCHECK(sync_type_ == syncer::EXTENSION_SETTINGS || |
| 34 sync_type_ == syncer::APP_SETTINGS); | 46 sync_type_ == syncer::APP_SETTINGS); |
| 35 } | 47 } |
| 36 | 48 |
| 37 SettingsBackend::~SettingsBackend() { | 49 SyncStorageBackend::~SyncStorageBackend() {} |
| 38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 39 } | |
| 40 | 50 |
| 41 ValueStore* SettingsBackend::GetStorage( | 51 ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) { |
| 42 const std::string& extension_id) const { | |
| 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 44 base::DictionaryValue empty; | 53 base::DictionaryValue empty; |
| 45 return GetOrCreateStorageWithSyncData(extension_id, empty); | 54 return GetOrCreateStorageWithSyncData(extension_id, empty); |
| 46 } | 55 } |
| 47 | 56 |
| 48 SyncableSettingsStorage* SettingsBackend::GetOrCreateStorageWithSyncData( | 57 SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData( |
| 49 const std::string& extension_id, | 58 const std::string& extension_id, |
| 50 const base::DictionaryValue& sync_data) const { | 59 const base::DictionaryValue& sync_data) const { |
| 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 52 | 61 |
| 53 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); | 62 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); |
| 54 if (maybe_storage != storage_objs_.end()) { | 63 if (maybe_storage != storage_objs_.end()) { |
| 55 return maybe_storage->second.get(); | 64 return maybe_storage->second.get(); |
| 56 } | 65 } |
| 57 | 66 |
| 58 ValueStore* storage = storage_factory_->Create(base_path_, extension_id); | 67 scoped_ptr<SettingsStorageQuotaEnforcer> storage = |
| 59 CHECK(storage); | 68 CreateStorageForExtension(extension_id); |
| 60 | 69 |
| 61 // It's fine to create the quota enforcer underneath the sync layer, since | 70 // It's fine to create the quota enforcer underneath the sync layer, since |
| 62 // sync will only go ahead if each underlying storage operation succeeds. | 71 // sync will only go ahead if each underlying storage operation succeeds. |
| 63 storage = new SettingsStorageQuotaEnforcer(quota_, storage); | |
| 64 | |
| 65 linked_ptr<SyncableSettingsStorage> syncable_storage( | 72 linked_ptr<SyncableSettingsStorage> syncable_storage( |
| 66 new SyncableSettingsStorage( | 73 new SyncableSettingsStorage( |
| 67 observers_, | 74 observers_, extension_id, storage.release(), sync_type_, flare_)); |
| 68 extension_id, | |
| 69 storage, | |
| 70 sync_type_, | |
| 71 flare_)); | |
| 72 storage_objs_[extension_id] = syncable_storage; | 75 storage_objs_[extension_id] = syncable_storage; |
| 73 | 76 |
| 74 if (sync_processor_.get()) { | 77 if (sync_processor_.get()) { |
| 75 syncer::SyncError error = | 78 syncer::SyncError error = syncable_storage->StartSyncing( |
| 76 syncable_storage->StartSyncing( | 79 sync_data, CreateSettingsSyncProcessor(extension_id).Pass()); |
| 77 sync_data, | |
| 78 CreateSettingsSyncProcessor(extension_id).Pass()); | |
| 79 if (error.IsSet()) | 80 if (error.IsSet()) |
| 80 syncable_storage.get()->StopSyncing(); | 81 syncable_storage.get()->StopSyncing(); |
| 81 } | 82 } |
| 82 return syncable_storage.get(); | 83 return syncable_storage.get(); |
| 83 } | 84 } |
| 84 | 85 |
| 85 void SettingsBackend::DeleteStorage(const std::string& extension_id) { | 86 void SyncStorageBackend::DeleteStorage(const std::string& extension_id) { |
| 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 87 | 88 |
| 88 // Clear settings when the extension is uninstalled. Leveldb implementations | 89 // Clear settings when the extension is uninstalled. Leveldb implementations |
| 89 // will also delete the database from disk when the object is destroyed as a | 90 // will also delete the database from disk when the object is destroyed as a |
| 90 // result of being removed from |storage_objs_|. | 91 // result of being removed from |storage_objs_|. |
| 91 // | 92 // |
| 92 // TODO(kalman): always GetStorage here (rather than only clearing if it | 93 // TODO(kalman): always GetStorage here (rather than only clearing if it |
| 93 // exists) since the storage area may have been unloaded, but we still want | 94 // exists) since the storage area may have been unloaded, but we still want |
| 94 // to clear the data from disk. | 95 // to clear the data from disk. |
| 95 // However, this triggers http://crbug.com/111072. | 96 // However, this triggers http://crbug.com/111072. |
| 96 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); | 97 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); |
| 97 if (maybe_storage == storage_objs_.end()) | 98 if (maybe_storage == storage_objs_.end()) |
| 98 return; | 99 return; |
| 99 maybe_storage->second->Clear(); | 100 maybe_storage->second->Clear(); |
| 100 storage_objs_.erase(extension_id); | 101 storage_objs_.erase(extension_id); |
| 101 } | 102 } |
| 102 | 103 |
| 103 std::set<std::string> SettingsBackend::GetKnownExtensionIDs() const { | 104 syncer::SyncableService* SyncStorageBackend::GetAsSyncableService() { |
| 105 return this; |
| 106 } |
| 107 |
| 108 std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs() const { |
| 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 105 std::set<std::string> result; | 110 std::set<std::string> result; |
| 106 | 111 |
| 107 // Storage areas can be in-memory as well as on disk. |storage_objs_| will | 112 // Storage areas can be in-memory as well as on disk. |storage_objs_| will |
| 108 // contain all that are in-memory. | 113 // contain all that are in-memory. |
| 109 for (StorageObjMap::iterator it = storage_objs_.begin(); | 114 for (StorageObjMap::iterator it = storage_objs_.begin(); |
| 110 it != storage_objs_.end(); ++it) { | 115 it != storage_objs_.end(); |
| 116 ++it) { |
| 111 result.insert(it->first); | 117 result.insert(it->first); |
| 112 } | 118 } |
| 113 | 119 |
| 114 // Leveldb databases are directories inside base_path_. | 120 // Leveldb databases are directories inside base_path(). |
| 115 base::FileEnumerator extension_dirs( | 121 base::FileEnumerator extension_dirs( |
| 116 base_path_, false, base::FileEnumerator::DIRECTORIES); | 122 base_path(), false, base::FileEnumerator::DIRECTORIES); |
| 117 while (!extension_dirs.Next().empty()) { | 123 while (!extension_dirs.Next().empty()) { |
| 118 base::FilePath extension_dir = extension_dirs.GetInfo().GetName(); | 124 base::FilePath extension_dir = extension_dirs.GetInfo().GetName(); |
| 119 DCHECK(!extension_dir.IsAbsolute()); | 125 DCHECK(!extension_dir.IsAbsolute()); |
| 120 // Extension IDs are created as std::strings so they *should* be ASCII. | 126 // Extension IDs are created as std::strings so they *should* be ASCII. |
| 121 std::string maybe_as_ascii(extension_dir.MaybeAsASCII()); | 127 std::string maybe_as_ascii(extension_dir.MaybeAsASCII()); |
| 122 if (!maybe_as_ascii.empty()) { | 128 if (!maybe_as_ascii.empty()) { |
| 123 result.insert(maybe_as_ascii); | 129 result.insert(maybe_as_ascii); |
| 124 } | 130 } |
| 125 } | 131 } |
| 126 | 132 |
| 127 return result; | 133 return result; |
| 128 } | 134 } |
| 129 | 135 |
| 130 static void AddAllSyncData( | 136 syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type) |
| 131 const std::string& extension_id, | 137 const { |
| 132 const base::DictionaryValue& src, | |
| 133 syncer::ModelType type, | |
| 134 syncer::SyncDataList* dst) { | |
| 135 for (base::DictionaryValue::Iterator it(src); !it.IsAtEnd(); it.Advance()) { | |
| 136 dst->push_back(settings_sync_util::CreateData( | |
| 137 extension_id, it.key(), it.value(), type)); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 syncer::SyncDataList SettingsBackend::GetAllSyncData( | |
| 142 syncer::ModelType type) const { | |
| 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 144 // Ignore the type, it's just for sanity checking; assume that whatever base | 139 // Ignore the type, it's just for sanity checking; assume that whatever base |
| 145 // path we're constructed with is correct for the sync type. | 140 // path we're constructed with is correct for the sync type. |
| 146 DCHECK(type == syncer::EXTENSION_SETTINGS || | 141 DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS); |
| 147 type == syncer::APP_SETTINGS); | |
| 148 | 142 |
| 149 // For all extensions, get all their settings. This has the effect | 143 // For all extensions, get all their settings. This has the effect |
| 150 // of bringing in the entire state of extension settings in memory; sad. | 144 // of bringing in the entire state of extension settings in memory; sad. |
| 151 syncer::SyncDataList all_sync_data; | 145 syncer::SyncDataList all_sync_data; |
| 152 std::set<std::string> known_extension_ids(GetKnownExtensionIDs()); | 146 std::set<std::string> known_extension_ids(GetKnownExtensionIDs()); |
| 153 | 147 |
| 154 for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); | 148 for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); |
| 155 it != known_extension_ids.end(); ++it) { | 149 it != known_extension_ids.end(); |
| 156 ValueStore::ReadResult maybe_settings = GetStorage(*it)->Get(); | 150 ++it) { |
| 151 ValueStore::ReadResult maybe_settings = |
| 152 GetOrCreateStorageWithSyncData(*it, base::DictionaryValue())->Get(); |
| 157 if (maybe_settings->HasError()) { | 153 if (maybe_settings->HasError()) { |
| 158 LOG(WARNING) << "Failed to get settings for " << *it << ": " << | 154 LOG(WARNING) << "Failed to get settings for " << *it << ": " |
| 159 maybe_settings->error().message; | 155 << maybe_settings->error().message; |
| 160 continue; | 156 continue; |
| 161 } | 157 } |
| 162 AddAllSyncData(*it, maybe_settings->settings(), type, &all_sync_data); | 158 AddAllSyncData(*it, maybe_settings->settings(), type, &all_sync_data); |
| 163 } | 159 } |
| 164 | 160 |
| 165 return all_sync_data; | 161 return all_sync_data; |
| 166 } | 162 } |
| 167 | 163 |
| 168 syncer::SyncMergeResult SettingsBackend::MergeDataAndStartSyncing( | 164 syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing( |
| 169 syncer::ModelType type, | 165 syncer::ModelType type, |
| 170 const syncer::SyncDataList& initial_sync_data, | 166 const syncer::SyncDataList& initial_sync_data, |
| 171 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 167 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, |
| 172 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { | 168 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { |
| 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 174 DCHECK_EQ(sync_type_, type); | 170 DCHECK_EQ(sync_type_, type); |
| 175 DCHECK(!sync_processor_.get()); | 171 DCHECK(!sync_processor_.get()); |
| 176 DCHECK(sync_processor.get()); | 172 DCHECK(sync_processor.get()); |
| 177 DCHECK(sync_error_factory.get()); | 173 DCHECK(sync_error_factory.get()); |
| 178 | 174 |
| 179 sync_processor_ = sync_processor.Pass(); | 175 sync_processor_ = sync_processor.Pass(); |
| 180 sync_error_factory_ = sync_error_factory.Pass(); | 176 sync_error_factory_ = sync_error_factory.Pass(); |
| 181 | 177 |
| 182 // Group the initial sync data by extension id. | 178 // Group the initial sync data by extension id. |
| 183 std::map<std::string, linked_ptr<base::DictionaryValue> > grouped_sync_data; | 179 std::map<std::string, linked_ptr<base::DictionaryValue> > grouped_sync_data; |
| 184 for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin(); | 180 for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin(); |
| 185 it != initial_sync_data.end(); ++it) { | 181 it != initial_sync_data.end(); |
| 182 ++it) { |
| 186 SettingSyncData data(*it); | 183 SettingSyncData data(*it); |
| 187 linked_ptr<base::DictionaryValue> sync_data = | 184 linked_ptr<base::DictionaryValue> sync_data = |
| 188 grouped_sync_data[data.extension_id()]; | 185 grouped_sync_data[data.extension_id()]; |
| 189 if (!sync_data.get()) { | 186 if (!sync_data.get()) { |
| 190 sync_data = linked_ptr<base::DictionaryValue>( | 187 sync_data = |
| 191 new base::DictionaryValue()); | 188 linked_ptr<base::DictionaryValue>(new base::DictionaryValue()); |
| 192 grouped_sync_data[data.extension_id()] = sync_data; | 189 grouped_sync_data[data.extension_id()] = sync_data; |
| 193 } | 190 } |
| 194 DCHECK(!sync_data->HasKey(data.key())) << | 191 DCHECK(!sync_data->HasKey(data.key())) << "Duplicate settings for " |
| 195 "Duplicate settings for " << data.extension_id() << "/" << data.key(); | 192 << data.extension_id() << "/" |
| 193 << data.key(); |
| 196 sync_data->SetWithoutPathExpansion(data.key(), data.value().DeepCopy()); | 194 sync_data->SetWithoutPathExpansion(data.key(), data.value().DeepCopy()); |
| 197 } | 195 } |
| 198 | 196 |
| 199 // Start syncing all existing storage areas. Any storage areas created in | 197 // Start syncing all existing storage areas. Any storage areas created in |
| 200 // the future will start being synced as part of the creation process. | 198 // the future will start being synced as part of the creation process. |
| 201 for (StorageObjMap::iterator it = storage_objs_.begin(); | 199 for (StorageObjMap::iterator it = storage_objs_.begin(); |
| 202 it != storage_objs_.end(); ++it) { | 200 it != storage_objs_.end(); |
| 201 ++it) { |
| 203 std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator | 202 std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator |
| 204 maybe_sync_data = grouped_sync_data.find(it->first); | 203 maybe_sync_data = grouped_sync_data.find(it->first); |
| 205 syncer::SyncError error; | 204 syncer::SyncError error; |
| 206 if (maybe_sync_data != grouped_sync_data.end()) { | 205 if (maybe_sync_data != grouped_sync_data.end()) { |
| 207 error = it->second->StartSyncing( | 206 error = it->second->StartSyncing( |
| 208 *maybe_sync_data->second, | 207 *maybe_sync_data->second, |
| 209 CreateSettingsSyncProcessor(it->first).Pass()); | 208 CreateSettingsSyncProcessor(it->first).Pass()); |
| 210 grouped_sync_data.erase(it->first); | 209 grouped_sync_data.erase(it->first); |
| 211 } else { | 210 } else { |
| 212 base::DictionaryValue empty; | 211 base::DictionaryValue empty; |
| 213 error = it->second->StartSyncing( | 212 error = it->second->StartSyncing( |
| 214 empty, | 213 empty, CreateSettingsSyncProcessor(it->first).Pass()); |
| 215 CreateSettingsSyncProcessor(it->first).Pass()); | |
| 216 } | 214 } |
| 217 if (error.IsSet()) | 215 if (error.IsSet()) |
| 218 it->second->StopSyncing(); | 216 it->second->StopSyncing(); |
| 219 } | 217 } |
| 220 | 218 |
| 221 // Eagerly create and init the rest of the storage areas that have sync data. | 219 // Eagerly create and init the rest of the storage areas that have sync data. |
| 222 // Under normal circumstances (i.e. not first-time sync) this will be all of | 220 // Under normal circumstances (i.e. not first-time sync) this will be all of |
| 223 // them. | 221 // them. |
| 224 for (std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator it = | 222 for (std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator it = |
| 225 grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { | 223 grouped_sync_data.begin(); |
| 224 it != grouped_sync_data.end(); |
| 225 ++it) { |
| 226 GetOrCreateStorageWithSyncData(it->first, *it->second); | 226 GetOrCreateStorageWithSyncData(it->first, *it->second); |
| 227 } | 227 } |
| 228 | 228 |
| 229 return syncer::SyncMergeResult(type); | 229 return syncer::SyncMergeResult(type); |
| 230 } | 230 } |
| 231 | 231 |
| 232 syncer::SyncError SettingsBackend::ProcessSyncChanges( | 232 syncer::SyncError SyncStorageBackend::ProcessSyncChanges( |
| 233 const tracked_objects::Location& from_here, | 233 const tracked_objects::Location& from_here, |
| 234 const syncer::SyncChangeList& sync_changes) { | 234 const syncer::SyncChangeList& sync_changes) { |
| 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 236 DCHECK(sync_processor_.get()); | 236 DCHECK(sync_processor_.get()); |
| 237 | 237 |
| 238 // Group changes by extension, to pass all changes in a single method call. | 238 // Group changes by extension, to pass all changes in a single method call. |
| 239 std::map<std::string, SettingSyncDataList> grouped_sync_data; | 239 std::map<std::string, SettingSyncDataList> grouped_sync_data; |
| 240 for (syncer::SyncChangeList::const_iterator it = sync_changes.begin(); | 240 for (syncer::SyncChangeList::const_iterator it = sync_changes.begin(); |
| 241 it != sync_changes.end(); ++it) { | 241 it != sync_changes.end(); |
| 242 ++it) { |
| 242 SettingSyncData data(*it); | 243 SettingSyncData data(*it); |
| 243 grouped_sync_data[data.extension_id()].push_back(data); | 244 grouped_sync_data[data.extension_id()].push_back(data); |
| 244 } | 245 } |
| 245 | 246 |
| 246 // Create any storage areas that don't exist yet but have sync data. | 247 // Create any storage areas that don't exist yet but have sync data. |
| 247 base::DictionaryValue empty; | 248 base::DictionaryValue empty; |
| 248 for (std::map<std::string, SettingSyncDataList>::iterator | 249 for (std::map<std::string, SettingSyncDataList>::iterator it = |
| 249 it = grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { | 250 grouped_sync_data.begin(); |
| 251 it != grouped_sync_data.end(); |
| 252 ++it) { |
| 250 SyncableSettingsStorage* storage = | 253 SyncableSettingsStorage* storage = |
| 251 GetOrCreateStorageWithSyncData(it->first, empty); | 254 GetOrCreateStorageWithSyncData(it->first, empty); |
| 252 syncer::SyncError error = storage->ProcessSyncChanges(it->second); | 255 syncer::SyncError error = storage->ProcessSyncChanges(it->second); |
| 253 if (error.IsSet()) | 256 if (error.IsSet()) |
| 254 storage->StopSyncing(); | 257 storage->StopSyncing(); |
| 255 } | 258 } |
| 256 | 259 |
| 257 return syncer::SyncError(); | 260 return syncer::SyncError(); |
| 258 } | 261 } |
| 259 | 262 |
| 260 void SettingsBackend::StopSyncing(syncer::ModelType type) { | 263 void SyncStorageBackend::StopSyncing(syncer::ModelType type) { |
| 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 262 DCHECK(type == syncer::EXTENSION_SETTINGS || | 265 DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS); |
| 263 type == syncer::APP_SETTINGS); | |
| 264 DCHECK_EQ(sync_type_, type); | 266 DCHECK_EQ(sync_type_, type); |
| 265 | 267 |
| 266 for (StorageObjMap::iterator it = storage_objs_.begin(); | 268 for (StorageObjMap::iterator it = storage_objs_.begin(); |
| 267 it != storage_objs_.end(); ++it) { | 269 it != storage_objs_.end(); |
| 270 ++it) { |
| 268 // Some storage areas may have already stopped syncing if they had areas | 271 // Some storage areas may have already stopped syncing if they had areas |
| 269 // and syncing was disabled, but StopSyncing is safe to call multiple times. | 272 // and syncing was disabled, but StopSyncing is safe to call multiple times. |
| 270 it->second->StopSyncing(); | 273 it->second->StopSyncing(); |
| 271 } | 274 } |
| 272 | 275 |
| 273 sync_processor_.reset(); | 276 sync_processor_.reset(); |
| 274 sync_error_factory_.reset(); | 277 sync_error_factory_.reset(); |
| 275 } | 278 } |
| 276 | 279 |
| 277 scoped_ptr<SettingsSyncProcessor> SettingsBackend::CreateSettingsSyncProcessor( | 280 scoped_ptr<SettingsSyncProcessor> |
| 278 const std::string& extension_id) const { | 281 SyncStorageBackend::CreateSettingsSyncProcessor(const std::string& extension_id) |
| 282 const { |
| 279 CHECK(sync_processor_.get()); | 283 CHECK(sync_processor_.get()); |
| 280 return scoped_ptr<SettingsSyncProcessor>( | 284 return scoped_ptr<SettingsSyncProcessor>(new SettingsSyncProcessor( |
| 281 new SettingsSyncProcessor(extension_id, | 285 extension_id, sync_type_, sync_processor_.get())); |
| 282 sync_type_, | |
| 283 sync_processor_.get())); | |
| 284 } | 286 } |
| 285 | 287 |
| 286 } // namespace extensions | 288 } // namespace extensions |
| OLD | NEW |