OLD | NEW |
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/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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 kTotalQuotaBytes, kQuotaPerSettingBytes, kMaxSettingKeys, storage); | 80 kTotalQuotaBytes, kQuotaPerSettingBytes, kMaxSettingKeys, storage); |
81 } else { | 81 } else { |
82 storage = new FailingSettingsStorage(); | 82 storage = new FailingSettingsStorage(); |
83 } | 83 } |
84 | 84 |
85 linked_ptr<SyncableSettingsStorage> syncable_storage( | 85 linked_ptr<SyncableSettingsStorage> syncable_storage( |
86 new SyncableSettingsStorage( | 86 new SyncableSettingsStorage( |
87 observers_, | 87 observers_, |
88 extension_id, | 88 extension_id, |
89 storage)); | 89 storage)); |
| 90 storage_objs_[extension_id] = syncable_storage; |
| 91 |
90 if (sync_processor_) { | 92 if (sync_processor_) { |
91 // TODO(kalman): do something if StartSyncing fails. | 93 SyncError error = |
92 ignore_result(syncable_storage->StartSyncing( | 94 syncable_storage->StartSyncing(sync_type_, sync_data, sync_processor_); |
93 sync_type_, sync_data, sync_processor_)); | 95 if (error.IsSet()) { |
| 96 DisableSyncForExtension(extension_id); |
| 97 } |
94 } | 98 } |
95 | 99 |
96 storage_objs_[extension_id] = syncable_storage; | |
97 return syncable_storage.get(); | 100 return syncable_storage.get(); |
98 } | 101 } |
99 | 102 |
100 void SettingsBackend::DeleteStorage(const std::string& extension_id) { | 103 void SettingsBackend::DeleteStorage(const std::string& extension_id) { |
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
102 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); | 105 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); |
103 if (maybe_storage == storage_objs_.end()) { | 106 if (maybe_storage == storage_objs_.end()) { |
104 return; | 107 return; |
105 } | 108 } |
106 | 109 |
(...skipping 26 matching lines...) Expand all Loading... |
133 // Extension IDs are created as std::strings so they *should* be ASCII. | 136 // Extension IDs are created as std::strings so they *should* be ASCII. |
134 std::string maybe_as_ascii(extension_dir.MaybeAsASCII()); | 137 std::string maybe_as_ascii(extension_dir.MaybeAsASCII()); |
135 if (!maybe_as_ascii.empty()) { | 138 if (!maybe_as_ascii.empty()) { |
136 result.insert(maybe_as_ascii); | 139 result.insert(maybe_as_ascii); |
137 } | 140 } |
138 } | 141 } |
139 | 142 |
140 return result; | 143 return result; |
141 } | 144 } |
142 | 145 |
| 146 void SettingsBackend::DisableSyncForExtension( |
| 147 const std::string& extension_id) const { |
| 148 linked_ptr<SyncableSettingsStorage> storage = storage_objs_[extension_id]; |
| 149 DCHECK(storage.get()); |
| 150 storage->StopSyncing(); |
| 151 } |
| 152 |
143 static void AddAllSyncData( | 153 static void AddAllSyncData( |
144 const std::string& extension_id, | 154 const std::string& extension_id, |
145 const DictionaryValue& src, | 155 const DictionaryValue& src, |
146 SyncDataList* dst) { | 156 SyncDataList* dst) { |
147 for (DictionaryValue::Iterator it(src); it.HasNext(); it.Advance()) { | 157 for (DictionaryValue::Iterator it(src); it.HasNext(); it.Advance()) { |
148 dst->push_back( | 158 dst->push_back( |
149 settings_sync_util::CreateData(extension_id, it.key(), it.value())); | 159 settings_sync_util::CreateData(extension_id, it.key(), it.value())); |
150 } | 160 } |
151 } | 161 } |
152 | 162 |
153 SyncDataList SettingsBackend::GetAllSyncData( | 163 SyncDataList SettingsBackend::GetAllSyncData( |
154 syncable::ModelType type) const { | 164 syncable::ModelType type) const { |
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
156 // Ignore the type, it's just for sanity checking; assume that whatever base | 166 // Ignore the type, it's just for sanity checking; assume that whatever base |
157 // path we're constructed with is correct for the sync type. | 167 // path we're constructed with is correct for the sync type. |
158 DCHECK(type == syncable::EXTENSION_SETTINGS || | 168 DCHECK(type == syncable::EXTENSION_SETTINGS || |
159 type == syncable::APP_SETTINGS); | 169 type == syncable::APP_SETTINGS); |
160 | 170 |
161 // For all extensions, get all their settings. This has the effect | 171 // For all extensions, get all their settings. This has the effect |
162 // of bringing in the entire state of extension settings in memory; sad. | 172 // of bringing in the entire state of extension settings in memory; sad. |
163 SyncDataList all_sync_data; | 173 SyncDataList all_sync_data; |
164 std::set<std::string> known_extension_ids(GetKnownExtensionIDs()); | 174 std::set<std::string> known_extension_ids(GetKnownExtensionIDs()); |
165 | 175 |
166 for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); | 176 for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); |
167 it != known_extension_ids.end(); ++it) { | 177 it != known_extension_ids.end(); ++it) { |
168 SettingsStorage::ReadResult maybe_settings = | 178 SettingsStorage::ReadResult maybe_settings = GetStorage(*it)->Get(); |
169 GetStorage(*it)->Get(); | |
170 if (maybe_settings.HasError()) { | 179 if (maybe_settings.HasError()) { |
171 LOG(WARNING) << "Failed to get settings for " << *it << ": " << | 180 LOG(WARNING) << "Failed to get settings for " << *it << ": " << |
172 maybe_settings.error(); | 181 maybe_settings.error(); |
173 continue; | 182 continue; |
174 } | 183 } |
175 AddAllSyncData(*it, maybe_settings.settings(), &all_sync_data); | 184 AddAllSyncData(*it, maybe_settings.settings(), &all_sync_data); |
176 } | 185 } |
177 | 186 |
178 return all_sync_data; | 187 return all_sync_data; |
179 } | 188 } |
(...skipping 26 matching lines...) Expand all Loading... |
206 "Duplicate settings for " << data.extension_id() << "/" << data.key(); | 215 "Duplicate settings for " << data.extension_id() << "/" << data.key(); |
207 sync_data->Set(data.key(), data.value().DeepCopy()); | 216 sync_data->Set(data.key(), data.value().DeepCopy()); |
208 } | 217 } |
209 | 218 |
210 // Start syncing all existing storage areas. Any storage areas created in | 219 // Start syncing all existing storage areas. Any storage areas created in |
211 // the future will start being synced as part of the creation process. | 220 // the future will start being synced as part of the creation process. |
212 for (StorageObjMap::iterator it = storage_objs_.begin(); | 221 for (StorageObjMap::iterator it = storage_objs_.begin(); |
213 it != storage_objs_.end(); ++it) { | 222 it != storage_objs_.end(); ++it) { |
214 std::map<std::string, linked_ptr<DictionaryValue> >::iterator | 223 std::map<std::string, linked_ptr<DictionaryValue> >::iterator |
215 maybe_sync_data = grouped_sync_data.find(it->first); | 224 maybe_sync_data = grouped_sync_data.find(it->first); |
| 225 SyncError error; |
216 if (maybe_sync_data != grouped_sync_data.end()) { | 226 if (maybe_sync_data != grouped_sync_data.end()) { |
217 // TODO(kalman): do something if StartSyncing fails. | 227 error = it->second->StartSyncing( |
218 ignore_result( | 228 type, *maybe_sync_data->second, sync_processor); |
219 it->second->StartSyncing( | |
220 type, *maybe_sync_data->second, sync_processor)); | |
221 grouped_sync_data.erase(it->first); | 229 grouped_sync_data.erase(it->first); |
222 } else { | 230 } else { |
223 DictionaryValue empty; | 231 DictionaryValue empty; |
224 // TODO(kalman): do something if StartSyncing fails. | 232 error = it->second->StartSyncing(type, empty, sync_processor); |
225 ignore_result(it->second->StartSyncing(type, empty, sync_processor)); | 233 } |
| 234 if (error.IsSet()) { |
| 235 DisableSyncForExtension(it->first); |
226 } | 236 } |
227 } | 237 } |
228 | 238 |
229 // Eagerly create and init the rest of the storage areas that have sync data. | 239 // Eagerly create and init the rest of the storage areas that have sync data. |
230 // Under normal circumstances (i.e. not first-time sync) this will be all of | 240 // Under normal circumstances (i.e. not first-time sync) this will be all of |
231 // them. | 241 // them. |
232 for (std::map<std::string, linked_ptr<DictionaryValue> >::iterator it = | 242 for (std::map<std::string, linked_ptr<DictionaryValue> >::iterator it = |
233 grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { | 243 grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { |
234 GetOrCreateStorageWithSyncData(it->first, *it->second); | 244 GetOrCreateStorageWithSyncData(it->first, *it->second); |
235 } | 245 } |
(...skipping 12 matching lines...) Expand all Loading... |
248 for (SyncChangeList::const_iterator it = sync_changes.begin(); | 258 for (SyncChangeList::const_iterator it = sync_changes.begin(); |
249 it != sync_changes.end(); ++it) { | 259 it != sync_changes.end(); ++it) { |
250 SettingSyncData data(*it); | 260 SettingSyncData data(*it); |
251 grouped_sync_data[data.extension_id()].push_back(data); | 261 grouped_sync_data[data.extension_id()].push_back(data); |
252 } | 262 } |
253 | 263 |
254 // Create any storage areas that don't exist yet but have sync data. | 264 // Create any storage areas that don't exist yet but have sync data. |
255 DictionaryValue empty; | 265 DictionaryValue empty; |
256 for (std::map<std::string, SettingSyncDataList>::iterator | 266 for (std::map<std::string, SettingSyncDataList>::iterator |
257 it = grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { | 267 it = grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) { |
258 // TODO(kalman): do something if ProcessSyncChanges fails. | 268 SyncError error = |
259 ignore_result( | |
260 GetOrCreateStorageWithSyncData(it->first, empty)-> | 269 GetOrCreateStorageWithSyncData(it->first, empty)-> |
261 ProcessSyncChanges(it->second)); | 270 ProcessSyncChanges(it->second); |
| 271 if (error.IsSet()) { |
| 272 DisableSyncForExtension(it->first); |
| 273 } |
262 } | 274 } |
263 | 275 |
264 return SyncError(); | 276 return SyncError(); |
265 } | 277 } |
266 | 278 |
267 void SettingsBackend::StopSyncing(syncable::ModelType type) { | 279 void SettingsBackend::StopSyncing(syncable::ModelType type) { |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
269 DCHECK(type == syncable::EXTENSION_SETTINGS || | 281 DCHECK(type == syncable::EXTENSION_SETTINGS || |
270 type == syncable::APP_SETTINGS); | 282 type == syncable::APP_SETTINGS); |
271 DCHECK_EQ(type, sync_type_); | 283 DCHECK_EQ(type, sync_type_); |
272 DCHECK(sync_processor_); | 284 DCHECK(sync_processor_); |
273 | 285 |
274 sync_type_ = syncable::UNSPECIFIED; | 286 sync_type_ = syncable::UNSPECIFIED; |
275 sync_processor_ = NULL; | 287 sync_processor_ = NULL; |
276 | 288 |
277 for (StorageObjMap::iterator it = storage_objs_.begin(); | 289 for (StorageObjMap::iterator it = storage_objs_.begin(); |
278 it != storage_objs_.end(); ++it) { | 290 it != storage_objs_.end(); ++it) { |
| 291 // Some storage areas may have already stopped syncing if they had areas |
| 292 // and syncing was disabled, but StopSyncing is safe to call multiple times. |
279 it->second->StopSyncing(); | 293 it->second->StopSyncing(); |
280 } | 294 } |
281 } | 295 } |
282 | 296 |
283 } // namespace extensions | 297 } // namespace extensions |
OLD | NEW |