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( |