OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "components/sync_driver/shared_change_processor.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/threading/thread_task_runner_handle.h" | |
10 #include "components/sync/api/sync_change.h" | |
11 #include "components/sync/api/syncable_service.h" | |
12 #include "components/sync/core/data_type_error_handler.h" | |
13 #include "components/sync_driver/generic_change_processor.h" | |
14 #include "components/sync_driver/generic_change_processor_factory.h" | |
15 #include "components/sync_driver/sync_client.h" | |
16 | |
17 using base::AutoLock; | |
18 | |
19 namespace syncer { | |
20 class AttachmentService; | |
21 } | |
22 | |
23 namespace sync_driver { | |
24 | |
25 SharedChangeProcessor::SharedChangeProcessor() | |
26 : disconnected_(false), | |
27 type_(syncer::UNSPECIFIED), | |
28 frontend_task_runner_(base::ThreadTaskRunnerHandle::Get()), | |
29 generic_change_processor_(NULL), | |
30 error_handler_(NULL) { | |
31 } | |
32 | |
33 SharedChangeProcessor::~SharedChangeProcessor() { | |
34 // We can either be deleted when the DTC is destroyed (on UI | |
35 // thread), or when the syncer::SyncableService stops syncing (datatype | |
36 // thread). |generic_change_processor_|, if non-NULL, must be | |
37 // deleted on |backend_loop_|. | |
38 if (backend_task_runner_.get()) { | |
39 if (backend_task_runner_->BelongsToCurrentThread()) { | |
40 delete generic_change_processor_; | |
41 } else { | |
42 DCHECK(frontend_task_runner_->BelongsToCurrentThread()); | |
43 if (!backend_task_runner_->DeleteSoon(FROM_HERE, | |
44 generic_change_processor_)) { | |
45 NOTREACHED(); | |
46 } | |
47 } | |
48 } else { | |
49 DCHECK(!generic_change_processor_); | |
50 } | |
51 } | |
52 | |
53 base::WeakPtr<syncer::SyncableService> SharedChangeProcessor::Connect( | |
54 SyncClient* sync_client, | |
55 GenericChangeProcessorFactory* processor_factory, | |
56 syncer::UserShare* user_share, | |
57 syncer::DataTypeErrorHandler* error_handler, | |
58 syncer::ModelType type, | |
59 const base::WeakPtr<syncer::SyncMergeResult>& merge_result) { | |
60 DCHECK(sync_client); | |
61 DCHECK(error_handler); | |
62 DCHECK_NE(type, syncer::UNSPECIFIED); | |
63 backend_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
64 AutoLock lock(monitor_lock_); | |
65 if (disconnected_) | |
66 return base::WeakPtr<syncer::SyncableService>(); | |
67 type_ = type; | |
68 error_handler_ = error_handler; | |
69 base::WeakPtr<syncer::SyncableService> local_service = | |
70 sync_client->GetSyncableServiceForType(type); | |
71 if (!local_service.get()) { | |
72 LOG(WARNING) << "SyncableService destroyed before DTC was stopped."; | |
73 disconnected_ = true; | |
74 return base::WeakPtr<syncer::SyncableService>(); | |
75 } | |
76 | |
77 generic_change_processor_ = | |
78 processor_factory->CreateGenericChangeProcessor(type, | |
79 user_share, | |
80 error_handler, | |
81 local_service, | |
82 merge_result, | |
83 sync_client).release(); | |
84 // If available, propagate attachment service to the syncable service. | |
85 std::unique_ptr<syncer::AttachmentService> attachment_service = | |
86 generic_change_processor_->GetAttachmentService(); | |
87 if (attachment_service) { | |
88 local_service->SetAttachmentService(std::move(attachment_service)); | |
89 } | |
90 return local_service; | |
91 } | |
92 | |
93 bool SharedChangeProcessor::Disconnect() { | |
94 // May be called from any thread. | |
95 DVLOG(1) << "Disconnecting change processor."; | |
96 AutoLock lock(monitor_lock_); | |
97 bool was_connected = !disconnected_; | |
98 disconnected_ = true; | |
99 error_handler_ = NULL; | |
100 return was_connected; | |
101 } | |
102 | |
103 ChangeProcessor* SharedChangeProcessor::generic_change_processor() { | |
104 return generic_change_processor_; | |
105 } | |
106 | |
107 int SharedChangeProcessor::GetSyncCount() { | |
108 DCHECK(backend_task_runner_.get()); | |
109 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
110 AutoLock lock(monitor_lock_); | |
111 if (disconnected_) { | |
112 LOG(ERROR) << "Change processor disconnected."; | |
113 return 0; | |
114 } | |
115 return generic_change_processor_->GetSyncCount(); | |
116 } | |
117 | |
118 syncer::SyncError SharedChangeProcessor::ProcessSyncChanges( | |
119 const tracked_objects::Location& from_here, | |
120 const syncer::SyncChangeList& list_of_changes) { | |
121 DCHECK(backend_task_runner_.get()); | |
122 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
123 AutoLock lock(monitor_lock_); | |
124 if (disconnected_) { | |
125 // The DTC that disconnects us must ensure it posts a StopSyncing task. | |
126 // If we reach this, it means it just hasn't executed yet. | |
127 syncer::SyncError error(FROM_HERE, | |
128 syncer::SyncError::DATATYPE_ERROR, | |
129 "Change processor disconnected.", | |
130 type_); | |
131 return error; | |
132 } | |
133 return generic_change_processor_->ProcessSyncChanges( | |
134 from_here, list_of_changes); | |
135 } | |
136 | |
137 syncer::SyncDataList SharedChangeProcessor::GetAllSyncData( | |
138 syncer::ModelType type) const { | |
139 syncer::SyncDataList data; | |
140 GetAllSyncDataReturnError(type, &data); // Handles the disconnect case. | |
141 return data; | |
142 } | |
143 | |
144 syncer::SyncError SharedChangeProcessor::GetAllSyncDataReturnError( | |
145 syncer::ModelType type, | |
146 syncer::SyncDataList* data) const { | |
147 DCHECK(backend_task_runner_.get()); | |
148 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
149 AutoLock lock(monitor_lock_); | |
150 if (disconnected_) { | |
151 syncer::SyncError error(FROM_HERE, | |
152 syncer::SyncError::DATATYPE_ERROR, | |
153 "Change processor disconnected.", | |
154 type_); | |
155 return error; | |
156 } | |
157 return generic_change_processor_->GetAllSyncDataReturnError(data); | |
158 } | |
159 | |
160 syncer::SyncError SharedChangeProcessor::UpdateDataTypeContext( | |
161 syncer::ModelType type, | |
162 syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, | |
163 const std::string& context) { | |
164 DCHECK(backend_task_runner_.get()); | |
165 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
166 AutoLock lock(monitor_lock_); | |
167 if (disconnected_) { | |
168 syncer::SyncError error(FROM_HERE, | |
169 syncer::SyncError::DATATYPE_ERROR, | |
170 "Change processor disconnected.", | |
171 type_); | |
172 return error; | |
173 } | |
174 return generic_change_processor_->UpdateDataTypeContext( | |
175 type, refresh_status, context); | |
176 } | |
177 | |
178 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { | |
179 DCHECK(backend_task_runner_.get()); | |
180 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
181 AutoLock lock(monitor_lock_); | |
182 if (disconnected_) { | |
183 LOG(ERROR) << "Change processor disconnected."; | |
184 return false; | |
185 } | |
186 return generic_change_processor_->SyncModelHasUserCreatedNodes(has_nodes); | |
187 } | |
188 | |
189 bool SharedChangeProcessor::CryptoReadyIfNecessary() { | |
190 DCHECK(backend_task_runner_.get()); | |
191 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
192 AutoLock lock(monitor_lock_); | |
193 if (disconnected_) { | |
194 LOG(ERROR) << "Change processor disconnected."; | |
195 return true; // Otherwise we get into infinite spin waiting. | |
196 } | |
197 return generic_change_processor_->CryptoReadyIfNecessary(); | |
198 } | |
199 | |
200 bool SharedChangeProcessor::GetDataTypeContext(std::string* context) const { | |
201 DCHECK(backend_task_runner_.get()); | |
202 DCHECK(backend_task_runner_->BelongsToCurrentThread()); | |
203 AutoLock lock(monitor_lock_); | |
204 if (disconnected_) { | |
205 LOG(ERROR) << "Change processor disconnected."; | |
206 return false; | |
207 } | |
208 return generic_change_processor_->GetDataTypeContext(context); | |
209 } | |
210 | |
211 syncer::SyncError SharedChangeProcessor::CreateAndUploadError( | |
212 const tracked_objects::Location& location, | |
213 const std::string& message) { | |
214 AutoLock lock(monitor_lock_); | |
215 if (!disconnected_) { | |
216 return error_handler_->CreateAndUploadError(location, message, type_); | |
217 } else { | |
218 return syncer::SyncError(location, | |
219 syncer::SyncError::DATATYPE_ERROR, | |
220 message, | |
221 type_); | |
222 } | |
223 } | |
224 | |
225 } // namespace sync_driver | |
OLD | NEW |