| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/frontend_data_type_controller.h" | 5 #include "components/sync/driver/frontend_data_type_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
| 10 #include "components/sync/api/data_type_error_handler_impl.h" | 10 #include "components/sync/api/data_type_error_handler_impl.h" |
| 11 #include "components/sync/api/sync_error.h" | 11 #include "components/sync/api/sync_error.h" |
| 12 #include "components/sync/api/sync_merge_result.h" | 12 #include "components/sync/api/sync_merge_result.h" |
| 13 #include "components/sync/base/data_type_histogram.h" | 13 #include "components/sync/base/data_type_histogram.h" |
| 14 #include "components/sync/base/model_type.h" | 14 #include "components/sync/base/model_type.h" |
| 15 #include "components/sync/driver/change_processor.h" | 15 #include "components/sync/driver/change_processor.h" |
| 16 #include "components/sync/driver/model_associator.h" | 16 #include "components/sync/driver/model_associator.h" |
| 17 #include "components/sync/driver/sync_client.h" | 17 #include "components/sync/driver/sync_client.h" |
| 18 #include "components/sync/driver/sync_service.h" | 18 #include "components/sync/driver/sync_service.h" |
| 19 | 19 |
| 20 namespace browser_sync { | 20 namespace syncer { |
| 21 | 21 |
| 22 FrontendDataTypeController::FrontendDataTypeController( | 22 FrontendDataTypeController::FrontendDataTypeController( |
| 23 syncer::ModelType type, | 23 ModelType type, |
| 24 const base::Closure& dump_stack, | 24 const base::Closure& dump_stack, |
| 25 sync_driver::SyncClient* sync_client) | 25 SyncClient* sync_client) |
| 26 : DirectoryDataTypeController(type, dump_stack, sync_client), | 26 : DirectoryDataTypeController(type, dump_stack, sync_client), |
| 27 state_(NOT_RUNNING) { | 27 state_(NOT_RUNNING) { |
| 28 DCHECK(CalledOnValidThread()); | 28 DCHECK(CalledOnValidThread()); |
| 29 DCHECK(sync_client); | 29 DCHECK(sync_client); |
| 30 } | 30 } |
| 31 | 31 |
| 32 void FrontendDataTypeController::LoadModels( | 32 void FrontendDataTypeController::LoadModels( |
| 33 const ModelLoadCallback& model_load_callback) { | 33 const ModelLoadCallback& model_load_callback) { |
| 34 DCHECK(CalledOnValidThread()); | 34 DCHECK(CalledOnValidThread()); |
| 35 model_load_callback_ = model_load_callback; | 35 model_load_callback_ = model_load_callback; |
| 36 | 36 |
| 37 if (state_ != NOT_RUNNING) { | 37 if (state_ != NOT_RUNNING) { |
| 38 model_load_callback.Run( | 38 model_load_callback.Run(type(), |
| 39 type(), syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 39 SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, |
| 40 "Model already running", type())); | 40 "Model already running", type())); |
| 41 return; | 41 return; |
| 42 } | 42 } |
| 43 | 43 |
| 44 state_ = MODEL_STARTING; | 44 state_ = MODEL_STARTING; |
| 45 if (!StartModels()) { | 45 if (!StartModels()) { |
| 46 // If we are waiting for some external service to load before associating | 46 // If we are waiting for some external service to load before associating |
| 47 // or we failed to start the models, we exit early. state_ will control | 47 // or we failed to start the models, we exit early. state_ will control |
| 48 // what we perform next. | 48 // what we perform next. |
| 49 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); | 49 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); |
| 50 return; | 50 return; |
| 51 } | 51 } |
| 52 | 52 |
| 53 OnModelLoaded(); | 53 OnModelLoaded(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 void FrontendDataTypeController::OnModelLoaded() { | 56 void FrontendDataTypeController::OnModelLoaded() { |
| 57 DCHECK(CalledOnValidThread()); | 57 DCHECK(CalledOnValidThread()); |
| 58 DCHECK_EQ(state_, MODEL_STARTING); | 58 DCHECK_EQ(state_, MODEL_STARTING); |
| 59 | 59 |
| 60 state_ = MODEL_LOADED; | 60 state_ = MODEL_LOADED; |
| 61 model_load_callback_.Run(type(), syncer::SyncError()); | 61 model_load_callback_.Run(type(), SyncError()); |
| 62 } | 62 } |
| 63 | 63 |
| 64 void FrontendDataTypeController::StartAssociating( | 64 void FrontendDataTypeController::StartAssociating( |
| 65 const StartCallback& start_callback) { | 65 const StartCallback& start_callback) { |
| 66 DCHECK(CalledOnValidThread()); | 66 DCHECK(CalledOnValidThread()); |
| 67 DCHECK(!start_callback.is_null()); | 67 DCHECK(!start_callback.is_null()); |
| 68 DCHECK_EQ(state_, MODEL_LOADED); | 68 DCHECK_EQ(state_, MODEL_LOADED); |
| 69 | 69 |
| 70 start_callback_ = start_callback; | 70 start_callback_ = start_callback; |
| 71 state_ = ASSOCIATING; | 71 state_ = ASSOCIATING; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 89 if (prev_state == MODEL_STARTING) { | 89 if (prev_state == MODEL_STARTING) { |
| 90 AbortModelLoad(); | 90 AbortModelLoad(); |
| 91 // We can just return here since we haven't performed association if we're | 91 // We can just return here since we haven't performed association if we're |
| 92 // still in MODEL_STARTING. | 92 // still in MODEL_STARTING. |
| 93 return; | 93 return; |
| 94 } | 94 } |
| 95 | 95 |
| 96 CleanUpState(); | 96 CleanUpState(); |
| 97 | 97 |
| 98 if (model_associator()) { | 98 if (model_associator()) { |
| 99 syncer::SyncError error; // Not used. | 99 SyncError error; // Not used. |
| 100 error = model_associator()->DisassociateModels(); | 100 error = model_associator()->DisassociateModels(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 set_model_associator(NULL); | 103 set_model_associator(NULL); |
| 104 change_processor_.reset(); | 104 change_processor_.reset(); |
| 105 | 105 |
| 106 state_ = NOT_RUNNING; | 106 state_ = NOT_RUNNING; |
| 107 } | 107 } |
| 108 | 108 |
| 109 syncer::ModelSafeGroup FrontendDataTypeController::model_safe_group() const { | 109 ModelSafeGroup FrontendDataTypeController::model_safe_group() const { |
| 110 return syncer::GROUP_UI; | 110 return GROUP_UI; |
| 111 } | 111 } |
| 112 | 112 |
| 113 std::string FrontendDataTypeController::name() const { | 113 std::string FrontendDataTypeController::name() const { |
| 114 // For logging only. | 114 // For logging only. |
| 115 return syncer::ModelTypeToString(type()); | 115 return ModelTypeToString(type()); |
| 116 } | 116 } |
| 117 | 117 |
| 118 sync_driver::DataTypeController::State FrontendDataTypeController::state() | 118 DataTypeController::State FrontendDataTypeController::state() const { |
| 119 const { | |
| 120 return state_; | 119 return state_; |
| 121 } | 120 } |
| 122 | 121 |
| 123 FrontendDataTypeController::FrontendDataTypeController() | 122 FrontendDataTypeController::FrontendDataTypeController() |
| 124 : DirectoryDataTypeController(syncer::UNSPECIFIED, | 123 : DirectoryDataTypeController(UNSPECIFIED, base::Closure(), nullptr), |
| 125 base::Closure(), | |
| 126 nullptr), | |
| 127 state_(NOT_RUNNING) {} | 124 state_(NOT_RUNNING) {} |
| 128 | 125 |
| 129 FrontendDataTypeController::~FrontendDataTypeController() {} | 126 FrontendDataTypeController::~FrontendDataTypeController() {} |
| 130 | 127 |
| 131 bool FrontendDataTypeController::StartModels() { | 128 bool FrontendDataTypeController::StartModels() { |
| 132 DCHECK(CalledOnValidThread()); | 129 DCHECK(CalledOnValidThread()); |
| 133 DCHECK_EQ(state_, MODEL_STARTING); | 130 DCHECK_EQ(state_, MODEL_STARTING); |
| 134 // By default, no additional services need to be started before we can proceed | 131 // By default, no additional services need to be started before we can proceed |
| 135 // with model association. | 132 // with model association. |
| 136 return true; | 133 return true; |
| 137 } | 134 } |
| 138 | 135 |
| 139 void FrontendDataTypeController::Associate() { | 136 void FrontendDataTypeController::Associate() { |
| 140 DCHECK(CalledOnValidThread()); | 137 DCHECK(CalledOnValidThread()); |
| 141 if (state_ != ASSOCIATING) { | 138 if (state_ != ASSOCIATING) { |
| 142 // Stop() must have been called while Associate() task have been waiting. | 139 // Stop() must have been called while Associate() task have been waiting. |
| 143 DCHECK_EQ(state_, NOT_RUNNING); | 140 DCHECK_EQ(state_, NOT_RUNNING); |
| 144 return; | 141 return; |
| 145 } | 142 } |
| 146 | 143 |
| 147 syncer::SyncMergeResult local_merge_result(type()); | 144 SyncMergeResult local_merge_result(type()); |
| 148 syncer::SyncMergeResult syncer_merge_result(type()); | 145 SyncMergeResult syncer_merge_result(type()); |
| 149 CreateSyncComponents(); | 146 CreateSyncComponents(); |
| 150 if (!model_associator()->CryptoReadyIfNecessary()) { | 147 if (!model_associator()->CryptoReadyIfNecessary()) { |
| 151 StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); | 148 StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); |
| 152 return; | 149 return; |
| 153 } | 150 } |
| 154 | 151 |
| 155 bool sync_has_nodes = false; | 152 bool sync_has_nodes = false; |
| 156 if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { | 153 if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { |
| 157 syncer::SyncError error(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR, | 154 SyncError error(FROM_HERE, SyncError::UNRECOVERABLE_ERROR, |
| 158 "Failed to load sync nodes", type()); | 155 "Failed to load sync nodes", type()); |
| 159 local_merge_result.set_error(error); | 156 local_merge_result.set_error(error); |
| 160 StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); | 157 StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); |
| 161 return; | 158 return; |
| 162 } | 159 } |
| 163 | 160 |
| 164 // TODO(zea): Have AssociateModels fill the local and syncer merge results. | 161 // TODO(zea): Have AssociateModels fill the local and syncer merge results. |
| 165 base::TimeTicks start_time = base::TimeTicks::Now(); | 162 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 166 syncer::SyncError error; | 163 SyncError error; |
| 167 error = model_associator()->AssociateModels(&local_merge_result, | 164 error = model_associator()->AssociateModels(&local_merge_result, |
| 168 &syncer_merge_result); | 165 &syncer_merge_result); |
| 169 // TODO(lipalani): crbug.com/122690 - handle abort. | 166 // TODO(lipalani): crbug.com/122690 - handle abort. |
| 170 RecordAssociationTime(base::TimeTicks::Now() - start_time); | 167 RecordAssociationTime(base::TimeTicks::Now() - start_time); |
| 171 if (error.IsSet()) { | 168 if (error.IsSet()) { |
| 172 local_merge_result.set_error(error); | 169 local_merge_result.set_error(error); |
| 173 StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); | 170 StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); |
| 174 return; | 171 return; |
| 175 } | 172 } |
| 176 | 173 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 193 } | 190 } |
| 194 | 191 |
| 195 void FrontendDataTypeController::AbortModelLoad() { | 192 void FrontendDataTypeController::AbortModelLoad() { |
| 196 DCHECK(CalledOnValidThread()); | 193 DCHECK(CalledOnValidThread()); |
| 197 CleanUp(); | 194 CleanUp(); |
| 198 state_ = NOT_RUNNING; | 195 state_ = NOT_RUNNING; |
| 199 } | 196 } |
| 200 | 197 |
| 201 void FrontendDataTypeController::StartDone( | 198 void FrontendDataTypeController::StartDone( |
| 202 ConfigureResult start_result, | 199 ConfigureResult start_result, |
| 203 const syncer::SyncMergeResult& local_merge_result, | 200 const SyncMergeResult& local_merge_result, |
| 204 const syncer::SyncMergeResult& syncer_merge_result) { | 201 const SyncMergeResult& syncer_merge_result) { |
| 205 DCHECK(CalledOnValidThread()); | 202 DCHECK(CalledOnValidThread()); |
| 206 if (!IsSuccessfulResult(start_result)) { | 203 if (!IsSuccessfulResult(start_result)) { |
| 207 CleanUp(); | 204 CleanUp(); |
| 208 if (start_result == ASSOCIATION_FAILED) { | 205 if (start_result == ASSOCIATION_FAILED) { |
| 209 state_ = DISABLED; | 206 state_ = DISABLED; |
| 210 } else { | 207 } else { |
| 211 state_ = NOT_RUNNING; | 208 state_ = NOT_RUNNING; |
| 212 } | 209 } |
| 213 RecordStartFailure(start_result); | 210 RecordStartFailure(start_result); |
| 214 } | 211 } |
| 215 | 212 |
| 216 start_callback_.Run(start_result, local_merge_result, syncer_merge_result); | 213 start_callback_.Run(start_result, local_merge_result, syncer_merge_result); |
| 217 } | 214 } |
| 218 | 215 |
| 219 std::unique_ptr<syncer::DataTypeErrorHandler> | 216 std::unique_ptr<DataTypeErrorHandler> |
| 220 FrontendDataTypeController::CreateErrorHandler() { | 217 FrontendDataTypeController::CreateErrorHandler() { |
| 221 return base::MakeUnique<syncer::DataTypeErrorHandlerImpl>( | 218 return base::MakeUnique<DataTypeErrorHandlerImpl>( |
| 222 base::ThreadTaskRunnerHandle::Get(), dump_stack_, | 219 base::ThreadTaskRunnerHandle::Get(), dump_stack_, |
| 223 base::Bind(&FrontendDataTypeController::OnUnrecoverableError, | 220 base::Bind(&FrontendDataTypeController::OnUnrecoverableError, |
| 224 base::AsWeakPtr(this))); | 221 base::AsWeakPtr(this))); |
| 225 } | 222 } |
| 226 | 223 |
| 227 void FrontendDataTypeController::OnUnrecoverableError( | 224 void FrontendDataTypeController::OnUnrecoverableError(const SyncError& error) { |
| 228 const syncer::SyncError& error) { | |
| 229 DCHECK(CalledOnValidThread()); | 225 DCHECK(CalledOnValidThread()); |
| 230 DCHECK_EQ(type(), error.model_type()); | 226 DCHECK_EQ(type(), error.model_type()); |
| 231 if (!model_load_callback_.is_null()) { | 227 if (!model_load_callback_.is_null()) { |
| 232 model_load_callback_.Run(type(), error); | 228 model_load_callback_.Run(type(), error); |
| 233 } | 229 } |
| 234 } | 230 } |
| 235 | 231 |
| 236 void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { | 232 void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { |
| 237 DCHECK(CalledOnValidThread()); | 233 DCHECK(CalledOnValidThread()); |
| 238 #define PER_DATA_TYPE_MACRO(type_str) \ | 234 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 239 UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); | 235 UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); |
| 240 SYNC_DATA_TYPE_HISTOGRAM(type()); | 236 SYNC_DATA_TYPE_HISTOGRAM(type()); |
| 241 #undef PER_DATA_TYPE_MACRO | 237 #undef PER_DATA_TYPE_MACRO |
| 242 } | 238 } |
| 243 | 239 |
| 244 void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { | 240 void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { |
| 245 DCHECK(CalledOnValidThread()); | 241 DCHECK(CalledOnValidThread()); |
| 246 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", | 242 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", |
| 247 ModelTypeToHistogramInt(type()), | 243 ModelTypeToHistogramInt(type()), MODEL_TYPE_COUNT); |
| 248 syncer::MODEL_TYPE_COUNT); | |
| 249 #define PER_DATA_TYPE_MACRO(type_str) \ | 244 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 250 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ | 245 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ |
| 251 MAX_CONFIGURE_RESULT); | 246 MAX_CONFIGURE_RESULT); |
| 252 SYNC_DATA_TYPE_HISTOGRAM(type()); | 247 SYNC_DATA_TYPE_HISTOGRAM(type()); |
| 253 #undef PER_DATA_TYPE_MACRO | 248 #undef PER_DATA_TYPE_MACRO |
| 254 } | 249 } |
| 255 | 250 |
| 256 sync_driver::AssociatorInterface* FrontendDataTypeController::model_associator() | 251 AssociatorInterface* FrontendDataTypeController::model_associator() const { |
| 257 const { | |
| 258 return model_associator_.get(); | 252 return model_associator_.get(); |
| 259 } | 253 } |
| 260 | 254 |
| 261 void FrontendDataTypeController::set_model_associator( | 255 void FrontendDataTypeController::set_model_associator( |
| 262 sync_driver::AssociatorInterface* model_associator) { | 256 AssociatorInterface* model_associator) { |
| 263 model_associator_.reset(model_associator); | 257 model_associator_.reset(model_associator); |
| 264 } | 258 } |
| 265 | 259 |
| 266 sync_driver::ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() | 260 ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() const { |
| 267 const { | |
| 268 return change_processor_.get(); | 261 return change_processor_.get(); |
| 269 } | 262 } |
| 270 | 263 |
| 271 void FrontendDataTypeController::set_change_processor( | 264 void FrontendDataTypeController::set_change_processor( |
| 272 sync_driver::ChangeProcessor* change_processor) { | 265 ChangeProcessor* change_processor) { |
| 273 change_processor_.reset(change_processor); | 266 change_processor_.reset(change_processor); |
| 274 } | 267 } |
| 275 | 268 |
| 276 } // namespace browser_sync | 269 } // namespace syncer |
| OLD | NEW |