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 <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 syncer::SUPERVISED_USER_SETTINGS, | 57 syncer::SUPERVISED_USER_SETTINGS, |
58 syncer::SUPERVISED_USER_SHARED_SETTINGS, | 58 syncer::SUPERVISED_USER_SHARED_SETTINGS, |
59 syncer::ARTICLES, | 59 syncer::ARTICLES, |
60 }; | 60 }; |
61 | 61 |
62 COMPILE_ASSERT(arraysize(kStartOrder) == | 62 COMPILE_ASSERT(arraysize(kStartOrder) == |
63 syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, | 63 syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, |
64 kStartOrder_IncorrectSize); | 64 kStartOrder_IncorrectSize); |
65 | 65 |
66 // The amount of time we wait for association to finish. If some types haven't | 66 // The amount of time we wait for association to finish. If some types haven't |
67 // finished association by the time, DataTypeManager is notified of the | 67 // finished association by the time, configuration result will be |
68 // unfinished types. | 68 // PARTIAL_SUCCESS and DataTypeManager is notified of the unfinished types. |
69 const int64 kAssociationTimeOutInSeconds = 600; | 69 const int64 kAssociationTimeOutInSeconds = 600; |
70 | 70 |
71 syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( | 71 syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( |
72 const syncer::SyncMergeResult& local_merge_result, | 72 const syncer::SyncMergeResult& local_merge_result, |
73 const syncer::SyncMergeResult& syncer_merge_result, | 73 const syncer::SyncMergeResult& syncer_merge_result, |
74 const base::TimeDelta& association_wait_time, | 74 const base::TimeDelta& association_wait_time, |
75 const base::TimeDelta& association_time) { | 75 const base::TimeDelta& association_time) { |
76 DCHECK_EQ(local_merge_result.model_type(), syncer_merge_result.model_type()); | 76 DCHECK_EQ(local_merge_result.model_type(), syncer_merge_result.model_type()); |
77 syncer::DataTypeAssociationStats stats; | 77 syncer::DataTypeAssociationStats stats; |
78 stats.had_error = local_merge_result.error().IsSet() || | 78 stats.had_error = local_merge_result.error().IsSet() || |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 } | 127 } |
128 | 128 |
129 void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { | 129 void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { |
130 // state_ can be INITIALIZED_TO_CONFIGURE if types are reconfigured when | 130 // state_ can be INITIALIZED_TO_CONFIGURE if types are reconfigured when |
131 // data is being downloaded, so StartAssociationAsync() is never called for | 131 // data is being downloaded, so StartAssociationAsync() is never called for |
132 // the first configuration. | 132 // the first configuration. |
133 DCHECK_NE(CONFIGURING, state_); | 133 DCHECK_NE(CONFIGURING, state_); |
134 | 134 |
135 // Only keep types that have controllers. | 135 // Only keep types that have controllers. |
136 desired_types_.Clear(); | 136 desired_types_.Clear(); |
| 137 slow_types_.Clear(); |
137 for (syncer::ModelTypeSet::Iterator it = desired_types.First(); | 138 for (syncer::ModelTypeSet::Iterator it = desired_types.First(); |
138 it.Good(); it.Inc()) { | 139 it.Good(); it.Inc()) { |
139 if (controllers_->find(it.Get()) != controllers_->end()) | 140 if (controllers_->find(it.Get()) != controllers_->end()) |
140 desired_types_.Put(it.Get()); | 141 desired_types_.Put(it.Get()); |
141 } | 142 } |
142 | 143 |
143 DVLOG(1) << "ModelAssociationManager: Initializing for " | 144 DVLOG(1) << "ModelAssociationManager: Initializing for " |
144 << syncer::ModelTypeSetToString(desired_types_); | 145 << syncer::ModelTypeSetToString(desired_types_); |
145 | 146 |
146 state_ = INITIALIZED_TO_CONFIGURE; | 147 state_ = INITIALIZED_TO_CONFIGURE; |
147 | 148 |
148 StopDisabledTypes(); | 149 StopDisabledTypes(); |
149 LoadEnabledTypes(); | 150 LoadEnabledTypes(); |
150 } | 151 } |
151 | 152 |
152 void ModelAssociationManager::StopDatatype( | 153 void ModelAssociationManager::StopDatatype(DataTypeController* dtc) { |
153 const syncer::SyncError& error, | 154 // First tell the sync backend that we no longer want to listen to |
154 DataTypeController* dtc) { | 155 // changes for this type. |
155 loaded_types_.Remove(dtc->type()); | 156 delegate_->OnSingleDataTypeWillStop(dtc->type()); |
156 associated_types_.Remove(dtc->type()); | |
157 associating_types_.Remove(dtc->type()); | |
158 | 157 |
159 if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { | 158 // Then tell all data type specific logic to shut down. |
160 // If an error was set, the delegate must be informed of the error. | 159 dtc->Stop(); |
161 delegate_->OnSingleDataTypeWillStop(dtc->type(), error); | |
162 dtc->Stop(); | |
163 } | |
164 } | 160 } |
165 | 161 |
166 void ModelAssociationManager::StopDisabledTypes() { | 162 void ModelAssociationManager::StopDisabledTypes() { |
167 DVLOG(1) << "ModelAssociationManager: Stopping disabled types."; | 163 DVLOG(1) << "ModelAssociationManager: Stopping disabled types."; |
168 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 164 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
169 it != controllers_->end(); ++it) { | 165 it != controllers_->end(); ++it) { |
170 DataTypeController* dtc = (*it).second.get(); | 166 DataTypeController* dtc = (*it).second.get(); |
171 if (dtc->state() != DataTypeController::NOT_RUNNING && | 167 if (dtc->state() != DataTypeController::NOT_RUNNING && |
172 !desired_types_.Has(dtc->type())) { | 168 (!desired_types_.Has(dtc->type()) || |
| 169 failed_data_types_info_.count(dtc->type()) > 0)) { |
173 DVLOG(1) << "ModelTypeToString: stop " << dtc->name(); | 170 DVLOG(1) << "ModelTypeToString: stop " << dtc->name(); |
174 StopDatatype(syncer::SyncError(), dtc); | 171 StopDatatype(dtc); |
| 172 loaded_types_.Remove(dtc->type()); |
| 173 associated_types_.Remove(dtc->type()); |
175 } | 174 } |
176 } | 175 } |
177 } | 176 } |
178 | 177 |
179 void ModelAssociationManager::LoadEnabledTypes() { | 178 void ModelAssociationManager::LoadEnabledTypes() { |
180 // Load in kStartOrder. | 179 // Load in kStartOrder. |
181 for (size_t i = 0; i < arraysize(kStartOrder); i++) { | 180 for (size_t i = 0; i < arraysize(kStartOrder); i++) { |
182 syncer::ModelType type = kStartOrder[i]; | 181 syncer::ModelType type = kStartOrder[i]; |
183 if (!desired_types_.Has(type)) | 182 if (!desired_types_.Has(type)) |
184 continue; | 183 continue; |
(...skipping 18 matching lines...) Expand all Loading... |
203 | 202 |
204 requested_types_ = types_to_associate; | 203 requested_types_ = types_to_associate; |
205 | 204 |
206 associating_types_ = types_to_associate; | 205 associating_types_ = types_to_associate; |
207 associating_types_.RetainAll(desired_types_); | 206 associating_types_.RetainAll(desired_types_); |
208 associating_types_.RemoveAll(associated_types_); | 207 associating_types_.RemoveAll(associated_types_); |
209 | 208 |
210 // Assume success. | 209 // Assume success. |
211 configure_status_ = DataTypeManager::OK; | 210 configure_status_ = DataTypeManager::OK; |
212 | 211 |
| 212 // Remove types that already failed. |
| 213 for (std::map<syncer::ModelType, syncer::SyncError>::const_iterator it = |
| 214 failed_data_types_info_.begin(); |
| 215 it != failed_data_types_info_.end(); ++it) { |
| 216 associating_types_.Remove(it->first); |
| 217 } |
| 218 |
213 // Done if no types to associate. | 219 // Done if no types to associate. |
214 if (associating_types_.Empty()) { | 220 if (associating_types_.Empty()) { |
215 ModelAssociationDone(); | 221 ModelAssociationDone(); |
216 return; | 222 return; |
217 } | 223 } |
218 | 224 |
219 timer_.Start(FROM_HERE, | 225 timer_.Start(FROM_HERE, |
220 base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), | 226 base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), |
221 this, | 227 this, |
222 &ModelAssociationManager::ModelAssociationDone); | 228 &ModelAssociationManager::ModelAssociationDone); |
(...skipping 19 matching lines...) Expand all Loading... |
242 type, base::TimeTicks::Now())); | 248 type, base::TimeTicks::Now())); |
243 } | 249 } |
244 } | 250 } |
245 } | 251 } |
246 | 252 |
247 void ModelAssociationManager::ResetForNextAssociation() { | 253 void ModelAssociationManager::ResetForNextAssociation() { |
248 DVLOG(1) << "ModelAssociationManager: Reseting for next configuration"; | 254 DVLOG(1) << "ModelAssociationManager: Reseting for next configuration"; |
249 // |loaded_types_| and |associated_types_| are not cleared. So | 255 // |loaded_types_| and |associated_types_| are not cleared. So |
250 // reconfiguration won't restart types that are already started. | 256 // reconfiguration won't restart types that are already started. |
251 requested_types_.Clear(); | 257 requested_types_.Clear(); |
| 258 failed_data_types_info_.clear(); |
252 associating_types_.Clear(); | 259 associating_types_.Clear(); |
| 260 needs_crypto_types_.Clear(); |
253 } | 261 } |
254 | 262 |
255 void ModelAssociationManager::Stop() { | 263 void ModelAssociationManager::Stop() { |
256 // Ignore callbacks from controllers. | 264 // Ignore callbacks from controllers. |
257 weak_ptr_factory_.InvalidateWeakPtrs(); | 265 weak_ptr_factory_.InvalidateWeakPtrs(); |
258 | 266 |
259 desired_types_.Clear(); | |
260 loaded_types_.Clear(); | |
261 associated_types_.Clear(); | |
262 associating_types_.Clear(); | |
263 | |
264 // Stop started data types. | 267 // Stop started data types. |
265 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 268 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
266 it != controllers_->end(); ++it) { | 269 it != controllers_->end(); ++it) { |
267 DataTypeController* dtc = (*it).second.get(); | 270 DataTypeController* dtc = (*it).second.get(); |
268 if (dtc->state() != DataTypeController::NOT_RUNNING) { | 271 if (dtc->state() != DataTypeController::NOT_RUNNING) { |
269 StopDatatype(syncer::SyncError(), dtc); | 272 StopDatatype(dtc); |
270 DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name(); | 273 DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name(); |
271 } | 274 } |
272 } | 275 } |
273 | 276 |
| 277 desired_types_.Clear(); |
| 278 loaded_types_.Clear(); |
| 279 associated_types_.Clear(); |
| 280 slow_types_.Clear(); |
| 281 |
274 if (state_ == CONFIGURING) { | 282 if (state_ == CONFIGURING) { |
275 if (configure_status_ == DataTypeManager::OK) | 283 if (configure_status_ == DataTypeManager::OK) |
276 configure_status_ = DataTypeManager::ABORTED; | 284 configure_status_ = DataTypeManager::ABORTED; |
277 DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone"; | 285 DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone"; |
278 ModelAssociationDone(); | 286 ModelAssociationDone(); |
279 } | 287 } |
280 | 288 |
281 ResetForNextAssociation(); | 289 ResetForNextAssociation(); |
282 | 290 |
283 state_ = IDLE; | 291 state_ = IDLE; |
284 } | 292 } |
285 | 293 |
| 294 void ModelAssociationManager::AppendToFailedDatatypesAndLogError( |
| 295 const syncer::SyncError& error) { |
| 296 failed_data_types_info_[error.model_type()] = error; |
| 297 LOG(ERROR) << "Failed to associate models for " |
| 298 << syncer::ModelTypeToString(error.model_type()); |
| 299 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", |
| 300 ModelTypeToHistogramInt(error.model_type()), |
| 301 syncer::MODEL_TYPE_COUNT); |
| 302 } |
| 303 |
286 void ModelAssociationManager::ModelLoadCallback(syncer::ModelType type, | 304 void ModelAssociationManager::ModelLoadCallback(syncer::ModelType type, |
287 syncer::SyncError error) { | 305 syncer::SyncError error) { |
288 DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " | 306 DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " |
289 << syncer::ModelTypeToString(type); | 307 << syncer::ModelTypeToString(type); |
290 | 308 |
| 309 // TODO(haitaol): temporary fix for 335606. |
| 310 if (slow_types_.Has(type)) |
| 311 return; |
| 312 |
291 // This happens when slow loading type is disabled by new configuration. | 313 // This happens when slow loading type is disabled by new configuration. |
292 if (!desired_types_.Has(type)) | 314 if (!desired_types_.Has(type)) |
293 return; | 315 return; |
294 | 316 |
295 DCHECK(!loaded_types_.Has(type)); | 317 DCHECK(!loaded_types_.Has(type)); |
296 if (error.IsSet()) { | 318 if (error.IsSet()) { |
297 syncer::SyncMergeResult local_merge_result(type); | 319 syncer::SyncMergeResult local_merge_result(type); |
298 local_merge_result.set_error(error); | 320 local_merge_result.set_error(error); |
299 TypeStartCallback(type, | 321 TypeStartCallback(type, |
300 base::TimeTicks::Now(), | 322 base::TimeTicks::Now(), |
301 DataTypeController::ASSOCIATION_FAILED, | 323 DataTypeController::ASSOCIATION_FAILED, |
302 local_merge_result, | 324 local_merge_result, |
303 syncer::SyncMergeResult(type)); | 325 syncer::SyncMergeResult(type)); |
304 return; | 326 return; |
305 } | 327 } |
306 | 328 |
307 loaded_types_.Put(type); | 329 loaded_types_.Put(type); |
308 if (associating_types_.Has(type)) { | 330 if (associating_types_.Has(type) || slow_types_.Has(type)) { |
309 DataTypeController* dtc = controllers_->find(type)->second.get(); | 331 DataTypeController* dtc = controllers_->find(type)->second.get(); |
310 dtc->StartAssociating( | 332 dtc->StartAssociating( |
311 base::Bind(&ModelAssociationManager::TypeStartCallback, | 333 base::Bind(&ModelAssociationManager::TypeStartCallback, |
312 weak_ptr_factory_.GetWeakPtr(), | 334 weak_ptr_factory_.GetWeakPtr(), |
313 type, base::TimeTicks::Now())); | 335 type, base::TimeTicks::Now())); |
314 } | 336 } |
315 } | 337 } |
316 | 338 |
317 void ModelAssociationManager::TypeStartCallback( | 339 void ModelAssociationManager::TypeStartCallback( |
318 syncer::ModelType type, | 340 syncer::ModelType type, |
319 base::TimeTicks type_start_time, | 341 base::TimeTicks type_start_time, |
320 DataTypeController::ConfigureResult start_result, | 342 DataTypeController::StartResult start_result, |
321 const syncer::SyncMergeResult& local_merge_result, | 343 const syncer::SyncMergeResult& local_merge_result, |
322 const syncer::SyncMergeResult& syncer_merge_result) { | 344 const syncer::SyncMergeResult& syncer_merge_result) { |
323 if (desired_types_.Has(type) && | 345 // TODO(haitaol): temporary fix for 335606. |
324 !DataTypeController::IsSuccessfulResult(start_result)) { | 346 if (slow_types_.Has(type)) |
325 DVLOG(1) << "ModelAssociationManager: Type encountered an error."; | 347 return; |
326 desired_types_.Remove(type); | |
327 DataTypeController* dtc = controllers_->find(type)->second.get(); | |
328 StopDatatype(local_merge_result.error(), dtc); | |
329 | 348 |
330 // Update configuration result. | 349 // This happens when slow associating type is disabled by new configuration. |
331 if (start_result == DataTypeController::UNRECOVERABLE_ERROR) | 350 if (!desired_types_.Has(type)) |
332 configure_status_ = DataTypeManager::UNRECOVERABLE_ERROR; | 351 return; |
333 } | |
334 | 352 |
335 // This happens when a slow associating type is disabled or if a type | 353 slow_types_.Remove(type); |
336 // disables itself after initial configuration. | |
337 if (!desired_types_.Has(type)) { | |
338 // It's possible all types failed to associate, in which case association | |
339 // is complete. | |
340 if (state_ == CONFIGURING && associating_types_.Empty()) | |
341 ModelAssociationDone(); | |
342 return; | |
343 } | |
344 | 354 |
345 DCHECK(!associated_types_.Has(type)); | 355 DCHECK(!associated_types_.Has(type)); |
346 DCHECK(DataTypeController::IsSuccessfulResult(start_result)); | 356 if (DataTypeController::IsSuccessfulResult(start_result)) { |
347 associated_types_.Put(type); | 357 associated_types_.Put(type); |
| 358 } else if (state_ == IDLE) { |
| 359 // For type that failed in IDLE mode, simply stop the controller. Next |
| 360 // configuration will try to restart from scratch if the type is still |
| 361 // enabled. |
| 362 DataTypeController* dtc = controllers_->find(type)->second.get(); |
| 363 if (dtc->state() != DataTypeController::NOT_RUNNING) |
| 364 StopDatatype(dtc); |
| 365 loaded_types_.Remove(type); |
| 366 } else { |
| 367 // Record error in CONFIGURING or INITIALIZED_TO_CONFIGURE mode. The error |
| 368 // will be reported when data types association finishes. |
| 369 if (start_result == DataTypeController::NEEDS_CRYPTO) { |
| 370 DVLOG(1) << "ModelAssociationManager: Encountered an undecryptable type"; |
| 371 needs_crypto_types_.Put(type); |
| 372 } else { |
| 373 DVLOG(1) << "ModelAssociationManager: Encountered a failed type"; |
| 374 AppendToFailedDatatypesAndLogError(local_merge_result.error()); |
| 375 } |
| 376 } |
348 | 377 |
349 if (state_ != CONFIGURING) | 378 if (state_ != CONFIGURING) |
350 return; | 379 return; |
351 | 380 |
352 TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", | 381 TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", |
353 controllers_->find(type)->second.get(), | 382 controllers_->find(type)->second.get(), |
354 "DataType", | 383 "DataType", |
355 ModelTypeToString(type)); | 384 ModelTypeToString(type)); |
356 | 385 |
357 // Track the merge results if we succeeded or an association failure | 386 // Track the merge results if we succeeded or an association failure |
358 // occurred. | 387 // occurred. |
359 if (syncer::ProtocolTypes().Has(type)) { | 388 if ((DataTypeController::IsSuccessfulResult(start_result) || |
| 389 start_result == DataTypeController::ASSOCIATION_FAILED) && |
| 390 syncer::ProtocolTypes().Has(type)) { |
360 base::TimeDelta association_wait_time = | 391 base::TimeDelta association_wait_time = |
361 std::max(base::TimeDelta(), type_start_time - association_start_time_); | 392 std::max(base::TimeDelta(), type_start_time - association_start_time_); |
362 base::TimeDelta association_time = | 393 base::TimeDelta association_time = |
363 base::TimeTicks::Now() - type_start_time;; | 394 base::TimeTicks::Now() - type_start_time;; |
364 syncer::DataTypeAssociationStats stats = | 395 syncer::DataTypeAssociationStats stats = |
365 BuildAssociationStatsFromMergeResults(local_merge_result, | 396 BuildAssociationStatsFromMergeResults(local_merge_result, |
366 syncer_merge_result, | 397 syncer_merge_result, |
367 association_wait_time, | 398 association_wait_time, |
368 association_time); | 399 association_time); |
369 delegate_->OnSingleDataTypeAssociationDone(type, stats); | 400 delegate_->OnSingleDataTypeAssociationDone(type, stats); |
370 } | 401 } |
371 | 402 |
| 403 // Update configuration result. |
| 404 if (configure_status_ == DataTypeManager::OK && |
| 405 start_result == DataTypeController::ASSOCIATION_FAILED) { |
| 406 configure_status_ = DataTypeManager::PARTIAL_SUCCESS; |
| 407 } |
| 408 if (start_result == DataTypeController::UNRECOVERABLE_ERROR) |
| 409 configure_status_ = DataTypeManager::UNRECOVERABLE_ERROR; |
| 410 |
372 associating_types_.Remove(type); | 411 associating_types_.Remove(type); |
373 | 412 |
374 if (associating_types_.Empty()) | 413 if (associating_types_.Empty()) |
375 ModelAssociationDone(); | 414 ModelAssociationDone(); |
376 } | 415 } |
377 | 416 |
378 void ModelAssociationManager::ModelAssociationDone() { | 417 void ModelAssociationManager::ModelAssociationDone() { |
379 CHECK_EQ(CONFIGURING, state_); | 418 CHECK_EQ(CONFIGURING, state_); |
380 | 419 |
381 timer_.Stop(); | 420 timer_.Stop(); |
382 | 421 |
383 // Treat any unfinished types as having errors. | 422 slow_types_.PutAll(associating_types_); |
384 desired_types_.RemoveAll(associating_types_); | 423 |
385 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 424 // TODO(haitaol): temporary fix for 335606. |
386 it != controllers_->end(); ++it) { | 425 for (syncer::ModelTypeSet::Iterator it = associating_types_.First(); |
387 DataTypeController* dtc = (*it).second.get(); | 426 it.Good(); it.Inc()) { |
388 if (associating_types_.Has(dtc->type()) && | 427 AppendToFailedDatatypesAndLogError( |
389 dtc->state() != DataTypeController::NOT_RUNNING) { | 428 syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
390 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", | 429 "Association timed out.", it.Get())); |
391 ModelTypeToHistogramInt(dtc->type()), | 430 } |
392 syncer::MODEL_TYPE_COUNT); | 431 |
393 StopDatatype(syncer::SyncError(FROM_HERE, | 432 // Stop controllers of failed types. |
394 syncer::SyncError::DATATYPE_ERROR, | 433 StopDisabledTypes(); |
395 "Association timed out.", | 434 |
396 dtc->type()), | 435 if (configure_status_ == DataTypeManager::OK && |
397 dtc); | 436 (!associating_types_.Empty() || !failed_data_types_info_.empty() || |
398 } | 437 !needs_crypto_types_.Empty())) { |
| 438 // We have not configured all types that we have been asked to configure. |
| 439 // Either we have failed types or types that have not completed loading |
| 440 // yet. |
| 441 DVLOG(1) << "ModelAssociationManager: setting partial success"; |
| 442 configure_status_ = DataTypeManager::PARTIAL_SUCCESS; |
399 } | 443 } |
400 | 444 |
401 DataTypeManager::ConfigureResult result(configure_status_, | 445 DataTypeManager::ConfigureResult result(configure_status_, |
402 requested_types_); | 446 requested_types_, |
| 447 failed_data_types_info_, |
| 448 associating_types_, |
| 449 needs_crypto_types_); |
403 | 450 |
404 // Reset state before notifying |delegate_| because that might | 451 // Reset state before notifying |delegate_| because that might |
405 // trigger a new round of configuration. | 452 // trigger a new round of configuration. |
406 ResetForNextAssociation(); | 453 ResetForNextAssociation(); |
407 state_ = IDLE; | 454 state_ = IDLE; |
408 | 455 |
409 delegate_->OnModelAssociationDone(result); | 456 delegate_->OnModelAssociationDone(result); |
410 } | 457 } |
411 | 458 |
412 base::OneShotTimer<ModelAssociationManager>* | 459 base::OneShotTimer<ModelAssociationManager>* |
413 ModelAssociationManager::GetTimerForTesting() { | 460 ModelAssociationManager::GetTimerForTesting() { |
414 return &timer_; | 461 return &timer_; |
415 } | 462 } |
416 | 463 |
417 } // namespace sync_driver | 464 } // namespace sync_driver |
OLD | NEW |