Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/sync/glue/generic_change_processor.h" | 5 #include "chrome/browser/sync/glue/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 "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 syncer::PASSWORDS) { | 32 syncer::PASSWORDS) { |
| 33 write_node->SetPasswordSpecifics( | 33 write_node->SetPasswordSpecifics( |
| 34 entity_specifics.password().client_only_encrypted_data()); | 34 entity_specifics.password().client_only_encrypted_data()); |
| 35 } else { | 35 } else { |
| 36 write_node->SetEntitySpecifics(entity_specifics); | 36 write_node->SetEntitySpecifics(entity_specifics); |
| 37 } | 37 } |
| 38 } | 38 } |
| 39 | 39 |
| 40 syncer::SyncData BuildRemoteSyncData( | 40 syncer::SyncData BuildRemoteSyncData( |
| 41 int64 sync_id, | 41 int64 sync_id, |
| 42 const syncer::BaseNode& read_node) { | 42 const syncer::BaseNode& read_node, |
| 43 const syncer::WeakHandle<syncer::AttachmentService>& attachment_service) { | |
| 43 // Use the specifics of non-password datatypes directly (encryption has | 44 // Use the specifics of non-password datatypes directly (encryption has |
| 44 // already been handled). | 45 // already been handled). |
| 45 if (read_node.GetModelType() != syncer::PASSWORDS) { | 46 if (read_node.GetModelType() != syncer::PASSWORDS) { |
| 46 return syncer::SyncData::CreateRemoteData(sync_id, | 47 return syncer::SyncData::CreateRemoteData(sync_id, |
| 47 read_node.GetEntitySpecifics(), | 48 read_node.GetEntitySpecifics(), |
| 48 read_node.GetModificationTime()); | 49 read_node.GetModificationTime(), |
| 50 attachment_service); | |
| 49 } | 51 } |
| 50 | 52 |
| 51 // Passwords must be accessed differently, to account for their encryption, | 53 // Passwords must be accessed differently, to account for their encryption, |
| 52 // and stored into a temporary EntitySpecifics. | 54 // and stored into a temporary EntitySpecifics. |
| 53 sync_pb::EntitySpecifics password_holder; | 55 sync_pb::EntitySpecifics password_holder; |
| 54 password_holder.mutable_password()->mutable_client_only_encrypted_data()-> | 56 password_holder.mutable_password()->mutable_client_only_encrypted_data()-> |
| 55 CopyFrom(read_node.GetPasswordSpecifics()); | 57 CopyFrom(read_node.GetPasswordSpecifics()); |
| 56 return syncer::SyncData::CreateRemoteData(sync_id, | 58 return syncer::SyncData::CreateRemoteData(sync_id, |
| 57 password_holder, | 59 password_holder, |
| 58 read_node.GetModificationTime()); | 60 read_node.GetModificationTime(), |
| 61 attachment_service); | |
| 59 } | 62 } |
| 60 | 63 |
| 61 } // namespace | 64 } // namespace |
| 62 | 65 |
| 63 GenericChangeProcessor::GenericChangeProcessor( | 66 GenericChangeProcessor::GenericChangeProcessor( |
| 64 DataTypeErrorHandler* error_handler, | 67 DataTypeErrorHandler* error_handler, |
| 65 const base::WeakPtr<syncer::SyncableService>& local_service, | 68 const base::WeakPtr<syncer::SyncableService>& local_service, |
| 66 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, | 69 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, |
| 67 syncer::UserShare* user_share) | 70 syncer::UserShare* user_share, |
| 71 scoped_ptr<syncer::AttachmentService> attachment_service) | |
| 68 : ChangeProcessor(error_handler), | 72 : ChangeProcessor(error_handler), |
| 69 local_service_(local_service), | 73 local_service_(local_service), |
| 70 merge_result_(merge_result), | 74 merge_result_(merge_result), |
| 71 share_handle_(user_share) { | 75 share_handle_(user_share), |
| 76 attachment_service_(attachment_service.Pass()), | |
| 77 attachment_service_weak_ptr_factory_(attachment_service_.get()), | |
| 78 attachment_service_weak_handle_( | |
|
tim (not reviewing)
2014/03/10 22:55:58
Do we actually need a weak_handle_ member? Is atta
maniscalco
2014/03/18 20:49:18
Good question. Since it's related to your comment
| |
| 79 MakeWeakHandle(attachment_service_weak_ptr_factory_.GetWeakPtr())) { | |
| 72 DCHECK(CalledOnValidThread()); | 80 DCHECK(CalledOnValidThread()); |
| 81 DCHECK(attachment_service_); | |
| 73 } | 82 } |
| 74 | 83 |
| 75 GenericChangeProcessor::~GenericChangeProcessor() { | 84 GenericChangeProcessor::~GenericChangeProcessor() { |
| 76 DCHECK(CalledOnValidThread()); | 85 DCHECK(CalledOnValidThread()); |
| 77 } | 86 } |
| 78 | 87 |
| 79 void GenericChangeProcessor::ApplyChangesFromSyncModel( | 88 void GenericChangeProcessor::ApplyChangesFromSyncModel( |
| 80 const syncer::BaseTransaction* trans, | 89 const syncer::BaseTransaction* trans, |
| 81 int64 model_version, | 90 int64 model_version, |
| 82 const syncer::ImmutableChangeRecordList& changes) { | 91 const syncer::ImmutableChangeRecordList& changes) { |
| 83 DCHECK(CalledOnValidThread()); | 92 DCHECK(CalledOnValidThread()); |
| 84 DCHECK(syncer_changes_.empty()); | 93 DCHECK(syncer_changes_.empty()); |
| 85 for (syncer::ChangeRecordList::const_iterator it = | 94 for (syncer::ChangeRecordList::const_iterator it = |
| 86 changes.Get().begin(); it != changes.Get().end(); ++it) { | 95 changes.Get().begin(); it != changes.Get().end(); ++it) { |
| 87 if (it->action == syncer::ChangeRecord::ACTION_DELETE) { | 96 if (it->action == syncer::ChangeRecord::ACTION_DELETE) { |
| 88 scoped_ptr<sync_pb::EntitySpecifics> specifics; | 97 scoped_ptr<sync_pb::EntitySpecifics> specifics; |
| 89 if (it->specifics.has_password()) { | 98 if (it->specifics.has_password()) { |
| 90 DCHECK(it->extra.get()); | 99 DCHECK(it->extra.get()); |
| 91 specifics.reset(new sync_pb::EntitySpecifics(it->specifics)); | 100 specifics.reset(new sync_pb::EntitySpecifics(it->specifics)); |
| 92 specifics->mutable_password()->mutable_client_only_encrypted_data()-> | 101 specifics->mutable_password()->mutable_client_only_encrypted_data()-> |
| 93 CopyFrom(it->extra->unencrypted()); | 102 CopyFrom(it->extra->unencrypted()); |
| 94 } | 103 } |
| 95 syncer_changes_.push_back(syncer::SyncChange( | 104 syncer_changes_.push_back( |
| 96 FROM_HERE, | 105 syncer::SyncChange(FROM_HERE, |
| 97 syncer::SyncChange::ACTION_DELETE, | 106 syncer::SyncChange::ACTION_DELETE, |
| 98 syncer::SyncData::CreateRemoteData( | 107 syncer::SyncData::CreateRemoteData( |
| 99 it->id, specifics ? *specifics : it->specifics, base::Time()))); | 108 it->id, |
| 109 specifics ? *specifics : it->specifics, | |
| 110 base::Time(), | |
| 111 attachment_service_weak_handle_))); | |
| 100 } else { | 112 } else { |
| 101 syncer::SyncChange::SyncChangeType action = | 113 syncer::SyncChange::SyncChangeType action = |
| 102 (it->action == syncer::ChangeRecord::ACTION_ADD) ? | 114 (it->action == syncer::ChangeRecord::ACTION_ADD) ? |
| 103 syncer::SyncChange::ACTION_ADD : syncer::SyncChange::ACTION_UPDATE; | 115 syncer::SyncChange::ACTION_ADD : syncer::SyncChange::ACTION_UPDATE; |
| 104 // Need to load specifics from node. | 116 // Need to load specifics from node. |
| 105 syncer::ReadNode read_node(trans); | 117 syncer::ReadNode read_node(trans); |
| 106 if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { | 118 if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { |
| 107 error_handler()->OnSingleDatatypeUnrecoverableError( | 119 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 108 FROM_HERE, | 120 FROM_HERE, |
| 109 "Failed to look up data for received change with id " + | 121 "Failed to look up data for received change with id " + |
| 110 base::Int64ToString(it->id)); | 122 base::Int64ToString(it->id)); |
| 111 return; | 123 return; |
| 112 } | 124 } |
| 113 syncer_changes_.push_back( | 125 syncer_changes_.push_back(syncer::SyncChange( |
| 114 syncer::SyncChange( | 126 FROM_HERE, |
| 115 FROM_HERE, | 127 action, |
| 116 action, | 128 BuildRemoteSyncData( |
| 117 BuildRemoteSyncData(it->id, read_node))); | 129 it->id, read_node, attachment_service_weak_handle_))); |
| 118 } | 130 } |
| 119 } | 131 } |
| 120 } | 132 } |
| 121 | 133 |
| 122 void GenericChangeProcessor::CommitChangesFromSyncModel() { | 134 void GenericChangeProcessor::CommitChangesFromSyncModel() { |
| 123 DCHECK(CalledOnValidThread()); | 135 DCHECK(CalledOnValidThread()); |
| 124 if (syncer_changes_.empty()) | 136 if (syncer_changes_.empty()) |
| 125 return; | 137 return; |
| 126 if (!local_service_.get()) { | 138 if (!local_service_.get()) { |
| 127 syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); | 139 syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 syncer::ReadNode sync_child_node(&trans); | 191 syncer::ReadNode sync_child_node(&trans); |
| 180 if (sync_child_node.InitByIdLookup(*it) != | 192 if (sync_child_node.InitByIdLookup(*it) != |
| 181 syncer::BaseNode::INIT_OK) { | 193 syncer::BaseNode::INIT_OK) { |
| 182 syncer::SyncError error(FROM_HERE, | 194 syncer::SyncError error(FROM_HERE, |
| 183 syncer::SyncError::DATATYPE_ERROR, | 195 syncer::SyncError::DATATYPE_ERROR, |
| 184 "Failed to fetch child node for type " + | 196 "Failed to fetch child node for type " + |
| 185 type_name + ".", | 197 type_name + ".", |
| 186 type); | 198 type); |
| 187 return error; | 199 return error; |
| 188 } | 200 } |
| 189 current_sync_data->push_back(BuildRemoteSyncData(sync_child_node.GetId(), | 201 current_sync_data->push_back( |
| 190 sync_child_node)); | 202 BuildRemoteSyncData(sync_child_node.GetId(), |
| 203 sync_child_node, | |
| 204 attachment_service_weak_handle_)); | |
| 191 } | 205 } |
| 192 return syncer::SyncError(); | 206 return syncer::SyncError(); |
| 193 } | 207 } |
| 194 | 208 |
| 195 int GenericChangeProcessor::GetSyncCountForType(syncer::ModelType type) { | 209 int GenericChangeProcessor::GetSyncCountForType(syncer::ModelType type) { |
| 196 syncer::ReadTransaction trans(FROM_HERE, share_handle()); | 210 syncer::ReadTransaction trans(FROM_HERE, share_handle()); |
| 197 syncer::ReadNode root(&trans); | 211 syncer::ReadNode root(&trans); |
| 198 if (root.InitByTagLookup(syncer::ModelTypeToRootTag(type)) != | 212 if (root.InitByTagLookup(syncer::ModelTypeToRootTag(type)) != |
| 199 syncer::BaseNode::INIT_OK) | 213 syncer::BaseNode::INIT_OK) |
| 200 return 0; | 214 return 0; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 syncer::ModelType type = change.sync_data().GetDataType(); | 345 syncer::ModelType type = change.sync_data().GetDataType(); |
| 332 std::string type_str = syncer::ModelTypeToString(type); | 346 std::string type_str = syncer::ModelTypeToString(type); |
| 333 syncer::WriteNode sync_node(&trans); | 347 syncer::WriteNode sync_node(&trans); |
| 334 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { | 348 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { |
| 335 syncer::SyncError error = | 349 syncer::SyncError error = |
| 336 AttemptDelete(change, type, type_str, &sync_node, error_handler()); | 350 AttemptDelete(change, type, type_str, &sync_node, error_handler()); |
| 337 if (error.IsSet()) { | 351 if (error.IsSet()) { |
| 338 NOTREACHED(); | 352 NOTREACHED(); |
| 339 return error; | 353 return error; |
| 340 } | 354 } |
| 355 attachment_service_->OnSyncDataDelete(change.sync_data()); | |
| 341 if (merge_result_.get()) { | 356 if (merge_result_.get()) { |
| 342 merge_result_->set_num_items_deleted( | 357 merge_result_->set_num_items_deleted( |
| 343 merge_result_->num_items_deleted() + 1); | 358 merge_result_->num_items_deleted() + 1); |
| 344 } | 359 } |
| 345 } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { | 360 } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { |
| 346 syncer::SyncError error = | 361 syncer::SyncError error = |
| 347 HandleActionAdd(change, type_str, type, trans, &sync_node); | 362 HandleActionAdd(change, type_str, type, trans, &sync_node); |
| 348 if (error.IsSet()) { | 363 if (error.IsSet()) { |
| 349 return error; | 364 return error; |
| 350 } | 365 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 error.Reset(FROM_HERE, error_prefix + "unknown error", type); | 457 error.Reset(FROM_HERE, error_prefix + "unknown error", type); |
| 443 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 458 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 444 error.message()); | 459 error.message()); |
| 445 LOG(ERROR) << "Create: Unknown error."; | 460 LOG(ERROR) << "Create: Unknown error."; |
| 446 return error; | 461 return error; |
| 447 } | 462 } |
| 448 } | 463 } |
| 449 } | 464 } |
| 450 sync_node->SetTitle(base::UTF8ToWide(change.sync_data().GetTitle())); | 465 sync_node->SetTitle(base::UTF8ToWide(change.sync_data().GetTitle())); |
| 451 SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node); | 466 SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node); |
| 467 attachment_service_->OnSyncDataAdd(change.sync_data()); | |
| 452 if (merge_result_.get()) { | 468 if (merge_result_.get()) { |
| 453 merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); | 469 merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); |
| 454 } | 470 } |
| 455 return syncer::SyncError(); | 471 return syncer::SyncError(); |
| 456 } | 472 } |
| 457 // WARNING: this code is sensitive to compiler optimizations. Be careful | 473 // WARNING: this code is sensitive to compiler optimizations. Be careful |
| 458 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else | 474 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else |
| 459 // the compiler attempts to merge it with other calls, losing useful information | 475 // the compiler attempts to merge it with other calls, losing useful information |
| 460 // in breakpad uploads. | 476 // in breakpad uploads. |
| 461 syncer::SyncError GenericChangeProcessor::HandleActionUpdate( | 477 syncer::SyncError GenericChangeProcessor::HandleActionUpdate( |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 559 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 544 error.message()); | 560 error.message()); |
| 545 LOG(ERROR) << "Update: encr case 4."; | 561 LOG(ERROR) << "Update: encr case 4."; |
| 546 return error; | 562 return error; |
| 547 } | 563 } |
| 548 } | 564 } |
| 549 } | 565 } |
| 550 | 566 |
| 551 sync_node->SetTitle(base::UTF8ToWide(change.sync_data().GetTitle())); | 567 sync_node->SetTitle(base::UTF8ToWide(change.sync_data().GetTitle())); |
| 552 SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node); | 568 SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node); |
| 569 attachment_service_->OnSyncDataUpdate(sync_node->GetAttachmentIds(), | |
| 570 change.sync_data()); | |
| 553 if (merge_result_.get()) { | 571 if (merge_result_.get()) { |
| 554 merge_result_->set_num_items_modified(merge_result_->num_items_modified() + | 572 merge_result_->set_num_items_modified(merge_result_->num_items_modified() + |
| 555 1); | 573 1); |
| 556 } | 574 } |
| 557 // TODO(sync): Support updating other parts of the sync node (title, | 575 // TODO(sync): Support updating other parts of the sync node (title, |
| 558 // successor, parent, etc.). | 576 // successor, parent, etc.). |
| 559 return syncer::SyncError(); | 577 return syncer::SyncError(); |
| 560 } | 578 } |
| 561 | 579 |
| 562 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( | 580 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 void GenericChangeProcessor::StartImpl(Profile* profile) { | 614 void GenericChangeProcessor::StartImpl(Profile* profile) { |
| 597 DCHECK(CalledOnValidThread()); | 615 DCHECK(CalledOnValidThread()); |
| 598 } | 616 } |
| 599 | 617 |
| 600 syncer::UserShare* GenericChangeProcessor::share_handle() const { | 618 syncer::UserShare* GenericChangeProcessor::share_handle() const { |
| 601 DCHECK(CalledOnValidThread()); | 619 DCHECK(CalledOnValidThread()); |
| 602 return share_handle_; | 620 return share_handle_; |
| 603 } | 621 } |
| 604 | 622 |
| 605 } // namespace browser_sync | 623 } // namespace browser_sync |
| OLD | NEW |