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 |