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"
15 namespace sync_driver
{
17 SharedChangeProcessor::SharedChangeProcessor()
18 : disconnected_(false),
19 type_(syncer::UNSPECIFIED
),
20 frontend_loop_(base::MessageLoopProxy::current()),
21 generic_change_processor_(NULL
),
22 error_handler_(NULL
) {
25 SharedChangeProcessor::~SharedChangeProcessor() {
26 // We can either be deleted when the DTC is destroyed (on UI
27 // thread), or when the syncer::SyncableService stop's syncing (datatype
28 // thread). |generic_change_processor_|, if non-NULL, must be
29 // deleted on |backend_loop_|.
30 if (frontend_loop_
->BelongsToCurrentThread()) {
31 if (backend_loop_
.get()) {
32 if (!backend_loop_
->DeleteSoon(FROM_HERE
, generic_change_processor_
)) {
36 DCHECK(!generic_change_processor_
);
39 DCHECK(backend_loop_
.get());
40 DCHECK(backend_loop_
->BelongsToCurrentThread());
41 delete generic_change_processor_
;
45 base::WeakPtr
<syncer::SyncableService
> SharedChangeProcessor::Connect(
46 SyncApiComponentFactory
* sync_factory
,
47 GenericChangeProcessorFactory
* processor_factory
,
48 syncer::UserShare
* user_share
,
49 DataTypeErrorHandler
* error_handler
,
50 syncer::ModelType type
,
51 const base::WeakPtr
<syncer::SyncMergeResult
>& merge_result
) {
53 DCHECK(error_handler
);
54 DCHECK_NE(type
, syncer::UNSPECIFIED
);
55 backend_loop_
= base::MessageLoopProxy::current();
56 AutoLock
lock(monitor_lock_
);
58 return base::WeakPtr
<syncer::SyncableService
>();
60 error_handler_
= error_handler
;
61 base::WeakPtr
<syncer::SyncableService
> local_service
=
62 sync_factory
->GetSyncableServiceForType(type
);
63 if (!local_service
.get()) {
64 LOG(WARNING
) << "SyncableService destroyed before DTC was stopped.";
66 return base::WeakPtr
<syncer::SyncableService
>();
69 generic_change_processor_
=
70 processor_factory
->CreateGenericChangeProcessor(user_share
,
74 sync_factory
).release();
78 bool SharedChangeProcessor::Disconnect() {
79 // May be called from any thread.
80 DVLOG(1) << "Disconnecting change processor.";
81 AutoLock
lock(monitor_lock_
);
82 bool was_connected
= !disconnected_
;
84 error_handler_
= NULL
;
88 ChangeProcessor
* SharedChangeProcessor::generic_change_processor() {
89 return generic_change_processor_
;
92 int SharedChangeProcessor::GetSyncCount() {
93 DCHECK(backend_loop_
.get());
94 DCHECK(backend_loop_
->BelongsToCurrentThread());
95 AutoLock
lock(monitor_lock_
);
97 LOG(ERROR
) << "Change processor disconnected.";
100 return generic_change_processor_
->GetSyncCountForType(type_
);
103 syncer::SyncError
SharedChangeProcessor::ProcessSyncChanges(
104 const tracked_objects::Location
& from_here
,
105 const syncer::SyncChangeList
& list_of_changes
) {
106 DCHECK(backend_loop_
.get());
107 DCHECK(backend_loop_
->BelongsToCurrentThread());
108 AutoLock
lock(monitor_lock_
);
110 // The DTC that disconnects us must ensure it posts a StopSyncing task.
111 // If we reach this, it means it just hasn't executed yet.
112 syncer::SyncError
error(FROM_HERE
,
113 syncer::SyncError::DATATYPE_ERROR
,
114 "Change processor disconnected.",
118 return generic_change_processor_
->ProcessSyncChanges(
119 from_here
, list_of_changes
);
122 syncer::SyncDataList
SharedChangeProcessor::GetAllSyncData(
123 syncer::ModelType type
) const {
124 syncer::SyncDataList data
;
125 GetAllSyncDataReturnError(type
, &data
); // Handles the disconnect case.
129 syncer::SyncError
SharedChangeProcessor::GetAllSyncDataReturnError(
130 syncer::ModelType type
,
131 syncer::SyncDataList
* data
) const {
132 DCHECK(backend_loop_
.get());
133 DCHECK(backend_loop_
->BelongsToCurrentThread());
134 AutoLock
lock(monitor_lock_
);
136 syncer::SyncError
error(FROM_HERE
,
137 syncer::SyncError::DATATYPE_ERROR
,
138 "Change processor disconnected.",
142 return generic_change_processor_
->GetAllSyncDataReturnError(type
, data
);
145 syncer::SyncError
SharedChangeProcessor::UpdateDataTypeContext(
146 syncer::ModelType type
,
147 syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status
,
148 const std::string
& context
) {
149 DCHECK(backend_loop_
.get());
150 DCHECK(backend_loop_
->BelongsToCurrentThread());
151 AutoLock
lock(monitor_lock_
);
153 syncer::SyncError
error(FROM_HERE
,
154 syncer::SyncError::DATATYPE_ERROR
,
155 "Change processor disconnected.",
159 return generic_change_processor_
->UpdateDataTypeContext(
160 type
, refresh_status
, context
);
163 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes
) {
164 DCHECK(backend_loop_
.get());
165 DCHECK(backend_loop_
->BelongsToCurrentThread());
166 AutoLock
lock(monitor_lock_
);
168 LOG(ERROR
) << "Change processor disconnected.";
171 return generic_change_processor_
->SyncModelHasUserCreatedNodes(
175 bool SharedChangeProcessor::CryptoReadyIfNecessary() {
176 DCHECK(backend_loop_
.get());
177 DCHECK(backend_loop_
->BelongsToCurrentThread());
178 AutoLock
lock(monitor_lock_
);
180 LOG(ERROR
) << "Change processor disconnected.";
181 return true; // Otherwise we get into infinite spin waiting.
183 return generic_change_processor_
->CryptoReadyIfNecessary(type_
);
186 bool SharedChangeProcessor::GetDataTypeContext(std::string
* context
) const {
187 DCHECK(backend_loop_
.get());
188 DCHECK(backend_loop_
->BelongsToCurrentThread());
189 AutoLock
lock(monitor_lock_
);
191 LOG(ERROR
) << "Change processor disconnected.";
194 return generic_change_processor_
->GetDataTypeContext(type_
, context
);
197 syncer::SyncError
SharedChangeProcessor::CreateAndUploadError(
198 const tracked_objects::Location
& location
,
199 const std::string
& message
) {
200 AutoLock
lock(monitor_lock_
);
201 if (!disconnected_
) {
202 return error_handler_
->CreateAndUploadError(location
, message
, type_
);
204 return syncer::SyncError(location
,
205 syncer::SyncError::DATATYPE_ERROR
,
211 } // namespace sync_driver