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