| 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 |