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/core/shared_model_type_processor.h" | 5 #include "components/sync/core/shared_model_type_processor.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
14 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
15 #include "components/sync/core/activation_context.h" | 15 #include "components/sync/core/activation_context.h" |
16 #include "components/sync/core/processor_entity_tracker.h" | 16 #include "components/sync/core/processor_entity_tracker.h" |
17 #include "components/sync/engine/commit_queue.h" | 17 #include "components/sync/engine/commit_queue.h" |
18 #include "components/sync/protocol/proto_value_conversions.h" | 18 #include "components/sync/protocol/proto_value_conversions.h" |
19 #include "components/sync/syncable/syncable_util.h" | 19 #include "components/sync/syncable/syncable_util.h" |
20 | 20 |
21 namespace syncer_v2 { | 21 namespace syncer { |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 class ModelTypeProcessorProxy : public ModelTypeProcessor { | 25 class ModelTypeProcessorProxy : public ModelTypeProcessor { |
26 public: | 26 public: |
27 ModelTypeProcessorProxy( | 27 ModelTypeProcessorProxy( |
28 const base::WeakPtr<ModelTypeProcessor>& processor, | 28 const base::WeakPtr<ModelTypeProcessor>& processor, |
29 const scoped_refptr<base::SequencedTaskRunner>& processor_task_runner); | 29 const scoped_refptr<base::SequencedTaskRunner>& processor_task_runner); |
30 ~ModelTypeProcessorProxy() override; | 30 ~ModelTypeProcessorProxy() override; |
31 | 31 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 void ModelTypeProcessorProxy::OnUpdateReceived( | 70 void ModelTypeProcessorProxy::OnUpdateReceived( |
71 const sync_pb::DataTypeState& type_state, | 71 const sync_pb::DataTypeState& type_state, |
72 const UpdateResponseDataList& updates) { | 72 const UpdateResponseDataList& updates) { |
73 processor_task_runner_->PostTask( | 73 processor_task_runner_->PostTask( |
74 FROM_HERE, base::Bind(&ModelTypeProcessor::OnUpdateReceived, processor_, | 74 FROM_HERE, base::Bind(&ModelTypeProcessor::OnUpdateReceived, processor_, |
75 type_state, updates)); | 75 type_state, updates)); |
76 } | 76 } |
77 | 77 |
78 } // namespace | 78 } // namespace |
79 | 79 |
80 SharedModelTypeProcessor::SharedModelTypeProcessor(syncer::ModelType type, | 80 SharedModelTypeProcessor::SharedModelTypeProcessor(ModelType type, |
81 ModelTypeService* service) | 81 ModelTypeService* service) |
82 : type_(type), | 82 : type_(type), |
83 is_metadata_loaded_(false), | 83 is_metadata_loaded_(false), |
84 is_initial_pending_data_loaded_(false), | 84 is_initial_pending_data_loaded_(false), |
85 service_(service), | 85 service_(service), |
86 error_handler_(nullptr), | 86 error_handler_(nullptr), |
87 weak_ptr_factory_(this) { | 87 weak_ptr_factory_(this) { |
88 DCHECK(service); | 88 DCHECK(service); |
89 } | 89 } |
90 | 90 |
91 SharedModelTypeProcessor::~SharedModelTypeProcessor() {} | 91 SharedModelTypeProcessor::~SharedModelTypeProcessor() {} |
92 | 92 |
93 // static | 93 // static |
94 std::unique_ptr<ModelTypeChangeProcessor> | 94 std::unique_ptr<ModelTypeChangeProcessor> |
95 SharedModelTypeProcessor::CreateAsChangeProcessor(syncer::ModelType type, | 95 SharedModelTypeProcessor::CreateAsChangeProcessor(ModelType type, |
96 ModelTypeService* service) { | 96 ModelTypeService* service) { |
97 return std::unique_ptr<ModelTypeChangeProcessor>( | 97 return std::unique_ptr<ModelTypeChangeProcessor>( |
98 new SharedModelTypeProcessor(type, service)); | 98 new SharedModelTypeProcessor(type, service)); |
99 } | 99 } |
100 | 100 |
101 void SharedModelTypeProcessor::OnSyncStarting( | 101 void SharedModelTypeProcessor::OnSyncStarting( |
102 std::unique_ptr<syncer::DataTypeErrorHandler> error_handler, | 102 std::unique_ptr<DataTypeErrorHandler> error_handler, |
103 const StartCallback& start_callback) { | 103 const StartCallback& start_callback) { |
104 DCHECK(CalledOnValidThread()); | 104 DCHECK(CalledOnValidThread()); |
105 DCHECK(start_callback_.is_null()); | 105 DCHECK(start_callback_.is_null()); |
106 DCHECK(!IsConnected()); | 106 DCHECK(!IsConnected()); |
107 DCHECK(error_handler); | 107 DCHECK(error_handler); |
108 DVLOG(1) << "Sync is starting for " << ModelTypeToString(type_); | 108 DVLOG(1) << "Sync is starting for " << ModelTypeToString(type_); |
109 | 109 |
110 error_handler_ = std::move(error_handler); | 110 error_handler_ = std::move(error_handler); |
111 start_callback_ = start_callback; | 111 start_callback_ = start_callback; |
112 ConnectIfReady(); | 112 ConnectIfReady(); |
113 } | 113 } |
114 | 114 |
115 void SharedModelTypeProcessor::OnMetadataLoaded( | 115 void SharedModelTypeProcessor::OnMetadataLoaded( |
116 syncer::SyncError error, | 116 SyncError error, |
117 std::unique_ptr<MetadataBatch> batch) { | 117 std::unique_ptr<MetadataBatch> batch) { |
118 DCHECK(CalledOnValidThread()); | 118 DCHECK(CalledOnValidThread()); |
119 DCHECK(entities_.empty()); | 119 DCHECK(entities_.empty()); |
120 DCHECK(!is_metadata_loaded_); | 120 DCHECK(!is_metadata_loaded_); |
121 DCHECK(!IsConnected()); | 121 DCHECK(!IsConnected()); |
122 | 122 |
123 is_metadata_loaded_ = true; | 123 is_metadata_loaded_ = true; |
124 // Flip this flag here to cover all cases where we don't need to load data. | 124 // Flip this flag here to cover all cases where we don't need to load data. |
125 is_initial_pending_data_loaded_ = true; | 125 is_initial_pending_data_loaded_ = true; |
126 | 126 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 return is_metadata_loaded_; | 187 return is_metadata_loaded_; |
188 } | 188 } |
189 | 189 |
190 bool SharedModelTypeProcessor::IsConnected() const { | 190 bool SharedModelTypeProcessor::IsConnected() const { |
191 DCHECK(CalledOnValidThread()); | 191 DCHECK(CalledOnValidThread()); |
192 return !!worker_; | 192 return !!worker_; |
193 } | 193 } |
194 | 194 |
195 void SharedModelTypeProcessor::GetAllNodes( | 195 void SharedModelTypeProcessor::GetAllNodes( |
196 const scoped_refptr<base::TaskRunner>& task_runner, | 196 const scoped_refptr<base::TaskRunner>& task_runner, |
197 const base::Callback<void(const syncer::ModelType, | 197 const base::Callback<void(const ModelType, |
198 std::unique_ptr<base::ListValue>)>& callback) { | 198 std::unique_ptr<base::ListValue>)>& callback) { |
199 DCHECK(service_); | 199 DCHECK(service_); |
200 service_->GetAllData( | 200 service_->GetAllData( |
201 base::Bind(&SharedModelTypeProcessor::MergeDataWithMetadata, | 201 base::Bind(&SharedModelTypeProcessor::MergeDataWithMetadata, |
202 base::Unretained(this), task_runner, callback)); | 202 base::Unretained(this), task_runner, callback)); |
203 } | 203 } |
204 | 204 |
205 void SharedModelTypeProcessor::DisableSync() { | 205 void SharedModelTypeProcessor::DisableSync() { |
206 DCHECK(CalledOnValidThread()); | 206 DCHECK(CalledOnValidThread()); |
207 std::unique_ptr<MetadataChangeList> change_list = | 207 std::unique_ptr<MetadataChangeList> change_list = |
208 service_->CreateMetadataChangeList(); | 208 service_->CreateMetadataChangeList(); |
209 for (auto it = entities_.begin(); it != entities_.end(); ++it) { | 209 for (auto it = entities_.begin(); it != entities_.end(); ++it) { |
210 change_list->ClearMetadata(it->second->storage_key()); | 210 change_list->ClearMetadata(it->second->storage_key()); |
211 } | 211 } |
212 change_list->ClearDataTypeState(); | 212 change_list->ClearDataTypeState(); |
213 // Nothing to do if this fails, so just ignore the error it might return. | 213 // Nothing to do if this fails, so just ignore the error it might return. |
214 service_->ApplySyncChanges(std::move(change_list), EntityChangeList()); | 214 service_->ApplySyncChanges(std::move(change_list), EntityChangeList()); |
215 } | 215 } |
216 | 216 |
217 syncer::SyncError SharedModelTypeProcessor::CreateAndUploadError( | 217 SyncError SharedModelTypeProcessor::CreateAndUploadError( |
218 const tracked_objects::Location& location, | 218 const tracked_objects::Location& location, |
219 const std::string& message) { | 219 const std::string& message) { |
220 if (error_handler_) { | 220 if (error_handler_) { |
221 return error_handler_->CreateAndUploadError(location, message, type_); | 221 return error_handler_->CreateAndUploadError(location, message, type_); |
222 } else { | 222 } else { |
223 return syncer::SyncError(location, syncer::SyncError::DATATYPE_ERROR, | 223 return SyncError(location, SyncError::DATATYPE_ERROR, message, type_); |
224 message, type_); | |
225 } | 224 } |
226 } | 225 } |
227 | 226 |
228 void SharedModelTypeProcessor::ConnectSync( | 227 void SharedModelTypeProcessor::ConnectSync( |
229 std::unique_ptr<CommitQueue> worker) { | 228 std::unique_ptr<CommitQueue> worker) { |
230 DCHECK(CalledOnValidThread()); | 229 DCHECK(CalledOnValidThread()); |
231 DVLOG(1) << "Successfully connected " << ModelTypeToString(type_); | 230 DVLOG(1) << "Successfully connected " << ModelTypeToString(type_); |
232 | 231 |
233 worker_ = std::move(worker); | 232 worker_ = std::move(worker); |
234 | 233 |
(...skipping 13 matching lines...) Expand all Loading... |
248 } | 247 } |
249 } | 248 } |
250 | 249 |
251 void SharedModelTypeProcessor::Put(const std::string& storage_key, | 250 void SharedModelTypeProcessor::Put(const std::string& storage_key, |
252 std::unique_ptr<EntityData> data, | 251 std::unique_ptr<EntityData> data, |
253 MetadataChangeList* metadata_change_list) { | 252 MetadataChangeList* metadata_change_list) { |
254 DCHECK(IsAllowingChanges()); | 253 DCHECK(IsAllowingChanges()); |
255 DCHECK(data.get()); | 254 DCHECK(data.get()); |
256 DCHECK(!data->is_deleted()); | 255 DCHECK(!data->is_deleted()); |
257 DCHECK(!data->non_unique_name.empty()); | 256 DCHECK(!data->non_unique_name.empty()); |
258 DCHECK_EQ(type_, syncer::GetModelTypeFromSpecifics(data->specifics)); | 257 DCHECK_EQ(type_, GetModelTypeFromSpecifics(data->specifics)); |
259 | 258 |
260 if (!data_type_state_.initial_sync_done()) { | 259 if (!data_type_state_.initial_sync_done()) { |
261 // Ignore changes before the initial sync is done. | 260 // Ignore changes before the initial sync is done. |
262 return; | 261 return; |
263 } | 262 } |
264 | 263 |
265 // Fill in some data. | 264 // Fill in some data. |
266 data->client_tag_hash = GetClientTagHash(storage_key, *data); | 265 data->client_tag_hash = GetClientTagHash(storage_key, *data); |
267 if (data->modification_time.is_null()) { | 266 if (data->modification_time.is_null()) { |
268 data->modification_time = base::Time::Now(); | 267 data->modification_time = base::Time::Now(); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 entity->ReceiveCommitResponse(data); | 357 entity->ReceiveCommitResponse(data); |
359 | 358 |
360 if (entity->CanClearMetadata()) { | 359 if (entity->CanClearMetadata()) { |
361 change_list->ClearMetadata(entity->storage_key()); | 360 change_list->ClearMetadata(entity->storage_key()); |
362 entities_.erase(entity->metadata().client_tag_hash()); | 361 entities_.erase(entity->metadata().client_tag_hash()); |
363 } else { | 362 } else { |
364 change_list->UpdateMetadata(entity->storage_key(), entity->metadata()); | 363 change_list->UpdateMetadata(entity->storage_key(), entity->metadata()); |
365 } | 364 } |
366 } | 365 } |
367 | 366 |
368 syncer::SyncError error = | 367 SyncError error = |
369 service_->ApplySyncChanges(std::move(change_list), EntityChangeList()); | 368 service_->ApplySyncChanges(std::move(change_list), EntityChangeList()); |
370 if (error.IsSet()) { | 369 if (error.IsSet()) { |
371 error_handler_->OnUnrecoverableError(error); | 370 error_handler_->OnUnrecoverableError(error); |
372 } | 371 } |
373 } | 372 } |
374 | 373 |
375 void SharedModelTypeProcessor::OnUpdateReceived( | 374 void SharedModelTypeProcessor::OnUpdateReceived( |
376 const sync_pb::DataTypeState& data_type_state, | 375 const sync_pb::DataTypeState& data_type_state, |
377 const UpdateResponseDataList& updates) { | 376 const UpdateResponseDataList& updates) { |
378 if (!data_type_state_.initial_sync_done()) { | 377 if (!data_type_state_.initial_sync_done()) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 if (got_new_encryption_requirements) { | 413 if (got_new_encryption_requirements) { |
415 already_updated.insert(entity->storage_key()); | 414 already_updated.insert(entity->storage_key()); |
416 } | 415 } |
417 } | 416 } |
418 | 417 |
419 if (got_new_encryption_requirements) { | 418 if (got_new_encryption_requirements) { |
420 RecommitAllForEncryption(already_updated, metadata_changes.get()); | 419 RecommitAllForEncryption(already_updated, metadata_changes.get()); |
421 } | 420 } |
422 | 421 |
423 // Inform the service of the new or updated data. | 422 // Inform the service of the new or updated data. |
424 syncer::SyncError error = | 423 SyncError error = |
425 service_->ApplySyncChanges(std::move(metadata_changes), entity_changes); | 424 service_->ApplySyncChanges(std::move(metadata_changes), entity_changes); |
426 | 425 |
427 if (error.IsSet()) { | 426 if (error.IsSet()) { |
428 error_handler_->OnUnrecoverableError(error); | 427 error_handler_->OnUnrecoverableError(error); |
429 } else { | 428 } else { |
430 // There may be new reasons to commit by the time this function is done. | 429 // There may be new reasons to commit by the time this function is done. |
431 FlushPendingCommitRequests(); | 430 FlushPendingCommitRequests(); |
432 } | 431 } |
433 } | 432 } |
434 | 433 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 | 606 |
608 for (const UpdateResponseData& update : updates) { | 607 for (const UpdateResponseData& update : updates) { |
609 ProcessorEntityTracker* entity = CreateEntity(update.entity.value()); | 608 ProcessorEntityTracker* entity = CreateEntity(update.entity.value()); |
610 const std::string& storage_key = entity->storage_key(); | 609 const std::string& storage_key = entity->storage_key(); |
611 entity->RecordAcceptedUpdate(update); | 610 entity->RecordAcceptedUpdate(update); |
612 metadata_changes->UpdateMetadata(storage_key, entity->metadata()); | 611 metadata_changes->UpdateMetadata(storage_key, entity->metadata()); |
613 data_map[storage_key] = update.entity; | 612 data_map[storage_key] = update.entity; |
614 } | 613 } |
615 | 614 |
616 // Let the service handle associating and merging the data. | 615 // Let the service handle associating and merging the data. |
617 syncer::SyncError error = | 616 SyncError error = |
618 service_->MergeSyncData(std::move(metadata_changes), data_map); | 617 service_->MergeSyncData(std::move(metadata_changes), data_map); |
619 | 618 |
620 if (error.IsSet()) { | 619 if (error.IsSet()) { |
621 error_handler_->OnUnrecoverableError(error); | 620 error_handler_->OnUnrecoverableError(error); |
622 } else { | 621 } else { |
623 // We may have new reasons to commit by the time this function is done. | 622 // We may have new reasons to commit by the time this function is done. |
624 FlushPendingCommitRequests(); | 623 FlushPendingCommitRequests(); |
625 } | 624 } |
626 } | 625 } |
627 | 626 |
628 void SharedModelTypeProcessor::OnInitialPendingDataLoaded( | 627 void SharedModelTypeProcessor::OnInitialPendingDataLoaded( |
629 syncer::SyncError error, | 628 SyncError error, |
630 std::unique_ptr<DataBatch> data_batch) { | 629 std::unique_ptr<DataBatch> data_batch) { |
631 DCHECK(!is_initial_pending_data_loaded_); | 630 DCHECK(!is_initial_pending_data_loaded_); |
632 | 631 |
633 if (error.IsSet()) { | 632 if (error.IsSet()) { |
634 start_error_ = error; | 633 start_error_ = error; |
635 } else { | 634 } else { |
636 ConsumeDataBatch(std::move(data_batch)); | 635 ConsumeDataBatch(std::move(data_batch)); |
637 } | 636 } |
638 | 637 |
639 is_initial_pending_data_loaded_ = true; | 638 is_initial_pending_data_loaded_ = true; |
640 ConnectIfReady(); | 639 ConnectIfReady(); |
641 } | 640 } |
642 | 641 |
643 void SharedModelTypeProcessor::OnDataLoadedForReEncryption( | 642 void SharedModelTypeProcessor::OnDataLoadedForReEncryption( |
644 syncer::SyncError error, | 643 SyncError error, |
645 std::unique_ptr<DataBatch> data_batch) { | 644 std::unique_ptr<DataBatch> data_batch) { |
646 DCHECK(is_initial_pending_data_loaded_); | 645 DCHECK(is_initial_pending_data_loaded_); |
647 | 646 |
648 if (error.IsSet()) { | 647 if (error.IsSet()) { |
649 error_handler_->OnUnrecoverableError(error); | 648 error_handler_->OnUnrecoverableError(error); |
650 return; | 649 return; |
651 } | 650 } |
652 | 651 |
653 ConsumeDataBatch(std::move(data_batch)); | 652 ConsumeDataBatch(std::move(data_batch)); |
654 FlushPendingCommitRequests(); | 653 FlushPendingCommitRequests(); |
655 } | 654 } |
656 | 655 |
657 void SharedModelTypeProcessor::ConsumeDataBatch( | 656 void SharedModelTypeProcessor::ConsumeDataBatch( |
658 std::unique_ptr<DataBatch> data_batch) { | 657 std::unique_ptr<DataBatch> data_batch) { |
659 while (data_batch->HasNext()) { | 658 while (data_batch->HasNext()) { |
660 KeyAndData data = data_batch->Next(); | 659 KeyAndData data = data_batch->Next(); |
661 ProcessorEntityTracker* entity = GetEntityForStorageKey(data.first); | 660 ProcessorEntityTracker* entity = GetEntityForStorageKey(data.first); |
662 // If the entity wasn't deleted or updated with new commit. | 661 // If the entity wasn't deleted or updated with new commit. |
663 if (entity != nullptr && entity->RequiresCommitData()) { | 662 if (entity != nullptr && entity->RequiresCommitData()) { |
664 entity->CacheCommitData(data.second.get()); | 663 entity->CacheCommitData(data.second.get()); |
665 } | 664 } |
666 } | 665 } |
667 } | 666 } |
668 | 667 |
669 std::string SharedModelTypeProcessor::GetHashForTag(const std::string& tag) { | 668 std::string SharedModelTypeProcessor::GetHashForTag(const std::string& tag) { |
670 return syncer::syncable::GenerateSyncableHash(type_, tag); | 669 return syncable::GenerateSyncableHash(type_, tag); |
671 } | 670 } |
672 | 671 |
673 std::string SharedModelTypeProcessor::GetClientTagHash( | 672 std::string SharedModelTypeProcessor::GetClientTagHash( |
674 const std::string& storage_key, | 673 const std::string& storage_key, |
675 const EntityData& data) { | 674 const EntityData& data) { |
676 auto iter = storage_key_to_tag_hash_.find(storage_key); | 675 auto iter = storage_key_to_tag_hash_.find(storage_key); |
677 return iter == storage_key_to_tag_hash_.end() | 676 return iter == storage_key_to_tag_hash_.end() |
678 ? GetHashForTag(service_->GetClientTag(data)) | 677 ? GetHashForTag(service_->GetClientTag(data)) |
679 : iter->second; | 678 : iter->second; |
680 } | 679 } |
(...skipping 29 matching lines...) Expand all Loading... |
710 | 709 |
711 ProcessorEntityTracker* SharedModelTypeProcessor::CreateEntity( | 710 ProcessorEntityTracker* SharedModelTypeProcessor::CreateEntity( |
712 const EntityData& data) { | 711 const EntityData& data) { |
713 // Verify the tag hash matches, may be relaxed in the future. | 712 // Verify the tag hash matches, may be relaxed in the future. |
714 DCHECK_EQ(data.client_tag_hash, GetHashForTag(service_->GetClientTag(data))); | 713 DCHECK_EQ(data.client_tag_hash, GetHashForTag(service_->GetClientTag(data))); |
715 return CreateEntity(service_->GetStorageKey(data), data); | 714 return CreateEntity(service_->GetStorageKey(data), data); |
716 } | 715 } |
717 | 716 |
718 void SharedModelTypeProcessor::MergeDataWithMetadata( | 717 void SharedModelTypeProcessor::MergeDataWithMetadata( |
719 const scoped_refptr<base::TaskRunner>& task_runner, | 718 const scoped_refptr<base::TaskRunner>& task_runner, |
720 const base::Callback<void(const syncer::ModelType, | 719 const base::Callback<void(const ModelType, |
721 std::unique_ptr<base::ListValue>)>& callback, | 720 std::unique_ptr<base::ListValue>)>& callback, |
722 syncer::SyncError error, | 721 SyncError error, |
723 std::unique_ptr<DataBatch> batch) { | 722 std::unique_ptr<DataBatch> batch) { |
724 std::unique_ptr<base::ListValue> all_nodes = | 723 std::unique_ptr<base::ListValue> all_nodes = |
725 base::MakeUnique<base::ListValue>(); | 724 base::MakeUnique<base::ListValue>(); |
726 std::string type_string = ModelTypeToString(type_); | 725 std::string type_string = ModelTypeToString(type_); |
727 | 726 |
728 while (batch->HasNext()) { | 727 while (batch->HasNext()) { |
729 KeyAndData data = batch->Next(); | 728 KeyAndData data = batch->Next(); |
730 std::unique_ptr<base::DictionaryValue> node = | 729 std::unique_ptr<base::DictionaryValue> node = |
731 data.second->ToDictionaryValue(); | 730 data.second->ToDictionaryValue(); |
732 ProcessorEntityTracker* entity = GetEntityForStorageKey(data.first); | 731 ProcessorEntityTracker* entity = GetEntityForStorageKey(data.first); |
733 // Entity could be null if there are some unapplied changes. | 732 // Entity could be null if there are some unapplied changes. |
734 if (entity != nullptr) { | 733 if (entity != nullptr) { |
735 node->Set("metadata", syncer::EntityMetadataToValue(entity->metadata())); | 734 node->Set("metadata", EntityMetadataToValue(entity->metadata())); |
736 } | 735 } |
737 node->SetString("modelType", type_string); | 736 node->SetString("modelType", type_string); |
738 all_nodes->Append(std::move(node)); | 737 all_nodes->Append(std::move(node)); |
739 } | 738 } |
740 | 739 |
741 // Create a permanent folder for this data type. Since sync server no longer | 740 // Create a permanent folder for this data type. Since sync server no longer |
742 // create root folders, and USS won't migrate root folders from directory, we | 741 // create root folders, and USS won't migrate root folders from directory, we |
743 // create root folders for each data type here. | 742 // create root folders for each data type here. |
744 std::unique_ptr<base::DictionaryValue> rootnode = | 743 std::unique_ptr<base::DictionaryValue> rootnode = |
745 base::MakeUnique<base::DictionaryValue>(); | 744 base::MakeUnique<base::DictionaryValue>(); |
746 // Function isTypeRootNode in sync_node_browser.js use PARENT_ID and | 745 // Function isTypeRootNode in sync_node_browser.js use PARENT_ID and |
747 // UNIQUE_SERVER_TAG to check if the node is root node. isChildOf in | 746 // UNIQUE_SERVER_TAG to check if the node is root node. isChildOf in |
748 // sync_node_browser.js uses modelType to check if root node is parent of real | 747 // sync_node_browser.js uses modelType to check if root node is parent of real |
749 // data node. NON_UNIQUE_NAME will be the name of node to display. | 748 // data node. NON_UNIQUE_NAME will be the name of node to display. |
750 rootnode->SetString("PARENT_ID", "r"); | 749 rootnode->SetString("PARENT_ID", "r"); |
751 rootnode->SetString("UNIQUE_SERVER_TAG", type_string); | 750 rootnode->SetString("UNIQUE_SERVER_TAG", type_string); |
752 rootnode->SetBoolean("IS_DIR", true); | 751 rootnode->SetBoolean("IS_DIR", true); |
753 rootnode->SetString("modelType", type_string); | 752 rootnode->SetString("modelType", type_string); |
754 rootnode->SetString("NON_UNIQUE_NAME", type_string); | 753 rootnode->SetString("NON_UNIQUE_NAME", type_string); |
755 all_nodes->Append(std::move(rootnode)); | 754 all_nodes->Append(std::move(rootnode)); |
756 | 755 |
757 task_runner->PostTask(FROM_HERE, | 756 task_runner->PostTask(FROM_HERE, |
758 base::Bind(callback, type_, base::Passed(&all_nodes))); | 757 base::Bind(callback, type_, base::Passed(&all_nodes))); |
759 } | 758 } |
760 | 759 |
761 } // namespace syncer_v2 | 760 } // namespace syncer |
OLD | NEW |