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