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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 sync_pb::EntitySpecifics password_holder; | 78 sync_pb::EntitySpecifics password_holder; |
79 password_holder.mutable_password()->mutable_client_only_encrypted_data()-> | 79 password_holder.mutable_password()->mutable_client_only_encrypted_data()-> |
80 CopyFrom(read_node.GetPasswordSpecifics()); | 80 CopyFrom(read_node.GetPasswordSpecifics()); |
81 return syncer::SyncData::CreateRemoteData(sync_id, | 81 return syncer::SyncData::CreateRemoteData(sync_id, |
82 password_holder, | 82 password_holder, |
83 read_node.GetModificationTime(), | 83 read_node.GetModificationTime(), |
84 attachment_ids, | 84 attachment_ids, |
85 attachment_service_proxy); | 85 attachment_service_proxy); |
86 } | 86 } |
87 | 87 |
88 const syncer::AttachmentId& AttachmentToAttachmentId( | |
89 const syncer::Attachment& attachment) { | |
90 return attachment.GetId(); | |
91 } | |
92 | |
93 } // namespace | 88 } // namespace |
94 | 89 |
95 GenericChangeProcessor::GenericChangeProcessor( | 90 GenericChangeProcessor::GenericChangeProcessor( |
96 DataTypeErrorHandler* error_handler, | 91 DataTypeErrorHandler* error_handler, |
97 const base::WeakPtr<syncer::SyncableService>& local_service, | 92 const base::WeakPtr<syncer::SyncableService>& local_service, |
98 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, | 93 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, |
99 syncer::UserShare* user_share, | 94 syncer::UserShare* user_share, |
100 SyncApiComponentFactory* sync_factory, | 95 SyncApiComponentFactory* sync_factory, |
101 const scoped_refptr<syncer::AttachmentStore>& attachment_store) | 96 const scoped_refptr<syncer::AttachmentStore>& attachment_store) |
102 : ChangeProcessor(error_handler), | 97 : ChangeProcessor(error_handler), |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 | 398 |
404 } // namespace | 399 } // namespace |
405 | 400 |
406 syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( | 401 syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( |
407 const tracked_objects::Location& from_here, | 402 const tracked_objects::Location& from_here, |
408 const syncer::SyncChangeList& list_of_changes) { | 403 const syncer::SyncChangeList& list_of_changes) { |
409 DCHECK(CalledOnValidThread()); | 404 DCHECK(CalledOnValidThread()); |
410 | 405 |
411 // Keep track of brand new attachments so we can persist them on this device | 406 // Keep track of brand new attachments so we can persist them on this device |
412 // and upload them to the server. | 407 // and upload them to the server. |
413 syncer::AttachmentList new_attachments; | 408 syncer::AttachmentIdList new_attachments; |
414 | 409 |
415 syncer::WriteTransaction trans(from_here, share_handle()); | 410 syncer::WriteTransaction trans(from_here, share_handle()); |
416 | 411 |
417 syncer::ModelType type = syncer::UNSPECIFIED; | 412 syncer::ModelType type = syncer::UNSPECIFIED; |
418 | 413 |
419 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); | 414 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); |
420 iter != list_of_changes.end(); | 415 iter != list_of_changes.end(); |
421 ++iter) { | 416 ++iter) { |
422 const syncer::SyncChange& change = *iter; | 417 const syncer::SyncChange& change = *iter; |
423 DCHECK_NE(change.sync_data().GetDataType(), syncer::UNSPECIFIED); | 418 DCHECK_NE(change.sync_data().GetDataType(), syncer::UNSPECIFIED); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 syncer::SyncError error( | 464 syncer::SyncError error( |
470 FROM_HERE, | 465 FROM_HERE, |
471 syncer::SyncError::DATATYPE_ERROR, | 466 syncer::SyncError::DATATYPE_ERROR, |
472 "Datatype performs attachment operation without initializing " | 467 "Datatype performs attachment operation without initializing " |
473 "attachment store", | 468 "attachment store", |
474 type); | 469 type); |
475 error_handler()->OnSingleDataTypeUnrecoverableError(error); | 470 error_handler()->OnSingleDataTypeUnrecoverableError(error); |
476 NOTREACHED(); | 471 NOTREACHED(); |
477 return error; | 472 return error; |
478 } | 473 } |
479 StoreAndUploadAttachments(new_attachments); | 474 UploadAttachments(new_attachments); |
480 } | 475 } |
481 | 476 |
482 return syncer::SyncError(); | 477 return syncer::SyncError(); |
483 } | 478 } |
484 | 479 |
485 // WARNING: this code is sensitive to compiler optimizations. Be careful | 480 // WARNING: this code is sensitive to compiler optimizations. Be careful |
486 // modifying any code around an OnSingleDataTypeUnrecoverableError call, else | 481 // modifying any code around an OnSingleDataTypeUnrecoverableError call, else |
487 // the compiler attempts to merge it with other calls, losing useful information | 482 // the compiler attempts to merge it with other calls, losing useful information |
488 // in breakpad uploads. | 483 // in breakpad uploads. |
489 syncer::SyncError GenericChangeProcessor::HandleActionAdd( | 484 syncer::SyncError GenericChangeProcessor::HandleActionAdd( |
490 const syncer::SyncChange& change, | 485 const syncer::SyncChange& change, |
491 const std::string& type_str, | 486 const std::string& type_str, |
492 const syncer::ModelType& type, | 487 const syncer::ModelType& type, |
493 const syncer::WriteTransaction& trans, | 488 const syncer::WriteTransaction& trans, |
494 syncer::WriteNode* sync_node, | 489 syncer::WriteNode* sync_node, |
495 syncer::AttachmentList* new_attachments) { | 490 syncer::AttachmentIdList* new_attachments) { |
496 // TODO(sync): Handle other types of creation (custom parents, folders, | 491 // TODO(sync): Handle other types of creation (custom parents, folders, |
497 // etc.). | 492 // etc.). |
498 syncer::ReadNode root_node(&trans); | 493 syncer::ReadNode root_node(&trans); |
499 const syncer::SyncDataLocal sync_data_local(change.sync_data()); | 494 const syncer::SyncDataLocal sync_data_local(change.sync_data()); |
500 if (root_node.InitTypeRoot(sync_data_local.GetDataType()) != | 495 if (root_node.InitTypeRoot(sync_data_local.GetDataType()) != |
501 syncer::BaseNode::INIT_OK) { | 496 syncer::BaseNode::INIT_OK) { |
502 syncer::SyncError error(FROM_HERE, | 497 syncer::SyncError error(FROM_HERE, |
503 syncer::SyncError::DATATYPE_ERROR, | 498 syncer::SyncError::DATATYPE_ERROR, |
504 "Failed to look up root node for type " + type_str, | 499 "Failed to look up root node for type " + type_str, |
505 type); | 500 type); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 } | 548 } |
554 } | 549 } |
555 } | 550 } |
556 sync_node->SetTitle(change.sync_data().GetTitle()); | 551 sync_node->SetTitle(change.sync_data().GetTitle()); |
557 SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); | 552 SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); |
558 | 553 |
559 syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); | 554 syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); |
560 SetAttachmentMetadata(attachment_ids, sync_node); | 555 SetAttachmentMetadata(attachment_ids, sync_node); |
561 | 556 |
562 // Return any newly added attachments. | 557 // Return any newly added attachments. |
563 const syncer::AttachmentList& local_attachments_for_upload = | 558 new_attachments->insert( |
564 sync_data_local.GetLocalAttachmentsForUpload(); | 559 new_attachments->end(), attachment_ids.begin(), attachment_ids.end()); |
565 new_attachments->insert(new_attachments->end(), | |
566 local_attachments_for_upload.begin(), | |
567 local_attachments_for_upload.end()); | |
568 | |
569 if (merge_result_.get()) { | 560 if (merge_result_.get()) { |
570 merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); | 561 merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); |
571 } | 562 } |
572 return syncer::SyncError(); | 563 return syncer::SyncError(); |
573 } | 564 } |
574 // WARNING: this code is sensitive to compiler optimizations. Be careful | 565 // WARNING: this code is sensitive to compiler optimizations. Be careful |
575 // modifying any code around an OnSingleDataTypeUnrecoverableError call, else | 566 // modifying any code around an OnSingleDataTypeUnrecoverableError call, else |
576 // the compiler attempts to merge it with other calls, losing useful information | 567 // the compiler attempts to merge it with other calls, losing useful information |
577 // in breakpad uploads. | 568 // in breakpad uploads. |
578 syncer::SyncError GenericChangeProcessor::HandleActionUpdate( | 569 syncer::SyncError GenericChangeProcessor::HandleActionUpdate( |
579 const syncer::SyncChange& change, | 570 const syncer::SyncChange& change, |
580 const std::string& type_str, | 571 const std::string& type_str, |
581 const syncer::ModelType& type, | 572 const syncer::ModelType& type, |
582 const syncer::WriteTransaction& trans, | 573 const syncer::WriteTransaction& trans, |
583 syncer::WriteNode* sync_node, | 574 syncer::WriteNode* sync_node, |
584 syncer::AttachmentList* new_attachments) { | 575 syncer::AttachmentIdList* new_attachments) { |
585 // TODO(zea): consider having this logic for all possible changes? | 576 // TODO(zea): consider having this logic for all possible changes? |
586 | 577 |
587 const syncer::SyncDataLocal sync_data_local(change.sync_data()); | 578 const syncer::SyncDataLocal sync_data_local(change.sync_data()); |
588 syncer::BaseNode::InitByLookupResult result = | 579 syncer::BaseNode::InitByLookupResult result = |
589 sync_node->InitByClientTagLookup(sync_data_local.GetDataType(), | 580 sync_node->InitByClientTagLookup(sync_data_local.GetDataType(), |
590 sync_data_local.GetTag()); | 581 sync_data_local.GetTag()); |
591 if (result != syncer::BaseNode::INIT_OK) { | 582 if (result != syncer::BaseNode::INIT_OK) { |
592 std::string error_prefix = "Failed to load " + type_str + " node. " + | 583 std::string error_prefix = "Failed to load " + type_str + " node. " + |
593 change.location().ToString() + ", "; | 584 change.location().ToString() + ", "; |
594 if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) { | 585 if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 type); | 647 type); |
657 error_handler()->OnSingleDataTypeUnrecoverableError(error); | 648 error_handler()->OnSingleDataTypeUnrecoverableError(error); |
658 LOG(ERROR) << "Update: encr case 4."; | 649 LOG(ERROR) << "Update: encr case 4."; |
659 return error; | 650 return error; |
660 } | 651 } |
661 } | 652 } |
662 } | 653 } |
663 | 654 |
664 sync_node->SetTitle(change.sync_data().GetTitle()); | 655 sync_node->SetTitle(change.sync_data().GetTitle()); |
665 SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); | 656 SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); |
666 SetAttachmentMetadata(sync_data_local.GetAttachmentIds(), sync_node); | 657 syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); |
| 658 SetAttachmentMetadata(attachment_ids, sync_node); |
667 | 659 |
668 // Return any newly added attachments. | 660 // Return any newly added attachments. |
669 const syncer::AttachmentList& local_attachments_for_upload = | 661 new_attachments->insert( |
670 sync_data_local.GetLocalAttachmentsForUpload(); | 662 new_attachments->end(), attachment_ids.begin(), attachment_ids.end()); |
671 new_attachments->insert(new_attachments->end(), | |
672 local_attachments_for_upload.begin(), | |
673 local_attachments_for_upload.end()); | |
674 | 663 |
675 if (merge_result_.get()) { | 664 if (merge_result_.get()) { |
676 merge_result_->set_num_items_modified(merge_result_->num_items_modified() + | 665 merge_result_->set_num_items_modified(merge_result_->num_items_modified() + |
677 1); | 666 1); |
678 } | 667 } |
679 // TODO(sync): Support updating other parts of the sync node (title, | 668 // TODO(sync): Support updating other parts of the sync node (title, |
680 // successor, parent, etc.). | 669 // successor, parent, etc.). |
681 return syncer::SyncError(); | 670 return syncer::SyncError(); |
682 } | 671 } |
683 | 672 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 } | 704 } |
716 | 705 |
717 void GenericChangeProcessor::StartImpl() { | 706 void GenericChangeProcessor::StartImpl() { |
718 } | 707 } |
719 | 708 |
720 syncer::UserShare* GenericChangeProcessor::share_handle() const { | 709 syncer::UserShare* GenericChangeProcessor::share_handle() const { |
721 DCHECK(CalledOnValidThread()); | 710 DCHECK(CalledOnValidThread()); |
722 return share_handle_; | 711 return share_handle_; |
723 } | 712 } |
724 | 713 |
725 void GenericChangeProcessor::StoreAndUploadAttachments( | 714 void GenericChangeProcessor::UploadAttachments( |
726 const syncer::AttachmentList& attachments) { | 715 const syncer::AttachmentIdList& attachment_ids) { |
727 DCHECK(CalledOnValidThread()); | 716 DCHECK(CalledOnValidThread()); |
728 DCHECK(attachment_service_.get() != NULL); | 717 DCHECK(attachment_service_.get() != NULL); |
729 attachment_service_->GetStore()->Write( | |
730 attachments, | |
731 base::Bind(&GenericChangeProcessor::WriteAttachmentsDone, | |
732 weak_ptr_factory_.GetWeakPtr(), | |
733 attachments)); | |
734 } | |
735 | 718 |
736 void GenericChangeProcessor::WriteAttachmentsDone( | 719 syncer::AttachmentIdSet attachment_id_set; |
737 const syncer::AttachmentList& attachments, | 720 attachment_id_set.insert(attachment_ids.begin(), attachment_ids.end()); |
738 const syncer::AttachmentStore::Result& result) { | 721 attachment_service_->UploadAttachments(attachment_id_set); |
739 DCHECK(CalledOnValidThread()); | |
740 DCHECK(attachment_service_.get() != NULL); | |
741 if (result != syncer::AttachmentStore::SUCCESS) { | |
742 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | |
743 return; | |
744 } | |
745 | |
746 // TODO(maniscalco): Here is where we're going to update the in-directory | |
747 // entry to indicate that the attachments have been successfully stored on | |
748 // disk. Why do we care? Because we might crash after persisting the | |
749 // directory to disk, but before we have persisted its attachments, leaving us | |
750 // with danging attachment ids. Having a flag that indicates we've stored the | |
751 // entry will allow us to detect and filter entries with dangling attachment | |
752 // ids (bug 368353). | |
753 | |
754 // Begin uploading the attachments now that they are safe on disk. | |
755 syncer::AttachmentIdSet attachment_ids; | |
756 std::transform(attachments.begin(), | |
757 attachments.end(), | |
758 std::inserter(attachment_ids, attachment_ids.end()), | |
759 AttachmentToAttachmentId); | |
760 attachment_service_->UploadAttachments(attachment_ids); | |
761 } | 722 } |
762 | 723 |
763 } // namespace sync_driver | 724 } // namespace sync_driver |
OLD | NEW |