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/model_association_manager.h" | 5 #include "components/sync/driver/model_association_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <functional> | 11 #include <functional> |
12 | 12 |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
16 #include "base/trace_event/trace_event.h" | 16 #include "base/trace_event/trace_event.h" |
17 #include "components/sync/api/sync_merge_result.h" | 17 #include "components/sync/api/sync_merge_result.h" |
18 #include "components/sync/base/model_type.h" | 18 #include "components/sync/base/model_type.h" |
19 | 19 |
20 namespace syncer { | 20 using syncer::ModelTypeSet; |
| 21 |
| 22 namespace sync_driver { |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
24 static const ModelType kStartOrder[] = { | 26 static const syncer::ModelType kStartOrder[] = { |
25 NIGORI, // Listed for completeness. | 27 syncer::NIGORI, // Listed for completeness. |
26 DEVICE_INFO, // Listed for completeness. | 28 syncer::DEVICE_INFO, // Listed for completeness. |
27 EXPERIMENTS, // Listed for completeness. | 29 syncer::EXPERIMENTS, // Listed for completeness. |
28 PROXY_TABS, // Listed for completeness. | 30 syncer::PROXY_TABS, // Listed for completeness. |
29 | 31 |
30 // Kick off the association of the non-UI types first so they can associate | 32 // Kick off the association of the non-UI types first so they can associate |
31 // in parallel with the UI types. | 33 // in parallel with the UI types. |
32 PASSWORDS, AUTOFILL, AUTOFILL_PROFILE, AUTOFILL_WALLET_DATA, | 34 syncer::PASSWORDS, syncer::AUTOFILL, syncer::AUTOFILL_PROFILE, |
33 AUTOFILL_WALLET_METADATA, EXTENSION_SETTINGS, APP_SETTINGS, TYPED_URLS, | 35 syncer::AUTOFILL_WALLET_DATA, syncer::AUTOFILL_WALLET_METADATA, |
34 HISTORY_DELETE_DIRECTIVES, SYNCED_NOTIFICATIONS, | 36 syncer::EXTENSION_SETTINGS, syncer::APP_SETTINGS, syncer::TYPED_URLS, |
35 SYNCED_NOTIFICATION_APP_INFO, | 37 syncer::HISTORY_DELETE_DIRECTIVES, syncer::SYNCED_NOTIFICATIONS, |
| 38 syncer::SYNCED_NOTIFICATION_APP_INFO, |
36 | 39 |
37 // UI thread data types. | 40 // UI thread data types. |
38 BOOKMARKS, | 41 syncer::BOOKMARKS, |
39 SUPERVISED_USERS, // Syncing supervised users on initial login | 42 syncer::SUPERVISED_USERS, // Syncing supervised users on initial login |
40 // might block creating a new supervised user, | 43 // might block creating a new supervised user, |
41 // so we want to do it early. | 44 // so we want to do it early. |
42 PREFERENCES, PRIORITY_PREFERENCES, EXTENSIONS, APPS, APP_LIST, ARC_PACKAGE, | 45 syncer::PREFERENCES, syncer::PRIORITY_PREFERENCES, syncer::EXTENSIONS, |
43 READING_LIST, THEMES, SEARCH_ENGINES, SESSIONS, APP_NOTIFICATIONS, | 46 syncer::APPS, syncer::APP_LIST, syncer::ARC_PACKAGE, syncer::READING_LIST, |
44 DICTIONARY, FAVICON_IMAGES, FAVICON_TRACKING, PRINTERS, | 47 syncer::THEMES, syncer::SEARCH_ENGINES, syncer::SESSIONS, |
45 SUPERVISED_USER_SETTINGS, SUPERVISED_USER_SHARED_SETTINGS, | 48 syncer::APP_NOTIFICATIONS, syncer::DICTIONARY, syncer::FAVICON_IMAGES, |
46 SUPERVISED_USER_WHITELISTS, ARTICLES, WIFI_CREDENTIALS, | 49 syncer::FAVICON_TRACKING, syncer::PRINTERS, |
| 50 syncer::SUPERVISED_USER_SETTINGS, syncer::SUPERVISED_USER_SHARED_SETTINGS, |
| 51 syncer::SUPERVISED_USER_WHITELISTS, syncer::ARTICLES, |
| 52 syncer::WIFI_CREDENTIALS, |
47 }; | 53 }; |
48 | 54 |
49 static_assert(arraysize(kStartOrder) == | 55 static_assert(arraysize(kStartOrder) == |
50 MODEL_TYPE_COUNT - FIRST_REAL_MODEL_TYPE, | 56 syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, |
51 "kStartOrder must have MODEL_TYPE_COUNT - " | 57 "kStartOrder must have MODEL_TYPE_COUNT - " |
52 "FIRST_REAL_MODEL_TYPE elements"); | 58 "FIRST_REAL_MODEL_TYPE elements"); |
53 | 59 |
54 // The amount of time we wait for association to finish. If some types haven't | 60 // The amount of time we wait for association to finish. If some types haven't |
55 // finished association by the time, DataTypeManager is notified of the | 61 // finished association by the time, DataTypeManager is notified of the |
56 // unfinished types. | 62 // unfinished types. |
57 const int64_t kAssociationTimeOutInSeconds = 600; | 63 const int64_t kAssociationTimeOutInSeconds = 600; |
58 | 64 |
59 DataTypeAssociationStats BuildAssociationStatsFromMergeResults( | 65 syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( |
60 const SyncMergeResult& local_merge_result, | 66 const syncer::SyncMergeResult& local_merge_result, |
61 const SyncMergeResult& syncer_merge_result, | 67 const syncer::SyncMergeResult& syncer_merge_result, |
62 const base::TimeDelta& association_wait_time, | 68 const base::TimeDelta& association_wait_time, |
63 const base::TimeDelta& association_time) { | 69 const base::TimeDelta& association_time) { |
64 DCHECK_EQ(local_merge_result.model_type(), syncer_merge_result.model_type()); | 70 DCHECK_EQ(local_merge_result.model_type(), syncer_merge_result.model_type()); |
65 DataTypeAssociationStats stats; | 71 syncer::DataTypeAssociationStats stats; |
66 stats.had_error = | 72 stats.had_error = |
67 local_merge_result.error().IsSet() || syncer_merge_result.error().IsSet(); | 73 local_merge_result.error().IsSet() || syncer_merge_result.error().IsSet(); |
68 stats.num_local_items_before_association = | 74 stats.num_local_items_before_association = |
69 local_merge_result.num_items_before_association(); | 75 local_merge_result.num_items_before_association(); |
70 stats.num_sync_items_before_association = | 76 stats.num_sync_items_before_association = |
71 syncer_merge_result.num_items_before_association(); | 77 syncer_merge_result.num_items_before_association(); |
72 stats.num_local_items_after_association = | 78 stats.num_local_items_after_association = |
73 local_merge_result.num_items_after_association(); | 79 local_merge_result.num_items_after_association(); |
74 stats.num_sync_items_after_association = | 80 stats.num_sync_items_after_association = |
75 syncer_merge_result.num_items_after_association(); | 81 syncer_merge_result.num_items_after_association(); |
(...skipping 25 matching lines...) Expand all Loading... |
101 weak_ptr_factory_(this) { | 107 weak_ptr_factory_(this) { |
102 // Ensure all data type controllers are stopped. | 108 // Ensure all data type controllers are stopped. |
103 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 109 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
104 it != controllers_->end(); ++it) { | 110 it != controllers_->end(); ++it) { |
105 DCHECK_EQ(DataTypeController::NOT_RUNNING, (*it).second->state()); | 111 DCHECK_EQ(DataTypeController::NOT_RUNNING, (*it).second->state()); |
106 } | 112 } |
107 } | 113 } |
108 | 114 |
109 ModelAssociationManager::~ModelAssociationManager() {} | 115 ModelAssociationManager::~ModelAssociationManager() {} |
110 | 116 |
111 void ModelAssociationManager::Initialize(ModelTypeSet desired_types) { | 117 void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { |
112 // state_ can be INITIALIZED if types are reconfigured when | 118 // state_ can be INITIALIZED if types are reconfigured when |
113 // data is being downloaded, so StartAssociationAsync() is never called for | 119 // data is being downloaded, so StartAssociationAsync() is never called for |
114 // the first configuration. | 120 // the first configuration. |
115 DCHECK_NE(ASSOCIATING, state_); | 121 DCHECK_NE(ASSOCIATING, state_); |
116 | 122 |
117 // Only keep types that have controllers. | 123 // Only keep types that have controllers. |
118 desired_types_.Clear(); | 124 desired_types_.Clear(); |
119 for (ModelTypeSet::Iterator it = desired_types.First(); it.Good(); it.Inc()) { | 125 for (syncer::ModelTypeSet::Iterator it = desired_types.First(); it.Good(); |
| 126 it.Inc()) { |
120 if (controllers_->find(it.Get()) != controllers_->end()) | 127 if (controllers_->find(it.Get()) != controllers_->end()) |
121 desired_types_.Put(it.Get()); | 128 desired_types_.Put(it.Get()); |
122 } | 129 } |
123 | 130 |
124 DVLOG(1) << "ModelAssociationManager: Initializing for " | 131 DVLOG(1) << "ModelAssociationManager: Initializing for " |
125 << ModelTypeSetToString(desired_types_); | 132 << syncer::ModelTypeSetToString(desired_types_); |
126 | 133 |
127 state_ = INITIALIZED; | 134 state_ = INITIALIZED; |
128 notified_about_ready_for_configure_ = false; | 135 notified_about_ready_for_configure_ = false; |
129 | 136 |
130 StopDisabledTypes(); | 137 StopDisabledTypes(); |
131 LoadEnabledTypes(); | 138 LoadEnabledTypes(); |
132 } | 139 } |
133 | 140 |
134 void ModelAssociationManager::StopDatatype(const SyncError& error, | 141 void ModelAssociationManager::StopDatatype(const syncer::SyncError& error, |
135 DataTypeController* dtc) { | 142 DataTypeController* dtc) { |
136 loaded_types_.Remove(dtc->type()); | 143 loaded_types_.Remove(dtc->type()); |
137 associated_types_.Remove(dtc->type()); | 144 associated_types_.Remove(dtc->type()); |
138 associating_types_.Remove(dtc->type()); | 145 associating_types_.Remove(dtc->type()); |
139 | 146 |
140 if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { | 147 if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { |
141 // If an error was set, the delegate must be informed of the error. | 148 // If an error was set, the delegate must be informed of the error. |
142 delegate_->OnSingleDataTypeWillStop(dtc->type(), error); | 149 delegate_->OnSingleDataTypeWillStop(dtc->type(), error); |
143 dtc->Stop(); | 150 dtc->Stop(); |
144 } | 151 } |
145 } | 152 } |
146 | 153 |
147 void ModelAssociationManager::StopDisabledTypes() { | 154 void ModelAssociationManager::StopDisabledTypes() { |
148 DVLOG(1) << "ModelAssociationManager: Stopping disabled types."; | 155 DVLOG(1) << "ModelAssociationManager: Stopping disabled types."; |
149 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 156 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
150 it != controllers_->end(); ++it) { | 157 it != controllers_->end(); ++it) { |
151 DataTypeController* dtc = (*it).second.get(); | 158 DataTypeController* dtc = (*it).second.get(); |
152 if (dtc->state() != DataTypeController::NOT_RUNNING && | 159 if (dtc->state() != DataTypeController::NOT_RUNNING && |
153 !desired_types_.Has(dtc->type())) { | 160 !desired_types_.Has(dtc->type())) { |
154 DVLOG(1) << "ModelAssociationManager: stop " << dtc->name(); | 161 DVLOG(1) << "ModelAssociationManager: stop " << dtc->name(); |
155 StopDatatype(SyncError(), dtc); | 162 StopDatatype(syncer::SyncError(), dtc); |
156 } | 163 } |
157 } | 164 } |
158 } | 165 } |
159 | 166 |
160 void ModelAssociationManager::LoadEnabledTypes() { | 167 void ModelAssociationManager::LoadEnabledTypes() { |
161 // Load in kStartOrder. | 168 // Load in kStartOrder. |
162 for (size_t i = 0; i < arraysize(kStartOrder); i++) { | 169 for (size_t i = 0; i < arraysize(kStartOrder); i++) { |
163 ModelType type = kStartOrder[i]; | 170 syncer::ModelType type = kStartOrder[i]; |
164 if (!desired_types_.Has(type)) | 171 if (!desired_types_.Has(type)) |
165 continue; | 172 continue; |
166 | 173 |
167 DCHECK(controllers_->find(type) != controllers_->end()); | 174 DCHECK(controllers_->find(type) != controllers_->end()); |
168 DataTypeController* dtc = controllers_->find(type)->second.get(); | 175 DataTypeController* dtc = controllers_->find(type)->second.get(); |
169 if (dtc->state() == DataTypeController::NOT_RUNNING) { | 176 if (dtc->state() == DataTypeController::NOT_RUNNING) { |
170 DCHECK(!loaded_types_.Has(dtc->type())); | 177 DCHECK(!loaded_types_.Has(dtc->type())); |
171 DCHECK(!associated_types_.Has(dtc->type())); | 178 DCHECK(!associated_types_.Has(dtc->type())); |
172 dtc->LoadModels(base::Bind(&ModelAssociationManager::ModelLoadCallback, | 179 dtc->LoadModels(base::Bind(&ModelAssociationManager::ModelLoadCallback, |
173 weak_ptr_factory_.GetWeakPtr())); | 180 weak_ptr_factory_.GetWeakPtr())); |
174 } | 181 } |
175 } | 182 } |
176 NotifyDelegateIfReadyForConfigure(); | 183 NotifyDelegateIfReadyForConfigure(); |
177 } | 184 } |
178 | 185 |
179 void ModelAssociationManager::StartAssociationAsync( | 186 void ModelAssociationManager::StartAssociationAsync( |
180 const ModelTypeSet& types_to_associate) { | 187 const syncer::ModelTypeSet& types_to_associate) { |
181 DCHECK_EQ(INITIALIZED, state_); | 188 DCHECK_EQ(INITIALIZED, state_); |
182 DVLOG(1) << "Starting association for " | 189 DVLOG(1) << "Starting association for " |
183 << ModelTypeSetToString(types_to_associate); | 190 << syncer::ModelTypeSetToString(types_to_associate); |
184 state_ = ASSOCIATING; | 191 state_ = ASSOCIATING; |
185 | 192 |
186 association_start_time_ = base::TimeTicks::Now(); | 193 association_start_time_ = base::TimeTicks::Now(); |
187 | 194 |
188 requested_types_ = types_to_associate; | 195 requested_types_ = types_to_associate; |
189 | 196 |
190 associating_types_ = types_to_associate; | 197 associating_types_ = types_to_associate; |
191 associating_types_.RetainAll(desired_types_); | 198 associating_types_.RetainAll(desired_types_); |
192 associating_types_.RemoveAll(associated_types_); | 199 associating_types_.RemoveAll(associated_types_); |
193 | 200 |
194 // Assume success. | 201 // Assume success. |
195 configure_status_ = DataTypeManager::OK; | 202 configure_status_ = DataTypeManager::OK; |
196 | 203 |
197 // Done if no types to associate. | 204 // Done if no types to associate. |
198 if (associating_types_.Empty()) { | 205 if (associating_types_.Empty()) { |
199 ModelAssociationDone(INITIALIZED); | 206 ModelAssociationDone(INITIALIZED); |
200 return; | 207 return; |
201 } | 208 } |
202 | 209 |
203 timer_.Start(FROM_HERE, | 210 timer_.Start(FROM_HERE, |
204 base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), | 211 base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), |
205 base::Bind(&ModelAssociationManager::ModelAssociationDone, | 212 base::Bind(&ModelAssociationManager::ModelAssociationDone, |
206 weak_ptr_factory_.GetWeakPtr(), INITIALIZED)); | 213 weak_ptr_factory_.GetWeakPtr(), INITIALIZED)); |
207 | 214 |
208 // Start association of types that are loaded in specified order. | 215 // Start association of types that are loaded in specified order. |
209 for (size_t i = 0; i < arraysize(kStartOrder); i++) { | 216 for (size_t i = 0; i < arraysize(kStartOrder); i++) { |
210 ModelType type = kStartOrder[i]; | 217 syncer::ModelType type = kStartOrder[i]; |
211 if (!associating_types_.Has(type) || !loaded_types_.Has(type)) | 218 if (!associating_types_.Has(type) || !loaded_types_.Has(type)) |
212 continue; | 219 continue; |
213 | 220 |
214 DataTypeController* dtc = controllers_->find(type)->second.get(); | 221 DataTypeController* dtc = controllers_->find(type)->second.get(); |
215 DCHECK(DataTypeController::MODEL_LOADED == dtc->state() || | 222 DCHECK(DataTypeController::MODEL_LOADED == dtc->state() || |
216 DataTypeController::ASSOCIATING == dtc->state()); | 223 DataTypeController::ASSOCIATING == dtc->state()); |
217 if (dtc->state() == DataTypeController::MODEL_LOADED) { | 224 if (dtc->state() == DataTypeController::MODEL_LOADED) { |
218 TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", dtc, "DataType", | 225 TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", dtc, "DataType", |
219 ModelTypeToString(type)); | 226 ModelTypeToString(type)); |
220 | 227 |
221 dtc->StartAssociating(base::Bind( | 228 dtc->StartAssociating(base::Bind( |
222 &ModelAssociationManager::TypeStartCallback, | 229 &ModelAssociationManager::TypeStartCallback, |
223 weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); | 230 weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); |
224 } | 231 } |
225 } | 232 } |
226 } | 233 } |
227 | 234 |
228 void ModelAssociationManager::Stop() { | 235 void ModelAssociationManager::Stop() { |
229 // Ignore callbacks from controllers. | 236 // Ignore callbacks from controllers. |
230 weak_ptr_factory_.InvalidateWeakPtrs(); | 237 weak_ptr_factory_.InvalidateWeakPtrs(); |
231 | 238 |
232 // Stop started data types. | 239 // Stop started data types. |
233 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 240 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
234 it != controllers_->end(); ++it) { | 241 it != controllers_->end(); ++it) { |
235 DataTypeController* dtc = (*it).second.get(); | 242 DataTypeController* dtc = (*it).second.get(); |
236 if (dtc->state() != DataTypeController::NOT_RUNNING) { | 243 if (dtc->state() != DataTypeController::NOT_RUNNING) { |
237 StopDatatype(SyncError(), dtc); | 244 StopDatatype(syncer::SyncError(), dtc); |
238 DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name(); | 245 DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name(); |
239 } | 246 } |
240 } | 247 } |
241 | 248 |
242 desired_types_.Clear(); | 249 desired_types_.Clear(); |
243 loaded_types_.Clear(); | 250 loaded_types_.Clear(); |
244 associated_types_.Clear(); | 251 associated_types_.Clear(); |
245 | 252 |
246 if (state_ == ASSOCIATING) { | 253 if (state_ == ASSOCIATING) { |
247 if (configure_status_ == DataTypeManager::OK) | 254 if (configure_status_ == DataTypeManager::OK) |
248 configure_status_ = DataTypeManager::ABORTED; | 255 configure_status_ = DataTypeManager::ABORTED; |
249 DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone"; | 256 DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone"; |
250 ModelAssociationDone(IDLE); | 257 ModelAssociationDone(IDLE); |
251 } else { | 258 } else { |
252 DCHECK(associating_types_.Empty()); | 259 DCHECK(associating_types_.Empty()); |
253 DCHECK(requested_types_.Empty()); | 260 DCHECK(requested_types_.Empty()); |
254 state_ = IDLE; | 261 state_ = IDLE; |
255 } | 262 } |
256 } | 263 } |
257 | 264 |
258 void ModelAssociationManager::ModelLoadCallback(ModelType type, | 265 void ModelAssociationManager::ModelLoadCallback( |
259 const SyncError& error) { | 266 syncer::ModelType type, |
| 267 const syncer::SyncError& error) { |
260 DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " | 268 DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " |
261 << ModelTypeToString(type); | 269 << syncer::ModelTypeToString(type); |
262 | 270 |
263 if (error.IsSet()) { | 271 if (error.IsSet()) { |
264 SyncMergeResult local_merge_result(type); | 272 syncer::SyncMergeResult local_merge_result(type); |
265 local_merge_result.set_error(error); | 273 local_merge_result.set_error(error); |
266 TypeStartCallback(type, base::TimeTicks::Now(), | 274 TypeStartCallback(type, base::TimeTicks::Now(), |
267 DataTypeController::ASSOCIATION_FAILED, | 275 DataTypeController::ASSOCIATION_FAILED, |
268 local_merge_result, SyncMergeResult(type)); | 276 local_merge_result, syncer::SyncMergeResult(type)); |
269 return; | 277 return; |
270 } | 278 } |
271 | 279 |
272 // This happens when slow loading type is disabled by new configuration. | 280 // This happens when slow loading type is disabled by new configuration. |
273 if (!desired_types_.Has(type)) | 281 if (!desired_types_.Has(type)) |
274 return; | 282 return; |
275 | 283 |
276 DCHECK(!loaded_types_.Has(type)); | 284 DCHECK(!loaded_types_.Has(type)); |
277 loaded_types_.Put(type); | 285 loaded_types_.Put(type); |
278 NotifyDelegateIfReadyForConfigure(); | 286 NotifyDelegateIfReadyForConfigure(); |
279 if (associating_types_.Has(type)) { | 287 if (associating_types_.Has(type)) { |
280 DataTypeController* dtc = controllers_->find(type)->second.get(); | 288 DataTypeController* dtc = controllers_->find(type)->second.get(); |
281 // If initial sync was done for this datatype then | 289 // If initial sync was done for this datatype then |
282 // NotifyDelegateIfReadyForConfigure possibly already triggered model | 290 // NotifyDelegateIfReadyForConfigure possibly already triggered model |
283 // association and StartAssociating was already called for this type. To | 291 // association and StartAssociating was already called for this type. To |
284 // ensure StartAssociating is called only once only make a call if state is | 292 // ensure StartAssociating is called only once only make a call if state is |
285 // MODEL_LOADED. | 293 // MODEL_LOADED. |
286 // TODO(pavely): Add test for this scenario in DataTypeManagerImpl | 294 // TODO(pavely): Add test for this scenario in DataTypeManagerImpl |
287 // unittests. | 295 // unittests. |
288 if (dtc->state() == DataTypeController::MODEL_LOADED) { | 296 if (dtc->state() == DataTypeController::MODEL_LOADED) { |
289 dtc->StartAssociating(base::Bind( | 297 dtc->StartAssociating(base::Bind( |
290 &ModelAssociationManager::TypeStartCallback, | 298 &ModelAssociationManager::TypeStartCallback, |
291 weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); | 299 weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); |
292 } | 300 } |
293 } | 301 } |
294 } | 302 } |
295 | 303 |
296 void ModelAssociationManager::TypeStartCallback( | 304 void ModelAssociationManager::TypeStartCallback( |
297 ModelType type, | 305 syncer::ModelType type, |
298 base::TimeTicks type_start_time, | 306 base::TimeTicks type_start_time, |
299 DataTypeController::ConfigureResult start_result, | 307 DataTypeController::ConfigureResult start_result, |
300 const SyncMergeResult& local_merge_result, | 308 const syncer::SyncMergeResult& local_merge_result, |
301 const SyncMergeResult& syncer_merge_result) { | 309 const syncer::SyncMergeResult& syncer_merge_result) { |
302 if (desired_types_.Has(type) && | 310 if (desired_types_.Has(type) && |
303 !DataTypeController::IsSuccessfulResult(start_result)) { | 311 !DataTypeController::IsSuccessfulResult(start_result)) { |
304 DVLOG(1) << "ModelAssociationManager: Type encountered an error."; | 312 DVLOG(1) << "ModelAssociationManager: Type encountered an error."; |
305 desired_types_.Remove(type); | 313 desired_types_.Remove(type); |
306 DataTypeController* dtc = controllers_->find(type)->second.get(); | 314 DataTypeController* dtc = controllers_->find(type)->second.get(); |
307 StopDatatype(local_merge_result.error(), dtc); | 315 StopDatatype(local_merge_result.error(), dtc); |
308 NotifyDelegateIfReadyForConfigure(); | 316 NotifyDelegateIfReadyForConfigure(); |
309 | 317 |
310 // Update configuration result. | 318 // Update configuration result. |
311 if (start_result == DataTypeController::UNRECOVERABLE_ERROR) | 319 if (start_result == DataTypeController::UNRECOVERABLE_ERROR) |
(...skipping 16 matching lines...) Expand all Loading... |
328 | 336 |
329 if (state_ != ASSOCIATING) | 337 if (state_ != ASSOCIATING) |
330 return; | 338 return; |
331 | 339 |
332 TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", | 340 TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", |
333 controllers_->find(type)->second.get(), "DataType", | 341 controllers_->find(type)->second.get(), "DataType", |
334 ModelTypeToString(type)); | 342 ModelTypeToString(type)); |
335 | 343 |
336 // Track the merge results if we succeeded or an association failure | 344 // Track the merge results if we succeeded or an association failure |
337 // occurred. | 345 // occurred. |
338 if (ProtocolTypes().Has(type)) { | 346 if (syncer::ProtocolTypes().Has(type)) { |
339 base::TimeDelta association_wait_time = | 347 base::TimeDelta association_wait_time = |
340 std::max(base::TimeDelta(), type_start_time - association_start_time_); | 348 std::max(base::TimeDelta(), type_start_time - association_start_time_); |
341 base::TimeDelta association_time = base::TimeTicks::Now() - type_start_time; | 349 base::TimeDelta association_time = base::TimeTicks::Now() - type_start_time; |
342 DataTypeAssociationStats stats = BuildAssociationStatsFromMergeResults( | 350 syncer::DataTypeAssociationStats stats = |
343 local_merge_result, syncer_merge_result, association_wait_time, | 351 BuildAssociationStatsFromMergeResults( |
344 association_time); | 352 local_merge_result, syncer_merge_result, association_wait_time, |
| 353 association_time); |
345 delegate_->OnSingleDataTypeAssociationDone(type, stats); | 354 delegate_->OnSingleDataTypeAssociationDone(type, stats); |
346 } | 355 } |
347 | 356 |
348 associating_types_.Remove(type); | 357 associating_types_.Remove(type); |
349 | 358 |
350 if (associating_types_.Empty()) | 359 if (associating_types_.Empty()) |
351 ModelAssociationDone(INITIALIZED); | 360 ModelAssociationDone(INITIALIZED); |
352 } | 361 } |
353 | 362 |
354 void ModelAssociationManager::ModelAssociationDone(State new_state) { | 363 void ModelAssociationManager::ModelAssociationDone(State new_state) { |
355 DCHECK_NE(IDLE, state_); | 364 DCHECK_NE(IDLE, state_); |
356 | 365 |
357 if (state_ == INITIALIZED) { | 366 if (state_ == INITIALIZED) { |
358 // No associations are currently happening. Just reset the state. | 367 // No associations are currently happening. Just reset the state. |
359 state_ = new_state; | 368 state_ = new_state; |
360 return; | 369 return; |
361 } | 370 } |
362 | 371 |
363 DVLOG(1) << "Model association complete for " | 372 DVLOG(1) << "Model association complete for " |
364 << ModelTypeSetToString(requested_types_); | 373 << syncer::ModelTypeSetToString(requested_types_); |
365 | 374 |
366 timer_.Stop(); | 375 timer_.Stop(); |
367 | 376 |
368 // Treat any unfinished types as having errors. | 377 // Treat any unfinished types as having errors. |
369 desired_types_.RemoveAll(associating_types_); | 378 desired_types_.RemoveAll(associating_types_); |
370 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 379 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
371 it != controllers_->end(); ++it) { | 380 it != controllers_->end(); ++it) { |
372 DataTypeController* dtc = (*it).second.get(); | 381 DataTypeController* dtc = (*it).second.get(); |
373 if (associating_types_.Has(dtc->type()) && | 382 if (associating_types_.Has(dtc->type()) && |
374 dtc->state() != DataTypeController::NOT_RUNNING) { | 383 dtc->state() != DataTypeController::NOT_RUNNING) { |
375 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", | 384 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", |
376 ModelTypeToHistogramInt(dtc->type()), | 385 ModelTypeToHistogramInt(dtc->type()), |
377 MODEL_TYPE_COUNT); | 386 syncer::MODEL_TYPE_COUNT); |
378 StopDatatype(SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, | 387 StopDatatype( |
379 "Association timed out.", dtc->type()), | 388 syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
380 dtc); | 389 "Association timed out.", dtc->type()), |
| 390 dtc); |
381 } | 391 } |
382 } | 392 } |
383 | 393 |
384 DataTypeManager::ConfigureResult result(configure_status_, requested_types_); | 394 DataTypeManager::ConfigureResult result(configure_status_, requested_types_); |
385 | 395 |
386 // Need to reset state before invoking delegate in order to avoid re-entrancy | 396 // Need to reset state before invoking delegate in order to avoid re-entrancy |
387 // issues (delegate may trigger a reconfiguration). | 397 // issues (delegate may trigger a reconfiguration). |
388 associating_types_.Clear(); | 398 associating_types_.Clear(); |
389 requested_types_.Clear(); | 399 requested_types_.Clear(); |
390 state_ = new_state; | 400 state_ = new_state; |
391 | 401 |
392 delegate_->OnModelAssociationDone(result); | 402 delegate_->OnModelAssociationDone(result); |
393 } | 403 } |
394 | 404 |
395 base::OneShotTimer* ModelAssociationManager::GetTimerForTesting() { | 405 base::OneShotTimer* ModelAssociationManager::GetTimerForTesting() { |
396 return &timer_; | 406 return &timer_; |
397 } | 407 } |
398 | 408 |
399 void ModelAssociationManager::NotifyDelegateIfReadyForConfigure() { | 409 void ModelAssociationManager::NotifyDelegateIfReadyForConfigure() { |
400 if (notified_about_ready_for_configure_) | 410 if (notified_about_ready_for_configure_) |
401 return; | 411 return; |
402 for (const auto& type_dtc_pair : *controllers_) { | 412 for (const auto& type_dtc_pair : *controllers_) { |
403 ModelType type = type_dtc_pair.first; | 413 syncer::ModelType type = type_dtc_pair.first; |
404 if (!desired_types_.Has(type)) | 414 if (!desired_types_.Has(type)) |
405 continue; | 415 continue; |
406 DataTypeController* dtc = type_dtc_pair.second.get(); | 416 DataTypeController* dtc = type_dtc_pair.second.get(); |
407 if (dtc->ShouldLoadModelBeforeConfigure() && !loaded_types_.Has(type)) { | 417 if (dtc->ShouldLoadModelBeforeConfigure() && !loaded_types_.Has(type)) { |
408 // At least one type is not ready. | 418 // At least one type is not ready. |
409 return; | 419 return; |
410 } | 420 } |
411 } | 421 } |
412 | 422 |
413 notified_about_ready_for_configure_ = true; | 423 notified_about_ready_for_configure_ = true; |
414 delegate_->OnAllDataTypesReadyForConfigure(); | 424 delegate_->OnAllDataTypesReadyForConfigure(); |
415 } | 425 } |
416 | 426 |
417 } // namespace syncer | 427 } // namespace sync_driver |
OLD | NEW |