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