| 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/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
| 18 #include "components/sync/api/sync_merge_result.h" | 18 #include "components/sync/api/sync_merge_result.h" |
| 19 #include "components/sync/base/model_type.h" | 19 #include "components/sync/base/model_type.h" |
| 20 | 20 |
| 21 using syncer::ModelTypeSet; | 21 using syncer::ModelTypeSet; |
| 22 | 22 |
| 23 namespace sync_driver { | 23 namespace sync_driver { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 static const syncer::ModelType kStartOrder[] = { | 27 static const syncer::ModelType kStartOrder[] = { |
| 28 syncer::NIGORI, // Listed for completeness. | 28 syncer::NIGORI, // Listed for completeness. |
| 29 syncer::DEVICE_INFO, // Listed for completeness. | 29 syncer::DEVICE_INFO, // Listed for completeness. |
| 30 syncer::EXPERIMENTS, // Listed for completeness. | 30 syncer::EXPERIMENTS, // Listed for completeness. |
| 31 syncer::PROXY_TABS, // Listed for completeness. | 31 syncer::PROXY_TABS, // Listed for completeness. |
| 32 | 32 |
| 33 // Kick off the association of the non-UI types first so they can associate | 33 // Kick off the association of the non-UI types first so they can associate |
| 34 // in parallel with the UI types. | 34 // in parallel with the UI types. |
| 35 syncer::PASSWORDS, | 35 syncer::PASSWORDS, syncer::AUTOFILL, syncer::AUTOFILL_PROFILE, |
| 36 syncer::AUTOFILL, | 36 syncer::AUTOFILL_WALLET_DATA, syncer::AUTOFILL_WALLET_METADATA, |
| 37 syncer::AUTOFILL_PROFILE, | 37 syncer::EXTENSION_SETTINGS, syncer::APP_SETTINGS, syncer::TYPED_URLS, |
| 38 syncer::AUTOFILL_WALLET_DATA, | 38 syncer::HISTORY_DELETE_DIRECTIVES, syncer::SYNCED_NOTIFICATIONS, |
| 39 syncer::AUTOFILL_WALLET_METADATA, | 39 syncer::SYNCED_NOTIFICATION_APP_INFO, |
| 40 syncer::EXTENSION_SETTINGS, | |
| 41 syncer::APP_SETTINGS, | |
| 42 syncer::TYPED_URLS, | |
| 43 syncer::HISTORY_DELETE_DIRECTIVES, | |
| 44 syncer::SYNCED_NOTIFICATIONS, | |
| 45 syncer::SYNCED_NOTIFICATION_APP_INFO, | |
| 46 | 40 |
| 47 // UI thread data types. | 41 // UI thread data types. |
| 48 syncer::BOOKMARKS, | 42 syncer::BOOKMARKS, |
| 49 syncer::SUPERVISED_USERS, // Syncing supervised users on initial login | 43 syncer::SUPERVISED_USERS, // Syncing supervised users on initial login |
| 50 // might block creating a new supervised user, | 44 // might block creating a new supervised user, |
| 51 // so we want to do it early. | 45 // so we want to do it early. |
| 52 syncer::PREFERENCES, | 46 syncer::PREFERENCES, syncer::PRIORITY_PREFERENCES, syncer::EXTENSIONS, |
| 53 syncer::PRIORITY_PREFERENCES, | 47 syncer::APPS, syncer::APP_LIST, syncer::ARC_PACKAGE, syncer::THEMES, |
| 54 syncer::EXTENSIONS, | 48 syncer::SEARCH_ENGINES, syncer::SESSIONS, syncer::APP_NOTIFICATIONS, |
| 55 syncer::APPS, | 49 syncer::DICTIONARY, syncer::FAVICON_IMAGES, syncer::FAVICON_TRACKING, |
| 56 syncer::APP_LIST, | 50 syncer::SUPERVISED_USER_SETTINGS, syncer::SUPERVISED_USER_SHARED_SETTINGS, |
| 57 syncer::ARC_PACKAGE, | 51 syncer::SUPERVISED_USER_WHITELISTS, syncer::ARTICLES, |
| 58 syncer::THEMES, | 52 syncer::WIFI_CREDENTIALS, |
| 59 syncer::SEARCH_ENGINES, | |
| 60 syncer::SESSIONS, | |
| 61 syncer::APP_NOTIFICATIONS, | |
| 62 syncer::DICTIONARY, | |
| 63 syncer::FAVICON_IMAGES, | |
| 64 syncer::FAVICON_TRACKING, | |
| 65 syncer::SUPERVISED_USER_SETTINGS, | |
| 66 syncer::SUPERVISED_USER_SHARED_SETTINGS, | |
| 67 syncer::SUPERVISED_USER_WHITELISTS, | |
| 68 syncer::ARTICLES, | |
| 69 syncer::WIFI_CREDENTIALS, | |
| 70 }; | 53 }; |
| 71 | 54 |
| 72 static_assert(arraysize(kStartOrder) == | 55 static_assert(arraysize(kStartOrder) == |
| 73 syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, | 56 syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, |
| 74 "kStartOrder must have MODEL_TYPE_COUNT - " | 57 "kStartOrder must have MODEL_TYPE_COUNT - " |
| 75 "FIRST_REAL_MODEL_TYPE elements"); | 58 "FIRST_REAL_MODEL_TYPE elements"); |
| 76 | 59 |
| 77 // 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 |
| 78 // finished association by the time, DataTypeManager is notified of the | 61 // finished association by the time, DataTypeManager is notified of the |
| 79 // unfinished types. | 62 // unfinished types. |
| 80 const int64_t kAssociationTimeOutInSeconds = 600; | 63 const int64_t kAssociationTimeOutInSeconds = 600; |
| 81 | 64 |
| 82 syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( | 65 syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( |
| 83 const syncer::SyncMergeResult& local_merge_result, | 66 const syncer::SyncMergeResult& local_merge_result, |
| 84 const syncer::SyncMergeResult& syncer_merge_result, | 67 const syncer::SyncMergeResult& syncer_merge_result, |
| 85 const base::TimeDelta& association_wait_time, | 68 const base::TimeDelta& association_wait_time, |
| 86 const base::TimeDelta& association_time) { | 69 const base::TimeDelta& association_time) { |
| 87 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()); |
| 88 syncer::DataTypeAssociationStats stats; | 71 syncer::DataTypeAssociationStats stats; |
| 89 stats.had_error = local_merge_result.error().IsSet() || | 72 stats.had_error = |
| 90 syncer_merge_result.error().IsSet(); | 73 local_merge_result.error().IsSet() || syncer_merge_result.error().IsSet(); |
| 91 stats.num_local_items_before_association = | 74 stats.num_local_items_before_association = |
| 92 local_merge_result.num_items_before_association(); | 75 local_merge_result.num_items_before_association(); |
| 93 stats.num_sync_items_before_association = | 76 stats.num_sync_items_before_association = |
| 94 syncer_merge_result.num_items_before_association(); | 77 syncer_merge_result.num_items_before_association(); |
| 95 stats.num_local_items_after_association = | 78 stats.num_local_items_after_association = |
| 96 local_merge_result.num_items_after_association(); | 79 local_merge_result.num_items_after_association(); |
| 97 stats.num_sync_items_after_association = | 80 stats.num_sync_items_after_association = |
| 98 syncer_merge_result.num_items_after_association(); | 81 syncer_merge_result.num_items_after_association(); |
| 99 stats.num_local_items_added = | 82 stats.num_local_items_added = local_merge_result.num_items_added(); |
| 100 local_merge_result.num_items_added(); | 83 stats.num_local_items_deleted = local_merge_result.num_items_deleted(); |
| 101 stats.num_local_items_deleted = | 84 stats.num_local_items_modified = local_merge_result.num_items_modified(); |
| 102 local_merge_result.num_items_deleted(); | |
| 103 stats.num_local_items_modified = | |
| 104 local_merge_result.num_items_modified(); | |
| 105 stats.local_version_pre_association = | 85 stats.local_version_pre_association = |
| 106 local_merge_result.pre_association_version(); | 86 local_merge_result.pre_association_version(); |
| 107 stats.num_sync_items_added = | 87 stats.num_sync_items_added = syncer_merge_result.num_items_added(); |
| 108 syncer_merge_result.num_items_added(); | 88 stats.num_sync_items_deleted = syncer_merge_result.num_items_deleted(); |
| 109 stats.num_sync_items_deleted = | 89 stats.num_sync_items_modified = syncer_merge_result.num_items_modified(); |
| 110 syncer_merge_result.num_items_deleted(); | |
| 111 stats.num_sync_items_modified = | |
| 112 syncer_merge_result.num_items_modified(); | |
| 113 stats.sync_version_pre_association = | 90 stats.sync_version_pre_association = |
| 114 syncer_merge_result.pre_association_version(); | 91 syncer_merge_result.pre_association_version(); |
| 115 stats.association_wait_time = association_wait_time; | 92 stats.association_wait_time = association_wait_time; |
| 116 stats.association_time = association_time; | 93 stats.association_time = association_time; |
| 117 return stats; | 94 return stats; |
| 118 } | 95 } |
| 119 | 96 |
| 120 } // namespace | 97 } // namespace |
| 121 | 98 |
| 122 ModelAssociationManager::ModelAssociationManager( | 99 ModelAssociationManager::ModelAssociationManager( |
| 123 const DataTypeController::TypeMap* controllers, | 100 const DataTypeController::TypeMap* controllers, |
| 124 ModelAssociationManagerDelegate* processor) | 101 ModelAssociationManagerDelegate* processor) |
| 125 : state_(IDLE), | 102 : state_(IDLE), |
| 126 controllers_(controllers), | 103 controllers_(controllers), |
| 127 delegate_(processor), | 104 delegate_(processor), |
| 128 configure_status_(DataTypeManager::UNKNOWN), | 105 configure_status_(DataTypeManager::UNKNOWN), |
| 129 notified_about_ready_for_configure_(false), | 106 notified_about_ready_for_configure_(false), |
| 130 weak_ptr_factory_(this) { | 107 weak_ptr_factory_(this) { |
| 131 // Ensure all data type controllers are stopped. | 108 // Ensure all data type controllers are stopped. |
| 132 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 109 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
| 133 it != controllers_->end(); ++it) { | 110 it != controllers_->end(); ++it) { |
| 134 DCHECK_EQ(DataTypeController::NOT_RUNNING, (*it).second->state()); | 111 DCHECK_EQ(DataTypeController::NOT_RUNNING, (*it).second->state()); |
| 135 } | 112 } |
| 136 } | 113 } |
| 137 | 114 |
| 138 ModelAssociationManager::~ModelAssociationManager() { | 115 ModelAssociationManager::~ModelAssociationManager() {} |
| 139 } | |
| 140 | 116 |
| 141 void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { | 117 void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { |
| 142 // state_ can be INITIALIZED if types are reconfigured when | 118 // state_ can be INITIALIZED if types are reconfigured when |
| 143 // data is being downloaded, so StartAssociationAsync() is never called for | 119 // data is being downloaded, so StartAssociationAsync() is never called for |
| 144 // the first configuration. | 120 // the first configuration. |
| 145 DCHECK_NE(ASSOCIATING, state_); | 121 DCHECK_NE(ASSOCIATING, state_); |
| 146 | 122 |
| 147 // Only keep types that have controllers. | 123 // Only keep types that have controllers. |
| 148 desired_types_.Clear(); | 124 desired_types_.Clear(); |
| 149 for (syncer::ModelTypeSet::Iterator it = desired_types.First(); | 125 for (syncer::ModelTypeSet::Iterator it = desired_types.First(); it.Good(); |
| 150 it.Good(); it.Inc()) { | 126 it.Inc()) { |
| 151 if (controllers_->find(it.Get()) != controllers_->end()) | 127 if (controllers_->find(it.Get()) != controllers_->end()) |
| 152 desired_types_.Put(it.Get()); | 128 desired_types_.Put(it.Get()); |
| 153 } | 129 } |
| 154 | 130 |
| 155 DVLOG(1) << "ModelAssociationManager: Initializing for " | 131 DVLOG(1) << "ModelAssociationManager: Initializing for " |
| 156 << syncer::ModelTypeSetToString(desired_types_); | 132 << syncer::ModelTypeSetToString(desired_types_); |
| 157 | 133 |
| 158 state_ = INITIALIZED; | 134 state_ = INITIALIZED; |
| 159 notified_about_ready_for_configure_ = false; | 135 notified_about_ready_for_configure_ = false; |
| 160 | 136 |
| 161 StopDisabledTypes(); | 137 StopDisabledTypes(); |
| 162 LoadEnabledTypes(); | 138 LoadEnabledTypes(); |
| 163 } | 139 } |
| 164 | 140 |
| 165 void ModelAssociationManager::StopDatatype( | 141 void ModelAssociationManager::StopDatatype(const syncer::SyncError& error, |
| 166 const syncer::SyncError& error, | 142 DataTypeController* dtc) { |
| 167 DataTypeController* dtc) { | |
| 168 loaded_types_.Remove(dtc->type()); | 143 loaded_types_.Remove(dtc->type()); |
| 169 associated_types_.Remove(dtc->type()); | 144 associated_types_.Remove(dtc->type()); |
| 170 associating_types_.Remove(dtc->type()); | 145 associating_types_.Remove(dtc->type()); |
| 171 | 146 |
| 172 if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { | 147 if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { |
| 173 // 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. |
| 174 delegate_->OnSingleDataTypeWillStop(dtc->type(), error); | 149 delegate_->OnSingleDataTypeWillStop(dtc->type(), error); |
| 175 dtc->Stop(); | 150 dtc->Stop(); |
| 176 } | 151 } |
| 177 } | 152 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 | 203 |
| 229 // Done if no types to associate. | 204 // Done if no types to associate. |
| 230 if (associating_types_.Empty()) { | 205 if (associating_types_.Empty()) { |
| 231 ModelAssociationDone(INITIALIZED); | 206 ModelAssociationDone(INITIALIZED); |
| 232 return; | 207 return; |
| 233 } | 208 } |
| 234 | 209 |
| 235 timer_.Start(FROM_HERE, | 210 timer_.Start(FROM_HERE, |
| 236 base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), | 211 base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), |
| 237 base::Bind(&ModelAssociationManager::ModelAssociationDone, | 212 base::Bind(&ModelAssociationManager::ModelAssociationDone, |
| 238 weak_ptr_factory_.GetWeakPtr(), | 213 weak_ptr_factory_.GetWeakPtr(), INITIALIZED)); |
| 239 INITIALIZED)); | |
| 240 | 214 |
| 241 // Start association of types that are loaded in specified order. | 215 // Start association of types that are loaded in specified order. |
| 242 for (size_t i = 0; i < arraysize(kStartOrder); i++) { | 216 for (size_t i = 0; i < arraysize(kStartOrder); i++) { |
| 243 syncer::ModelType type = kStartOrder[i]; | 217 syncer::ModelType type = kStartOrder[i]; |
| 244 if (!associating_types_.Has(type) || !loaded_types_.Has(type)) | 218 if (!associating_types_.Has(type) || !loaded_types_.Has(type)) |
| 245 continue; | 219 continue; |
| 246 | 220 |
| 247 DataTypeController* dtc = controllers_->find(type)->second.get(); | 221 DataTypeController* dtc = controllers_->find(type)->second.get(); |
| 248 DCHECK(DataTypeController::MODEL_LOADED == dtc->state() || | 222 DCHECK(DataTypeController::MODEL_LOADED == dtc->state() || |
| 249 DataTypeController::ASSOCIATING == dtc->state()); | 223 DataTypeController::ASSOCIATING == dtc->state()); |
| 250 if (dtc->state() == DataTypeController::MODEL_LOADED) { | 224 if (dtc->state() == DataTypeController::MODEL_LOADED) { |
| 251 TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", | 225 TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", dtc, "DataType", |
| 252 dtc, | |
| 253 "DataType", | |
| 254 ModelTypeToString(type)); | 226 ModelTypeToString(type)); |
| 255 | 227 |
| 256 dtc->StartAssociating( | 228 dtc->StartAssociating(base::Bind( |
| 257 base::Bind(&ModelAssociationManager::TypeStartCallback, | 229 &ModelAssociationManager::TypeStartCallback, |
| 258 weak_ptr_factory_.GetWeakPtr(), | 230 weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); |
| 259 type, base::TimeTicks::Now())); | |
| 260 } | 231 } |
| 261 } | 232 } |
| 262 } | 233 } |
| 263 | 234 |
| 264 void ModelAssociationManager::Stop() { | 235 void ModelAssociationManager::Stop() { |
| 265 // Ignore callbacks from controllers. | 236 // Ignore callbacks from controllers. |
| 266 weak_ptr_factory_.InvalidateWeakPtrs(); | 237 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 267 | 238 |
| 268 // Stop started data types. | 239 // Stop started data types. |
| 269 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 240 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 287 } else { | 258 } else { |
| 288 DCHECK(associating_types_.Empty()); | 259 DCHECK(associating_types_.Empty()); |
| 289 DCHECK(requested_types_.Empty()); | 260 DCHECK(requested_types_.Empty()); |
| 290 state_ = IDLE; | 261 state_ = IDLE; |
| 291 } | 262 } |
| 292 } | 263 } |
| 293 | 264 |
| 294 void ModelAssociationManager::ModelLoadCallback(syncer::ModelType type, | 265 void ModelAssociationManager::ModelLoadCallback(syncer::ModelType type, |
| 295 syncer::SyncError error) { | 266 syncer::SyncError error) { |
| 296 DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " | 267 DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " |
| 297 << syncer::ModelTypeToString(type); | 268 << syncer::ModelTypeToString(type); |
| 298 | 269 |
| 299 if (error.IsSet()) { | 270 if (error.IsSet()) { |
| 300 syncer::SyncMergeResult local_merge_result(type); | 271 syncer::SyncMergeResult local_merge_result(type); |
| 301 local_merge_result.set_error(error); | 272 local_merge_result.set_error(error); |
| 302 TypeStartCallback(type, | 273 TypeStartCallback(type, base::TimeTicks::Now(), |
| 303 base::TimeTicks::Now(), | |
| 304 DataTypeController::ASSOCIATION_FAILED, | 274 DataTypeController::ASSOCIATION_FAILED, |
| 305 local_merge_result, | 275 local_merge_result, syncer::SyncMergeResult(type)); |
| 306 syncer::SyncMergeResult(type)); | |
| 307 return; | 276 return; |
| 308 } | 277 } |
| 309 | 278 |
| 310 // This happens when slow loading type is disabled by new configuration. | 279 // This happens when slow loading type is disabled by new configuration. |
| 311 if (!desired_types_.Has(type)) | 280 if (!desired_types_.Has(type)) |
| 312 return; | 281 return; |
| 313 | 282 |
| 314 DCHECK(!loaded_types_.Has(type)); | 283 DCHECK(!loaded_types_.Has(type)); |
| 315 loaded_types_.Put(type); | 284 loaded_types_.Put(type); |
| 316 NotifyDelegateIfReadyForConfigure(); | 285 NotifyDelegateIfReadyForConfigure(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 346 NotifyDelegateIfReadyForConfigure(); | 315 NotifyDelegateIfReadyForConfigure(); |
| 347 | 316 |
| 348 // Update configuration result. | 317 // Update configuration result. |
| 349 if (start_result == DataTypeController::UNRECOVERABLE_ERROR) | 318 if (start_result == DataTypeController::UNRECOVERABLE_ERROR) |
| 350 configure_status_ = DataTypeManager::UNRECOVERABLE_ERROR; | 319 configure_status_ = DataTypeManager::UNRECOVERABLE_ERROR; |
| 351 } | 320 } |
| 352 | 321 |
| 353 // This happens when a slow associating type is disabled or if a type | 322 // This happens when a slow associating type is disabled or if a type |
| 354 // disables itself after initial configuration. | 323 // disables itself after initial configuration. |
| 355 if (!desired_types_.Has(type)) { | 324 if (!desired_types_.Has(type)) { |
| 356 // It's possible all types failed to associate, in which case association | 325 // It's possible all types failed to associate, in which case association |
| 357 // is complete. | 326 // is complete. |
| 358 if (state_ == ASSOCIATING && associating_types_.Empty()) | 327 if (state_ == ASSOCIATING && associating_types_.Empty()) |
| 359 ModelAssociationDone(INITIALIZED); | 328 ModelAssociationDone(INITIALIZED); |
| 360 return; | 329 return; |
| 361 } | 330 } |
| 362 | 331 |
| 363 DCHECK(!associated_types_.Has(type)); | 332 DCHECK(!associated_types_.Has(type)); |
| 364 DCHECK(DataTypeController::IsSuccessfulResult(start_result)); | 333 DCHECK(DataTypeController::IsSuccessfulResult(start_result)); |
| 365 associated_types_.Put(type); | 334 associated_types_.Put(type); |
| 366 | 335 |
| 367 if (state_ != ASSOCIATING) | 336 if (state_ != ASSOCIATING) |
| 368 return; | 337 return; |
| 369 | 338 |
| 370 TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", | 339 TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", |
| 371 controllers_->find(type)->second.get(), | 340 controllers_->find(type)->second.get(), "DataType", |
| 372 "DataType", | |
| 373 ModelTypeToString(type)); | 341 ModelTypeToString(type)); |
| 374 | 342 |
| 375 // Track the merge results if we succeeded or an association failure | 343 // Track the merge results if we succeeded or an association failure |
| 376 // occurred. | 344 // occurred. |
| 377 if (syncer::ProtocolTypes().Has(type)) { | 345 if (syncer::ProtocolTypes().Has(type)) { |
| 378 base::TimeDelta association_wait_time = | 346 base::TimeDelta association_wait_time = |
| 379 std::max(base::TimeDelta(), type_start_time - association_start_time_); | 347 std::max(base::TimeDelta(), type_start_time - association_start_time_); |
| 380 base::TimeDelta association_time = | 348 base::TimeDelta association_time = base::TimeTicks::Now() - type_start_time; |
| 381 base::TimeTicks::Now() - type_start_time; | |
| 382 syncer::DataTypeAssociationStats stats = | 349 syncer::DataTypeAssociationStats stats = |
| 383 BuildAssociationStatsFromMergeResults(local_merge_result, | 350 BuildAssociationStatsFromMergeResults( |
| 384 syncer_merge_result, | 351 local_merge_result, syncer_merge_result, association_wait_time, |
| 385 association_wait_time, | 352 association_time); |
| 386 association_time); | |
| 387 delegate_->OnSingleDataTypeAssociationDone(type, stats); | 353 delegate_->OnSingleDataTypeAssociationDone(type, stats); |
| 388 } | 354 } |
| 389 | 355 |
| 390 associating_types_.Remove(type); | 356 associating_types_.Remove(type); |
| 391 | 357 |
| 392 if (associating_types_.Empty()) | 358 if (associating_types_.Empty()) |
| 393 ModelAssociationDone(INITIALIZED); | 359 ModelAssociationDone(INITIALIZED); |
| 394 } | 360 } |
| 395 | 361 |
| 396 void ModelAssociationManager::ModelAssociationDone(State new_state) { | 362 void ModelAssociationManager::ModelAssociationDone(State new_state) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 410 // Treat any unfinished types as having errors. | 376 // Treat any unfinished types as having errors. |
| 411 desired_types_.RemoveAll(associating_types_); | 377 desired_types_.RemoveAll(associating_types_); |
| 412 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); | 378 for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); |
| 413 it != controllers_->end(); ++it) { | 379 it != controllers_->end(); ++it) { |
| 414 DataTypeController* dtc = (*it).second.get(); | 380 DataTypeController* dtc = (*it).second.get(); |
| 415 if (associating_types_.Has(dtc->type()) && | 381 if (associating_types_.Has(dtc->type()) && |
| 416 dtc->state() != DataTypeController::NOT_RUNNING) { | 382 dtc->state() != DataTypeController::NOT_RUNNING) { |
| 417 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", | 383 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", |
| 418 ModelTypeToHistogramInt(dtc->type()), | 384 ModelTypeToHistogramInt(dtc->type()), |
| 419 syncer::MODEL_TYPE_COUNT); | 385 syncer::MODEL_TYPE_COUNT); |
| 420 StopDatatype(syncer::SyncError(FROM_HERE, | 386 StopDatatype( |
| 421 syncer::SyncError::DATATYPE_ERROR, | 387 syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 422 "Association timed out.", | 388 "Association timed out.", dtc->type()), |
| 423 dtc->type()), | 389 dtc); |
| 424 dtc); | |
| 425 } | 390 } |
| 426 } | 391 } |
| 427 | 392 |
| 428 DataTypeManager::ConfigureResult result(configure_status_, | 393 DataTypeManager::ConfigureResult result(configure_status_, requested_types_); |
| 429 requested_types_); | |
| 430 | 394 |
| 431 // Need to reset state before invoking delegate in order to avoid re-entrancy | 395 // Need to reset state before invoking delegate in order to avoid re-entrancy |
| 432 // issues (delegate may trigger a reconfiguration). | 396 // issues (delegate may trigger a reconfiguration). |
| 433 associating_types_.Clear(); | 397 associating_types_.Clear(); |
| 434 requested_types_.Clear(); | 398 requested_types_.Clear(); |
| 435 state_ = new_state; | 399 state_ = new_state; |
| 436 | 400 |
| 437 delegate_->OnModelAssociationDone(result); | 401 delegate_->OnModelAssociationDone(result); |
| 438 } | 402 } |
| 439 | 403 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 453 // At least one type is not ready. | 417 // At least one type is not ready. |
| 454 return; | 418 return; |
| 455 } | 419 } |
| 456 } | 420 } |
| 457 | 421 |
| 458 notified_about_ready_for_configure_ = true; | 422 notified_about_ready_for_configure_ = true; |
| 459 delegate_->OnAllDataTypesReadyForConfigure(); | 423 delegate_->OnAllDataTypesReadyForConfigure(); |
| 460 } | 424 } |
| 461 | 425 |
| 462 } // namespace sync_driver | 426 } // namespace sync_driver |
| OLD | NEW |