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