OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/sync_driver/generic_change_processor.h" | 5 #include "components/sync_driver/generic_change_processor.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "components/sync_driver/sync_api_component_factory.h" | 10 #include "components/sync_driver/sync_api_component_factory.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 return attachment.GetId(); | 90 return attachment.GetId(); |
91 } | 91 } |
92 | 92 |
93 } // namespace | 93 } // namespace |
94 | 94 |
95 GenericChangeProcessor::GenericChangeProcessor( | 95 GenericChangeProcessor::GenericChangeProcessor( |
96 DataTypeErrorHandler* error_handler, | 96 DataTypeErrorHandler* error_handler, |
97 const base::WeakPtr<syncer::SyncableService>& local_service, | 97 const base::WeakPtr<syncer::SyncableService>& local_service, |
98 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, | 98 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, |
99 syncer::UserShare* user_share, | 99 syncer::UserShare* user_share, |
100 SyncApiComponentFactory* sync_factory) | 100 SyncApiComponentFactory* sync_factory, |
| 101 const scoped_refptr<syncer::AttachmentStore>& attachment_store) |
101 : ChangeProcessor(error_handler), | 102 : ChangeProcessor(error_handler), |
102 local_service_(local_service), | 103 local_service_(local_service), |
103 merge_result_(merge_result), | 104 merge_result_(merge_result), |
104 share_handle_(user_share), | 105 share_handle_(user_share), |
105 attachment_service_( | |
106 sync_factory->CreateAttachmentService(*user_share, this)), | |
107 attachment_service_weak_ptr_factory_(attachment_service_.get()), | |
108 attachment_service_proxy_( | |
109 base::MessageLoopProxy::current(), | |
110 attachment_service_weak_ptr_factory_.GetWeakPtr()), | |
111 weak_ptr_factory_(this) { | 106 weak_ptr_factory_(this) { |
112 DCHECK(CalledOnValidThread()); | 107 DCHECK(CalledOnValidThread()); |
113 DCHECK(attachment_service_); | 108 if (attachment_store.get()) { |
| 109 attachment_service_ = sync_factory->CreateAttachmentService( |
| 110 attachment_store, *user_share, this); |
| 111 attachment_service_weak_ptr_factory_.reset( |
| 112 new base::WeakPtrFactory<syncer::AttachmentService>( |
| 113 attachment_service_.get())); |
| 114 attachment_service_proxy_.reset(new syncer::AttachmentServiceProxy( |
| 115 base::MessageLoopProxy::current(), |
| 116 attachment_service_weak_ptr_factory_->GetWeakPtr())); |
| 117 } else { |
| 118 attachment_service_proxy_.reset(new syncer::AttachmentServiceProxy( |
| 119 base::MessageLoopProxy::current(), |
| 120 base::WeakPtr<syncer::AttachmentService>())); |
| 121 } |
114 } | 122 } |
115 | 123 |
116 GenericChangeProcessor::~GenericChangeProcessor() { | 124 GenericChangeProcessor::~GenericChangeProcessor() { |
117 DCHECK(CalledOnValidThread()); | 125 DCHECK(CalledOnValidThread()); |
118 } | 126 } |
119 | 127 |
120 void GenericChangeProcessor::ApplyChangesFromSyncModel( | 128 void GenericChangeProcessor::ApplyChangesFromSyncModel( |
121 const syncer::BaseTransaction* trans, | 129 const syncer::BaseTransaction* trans, |
122 int64 model_version, | 130 int64 model_version, |
123 const syncer::ImmutableChangeRecordList& changes) { | 131 const syncer::ImmutableChangeRecordList& changes) { |
(...skipping 11 matching lines...) Expand all Loading... |
135 } | 143 } |
136 const syncer::AttachmentIdList empty_list_of_attachment_ids; | 144 const syncer::AttachmentIdList empty_list_of_attachment_ids; |
137 syncer_changes_.push_back( | 145 syncer_changes_.push_back( |
138 syncer::SyncChange(FROM_HERE, | 146 syncer::SyncChange(FROM_HERE, |
139 syncer::SyncChange::ACTION_DELETE, | 147 syncer::SyncChange::ACTION_DELETE, |
140 syncer::SyncData::CreateRemoteData( | 148 syncer::SyncData::CreateRemoteData( |
141 it->id, | 149 it->id, |
142 specifics ? *specifics : it->specifics, | 150 specifics ? *specifics : it->specifics, |
143 base::Time(), | 151 base::Time(), |
144 empty_list_of_attachment_ids, | 152 empty_list_of_attachment_ids, |
145 attachment_service_proxy_))); | 153 *attachment_service_proxy_))); |
146 } else { | 154 } else { |
147 syncer::SyncChange::SyncChangeType action = | 155 syncer::SyncChange::SyncChangeType action = |
148 (it->action == syncer::ChangeRecord::ACTION_ADD) ? | 156 (it->action == syncer::ChangeRecord::ACTION_ADD) ? |
149 syncer::SyncChange::ACTION_ADD : syncer::SyncChange::ACTION_UPDATE; | 157 syncer::SyncChange::ACTION_ADD : syncer::SyncChange::ACTION_UPDATE; |
150 // Need to load specifics from node. | 158 // Need to load specifics from node. |
151 syncer::ReadNode read_node(trans); | 159 syncer::ReadNode read_node(trans); |
152 if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { | 160 if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { |
153 syncer::SyncError error( | 161 syncer::SyncError error( |
154 FROM_HERE, | 162 FROM_HERE, |
155 syncer::SyncError::DATATYPE_ERROR, | 163 syncer::SyncError::DATATYPE_ERROR, |
156 "Failed to look up data for received change with id " + | 164 "Failed to look up data for received change with id " + |
157 base::Int64ToString(it->id), | 165 base::Int64ToString(it->id), |
158 syncer::GetModelTypeFromSpecifics(it->specifics)); | 166 syncer::GetModelTypeFromSpecifics(it->specifics)); |
159 error_handler()->OnSingleDataTypeUnrecoverableError(error); | 167 error_handler()->OnSingleDataTypeUnrecoverableError(error); |
160 return; | 168 return; |
161 } | 169 } |
162 syncer_changes_.push_back(syncer::SyncChange( | 170 syncer_changes_.push_back(syncer::SyncChange( |
163 FROM_HERE, | 171 FROM_HERE, |
164 action, | 172 action, |
165 BuildRemoteSyncData(it->id, read_node, attachment_service_proxy_))); | 173 BuildRemoteSyncData(it->id, read_node, *attachment_service_proxy_))); |
166 } | 174 } |
167 } | 175 } |
168 } | 176 } |
169 | 177 |
170 void GenericChangeProcessor::CommitChangesFromSyncModel() { | 178 void GenericChangeProcessor::CommitChangesFromSyncModel() { |
171 DCHECK(CalledOnValidThread()); | 179 DCHECK(CalledOnValidThread()); |
172 if (syncer_changes_.empty()) | 180 if (syncer_changes_.empty()) |
173 return; | 181 return; |
174 if (!local_service_.get()) { | 182 if (!local_service_.get()) { |
175 syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); | 183 syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 if (sync_child_node.InitByIdLookup(*it) != | 260 if (sync_child_node.InitByIdLookup(*it) != |
253 syncer::BaseNode::INIT_OK) { | 261 syncer::BaseNode::INIT_OK) { |
254 syncer::SyncError error(FROM_HERE, | 262 syncer::SyncError error(FROM_HERE, |
255 syncer::SyncError::DATATYPE_ERROR, | 263 syncer::SyncError::DATATYPE_ERROR, |
256 "Failed to fetch child node for type " + | 264 "Failed to fetch child node for type " + |
257 type_name + ".", | 265 type_name + ".", |
258 type); | 266 type); |
259 return error; | 267 return error; |
260 } | 268 } |
261 current_sync_data->push_back(BuildRemoteSyncData( | 269 current_sync_data->push_back(BuildRemoteSyncData( |
262 sync_child_node.GetId(), sync_child_node, attachment_service_proxy_)); | 270 sync_child_node.GetId(), sync_child_node, *attachment_service_proxy_)); |
263 } | 271 } |
264 return syncer::SyncError(); | 272 return syncer::SyncError(); |
265 } | 273 } |
266 | 274 |
267 bool GenericChangeProcessor::GetDataTypeContext(syncer::ModelType type, | 275 bool GenericChangeProcessor::GetDataTypeContext(syncer::ModelType type, |
268 std::string* context) const { | 276 std::string* context) const { |
269 syncer::ReadTransaction trans(FROM_HERE, share_handle()); | 277 syncer::ReadTransaction trans(FROM_HERE, share_handle()); |
270 sync_pb::DataTypeContext context_proto; | 278 sync_pb::DataTypeContext context_proto; |
271 trans.GetDataTypeContext(type, &context_proto); | 279 trans.GetDataTypeContext(type, &context_proto); |
272 if (!context_proto.has_context()) | 280 if (!context_proto.has_context()) |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 const tracked_objects::Location& from_here, | 407 const tracked_objects::Location& from_here, |
400 const syncer::SyncChangeList& list_of_changes) { | 408 const syncer::SyncChangeList& list_of_changes) { |
401 DCHECK(CalledOnValidThread()); | 409 DCHECK(CalledOnValidThread()); |
402 | 410 |
403 // Keep track of brand new attachments so we can persist them on this device | 411 // Keep track of brand new attachments so we can persist them on this device |
404 // and upload them to the server. | 412 // and upload them to the server. |
405 syncer::AttachmentList new_attachments; | 413 syncer::AttachmentList new_attachments; |
406 | 414 |
407 syncer::WriteTransaction trans(from_here, share_handle()); | 415 syncer::WriteTransaction trans(from_here, share_handle()); |
408 | 416 |
| 417 syncer::ModelType type = syncer::UNSPECIFIED; |
| 418 |
409 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); | 419 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); |
410 iter != list_of_changes.end(); | 420 iter != list_of_changes.end(); |
411 ++iter) { | 421 ++iter) { |
412 const syncer::SyncChange& change = *iter; | 422 const syncer::SyncChange& change = *iter; |
413 DCHECK_NE(change.sync_data().GetDataType(), syncer::UNSPECIFIED); | 423 DCHECK_NE(change.sync_data().GetDataType(), syncer::UNSPECIFIED); |
414 syncer::ModelType type = change.sync_data().GetDataType(); | 424 type = change.sync_data().GetDataType(); |
415 std::string type_str = syncer::ModelTypeToString(type); | 425 std::string type_str = syncer::ModelTypeToString(type); |
416 syncer::WriteNode sync_node(&trans); | 426 syncer::WriteNode sync_node(&trans); |
417 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { | 427 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { |
418 syncer::SyncError error = | 428 syncer::SyncError error = |
419 AttemptDelete(change, type, type_str, &sync_node, error_handler()); | 429 AttemptDelete(change, type, type_str, &sync_node, error_handler()); |
420 if (error.IsSet()) { | 430 if (error.IsSet()) { |
421 NOTREACHED(); | 431 NOTREACHED(); |
422 return error; | 432 return error; |
423 } | 433 } |
424 if (merge_result_.get()) { | 434 if (merge_result_.get()) { |
(...skipping 20 matching lines...) Expand all Loading... |
445 change.location().ToString(), | 455 change.location().ToString(), |
446 type); | 456 type); |
447 error_handler()->OnSingleDataTypeUnrecoverableError(error); | 457 error_handler()->OnSingleDataTypeUnrecoverableError(error); |
448 NOTREACHED(); | 458 NOTREACHED(); |
449 LOG(ERROR) << "Unset sync change."; | 459 LOG(ERROR) << "Unset sync change."; |
450 return error; | 460 return error; |
451 } | 461 } |
452 } | 462 } |
453 | 463 |
454 if (!new_attachments.empty()) { | 464 if (!new_attachments.empty()) { |
| 465 // If datatype uses attachments it should have supplied attachment store |
| 466 // which would initialize attachment_service_. Fail if it isn't so. |
| 467 if (!attachment_service_.get()) { |
| 468 DCHECK_NE(type, syncer::UNSPECIFIED); |
| 469 syncer::SyncError error( |
| 470 FROM_HERE, |
| 471 syncer::SyncError::DATATYPE_ERROR, |
| 472 "Datatype performs attachment operation without initializing " |
| 473 "attachment store", |
| 474 type); |
| 475 error_handler()->OnSingleDataTypeUnrecoverableError(error); |
| 476 NOTREACHED(); |
| 477 return error; |
| 478 } |
455 StoreAndUploadAttachments(new_attachments); | 479 StoreAndUploadAttachments(new_attachments); |
456 } | 480 } |
457 | 481 |
458 return syncer::SyncError(); | 482 return syncer::SyncError(); |
459 } | 483 } |
460 | 484 |
461 // WARNING: this code is sensitive to compiler optimizations. Be careful | 485 // WARNING: this code is sensitive to compiler optimizations. Be careful |
462 // modifying any code around an OnSingleDataTypeUnrecoverableError call, else | 486 // modifying any code around an OnSingleDataTypeUnrecoverableError call, else |
463 // the compiler attempts to merge it with other calls, losing useful information | 487 // the compiler attempts to merge it with other calls, losing useful information |
464 // in breakpad uploads. | 488 // in breakpad uploads. |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 } | 718 } |
695 | 719 |
696 syncer::UserShare* GenericChangeProcessor::share_handle() const { | 720 syncer::UserShare* GenericChangeProcessor::share_handle() const { |
697 DCHECK(CalledOnValidThread()); | 721 DCHECK(CalledOnValidThread()); |
698 return share_handle_; | 722 return share_handle_; |
699 } | 723 } |
700 | 724 |
701 void GenericChangeProcessor::StoreAndUploadAttachments( | 725 void GenericChangeProcessor::StoreAndUploadAttachments( |
702 const syncer::AttachmentList& attachments) { | 726 const syncer::AttachmentList& attachments) { |
703 DCHECK(CalledOnValidThread()); | 727 DCHECK(CalledOnValidThread()); |
| 728 DCHECK(attachment_service_.get() != NULL); |
704 attachment_service_->GetStore()->Write( | 729 attachment_service_->GetStore()->Write( |
705 attachments, | 730 attachments, |
706 base::Bind(&GenericChangeProcessor::WriteAttachmentsDone, | 731 base::Bind(&GenericChangeProcessor::WriteAttachmentsDone, |
707 weak_ptr_factory_.GetWeakPtr(), | 732 weak_ptr_factory_.GetWeakPtr(), |
708 attachments)); | 733 attachments)); |
709 } | 734 } |
710 | 735 |
711 void GenericChangeProcessor::WriteAttachmentsDone( | 736 void GenericChangeProcessor::WriteAttachmentsDone( |
712 const syncer::AttachmentList& attachments, | 737 const syncer::AttachmentList& attachments, |
713 const syncer::AttachmentStore::Result& result) { | 738 const syncer::AttachmentStore::Result& result) { |
714 DCHECK(CalledOnValidThread()); | 739 DCHECK(CalledOnValidThread()); |
| 740 DCHECK(attachment_service_.get() != NULL); |
715 if (result != syncer::AttachmentStore::SUCCESS) { | 741 if (result != syncer::AttachmentStore::SUCCESS) { |
716 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | 742 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). |
717 return; | 743 return; |
718 } | 744 } |
719 | 745 |
720 // TODO(maniscalco): Here is where we're going to update the in-directory | 746 // TODO(maniscalco): Here is where we're going to update the in-directory |
721 // entry to indicate that the attachments have been successfully stored on | 747 // entry to indicate that the attachments have been successfully stored on |
722 // disk. Why do we care? Because we might crash after persisting the | 748 // disk. Why do we care? Because we might crash after persisting the |
723 // directory to disk, but before we have persisted its attachments, leaving us | 749 // directory to disk, but before we have persisted its attachments, leaving us |
724 // with danging attachment ids. Having a flag that indicates we've stored the | 750 // with danging attachment ids. Having a flag that indicates we've stored the |
725 // entry will allow us to detect and filter entries with dangling attachment | 751 // entry will allow us to detect and filter entries with dangling attachment |
726 // ids (bug 368353). | 752 // ids (bug 368353). |
727 | 753 |
728 // Begin uploading the attachments now that they are safe on disk. | 754 // Begin uploading the attachments now that they are safe on disk. |
729 syncer::AttachmentIdSet attachment_ids; | 755 syncer::AttachmentIdSet attachment_ids; |
730 std::transform(attachments.begin(), | 756 std::transform(attachments.begin(), |
731 attachments.end(), | 757 attachments.end(), |
732 std::inserter(attachment_ids, attachment_ids.end()), | 758 std::inserter(attachment_ids, attachment_ids.end()), |
733 AttachmentToAttachmentId); | 759 AttachmentToAttachmentId); |
734 attachment_service_->UploadAttachments(attachment_ids); | 760 attachment_service_->UploadAttachments(attachment_ids); |
735 } | 761 } |
736 | 762 |
737 } // namespace sync_driver | 763 } // namespace sync_driver |
OLD | NEW |