| 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/settings_backend.h" | 5 #include "chrome/browser/extensions/settings/settings_backend.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 SettingsBackend::SettingsBackend( | 25 SettingsBackend::SettingsBackend( |
| 26 const scoped_refptr<SettingsStorageFactory>& storage_factory, | 26 const scoped_refptr<SettingsStorageFactory>& storage_factory, |
| 27 const FilePath& base_path, | 27 const FilePath& base_path, |
| 28 const SettingsStorageQuotaEnforcer::Limits& quota, | 28 const SettingsStorageQuotaEnforcer::Limits& quota, |
| 29 const scoped_refptr<SettingsObserverList>& observers) | 29 const scoped_refptr<SettingsObserverList>& observers) |
| 30 : storage_factory_(storage_factory), | 30 : storage_factory_(storage_factory), |
| 31 base_path_(base_path), | 31 base_path_(base_path), |
| 32 quota_(quota), | 32 quota_(quota), |
| 33 observers_(observers), | 33 observers_(observers), |
| 34 sync_type_(syncable::UNSPECIFIED), | 34 sync_type_(syncable::UNSPECIFIED) { |
| 35 sync_processor_(NULL) { | |
| 36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 37 } | 36 } |
| 38 | 37 |
| 39 SettingsBackend::~SettingsBackend() { | 38 SettingsBackend::~SettingsBackend() { |
| 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 41 } | 40 } |
| 42 | 41 |
| 43 SettingsStorage* SettingsBackend::GetStorage( | 42 SettingsStorage* SettingsBackend::GetStorage( |
| 44 const std::string& extension_id) const { | 43 const std::string& extension_id) const { |
| 45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 65 storage = new FailingSettingsStorage(); | 64 storage = new FailingSettingsStorage(); |
| 66 } | 65 } |
| 67 | 66 |
| 68 linked_ptr<SyncableSettingsStorage> syncable_storage( | 67 linked_ptr<SyncableSettingsStorage> syncable_storage( |
| 69 new SyncableSettingsStorage( | 68 new SyncableSettingsStorage( |
| 70 observers_, | 69 observers_, |
| 71 extension_id, | 70 extension_id, |
| 72 storage)); | 71 storage)); |
| 73 storage_objs_[extension_id] = syncable_storage; | 72 storage_objs_[extension_id] = syncable_storage; |
| 74 | 73 |
| 75 if (sync_processor_) { | 74 if (sync_processor_.get()) { |
| 76 SyncError error = | 75 SyncError error = |
| 77 syncable_storage->StartSyncing(sync_type_, sync_data, sync_processor_); | 76 syncable_storage->StartSyncing(sync_type_, |
| 77 sync_data, |
| 78 sync_processor_.get()); |
| 78 if (error.IsSet()) { | 79 if (error.IsSet()) { |
| 79 syncable_storage.get()->StopSyncing(); | 80 syncable_storage.get()->StopSyncing(); |
| 80 } | 81 } |
| 81 } | 82 } |
| 82 | 83 |
| 83 return syncable_storage.get(); | 84 return syncable_storage.get(); |
| 84 } | 85 } |
| 85 | 86 |
| 86 void SettingsBackend::DeleteStorage(const std::string& extension_id) { | 87 void SettingsBackend::DeleteStorage(const std::string& extension_id) { |
| 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 165 } |
| 165 AddAllSyncData(*it, maybe_settings.settings(), type, &all_sync_data); | 166 AddAllSyncData(*it, maybe_settings.settings(), type, &all_sync_data); |
| 166 } | 167 } |
| 167 | 168 |
| 168 return all_sync_data; | 169 return all_sync_data; |
| 169 } | 170 } |
| 170 | 171 |
| 171 SyncError SettingsBackend::MergeDataAndStartSyncing( | 172 SyncError SettingsBackend::MergeDataAndStartSyncing( |
| 172 syncable::ModelType type, | 173 syncable::ModelType type, |
| 173 const SyncDataList& initial_sync_data, | 174 const SyncDataList& initial_sync_data, |
| 174 SyncChangeProcessor* sync_processor) { | 175 scoped_ptr<SyncChangeProcessor> sync_processor) { |
| 175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 176 DCHECK(type == syncable::EXTENSION_SETTINGS || | 177 DCHECK(type == syncable::EXTENSION_SETTINGS || |
| 177 type == syncable::APP_SETTINGS); | 178 type == syncable::APP_SETTINGS); |
| 178 DCHECK_EQ(sync_type_, syncable::UNSPECIFIED); | 179 DCHECK_EQ(sync_type_, syncable::UNSPECIFIED); |
| 179 DCHECK(!sync_processor_); | 180 DCHECK(!sync_processor_.get()); |
| 181 DCHECK(sync_processor.get()); |
| 180 | 182 |
| 181 sync_type_ = type; | 183 sync_type_ = type; |
| 182 sync_processor_ = sync_processor; | 184 sync_processor_ = sync_processor.Pass(); |
| 183 | 185 |
| 184 // Group the initial sync data by extension id. | 186 // Group the initial sync data by extension id. |
| 185 std::map<std::string, linked_ptr<DictionaryValue> > grouped_sync_data; | 187 std::map<std::string, linked_ptr<DictionaryValue> > grouped_sync_data; |
| 186 for (SyncDataList::const_iterator it = initial_sync_data.begin(); | 188 for (SyncDataList::const_iterator it = initial_sync_data.begin(); |
| 187 it != initial_sync_data.end(); ++it) { | 189 it != initial_sync_data.end(); ++it) { |
| 188 SettingSyncData data(*it); | 190 SettingSyncData data(*it); |
| 189 linked_ptr<DictionaryValue> sync_data = | 191 linked_ptr<DictionaryValue> sync_data = |
| 190 grouped_sync_data[data.extension_id()]; | 192 grouped_sync_data[data.extension_id()]; |
| 191 if (!sync_data.get()) { | 193 if (!sync_data.get()) { |
| 192 sync_data = linked_ptr<DictionaryValue>(new DictionaryValue()); | 194 sync_data = linked_ptr<DictionaryValue>(new DictionaryValue()); |
| 193 grouped_sync_data[data.extension_id()] = sync_data; | 195 grouped_sync_data[data.extension_id()] = sync_data; |
| 194 } | 196 } |
| 195 DCHECK(!sync_data->HasKey(data.key())) << | 197 DCHECK(!sync_data->HasKey(data.key())) << |
| 196 "Duplicate settings for " << data.extension_id() << "/" << data.key(); | 198 "Duplicate settings for " << data.extension_id() << "/" << data.key(); |
| 197 sync_data->Set(data.key(), data.value().DeepCopy()); | 199 sync_data->Set(data.key(), data.value().DeepCopy()); |
| 198 } | 200 } |
| 199 | 201 |
| 200 // Start syncing all existing storage areas. Any storage areas created in | 202 // Start syncing all existing storage areas. Any storage areas created in |
| 201 // the future will start being synced as part of the creation process. | 203 // the future will start being synced as part of the creation process. |
| 202 for (StorageObjMap::iterator it = storage_objs_.begin(); | 204 for (StorageObjMap::iterator it = storage_objs_.begin(); |
| 203 it != storage_objs_.end(); ++it) { | 205 it != storage_objs_.end(); ++it) { |
| 204 std::map<std::string, linked_ptr<DictionaryValue> >::iterator | 206 std::map<std::string, linked_ptr<DictionaryValue> >::iterator |
| 205 maybe_sync_data = grouped_sync_data.find(it->first); | 207 maybe_sync_data = grouped_sync_data.find(it->first); |
| 206 SyncError error; | 208 SyncError error; |
| 207 if (maybe_sync_data != grouped_sync_data.end()) { | 209 if (maybe_sync_data != grouped_sync_data.end()) { |
| 208 error = it->second->StartSyncing( | 210 error = it->second->StartSyncing( |
| 209 type, *maybe_sync_data->second, sync_processor); | 211 type, *maybe_sync_data->second, sync_processor_.get()); |
| 210 grouped_sync_data.erase(it->first); | 212 grouped_sync_data.erase(it->first); |
| 211 } else { | 213 } else { |
| 212 DictionaryValue empty; | 214 DictionaryValue empty; |
| 213 error = it->second->StartSyncing(type, empty, sync_processor); | 215 error = it->second->StartSyncing(type, empty, sync_processor_.get()); |
| 214 } | 216 } |
| 215 if (error.IsSet()) { | 217 if (error.IsSet()) { |
| 216 it->second->StopSyncing(); | 218 it->second->StopSyncing(); |
| 217 } | 219 } |
| 218 } | 220 } |
| 219 | 221 |
| 220 // Eagerly create and init the rest of the storage areas that have sync data. | 222 // Eagerly create and init the rest of the storage areas that have sync data. |
| 221 // Under normal circumstances (i.e. not first-time sync) this will be all of | 223 // Under normal circumstances (i.e. not first-time sync) this will be all of |
| 222 // them. | 224 // them. |
| 223 for (std::map<std::string, linked_ptr<DictionaryValue> >::iterator it = | 225 for (std::map<std::string, linked_ptr<DictionaryValue> >::iterator it = |
| 224 grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { | 226 grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { |
| 225 GetOrCreateStorageWithSyncData(it->first, *it->second); | 227 GetOrCreateStorageWithSyncData(it->first, *it->second); |
| 226 } | 228 } |
| 227 | 229 |
| 228 return SyncError(); | 230 return SyncError(); |
| 229 } | 231 } |
| 230 | 232 |
| 231 SyncError SettingsBackend::ProcessSyncChanges( | 233 SyncError SettingsBackend::ProcessSyncChanges( |
| 232 const tracked_objects::Location& from_here, | 234 const tracked_objects::Location& from_here, |
| 233 const SyncChangeList& sync_changes) { | 235 const SyncChangeList& sync_changes) { |
| 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 235 DCHECK(sync_processor_); | 237 DCHECK(sync_processor_.get()); |
| 236 | 238 |
| 237 // Group changes by extension, to pass all changes in a single method call. | 239 // Group changes by extension, to pass all changes in a single method call. |
| 238 std::map<std::string, SettingSyncDataList> grouped_sync_data; | 240 std::map<std::string, SettingSyncDataList> grouped_sync_data; |
| 239 for (SyncChangeList::const_iterator it = sync_changes.begin(); | 241 for (SyncChangeList::const_iterator it = sync_changes.begin(); |
| 240 it != sync_changes.end(); ++it) { | 242 it != sync_changes.end(); ++it) { |
| 241 SettingSyncData data(*it); | 243 SettingSyncData data(*it); |
| 242 grouped_sync_data[data.extension_id()].push_back(data); | 244 grouped_sync_data[data.extension_id()].push_back(data); |
| 243 } | 245 } |
| 244 | 246 |
| 245 // 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. |
| 246 DictionaryValue empty; | 248 DictionaryValue empty; |
| 247 for (std::map<std::string, SettingSyncDataList>::iterator | 249 for (std::map<std::string, SettingSyncDataList>::iterator |
| 248 it = grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { | 250 it = grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { |
| 249 SyncableSettingsStorage* storage = | 251 SyncableSettingsStorage* storage = |
| 250 GetOrCreateStorageWithSyncData(it->first, empty); | 252 GetOrCreateStorageWithSyncData(it->first, empty); |
| 251 SyncError error = storage->ProcessSyncChanges(it->second); | 253 SyncError error = storage->ProcessSyncChanges(it->second); |
| 252 if (error.IsSet()) | 254 if (error.IsSet()) |
| 253 storage->StopSyncing(); | 255 storage->StopSyncing(); |
| 254 } | 256 } |
| 255 | 257 |
| 256 return SyncError(); | 258 return SyncError(); |
| 257 } | 259 } |
| 258 | 260 |
| 259 void SettingsBackend::StopSyncing(syncable::ModelType type) { | 261 void SettingsBackend::StopSyncing(syncable::ModelType type) { |
| 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 261 DCHECK(type == syncable::EXTENSION_SETTINGS || | 263 DCHECK(type == syncable::EXTENSION_SETTINGS || |
| 262 type == syncable::APP_SETTINGS); | 264 type == syncable::APP_SETTINGS); |
| 263 DCHECK_EQ(type, sync_type_); | 265 DCHECK_EQ(type, sync_type_); |
| 264 DCHECK(sync_processor_); | |
| 265 | |
| 266 sync_type_ = syncable::UNSPECIFIED; | |
| 267 sync_processor_ = NULL; | |
| 268 | 266 |
| 269 for (StorageObjMap::iterator it = storage_objs_.begin(); | 267 for (StorageObjMap::iterator it = storage_objs_.begin(); |
| 270 it != storage_objs_.end(); ++it) { | 268 it != storage_objs_.end(); ++it) { |
| 271 // Some storage areas may have already stopped syncing if they had areas | 269 // Some storage areas may have already stopped syncing if they had areas |
| 272 // and syncing was disabled, but StopSyncing is safe to call multiple times. | 270 // and syncing was disabled, but StopSyncing is safe to call multiple times. |
| 273 it->second->StopSyncing(); | 271 it->second->StopSyncing(); |
| 274 } | 272 } |
| 273 |
| 274 sync_type_ = syncable::UNSPECIFIED; |
| 275 sync_processor_.reset(); |
| 275 } | 276 } |
| 276 | 277 |
| 277 } // namespace extensions | 278 } // namespace extensions |
| OLD | NEW |