Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: components/sync/driver/non_ui_data_type_controller.cc

Issue 2549223003: [Sync] Rename NonUIDataTypeController to AsyncDirectoryTypeController (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/non_ui_data_type_controller.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "components/sync/base/bind_to_task_runner.h"
12 #include "components/sync/base/data_type_histogram.h"
13 #include "components/sync/base/model_type.h"
14 #include "components/sync/driver/generic_change_processor_factory.h"
15 #include "components/sync/driver/sync_api_component_factory.h"
16 #include "components/sync/driver/sync_client.h"
17 #include "components/sync/driver/sync_service.h"
18 #include "components/sync/model/data_type_error_handler_impl.h"
19 #include "components/sync/model/sync_error.h"
20 #include "components/sync/model/sync_merge_result.h"
21 #include "components/sync/model/syncable_service.h"
22
23 namespace syncer {
24
25 SharedChangeProcessor* NonUIDataTypeController::CreateSharedChangeProcessor() {
26 return new SharedChangeProcessor(type());
27 }
28
29 NonUIDataTypeController::NonUIDataTypeController(
30 ModelType type,
31 const base::Closure& dump_stack,
32 SyncClient* sync_client,
33 ModelSafeGroup model_safe_group,
34 scoped_refptr<base::SequencedTaskRunner> model_thread)
35 : DirectoryDataTypeController(type,
36 dump_stack,
37 sync_client,
38 model_safe_group),
39 user_share_(nullptr),
40 processor_factory_(new GenericChangeProcessorFactory()),
41 state_(NOT_RUNNING),
42 model_thread_(std::move(model_thread)) {}
43
44 void NonUIDataTypeController::LoadModels(
45 const ModelLoadCallback& model_load_callback) {
46 DCHECK(CalledOnValidThread());
47 model_load_callback_ = model_load_callback;
48 if (state() != NOT_RUNNING) {
49 model_load_callback.Run(type(),
50 SyncError(FROM_HERE, SyncError::DATATYPE_ERROR,
51 "Model already running", type()));
52 return;
53 }
54
55 state_ = MODEL_STARTING;
56 // Since we can't be called multiple times before Stop() is called,
57 // |shared_change_processor_| must be null here.
58 DCHECK(!shared_change_processor_.get());
59 shared_change_processor_ = CreateSharedChangeProcessor();
60 DCHECK(shared_change_processor_.get());
61 if (!StartModels()) {
62 // If we are waiting for some external service to load before associating
63 // or we failed to start the models, we exit early.
64 DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING);
65 return;
66 }
67
68 OnModelLoaded();
69 }
70
71 void NonUIDataTypeController::OnModelLoaded() {
72 DCHECK(CalledOnValidThread());
73 DCHECK_EQ(state_, MODEL_STARTING);
74 state_ = MODEL_LOADED;
75 model_load_callback_.Run(type(), SyncError());
76 }
77
78 bool NonUIDataTypeController::StartModels() {
79 DCHECK(CalledOnValidThread());
80 DCHECK_EQ(state_, MODEL_STARTING);
81 // By default, no additional services need to be started before we can proceed
82 // with model association.
83 return true;
84 }
85
86 void NonUIDataTypeController::StopModels() {
87 DCHECK(CalledOnValidThread());
88 }
89
90 bool NonUIDataTypeController::PostTaskOnModelThread(
91 const tracked_objects::Location& from_here,
92 const base::Closure& task) {
93 DCHECK(CalledOnValidThread());
94 return model_thread_->PostTask(from_here, task);
95 }
96
97 void NonUIDataTypeController::StartAssociating(
98 const StartCallback& start_callback) {
99 DCHECK(CalledOnValidThread());
100 DCHECK(!start_callback.is_null());
101 DCHECK_EQ(state_, MODEL_LOADED);
102 state_ = ASSOCIATING;
103
104 // Store UserShare now while on UI thread to avoid potential race
105 // condition in StartAssociationWithSharedChangeProcessor.
106 DCHECK(sync_client_->GetSyncService());
107 user_share_ = sync_client_->GetSyncService()->GetUserShare();
108
109 start_callback_ = start_callback;
110 if (!StartAssociationAsync()) {
111 SyncError error(FROM_HERE, SyncError::DATATYPE_ERROR,
112 "Failed to post StartAssociation", type());
113 SyncMergeResult local_merge_result(type());
114 local_merge_result.set_error(error);
115 StartDone(ASSOCIATION_FAILED, local_merge_result, SyncMergeResult(type()));
116 // StartDone should have cleared the SharedChangeProcessor.
117 DCHECK(!shared_change_processor_.get());
118 return;
119 }
120 }
121
122 void NonUIDataTypeController::Stop() {
123 DCHECK(CalledOnValidThread());
124
125 if (state() == NOT_RUNNING)
126 return;
127
128 // Disconnect the change processor. At this point, the
129 // SyncableService can no longer interact with the Syncer, even if
130 // it hasn't finished MergeDataAndStartSyncing.
131 DisconnectSharedChangeProcessor();
132
133 // If we haven't finished starting, we need to abort the start.
134 bool service_started = state() == ASSOCIATING || state() == RUNNING;
135 state_ = service_started ? STOPPING : NOT_RUNNING;
136 StopModels();
137
138 if (service_started)
139 StopSyncableService();
140
141 shared_change_processor_ = nullptr;
142 state_ = NOT_RUNNING;
143 }
144
145 std::string NonUIDataTypeController::name() const {
146 // For logging only.
147 return ModelTypeToString(type());
148 }
149
150 DataTypeController::State NonUIDataTypeController::state() const {
151 return state_;
152 }
153
154 void NonUIDataTypeController::SetGenericChangeProcessorFactoryForTest(
155 std::unique_ptr<GenericChangeProcessorFactory> factory) {
156 DCHECK_EQ(state_, NOT_RUNNING);
157 processor_factory_ = std::move(factory);
158 }
159
160 NonUIDataTypeController::NonUIDataTypeController()
161 : DirectoryDataTypeController(UNSPECIFIED,
162 base::Closure(),
163 nullptr,
164 GROUP_PASSIVE) {}
165
166 NonUIDataTypeController::~NonUIDataTypeController() {}
167
168 void NonUIDataTypeController::StartDone(
169 DataTypeController::ConfigureResult start_result,
170 const SyncMergeResult& local_merge_result,
171 const SyncMergeResult& syncer_merge_result) {
172 DCHECK(CalledOnValidThread());
173
174 DataTypeController::State new_state;
175 if (IsSuccessfulResult(start_result)) {
176 new_state = RUNNING;
177 } else {
178 new_state = (start_result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING);
179 }
180
181 // If we failed to start up, and we haven't been stopped yet, we need to
182 // ensure we clean up the local service and shared change processor properly.
183 if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) {
184 DisconnectSharedChangeProcessor();
185 StopSyncableService();
186 shared_change_processor_ = nullptr;
187 }
188
189 // It's possible to have StartDone called first from the UI thread
190 // (due to Stop being called) and then posted from the non-UI thread. In
191 // this case, we drop the second call because we've already been stopped.
192 if (state_ == NOT_RUNNING) {
193 return;
194 }
195
196 state_ = new_state;
197 if (state_ != RUNNING) {
198 // Start failed.
199 StopModels();
200 RecordStartFailure(start_result);
201 }
202
203 start_callback_.Run(start_result, local_merge_result, syncer_merge_result);
204 }
205
206 void NonUIDataTypeController::RecordStartFailure(ConfigureResult result) {
207 DCHECK(CalledOnValidThread());
208 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures",
209 ModelTypeToHistogramInt(type()), MODEL_TYPE_COUNT);
210 #define PER_DATA_TYPE_MACRO(type_str) \
211 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \
212 MAX_CONFIGURE_RESULT);
213 SYNC_DATA_TYPE_HISTOGRAM(type());
214 #undef PER_DATA_TYPE_MACRO
215 }
216
217 void NonUIDataTypeController::DisableImpl(const SyncError& error) {
218 DCHECK(CalledOnValidThread());
219 if (!model_load_callback_.is_null()) {
220 model_load_callback_.Run(type(), error);
221 }
222 }
223
224 bool NonUIDataTypeController::StartAssociationAsync() {
225 DCHECK(CalledOnValidThread());
226 DCHECK_EQ(state(), ASSOCIATING);
227 return PostTaskOnModelThread(
228 FROM_HERE,
229 base::Bind(
230 &SharedChangeProcessor::StartAssociation, shared_change_processor_,
231 BindToCurrentThread(base::Bind(&NonUIDataTypeController::StartDone,
232 base::AsWeakPtr(this))),
233 sync_client_, processor_factory_.get(), user_share_,
234 base::Passed(CreateErrorHandler())));
235 }
236
237 ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const {
238 DCHECK(CalledOnValidThread());
239 DCHECK_EQ(state_, RUNNING);
240 return shared_change_processor_->generic_change_processor();
241 }
242
243 void NonUIDataTypeController::DisconnectSharedChangeProcessor() {
244 DCHECK(CalledOnValidThread());
245 // |shared_change_processor_| can already be null if Stop() is
246 // called after StartDone(_, DISABLED, _).
247 if (shared_change_processor_.get()) {
248 shared_change_processor_->Disconnect();
249 }
250 }
251
252 void NonUIDataTypeController::StopSyncableService() {
253 DCHECK(CalledOnValidThread());
254 if (shared_change_processor_.get()) {
255 PostTaskOnModelThread(FROM_HERE,
256 base::Bind(&SharedChangeProcessor::StopLocalService,
257 shared_change_processor_));
258 }
259 }
260
261 std::unique_ptr<DataTypeErrorHandler>
262 NonUIDataTypeController::CreateErrorHandler() {
263 DCHECK(CalledOnValidThread());
264 return base::MakeUnique<DataTypeErrorHandlerImpl>(
265 base::ThreadTaskRunnerHandle::Get(), dump_stack_,
266 base::Bind(&NonUIDataTypeController::DisableImpl, base::AsWeakPtr(this)));
267 }
268
269 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/driver/non_ui_data_type_controller.h ('k') | components/sync/driver/non_ui_data_type_controller_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698