Chromium Code Reviews| Index: components/sync_driver/generic_change_processor.cc |
| diff --git a/components/sync_driver/generic_change_processor.cc b/components/sync_driver/generic_change_processor.cc |
| index adc4c90ed42d96897330b9168588cea05beb58b3..699d414c2dd06646a4df4589577f63465495a151 100644 |
| --- a/components/sync_driver/generic_change_processor.cc |
| +++ b/components/sync_driver/generic_change_processor.cc |
| @@ -36,6 +36,27 @@ void SetNodeSpecifics(const sync_pb::EntitySpecifics& entity_specifics, |
| } |
| } |
| +// Helper function to convert AttachmentId to AttachmentMetadataRecord. |
| +sync_pb::AttachmentMetadataRecord AttachmentIdToRecord( |
| + const syncer::AttachmentId& attachment_id) { |
| + sync_pb::AttachmentMetadataRecord record; |
| + *record.mutable_id() = attachment_id.GetProto(); |
| + return record; |
| +} |
| + |
| +// Replace |write_nodes|'s attachment ids with |attachment_ids|. |
| +void SetAttachmentMetadata(const syncer::AttachmentIdList& attachment_ids, |
| + syncer::WriteNode* write_node) { |
| + DCHECK(write_node); |
| + sync_pb::AttachmentMetadata attachment_metadata; |
| + std::transform( |
| + attachment_ids.begin(), |
| + attachment_ids.end(), |
| + RepeatedFieldBackInserter(attachment_metadata.mutable_record()), |
| + AttachmentIdToRecord); |
| + write_node->SetAttachmentMetadata(attachment_metadata); |
| +} |
| + |
| syncer::SyncData BuildRemoteSyncData( |
| int64 sync_id, |
| const syncer::BaseNode& read_node, |
| @@ -319,8 +340,7 @@ syncer::SyncError LogLookupFailure( |
| } |
| } |
| -syncer::SyncError AttemptDelete( |
| - const syncer::SyncChange& change, |
| +syncer::SyncError AttemptDelete(const syncer::SyncChange& change, |
| syncer::ModelType type, |
|
pavely
2014/04/28 23:26:27
nit: Indentation is off.
maniscalco
2014/04/29 20:53:22
Fixed (and ran through "git cl format").
|
| const std::string& type_str, |
| syncer::WriteNode* node, |
| @@ -368,12 +388,30 @@ syncer::SyncError AttemptDelete( |
| return syncer::SyncError(); |
| } |
| +// A callback invoked on completion of AttachmentService::StoreAttachment. |
| +void IgnoreStoreResult(const syncer::AttachmentService::StoreResult&) { |
| + // TODO(maniscalco): Log errors? |
| +} |
| + |
| +void StoreAttachments(syncer::AttachmentService* attachment_service, |
| + const syncer::AttachmentList& attachments) { |
| + DCHECK(attachment_service); |
| + syncer::AttachmentService::StoreCallback ignore_store_result = |
| + base::Bind(&IgnoreStoreResult); |
| + attachment_service->StoreAttachments(attachments, ignore_store_result); |
| +} |
| + |
| } // namespace |
| syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( |
| const tracked_objects::Location& from_here, |
| const syncer::SyncChangeList& list_of_changes) { |
| DCHECK(CalledOnValidThread()); |
| + |
| + // Keep track of brand new attachments so we can persist them on this device |
| + // and upload them to the server. |
| + syncer::AttachmentList new_attachments; |
| + |
| syncer::WriteTransaction trans(from_here, share_handle()); |
| for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); |
| @@ -391,20 +429,19 @@ syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( |
| NOTREACHED(); |
| return error; |
| } |
| - attachment_service_->OnSyncDataDelete(change.sync_data()); |
| if (merge_result_.get()) { |
| merge_result_->set_num_items_deleted( |
| merge_result_->num_items_deleted() + 1); |
| } |
| } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { |
| - syncer::SyncError error = |
| - HandleActionAdd(change, type_str, type, trans, &sync_node); |
| + syncer::SyncError error = HandleActionAdd( |
| + change, type_str, type, trans, &sync_node, &new_attachments); |
| if (error.IsSet()) { |
| return error; |
| } |
| } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) { |
| - syncer::SyncError error = |
| - HandleActionUpdate(change, type_str, type, trans, &sync_node); |
| + syncer::SyncError error = HandleActionUpdate( |
| + change, type_str, type, trans, &sync_node, &new_attachments); |
| if (error.IsSet()) { |
| return error; |
| } |
| @@ -422,6 +459,11 @@ syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( |
| return error; |
| } |
| } |
| + |
| + if (!new_attachments.empty()) { |
| + StoreAttachments(attachment_service_.get(), new_attachments); |
| + } |
| + |
| return syncer::SyncError(); |
| } |
| @@ -434,12 +476,14 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd( |
| const std::string& type_str, |
| const syncer::ModelType& type, |
| const syncer::WriteTransaction& trans, |
| - syncer::WriteNode* sync_node) { |
| + syncer::WriteNode* sync_node, |
| + syncer::AttachmentList* new_attachments) { |
| // TODO(sync): Handle other types of creation (custom parents, folders, |
| // etc.). |
| syncer::ReadNode root_node(&trans); |
| + const syncer::SyncDataLocal sync_data_local(change.sync_data()); |
| if (root_node.InitByTagLookup(syncer::ModelTypeToRootTag( |
| - change.sync_data().GetDataType())) != syncer::BaseNode::INIT_OK) { |
| + sync_data_local.GetDataType())) != syncer::BaseNode::INIT_OK) { |
| syncer::SyncError error(FROM_HERE, |
| syncer::SyncError::DATATYPE_ERROR, |
| "Failed to look up root node for type " + type_str, |
| @@ -452,9 +496,7 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd( |
| } |
| syncer::WriteNode::InitUniqueByCreationResult result = |
| sync_node->InitUniqueByCreation( |
| - change.sync_data().GetDataType(), |
| - root_node, |
| - syncer::SyncDataLocal(change.sync_data()).GetTag()); |
| + sync_data_local.GetDataType(), root_node, sync_data_local.GetTag()); |
| if (result != syncer::WriteNode::INIT_SUCCESS) { |
| std::string error_prefix = "Failed to create " + type_str + " node: " + |
| change.location().ToString() + ", "; |
| @@ -503,8 +545,18 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd( |
| } |
| } |
| sync_node->SetTitle(change.sync_data().GetTitle()); |
| - SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node); |
| - attachment_service_->OnSyncDataAdd(change.sync_data()); |
| + SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); |
| + |
| + syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); |
| + SetAttachmentMetadata(attachment_ids, sync_node); |
| + |
| + // Return any newly added attachments. |
| + const syncer::AttachmentList& local_attachments_for_upload = |
| + sync_data_local.GetLocalAttachmentsForUpload(); |
| + new_attachments->insert(new_attachments->end(), |
| + local_attachments_for_upload.begin(), |
| + local_attachments_for_upload.end()); |
| + |
| if (merge_result_.get()) { |
| merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); |
| } |
| @@ -519,12 +571,14 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate( |
| const std::string& type_str, |
| const syncer::ModelType& type, |
| const syncer::WriteTransaction& trans, |
| - syncer::WriteNode* sync_node) { |
| + syncer::WriteNode* sync_node, |
| + syncer::AttachmentList* new_attachments) { |
| // TODO(zea): consider having this logic for all possible changes? |
| + |
| + const syncer::SyncDataLocal sync_data_local(change.sync_data()); |
| syncer::BaseNode::InitByLookupResult result = |
| - sync_node->InitByClientTagLookup( |
| - change.sync_data().GetDataType(), |
| - syncer::SyncDataLocal(change.sync_data()).GetTag()); |
| + sync_node->InitByClientTagLookup(sync_data_local.GetDataType(), |
| + sync_data_local.GetTag()); |
| if (result != syncer::BaseNode::INIT_OK) { |
| std::string error_prefix = "Failed to load " + type_str + " node. " + |
| change.location().ToString() + ", "; |
| @@ -606,9 +660,16 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate( |
| } |
| sync_node->SetTitle(change.sync_data().GetTitle()); |
| - SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node); |
| - attachment_service_->OnSyncDataUpdate(sync_node->GetAttachmentIds(), |
| - change.sync_data()); |
| + SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); |
| + SetAttachmentMetadata(sync_data_local.GetAttachmentIds(), sync_node); |
| + |
| + // Return any newly added attachments. |
| + const syncer::AttachmentList& local_attachments_for_upload = |
| + sync_data_local.GetLocalAttachmentsForUpload(); |
| + new_attachments->insert(new_attachments->end(), |
| + local_attachments_for_upload.begin(), |
| + local_attachments_for_upload.end()); |
| + |
| if (merge_result_.get()) { |
| merge_result_->set_num_items_modified(merge_result_->num_items_modified() + |
| 1); |