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/syncable_extension_settings_storage.h" | 5 #include "chrome/browser/extensions/syncable_extension_settings_storage.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "chrome/browser/extensions/extension_settings_sync_util.h" | 8 #include "chrome/browser/extensions/extension_settings_sync_util.h" |
9 #include "chrome/browser/sync/api/sync_data.h" | 9 #include "chrome/browser/sync/api/sync_data.h" |
10 #include "chrome/browser/sync/protocol/extension_setting_specifics.pb.h" | 10 #include "chrome/browser/sync/protocol/extension_setting_specifics.pb.h" |
11 #include "content/browser/browser_thread.h" | 11 #include "content/browser/browser_thread.h" |
12 | 12 |
13 SyncableExtensionSettingsStorage::SyncableExtensionSettingsStorage( | 13 SyncableExtensionSettingsStorage::SyncableExtensionSettingsStorage( |
14 std::string extension_id, ExtensionSettingsStorage* delegate) | 14 ObserverListThreadSafe<ExtensionSettingsObserver>* observers, |
15 : extension_id_(extension_id), delegate_(delegate), sync_processor_(NULL) { | 15 std::string extension_id, |
16 ExtensionSettingsStorage* delegate) | |
17 : observers_(observers), | |
18 extension_id_(extension_id), | |
19 delegate_(delegate), | |
20 sync_processor_(NULL) { | |
16 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 21 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
17 } | 22 } |
18 | 23 |
19 SyncableExtensionSettingsStorage::~SyncableExtensionSettingsStorage() { | 24 SyncableExtensionSettingsStorage::~SyncableExtensionSettingsStorage() { |
20 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 25 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
21 } | 26 } |
22 | 27 |
23 ExtensionSettingsStorage::Result SyncableExtensionSettingsStorage::Get( | 28 ExtensionSettingsStorage::Result SyncableExtensionSettingsStorage::Get( |
24 const std::string& key) { | 29 const std::string& key) { |
25 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 } | 223 } |
219 | 224 |
220 std::vector<SyncError> SyncableExtensionSettingsStorage::ProcessSyncChanges( | 225 std::vector<SyncError> SyncableExtensionSettingsStorage::ProcessSyncChanges( |
221 const ExtensionSettingSyncDataList& sync_changes) { | 226 const ExtensionSettingSyncDataList& sync_changes) { |
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
223 DCHECK(sync_processor_); | 228 DCHECK(sync_processor_); |
224 DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_; | 229 DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_; |
225 | 230 |
226 std::vector<SyncError> errors; | 231 std::vector<SyncError> errors; |
227 | 232 |
233 // Change event to build then send to onChanged listeners of the settings API. | |
234 ExtensionSettingsObserver::ChangeList change_event; | |
235 | |
228 for (ExtensionSettingSyncDataList::const_iterator it = sync_changes.begin(); | 236 for (ExtensionSettingSyncDataList::const_iterator it = sync_changes.begin(); |
229 it != sync_changes.end(); ++it) { | 237 it != sync_changes.end(); ++it) { |
230 DCHECK_EQ(extension_id_, it->extension_id()); | 238 DCHECK_EQ(extension_id_, it->extension_id()); |
239 | |
240 scoped_ptr<Value> current_value; | |
241 { | |
242 Result maybe_settings = Get(it->key()); | |
243 if (maybe_settings.HasError()) { | |
244 errors.push_back(SyncError( | |
245 FROM_HERE, | |
246 std::string("Error getting current sync state for ") + | |
Matt Perry
2011/10/07 22:39:52
use StringPrintf
not at google - send to devlin
2011/10/13 06:40:43
...
akalin
2011/10/13 20:40:41
Ah, so that's why it happened. Why? StringPrintf
Matt Perry
2011/10/13 23:20:24
I disagree. StringPrintf is perfectly typesafe if
| |
247 extension_id_ + "/" + it->key() + ": " + | |
248 maybe_settings.GetError(), | |
249 syncable::EXTENSION_SETTINGS)); | |
250 continue; | |
251 } | |
252 if (maybe_settings.GetSettings() != NULL) { | |
253 Value* value_ownership = NULL; | |
254 maybe_settings.GetSettings()->RemoveWithoutPathExpansion( | |
255 it->key(), &value_ownership); | |
256 current_value.reset(value_ownership); | |
257 } | |
258 } | |
259 | |
231 switch (it->change_type()) { | 260 switch (it->change_type()) { |
232 case SyncChange::ACTION_ADD: | 261 case SyncChange::ACTION_ADD: { |
233 case SyncChange::ACTION_UPDATE: { | 262 if (current_value.get()) { |
263 errors.push_back(SyncError( | |
akalin
2011/10/07 21:06:23
i don't know if this should be an error -- it's po
not at google - send to devlin
2011/10/10 01:00:16
Probably... maybe? If somebody adds a key then it
| |
264 FROM_HERE, | |
265 std::string("Got add from sync for existing setting ") + | |
266 extension_id_ + "/" + it->key(), | |
267 syncable::EXTENSION_SETTINGS)); | |
268 break; | |
269 } | |
270 | |
234 synced_keys_.insert(it->key()); | 271 synced_keys_.insert(it->key()); |
235 Result result = delegate_->Set(it->key(), it->value()); | 272 Result result = delegate_->Set(it->key(), it->value()); |
236 if (result.HasError()) { | 273 if (result.HasError()) { |
237 errors.push_back(SyncError( | 274 errors.push_back(SyncError( |
238 FROM_HERE, | 275 FROM_HERE, |
239 std::string("Error pushing sync change to local settings: ") + | 276 std::string("Error pushing sync add to local settings: ") + |
240 result.GetError(), | 277 result.GetError(), |
241 syncable::EXTENSION_SETTINGS)); | 278 syncable::EXTENSION_SETTINGS)); |
279 break; | |
242 } | 280 } |
281 | |
282 change_event.AppendChange(it->key(), NULL, it->value().DeepCopy()); | |
283 break; | |
284 } | |
285 | |
286 case SyncChange::ACTION_UPDATE: { | |
287 if (!current_value.get()) { | |
akalin
2011/10/07 21:06:23
same here -- local delete, update from sync. mayb
not at google - send to devlin
2011/10/10 01:00:16
Ditto.
Btw assuming sync *does* just send the add
| |
288 errors.push_back(SyncError( | |
289 FROM_HERE, | |
290 std::string("Got update from sync for nonexistent setting ") + | |
291 extension_id_ + "/" + it->key(), | |
292 syncable::EXTENSION_SETTINGS)); | |
293 break; | |
294 } | |
295 | |
296 synced_keys_.insert(it->key()); | |
297 Result result = delegate_->Set(it->key(), it->value()); | |
298 if (result.HasError()) { | |
299 errors.push_back(SyncError( | |
300 FROM_HERE, | |
301 std::string("Error pushing sync update to local settings: ") + | |
302 result.GetError(), | |
303 syncable::EXTENSION_SETTINGS)); | |
304 break; | |
305 } | |
306 | |
307 change_event.AppendChange( | |
308 it->key(), current_value.release(), it->value().DeepCopy()); | |
243 break; | 309 break; |
244 } | 310 } |
245 | 311 |
246 case SyncChange::ACTION_DELETE: { | 312 case SyncChange::ACTION_DELETE: { |
313 if (!current_value.get()) { | |
akalin
2011/10/07 21:06:23
yeah, this should be a warning, too
not at google - send to devlin
2011/10/10 01:00:16
Ditto.
| |
314 errors.push_back(SyncError( | |
315 FROM_HERE, | |
316 std::string("Got delete from sync for nonexistent setting ") + | |
317 extension_id_ + "/" + it->key(), | |
318 syncable::EXTENSION_SETTINGS)); | |
319 break; | |
320 } | |
321 | |
247 synced_keys_.erase(it->key()); | 322 synced_keys_.erase(it->key()); |
248 Result result = delegate_->Remove(it->key()); | 323 Result result = delegate_->Remove(it->key()); |
249 if (result.HasError()) { | 324 if (result.HasError()) { |
250 errors.push_back(SyncError( | 325 errors.push_back(SyncError( |
251 FROM_HERE, | 326 FROM_HERE, |
252 std::string("Error removing sync change from local settings: ") + | 327 std::string("Error removing sync change from local settings: ") + |
253 result.GetError(), | 328 result.GetError(), |
254 syncable::EXTENSION_SETTINGS)); | 329 syncable::EXTENSION_SETTINGS)); |
330 break; | |
255 } | 331 } |
332 | |
333 change_event.AppendChange(it->key(), current_value.release(), NULL); | |
256 break; | 334 break; |
257 } | 335 } |
258 | 336 |
259 default: | 337 default: |
260 NOTREACHED(); | 338 NOTREACHED(); |
261 } | 339 } |
262 } | 340 } |
263 | 341 |
342 observers_->Notify( | |
343 &ExtensionSettingsObserver::OnSettingsChanged, | |
344 static_cast<Profile*>(NULL), | |
345 extension_id_, | |
346 change_event.GetEventJson()); | |
347 | |
264 return errors; | 348 return errors; |
265 } | 349 } |
266 | 350 |
267 void SyncableExtensionSettingsStorage::SendAddsOrUpdatesToSync( | 351 void SyncableExtensionSettingsStorage::SendAddsOrUpdatesToSync( |
268 const std::set<std::string>& changed_keys, | 352 const std::set<std::string>& changed_keys, |
269 const DictionaryValue& settings) { | 353 const DictionaryValue& settings) { |
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
271 DCHECK(sync_processor_); | 355 DCHECK(sync_processor_); |
272 DCHECK(!changed_keys.empty()); | 356 DCHECK(!changed_keys.empty()); |
273 | 357 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 if (error.IsSet()) { | 400 if (error.IsSet()) { |
317 LOG(WARNING) << "Failed to send changes to sync: " << error.message(); | 401 LOG(WARNING) << "Failed to send changes to sync: " << error.message(); |
318 return; | 402 return; |
319 } | 403 } |
320 | 404 |
321 for (std::set<std::string>::const_iterator it = keys.begin(); | 405 for (std::set<std::string>::const_iterator it = keys.begin(); |
322 it != keys.end(); ++it) { | 406 it != keys.end(); ++it) { |
323 synced_keys_.erase(*it); | 407 synced_keys_.erase(*it); |
324 } | 408 } |
325 } | 409 } |
OLD | NEW |