OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/frontend_data_type_controller.h" | 5 #include "components/sync/driver/frontend_data_type_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
10 #include "components/sync/api/data_type_error_handler_impl.h" | 10 #include "components/sync/api/data_type_error_handler_impl.h" |
11 #include "components/sync/api/sync_error.h" | 11 #include "components/sync/api/sync_error.h" |
12 #include "components/sync/api/sync_merge_result.h" | 12 #include "components/sync/api/sync_merge_result.h" |
13 #include "components/sync/base/data_type_histogram.h" | 13 #include "components/sync/base/data_type_histogram.h" |
14 #include "components/sync/base/model_type.h" | 14 #include "components/sync/base/model_type.h" |
15 #include "components/sync/driver/change_processor.h" | 15 #include "components/sync/driver/change_processor.h" |
16 #include "components/sync/driver/model_associator.h" | 16 #include "components/sync/driver/model_associator.h" |
17 #include "components/sync/driver/sync_client.h" | 17 #include "components/sync/driver/sync_client.h" |
18 #include "components/sync/driver/sync_service.h" | 18 #include "components/sync/driver/sync_service.h" |
19 | 19 |
20 namespace browser_sync { | 20 namespace syncer { |
21 | 21 |
22 FrontendDataTypeController::FrontendDataTypeController( | 22 FrontendDataTypeController::FrontendDataTypeController( |
23 syncer::ModelType type, | 23 ModelType type, |
24 const base::Closure& dump_stack, | 24 const base::Closure& dump_stack, |
25 sync_driver::SyncClient* sync_client) | 25 SyncClient* sync_client) |
26 : DirectoryDataTypeController(type, dump_stack, sync_client), | 26 : DirectoryDataTypeController(type, dump_stack, sync_client), |
27 state_(NOT_RUNNING) { | 27 state_(NOT_RUNNING) { |
28 DCHECK(CalledOnValidThread()); | 28 DCHECK(CalledOnValidThread()); |
29 DCHECK(sync_client); | 29 DCHECK(sync_client); |
30 } | 30 } |
31 | 31 |
32 void FrontendDataTypeController::LoadModels( | 32 void FrontendDataTypeController::LoadModels( |
33 const ModelLoadCallback& model_load_callback) { | 33 const ModelLoadCallback& model_load_callback) { |
34 DCHECK(CalledOnValidThread()); | 34 DCHECK(CalledOnValidThread()); |
35 model_load_callback_ = model_load_callback; | 35 model_load_callback_ = model_load_callback; |
36 | 36 |
37 if (state_ != NOT_RUNNING) { | 37 if (state_ != NOT_RUNNING) { |
38 model_load_callback.Run( | 38 model_load_callback.Run(type(), |
39 type(), syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 39 SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, |
40 "Model already running", type())); | 40 "Model already running", type())); |
41 return; | 41 return; |
42 } | 42 } |
43 | 43 |
44 state_ = MODEL_STARTING; | 44 state_ = MODEL_STARTING; |
45 if (!StartModels()) { | 45 if (!StartModels()) { |
46 // If we are waiting for some external service to load before associating | 46 // If we are waiting for some external service to load before associating |
47 // or we failed to start the models, we exit early. state_ will control | 47 // or we failed to start the models, we exit early. state_ will control |
48 // what we perform next. | 48 // what we perform next. |
49 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); | 49 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); |
50 return; | 50 return; |
51 } | 51 } |
52 | 52 |
53 OnModelLoaded(); | 53 OnModelLoaded(); |
54 } | 54 } |
55 | 55 |
56 void FrontendDataTypeController::OnModelLoaded() { | 56 void FrontendDataTypeController::OnModelLoaded() { |
57 DCHECK(CalledOnValidThread()); | 57 DCHECK(CalledOnValidThread()); |
58 DCHECK_EQ(state_, MODEL_STARTING); | 58 DCHECK_EQ(state_, MODEL_STARTING); |
59 | 59 |
60 state_ = MODEL_LOADED; | 60 state_ = MODEL_LOADED; |
61 model_load_callback_.Run(type(), syncer::SyncError()); | 61 model_load_callback_.Run(type(), SyncError()); |
62 } | 62 } |
63 | 63 |
64 void FrontendDataTypeController::StartAssociating( | 64 void FrontendDataTypeController::StartAssociating( |
65 const StartCallback& start_callback) { | 65 const StartCallback& start_callback) { |
66 DCHECK(CalledOnValidThread()); | 66 DCHECK(CalledOnValidThread()); |
67 DCHECK(!start_callback.is_null()); | 67 DCHECK(!start_callback.is_null()); |
68 DCHECK_EQ(state_, MODEL_LOADED); | 68 DCHECK_EQ(state_, MODEL_LOADED); |
69 | 69 |
70 start_callback_ = start_callback; | 70 start_callback_ = start_callback; |
71 state_ = ASSOCIATING; | 71 state_ = ASSOCIATING; |
(...skipping 17 matching lines...) Expand all Loading... |
89 if (prev_state == MODEL_STARTING) { | 89 if (prev_state == MODEL_STARTING) { |
90 AbortModelLoad(); | 90 AbortModelLoad(); |
91 // We can just return here since we haven't performed association if we're | 91 // We can just return here since we haven't performed association if we're |
92 // still in MODEL_STARTING. | 92 // still in MODEL_STARTING. |
93 return; | 93 return; |
94 } | 94 } |
95 | 95 |
96 CleanUpState(); | 96 CleanUpState(); |
97 | 97 |
98 if (model_associator()) { | 98 if (model_associator()) { |
99 syncer::SyncError error; // Not used. | 99 SyncError error; // Not used. |
100 error = model_associator()->DisassociateModels(); | 100 error = model_associator()->DisassociateModels(); |
101 } | 101 } |
102 | 102 |
103 set_model_associator(NULL); | 103 set_model_associator(NULL); |
104 change_processor_.reset(); | 104 change_processor_.reset(); |
105 | 105 |
106 state_ = NOT_RUNNING; | 106 state_ = NOT_RUNNING; |
107 } | 107 } |
108 | 108 |
109 syncer::ModelSafeGroup FrontendDataTypeController::model_safe_group() const { | 109 ModelSafeGroup FrontendDataTypeController::model_safe_group() const { |
110 return syncer::GROUP_UI; | 110 return GROUP_UI; |
111 } | 111 } |
112 | 112 |
113 std::string FrontendDataTypeController::name() const { | 113 std::string FrontendDataTypeController::name() const { |
114 // For logging only. | 114 // For logging only. |
115 return syncer::ModelTypeToString(type()); | 115 return ModelTypeToString(type()); |
116 } | 116 } |
117 | 117 |
118 sync_driver::DataTypeController::State FrontendDataTypeController::state() | 118 DataTypeController::State FrontendDataTypeController::state() const { |
119 const { | |
120 return state_; | 119 return state_; |
121 } | 120 } |
122 | 121 |
123 FrontendDataTypeController::FrontendDataTypeController() | 122 FrontendDataTypeController::FrontendDataTypeController() |
124 : DirectoryDataTypeController(syncer::UNSPECIFIED, | 123 : DirectoryDataTypeController(UNSPECIFIED, base::Closure(), nullptr), |
125 base::Closure(), | |
126 nullptr), | |
127 state_(NOT_RUNNING) {} | 124 state_(NOT_RUNNING) {} |
128 | 125 |
129 FrontendDataTypeController::~FrontendDataTypeController() {} | 126 FrontendDataTypeController::~FrontendDataTypeController() {} |
130 | 127 |
131 bool FrontendDataTypeController::StartModels() { | 128 bool FrontendDataTypeController::StartModels() { |
132 DCHECK(CalledOnValidThread()); | 129 DCHECK(CalledOnValidThread()); |
133 DCHECK_EQ(state_, MODEL_STARTING); | 130 DCHECK_EQ(state_, MODEL_STARTING); |
134 // By default, no additional services need to be started before we can proceed | 131 // By default, no additional services need to be started before we can proceed |
135 // with model association. | 132 // with model association. |
136 return true; | 133 return true; |
137 } | 134 } |
138 | 135 |
139 void FrontendDataTypeController::Associate() { | 136 void FrontendDataTypeController::Associate() { |
140 DCHECK(CalledOnValidThread()); | 137 DCHECK(CalledOnValidThread()); |
141 if (state_ != ASSOCIATING) { | 138 if (state_ != ASSOCIATING) { |
142 // Stop() must have been called while Associate() task have been waiting. | 139 // Stop() must have been called while Associate() task have been waiting. |
143 DCHECK_EQ(state_, NOT_RUNNING); | 140 DCHECK_EQ(state_, NOT_RUNNING); |
144 return; | 141 return; |
145 } | 142 } |
146 | 143 |
147 syncer::SyncMergeResult local_merge_result(type()); | 144 SyncMergeResult local_merge_result(type()); |
148 syncer::SyncMergeResult syncer_merge_result(type()); | 145 SyncMergeResult syncer_merge_result(type()); |
149 CreateSyncComponents(); | 146 CreateSyncComponents(); |
150 if (!model_associator()->CryptoReadyIfNecessary()) { | 147 if (!model_associator()->CryptoReadyIfNecessary()) { |
151 StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); | 148 StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); |
152 return; | 149 return; |
153 } | 150 } |
154 | 151 |
155 bool sync_has_nodes = false; | 152 bool sync_has_nodes = false; |
156 if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { | 153 if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { |
157 syncer::SyncError error(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR, | 154 SyncError error(FROM_HERE, SyncError::UNRECOVERABLE_ERROR, |
158 "Failed to load sync nodes", type()); | 155 "Failed to load sync nodes", type()); |
159 local_merge_result.set_error(error); | 156 local_merge_result.set_error(error); |
160 StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); | 157 StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); |
161 return; | 158 return; |
162 } | 159 } |
163 | 160 |
164 // TODO(zea): Have AssociateModels fill the local and syncer merge results. | 161 // TODO(zea): Have AssociateModels fill the local and syncer merge results. |
165 base::TimeTicks start_time = base::TimeTicks::Now(); | 162 base::TimeTicks start_time = base::TimeTicks::Now(); |
166 syncer::SyncError error; | 163 SyncError error; |
167 error = model_associator()->AssociateModels(&local_merge_result, | 164 error = model_associator()->AssociateModels(&local_merge_result, |
168 &syncer_merge_result); | 165 &syncer_merge_result); |
169 // TODO(lipalani): crbug.com/122690 - handle abort. | 166 // TODO(lipalani): crbug.com/122690 - handle abort. |
170 RecordAssociationTime(base::TimeTicks::Now() - start_time); | 167 RecordAssociationTime(base::TimeTicks::Now() - start_time); |
171 if (error.IsSet()) { | 168 if (error.IsSet()) { |
172 local_merge_result.set_error(error); | 169 local_merge_result.set_error(error); |
173 StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); | 170 StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); |
174 return; | 171 return; |
175 } | 172 } |
176 | 173 |
(...skipping 16 matching lines...) Expand all Loading... |
193 } | 190 } |
194 | 191 |
195 void FrontendDataTypeController::AbortModelLoad() { | 192 void FrontendDataTypeController::AbortModelLoad() { |
196 DCHECK(CalledOnValidThread()); | 193 DCHECK(CalledOnValidThread()); |
197 CleanUp(); | 194 CleanUp(); |
198 state_ = NOT_RUNNING; | 195 state_ = NOT_RUNNING; |
199 } | 196 } |
200 | 197 |
201 void FrontendDataTypeController::StartDone( | 198 void FrontendDataTypeController::StartDone( |
202 ConfigureResult start_result, | 199 ConfigureResult start_result, |
203 const syncer::SyncMergeResult& local_merge_result, | 200 const SyncMergeResult& local_merge_result, |
204 const syncer::SyncMergeResult& syncer_merge_result) { | 201 const SyncMergeResult& syncer_merge_result) { |
205 DCHECK(CalledOnValidThread()); | 202 DCHECK(CalledOnValidThread()); |
206 if (!IsSuccessfulResult(start_result)) { | 203 if (!IsSuccessfulResult(start_result)) { |
207 CleanUp(); | 204 CleanUp(); |
208 if (start_result == ASSOCIATION_FAILED) { | 205 if (start_result == ASSOCIATION_FAILED) { |
209 state_ = DISABLED; | 206 state_ = DISABLED; |
210 } else { | 207 } else { |
211 state_ = NOT_RUNNING; | 208 state_ = NOT_RUNNING; |
212 } | 209 } |
213 RecordStartFailure(start_result); | 210 RecordStartFailure(start_result); |
214 } | 211 } |
215 | 212 |
216 start_callback_.Run(start_result, local_merge_result, syncer_merge_result); | 213 start_callback_.Run(start_result, local_merge_result, syncer_merge_result); |
217 } | 214 } |
218 | 215 |
219 std::unique_ptr<syncer::DataTypeErrorHandler> | 216 std::unique_ptr<DataTypeErrorHandler> |
220 FrontendDataTypeController::CreateErrorHandler() { | 217 FrontendDataTypeController::CreateErrorHandler() { |
221 return base::MakeUnique<syncer::DataTypeErrorHandlerImpl>( | 218 return base::MakeUnique<DataTypeErrorHandlerImpl>( |
222 base::ThreadTaskRunnerHandle::Get(), dump_stack_, | 219 base::ThreadTaskRunnerHandle::Get(), dump_stack_, |
223 base::Bind(&FrontendDataTypeController::OnUnrecoverableError, | 220 base::Bind(&FrontendDataTypeController::OnUnrecoverableError, |
224 base::AsWeakPtr(this))); | 221 base::AsWeakPtr(this))); |
225 } | 222 } |
226 | 223 |
227 void FrontendDataTypeController::OnUnrecoverableError( | 224 void FrontendDataTypeController::OnUnrecoverableError(const SyncError& error) { |
228 const syncer::SyncError& error) { | |
229 DCHECK(CalledOnValidThread()); | 225 DCHECK(CalledOnValidThread()); |
230 DCHECK_EQ(type(), error.model_type()); | 226 DCHECK_EQ(type(), error.model_type()); |
231 if (!model_load_callback_.is_null()) { | 227 if (!model_load_callback_.is_null()) { |
232 model_load_callback_.Run(type(), error); | 228 model_load_callback_.Run(type(), error); |
233 } | 229 } |
234 } | 230 } |
235 | 231 |
236 void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { | 232 void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { |
237 DCHECK(CalledOnValidThread()); | 233 DCHECK(CalledOnValidThread()); |
238 #define PER_DATA_TYPE_MACRO(type_str) \ | 234 #define PER_DATA_TYPE_MACRO(type_str) \ |
239 UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); | 235 UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); |
240 SYNC_DATA_TYPE_HISTOGRAM(type()); | 236 SYNC_DATA_TYPE_HISTOGRAM(type()); |
241 #undef PER_DATA_TYPE_MACRO | 237 #undef PER_DATA_TYPE_MACRO |
242 } | 238 } |
243 | 239 |
244 void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { | 240 void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { |
245 DCHECK(CalledOnValidThread()); | 241 DCHECK(CalledOnValidThread()); |
246 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", | 242 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", |
247 ModelTypeToHistogramInt(type()), | 243 ModelTypeToHistogramInt(type()), MODEL_TYPE_COUNT); |
248 syncer::MODEL_TYPE_COUNT); | |
249 #define PER_DATA_TYPE_MACRO(type_str) \ | 244 #define PER_DATA_TYPE_MACRO(type_str) \ |
250 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ | 245 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ |
251 MAX_CONFIGURE_RESULT); | 246 MAX_CONFIGURE_RESULT); |
252 SYNC_DATA_TYPE_HISTOGRAM(type()); | 247 SYNC_DATA_TYPE_HISTOGRAM(type()); |
253 #undef PER_DATA_TYPE_MACRO | 248 #undef PER_DATA_TYPE_MACRO |
254 } | 249 } |
255 | 250 |
256 sync_driver::AssociatorInterface* FrontendDataTypeController::model_associator() | 251 AssociatorInterface* FrontendDataTypeController::model_associator() const { |
257 const { | |
258 return model_associator_.get(); | 252 return model_associator_.get(); |
259 } | 253 } |
260 | 254 |
261 void FrontendDataTypeController::set_model_associator( | 255 void FrontendDataTypeController::set_model_associator( |
262 sync_driver::AssociatorInterface* model_associator) { | 256 AssociatorInterface* model_associator) { |
263 model_associator_.reset(model_associator); | 257 model_associator_.reset(model_associator); |
264 } | 258 } |
265 | 259 |
266 sync_driver::ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() | 260 ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() const { |
267 const { | |
268 return change_processor_.get(); | 261 return change_processor_.get(); |
269 } | 262 } |
270 | 263 |
271 void FrontendDataTypeController::set_change_processor( | 264 void FrontendDataTypeController::set_change_processor( |
272 sync_driver::ChangeProcessor* change_processor) { | 265 ChangeProcessor* change_processor) { |
273 change_processor_.reset(change_processor); | 266 change_processor_.reset(change_processor); |
274 } | 267 } |
275 | 268 |
276 } // namespace browser_sync | 269 } // namespace syncer |
OLD | NEW |