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