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 |