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"
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_
;
38 DCHECK(frontend_loop_
->BelongsToCurrentThread());
39 if (!backend_loop_
->DeleteSoon(FROM_HERE
, generic_change_processor_
)) {
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
) {
56 DCHECK(error_handler
);
57 DCHECK_NE(type
, syncer::UNSPECIFIED
);
58 backend_loop_
= base::MessageLoopProxy::current();
59 AutoLock
lock(monitor_lock_
);
61 return base::WeakPtr
<syncer::SyncableService
>();
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.";
69 return base::WeakPtr
<syncer::SyncableService
>();
72 generic_change_processor_
=
73 processor_factory
->CreateGenericChangeProcessor(type
,
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());
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_
;
94 error_handler_
= NULL
;
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_
);
107 LOG(ERROR
) << "Change processor disconnected.";
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_
);
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.",
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.
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_
);
146 syncer::SyncError
error(FROM_HERE
,
147 syncer::SyncError::DATATYPE_ERROR
,
148 "Change processor disconnected.",
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_
);
163 syncer::SyncError
error(FROM_HERE
,
164 syncer::SyncError::DATATYPE_ERROR
,
165 "Change processor disconnected.",
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_
);
178 LOG(ERROR
) << "Change processor disconnected.";
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_
);
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_
);
200 LOG(ERROR
) << "Change processor disconnected.";
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_
);
213 return syncer::SyncError(location
,
214 syncer::SyncError::DATATYPE_ERROR
,
220 } // namespace sync_driver