Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / components / sync_driver / shared_change_processor.cc
blob64cf35a0911b76b6efabbadf4e5fc0b309b03dce
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"
14 using base::AutoLock;
16 namespace syncer {
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_;
38 } else {
39 DCHECK(frontend_task_runner_->BelongsToCurrentThread());
40 if (!backend_task_runner_->DeleteSoon(FROM_HERE,
41 generic_change_processor_)) {
42 NOTREACHED();
45 } else {
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) {
57 DCHECK(sync_client);
58 DCHECK(error_handler);
59 DCHECK_NE(type, syncer::UNSPECIFIED);
60 backend_task_runner_ = base::ThreadTaskRunnerHandle::Get();
61 AutoLock lock(monitor_lock_);
62 if (disconnected_)
63 return base::WeakPtr<syncer::SyncableService>();
64 type_ = type;
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.";
70 disconnected_ = true;
71 return base::WeakPtr<syncer::SyncableService>();
74 generic_change_processor_ =
75 processor_factory->CreateGenericChangeProcessor(type,
76 user_share,
77 error_handler,
78 local_service,
79 merge_result,
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());
87 return local_service;
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_;
95 disconnected_ = true;
96 error_handler_ = NULL;
97 return was_connected;
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_);
108 if (disconnected_) {
109 LOG(ERROR) << "Change processor disconnected.";
110 return 0;
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_);
121 if (disconnected_) {
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.",
127 type_);
128 return error;
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.
138 return data;
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_);
147 if (disconnected_) {
148 syncer::SyncError error(FROM_HERE,
149 syncer::SyncError::DATATYPE_ERROR,
150 "Change processor disconnected.",
151 type_);
152 return error;
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_);
164 if (disconnected_) {
165 syncer::SyncError error(FROM_HERE,
166 syncer::SyncError::DATATYPE_ERROR,
167 "Change processor disconnected.",
168 type_);
169 return error;
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_);
179 if (disconnected_) {
180 LOG(ERROR) << "Change processor disconnected.";
181 return false;
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_);
190 if (disconnected_) {
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_);
201 if (disconnected_) {
202 LOG(ERROR) << "Change processor disconnected.";
203 return false;
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_);
214 } else {
215 return syncer::SyncError(location,
216 syncer::SyncError::DATATYPE_ERROR,
217 message,
218 type_);
222 } // namespace sync_driver