Chromium Code Reviews| Index: components/sync_driver/device_info_service.cc |
| diff --git a/components/sync_driver/device_info_service.cc b/components/sync_driver/device_info_service.cc |
| index 1049ede177b58a96b9ca0b05a0ab412e7c140242..639197e9af33d030d3e6c2c54e36bbd522ff8723 100644 |
| --- a/components/sync_driver/device_info_service.cc |
| +++ b/components/sync_driver/device_info_service.cc |
| @@ -4,6 +4,7 @@ |
| #include "components/sync_driver/device_info_service.h" |
| +#include <set> |
| #include <utility> |
| #include <vector> |
| @@ -25,6 +26,7 @@ using syncer_v2::EntityChange; |
| using syncer_v2::EntityChangeList; |
| using syncer_v2::EntityData; |
| using syncer_v2::EntityDataList; |
| +using syncer_v2::EntityDataPtr; |
| using syncer_v2::MetadataBatch; |
| using syncer_v2::MetadataChangeList; |
| using syncer_v2::ModelTypeStore; |
| @@ -69,8 +71,54 @@ scoped_ptr<MetadataChangeList> DeviceInfoService::CreateMetadataChangeList() { |
| SyncError DeviceInfoService::MergeSyncData( |
| scoped_ptr<MetadataChangeList> metadata_change_list, |
| EntityDataList entity_data_list) { |
| - // TODO(skym): crbug.com/543406: Implementation. |
| - return SyncError(); |
| + if (!has_provider_initialized_ || !has_data_loaded_ || !change_processor()) { |
| + return SyncError( |
| + FROM_HERE, SyncError::DATATYPE_ERROR, |
| + "Cannot call MergeSyncData without provider, data, and processor.", |
| + syncer::DEVICE_INFO); |
| + } |
| + |
| + // Local data should typically be near empty, with the only possible value |
| + // corresponding to this device. This is because on signout all device info |
| + // data is blown away. However, this simplification is being ignored here and |
| + // a full difference is going to be calculated to explore what other service |
| + // implementations may look like. |
| + std::set<std::string> local_only_tags; |
| + for (auto& kv : all_data_) { |
|
maxbogue
2016/02/23 01:04:02
"const auto&"?
skym
2016/03/04 20:28:10
Done.
|
| + local_only_tags.insert(kv.first); |
| + } |
| + |
| + std::string local_tag = |
| + local_device_info_provider_->GetLocalDeviceInfo()->guid(); |
| + scoped_ptr<WriteBatch> batch = store_->CreateWriteBatch(); |
| + for (EntityDataPtr& entity_data_ptr : entity_data_list) { |
|
maxbogue
2016/02/23 01:04:02
"const EntityDataPtr&"?
skym
2016/03/04 20:28:10
Done.
|
| + const std::string tag = GetClientTag(entity_data_ptr.value()); |
| + const DeviceInfoSpecifics& specifics = |
| + entity_data_ptr.value().specifics.device_info(); |
| + |
| + // Ignore any remote changes that have our local cache guid. |
| + if (tag == local_tag) { |
| + continue; |
| + } |
| + |
| + // Remote data wins conflicts. |
| + local_only_tags.erase(tag); |
| + StoreSpecifics(make_scoped_ptr(new DeviceInfoSpecifics(specifics)), |
| + batch.get()); |
| + } |
| + |
| + for (const std::string& tag : local_only_tags) { |
| + change_processor()->Put(tag, CopyIntoNewEntityData(*all_data_[tag].get()), |
|
maxbogue
2016/02/23 01:04:02
Nit: pretty sure the .get() is superfluous here an
skym
2016/03/04 20:28:10
TIL. Done.
|
| + metadata_change_list.get()); |
| + } |
| + |
| + // Transfer at the end because processor Put calls may update metadata. |
| + static_cast<SimpleMetadataChangeList*>(metadata_change_list.get()) |
| + ->TransferChanges(store_.get(), batch.get()); |
| + store_->CommitWriteBatch( |
| + std::move(batch), |
| + base::Bind(&DeviceInfoService::OnCommit, weak_factory_.GetWeakPtr())); |
|
skym
2016/02/22 17:43:10
Should be calling NotifyObservers(); at the end of
skym
2016/03/04 20:28:10
Done.
|
| + return syncer::SyncError(); |
| } |
| SyncError DeviceInfoService::ApplySyncChanges( |