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/thread_task_runner_handle.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_client.h"
11 #include "sync/api/sync_change.h"
12 #include "sync/api/syncable_service.h"
17 class AttachmentService
;
20 namespace sync_driver
{
22 SharedChangeProcessor::SharedChangeProcessor()
23 : disconnected_(false),
24 type_(syncer::UNSPECIFIED
),
25 frontend_task_runner_(base::ThreadTaskRunnerHandle::Get()),
26 generic_change_processor_(NULL
),
27 error_handler_(NULL
) {
30 SharedChangeProcessor::~SharedChangeProcessor() {
31 // We can either be deleted when the DTC is destroyed (on UI
32 // thread), or when the syncer::SyncableService stops syncing (datatype
33 // thread). |generic_change_processor_|, if non-NULL, must be
34 // deleted on |backend_loop_|.
35 if (backend_task_runner_
.get()) {
36 if (backend_task_runner_
->BelongsToCurrentThread()) {
37 delete generic_change_processor_
;
39 DCHECK(frontend_task_runner_
->BelongsToCurrentThread());
40 if (!backend_task_runner_
->DeleteSoon(FROM_HERE
,
41 generic_change_processor_
)) {
46 DCHECK(!generic_change_processor_
);
50 base::WeakPtr
<syncer::SyncableService
> SharedChangeProcessor::Connect(
51 SyncClient
* sync_client
,
52 GenericChangeProcessorFactory
* processor_factory
,
53 syncer::UserShare
* user_share
,
54 DataTypeErrorHandler
* error_handler
,
55 syncer::ModelType type
,
56 const base::WeakPtr
<syncer::SyncMergeResult
>& merge_result
) {
58 DCHECK(error_handler
);
59 DCHECK_NE(type
, syncer::UNSPECIFIED
);
60 backend_task_runner_
= base::ThreadTaskRunnerHandle::Get();
61 AutoLock
lock(monitor_lock_
);
63 return base::WeakPtr
<syncer::SyncableService
>();
65 error_handler_
= error_handler
;
66 base::WeakPtr
<syncer::SyncableService
> local_service
=
67 sync_client
->GetSyncableServiceForType(type
);
68 if (!local_service
.get()) {
69 LOG(WARNING
) << "SyncableService destroyed before DTC was stopped.";
71 return base::WeakPtr
<syncer::SyncableService
>();
74 generic_change_processor_
=
75 processor_factory
->CreateGenericChangeProcessor(type
,
80 sync_client
).release();
81 // If available, propagate attachment service to the syncable service.
82 scoped_ptr
<syncer::AttachmentService
> attachment_service
=
83 generic_change_processor_
->GetAttachmentService();
84 if (attachment_service
) {
85 local_service
->SetAttachmentService(attachment_service
.Pass());
90 bool SharedChangeProcessor::Disconnect() {
91 // May be called from any thread.
92 DVLOG(1) << "Disconnecting change processor.";
93 AutoLock
lock(monitor_lock_
);
94 bool was_connected
= !disconnected_
;
96 error_handler_
= NULL
;
100 ChangeProcessor
* SharedChangeProcessor::generic_change_processor() {
101 return generic_change_processor_
;
104 int SharedChangeProcessor::GetSyncCount() {
105 DCHECK(backend_task_runner_
.get());
106 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
107 AutoLock
lock(monitor_lock_
);
109 LOG(ERROR
) << "Change processor disconnected.";
112 return generic_change_processor_
->GetSyncCount();
115 syncer::SyncError
SharedChangeProcessor::ProcessSyncChanges(
116 const tracked_objects::Location
& from_here
,
117 const syncer::SyncChangeList
& list_of_changes
) {
118 DCHECK(backend_task_runner_
.get());
119 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
120 AutoLock
lock(monitor_lock_
);
122 // The DTC that disconnects us must ensure it posts a StopSyncing task.
123 // If we reach this, it means it just hasn't executed yet.
124 syncer::SyncError
error(FROM_HERE
,
125 syncer::SyncError::DATATYPE_ERROR
,
126 "Change processor disconnected.",
130 return generic_change_processor_
->ProcessSyncChanges(
131 from_here
, list_of_changes
);
134 syncer::SyncDataList
SharedChangeProcessor::GetAllSyncData(
135 syncer::ModelType type
) const {
136 syncer::SyncDataList data
;
137 GetAllSyncDataReturnError(type
, &data
); // Handles the disconnect case.
141 syncer::SyncError
SharedChangeProcessor::GetAllSyncDataReturnError(
142 syncer::ModelType type
,
143 syncer::SyncDataList
* data
) const {
144 DCHECK(backend_task_runner_
.get());
145 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
146 AutoLock
lock(monitor_lock_
);
148 syncer::SyncError
error(FROM_HERE
,
149 syncer::SyncError::DATATYPE_ERROR
,
150 "Change processor disconnected.",
154 return generic_change_processor_
->GetAllSyncDataReturnError(data
);
157 syncer::SyncError
SharedChangeProcessor::UpdateDataTypeContext(
158 syncer::ModelType type
,
159 syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status
,
160 const std::string
& context
) {
161 DCHECK(backend_task_runner_
.get());
162 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
163 AutoLock
lock(monitor_lock_
);
165 syncer::SyncError
error(FROM_HERE
,
166 syncer::SyncError::DATATYPE_ERROR
,
167 "Change processor disconnected.",
171 return generic_change_processor_
->UpdateDataTypeContext(
172 type
, refresh_status
, context
);
175 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes
) {
176 DCHECK(backend_task_runner_
.get());
177 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
178 AutoLock
lock(monitor_lock_
);
180 LOG(ERROR
) << "Change processor disconnected.";
183 return generic_change_processor_
->SyncModelHasUserCreatedNodes(has_nodes
);
186 bool SharedChangeProcessor::CryptoReadyIfNecessary() {
187 DCHECK(backend_task_runner_
.get());
188 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
189 AutoLock
lock(monitor_lock_
);
191 LOG(ERROR
) << "Change processor disconnected.";
192 return true; // Otherwise we get into infinite spin waiting.
194 return generic_change_processor_
->CryptoReadyIfNecessary();
197 bool SharedChangeProcessor::GetDataTypeContext(std::string
* context
) const {
198 DCHECK(backend_task_runner_
.get());
199 DCHECK(backend_task_runner_
->BelongsToCurrentThread());
200 AutoLock
lock(monitor_lock_
);
202 LOG(ERROR
) << "Change processor disconnected.";
205 return generic_change_processor_
->GetDataTypeContext(context
);
208 syncer::SyncError
SharedChangeProcessor::CreateAndUploadError(
209 const tracked_objects::Location
& location
,
210 const std::string
& message
) {
211 AutoLock
lock(monitor_lock_
);
212 if (!disconnected_
) {
213 return error_handler_
->CreateAndUploadError(location
, message
, type_
);
215 return syncer::SyncError(location
,
216 syncer::SyncError::DATATYPE_ERROR
,
222 } // namespace sync_driver