Add abhijeet.k@samsung.com to AUTHORS list.
[chromium-blink-merge.git] / components / sync_driver / shared_change_processor.cc
blob24e7136e43a8e31681a1bc2be2ff826c7b2af12b
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
3 // found in the LICENSE file.
5 #include "components/sync_driver/shared_change_processor.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "components/sync_driver/generic_change_processor.h"
9 #include "components/sync_driver/generic_change_processor_factory.h"
10 #include "components/sync_driver/sync_api_component_factory.h"
11 #include "sync/api/sync_change.h"
13 using base::AutoLock;
15 namespace syncer {
16 class AttachmentService;
19 namespace sync_driver {
21 SharedChangeProcessor::SharedChangeProcessor()
22 : disconnected_(false),
23 type_(syncer::UNSPECIFIED),
24 frontend_loop_(base::MessageLoopProxy::current()),
25 generic_change_processor_(NULL),
26 error_handler_(NULL) {
29 SharedChangeProcessor::~SharedChangeProcessor() {
30 // We can either be deleted when the DTC is destroyed (on UI
31 // thread), or when the syncer::SyncableService stops syncing (datatype
32 // thread). |generic_change_processor_|, if non-NULL, must be
33 // deleted on |backend_loop_|.
34 if (backend_loop_.get()) {
35 if (backend_loop_->BelongsToCurrentThread()) {
36 delete generic_change_processor_;
37 } else {
38 DCHECK(frontend_loop_->BelongsToCurrentThread());
39 if (!backend_loop_->DeleteSoon(FROM_HERE, generic_change_processor_)) {
40 NOTREACHED();
43 } else {
44 DCHECK(!generic_change_processor_);
48 base::WeakPtr<syncer::SyncableService> SharedChangeProcessor::Connect(
49 SyncApiComponentFactory* sync_factory,
50 GenericChangeProcessorFactory* processor_factory,
51 syncer::UserShare* user_share,
52 DataTypeErrorHandler* error_handler,
53 syncer::ModelType type,
54 const base::WeakPtr<syncer::SyncMergeResult>& merge_result) {
55 DCHECK(sync_factory);
56 DCHECK(error_handler);
57 DCHECK_NE(type, syncer::UNSPECIFIED);
58 backend_loop_ = base::MessageLoopProxy::current();
59 AutoLock lock(monitor_lock_);
60 if (disconnected_)
61 return base::WeakPtr<syncer::SyncableService>();
62 type_ = type;
63 error_handler_ = error_handler;
64 base::WeakPtr<syncer::SyncableService> local_service =
65 sync_factory->GetSyncableServiceForType(type);
66 if (!local_service.get()) {
67 LOG(WARNING) << "SyncableService destroyed before DTC was stopped.";
68 disconnected_ = true;
69 return base::WeakPtr<syncer::SyncableService>();
72 generic_change_processor_ =
73 processor_factory->CreateGenericChangeProcessor(type,
74 user_share,
75 error_handler,
76 local_service,
77 merge_result,
78 sync_factory).release();
79 // If available, propagate attachment service to the syncable service.
80 scoped_ptr<syncer::AttachmentService> attachment_service =
81 generic_change_processor_->GetAttachmentService();
82 if (attachment_service) {
83 local_service->SetAttachmentService(attachment_service.Pass());
85 return local_service;
88 bool SharedChangeProcessor::Disconnect() {
89 // May be called from any thread.
90 DVLOG(1) << "Disconnecting change processor.";
91 AutoLock lock(monitor_lock_);
92 bool was_connected = !disconnected_;
93 disconnected_ = true;
94 error_handler_ = NULL;
95 return was_connected;
98 ChangeProcessor* SharedChangeProcessor::generic_change_processor() {
99 return generic_change_processor_;
102 int SharedChangeProcessor::GetSyncCount() {
103 DCHECK(backend_loop_.get());
104 DCHECK(backend_loop_->BelongsToCurrentThread());
105 AutoLock lock(monitor_lock_);
106 if (disconnected_) {
107 LOG(ERROR) << "Change processor disconnected.";
108 return 0;
110 return generic_change_processor_->GetSyncCount();
113 syncer::SyncError SharedChangeProcessor::ProcessSyncChanges(
114 const tracked_objects::Location& from_here,
115 const syncer::SyncChangeList& list_of_changes) {
116 DCHECK(backend_loop_.get());
117 DCHECK(backend_loop_->BelongsToCurrentThread());
118 AutoLock lock(monitor_lock_);
119 if (disconnected_) {
120 // The DTC that disconnects us must ensure it posts a StopSyncing task.
121 // If we reach this, it means it just hasn't executed yet.
122 syncer::SyncError error(FROM_HERE,
123 syncer::SyncError::DATATYPE_ERROR,
124 "Change processor disconnected.",
125 type_);
126 return error;
128 return generic_change_processor_->ProcessSyncChanges(
129 from_here, list_of_changes);
132 syncer::SyncDataList SharedChangeProcessor::GetAllSyncData(
133 syncer::ModelType type) const {
134 syncer::SyncDataList data;
135 GetAllSyncDataReturnError(type, &data); // Handles the disconnect case.
136 return data;
139 syncer::SyncError SharedChangeProcessor::GetAllSyncDataReturnError(
140 syncer::ModelType type,
141 syncer::SyncDataList* data) const {
142 DCHECK(backend_loop_.get());
143 DCHECK(backend_loop_->BelongsToCurrentThread());
144 AutoLock lock(monitor_lock_);
145 if (disconnected_) {
146 syncer::SyncError error(FROM_HERE,
147 syncer::SyncError::DATATYPE_ERROR,
148 "Change processor disconnected.",
149 type_);
150 return error;
152 return generic_change_processor_->GetAllSyncDataReturnError(data);
155 syncer::SyncError SharedChangeProcessor::UpdateDataTypeContext(
156 syncer::ModelType type,
157 syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status,
158 const std::string& context) {
159 DCHECK(backend_loop_.get());
160 DCHECK(backend_loop_->BelongsToCurrentThread());
161 AutoLock lock(monitor_lock_);
162 if (disconnected_) {
163 syncer::SyncError error(FROM_HERE,
164 syncer::SyncError::DATATYPE_ERROR,
165 "Change processor disconnected.",
166 type_);
167 return error;
169 return generic_change_processor_->UpdateDataTypeContext(
170 type, refresh_status, context);
173 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) {
174 DCHECK(backend_loop_.get());
175 DCHECK(backend_loop_->BelongsToCurrentThread());
176 AutoLock lock(monitor_lock_);
177 if (disconnected_) {
178 LOG(ERROR) << "Change processor disconnected.";
179 return false;
181 return generic_change_processor_->SyncModelHasUserCreatedNodes(has_nodes);
184 bool SharedChangeProcessor::CryptoReadyIfNecessary() {
185 DCHECK(backend_loop_.get());
186 DCHECK(backend_loop_->BelongsToCurrentThread());
187 AutoLock lock(monitor_lock_);
188 if (disconnected_) {
189 LOG(ERROR) << "Change processor disconnected.";
190 return true; // Otherwise we get into infinite spin waiting.
192 return generic_change_processor_->CryptoReadyIfNecessary();
195 bool SharedChangeProcessor::GetDataTypeContext(std::string* context) const {
196 DCHECK(backend_loop_.get());
197 DCHECK(backend_loop_->BelongsToCurrentThread());
198 AutoLock lock(monitor_lock_);
199 if (disconnected_) {
200 LOG(ERROR) << "Change processor disconnected.";
201 return false;
203 return generic_change_processor_->GetDataTypeContext(context);
206 syncer::SyncError SharedChangeProcessor::CreateAndUploadError(
207 const tracked_objects::Location& location,
208 const std::string& message) {
209 AutoLock lock(monitor_lock_);
210 if (!disconnected_) {
211 return error_handler_->CreateAndUploadError(location, message, type_);
212 } else {
213 return syncer::SyncError(location,
214 syncer::SyncError::DATATYPE_ERROR,
215 message,
216 type_);
220 } // namespace sync_driver