| 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/non_blocking_data_type_controller.h" | 5 #include "components/sync/driver/non_blocking_data_type_controller.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "components/sync/api/data_type_error_handler_impl.h" | 15 #include "components/sync/api/data_type_error_handler_impl.h" |
| 16 #include "components/sync/api/model_type_change_processor.h" | 16 #include "components/sync/api/model_type_change_processor.h" |
| 17 #include "components/sync/api/model_type_service.h" | 17 #include "components/sync/api/model_type_service.h" |
| 18 #include "components/sync/api/sync_error.h" | 18 #include "components/sync/api/sync_error.h" |
| 19 #include "components/sync/api/sync_merge_result.h" | 19 #include "components/sync/api/sync_merge_result.h" |
| 20 #include "components/sync/base/bind_to_task_runner.h" | 20 #include "components/sync/base/bind_to_task_runner.h" |
| 21 #include "components/sync/base/data_type_histogram.h" | 21 #include "components/sync/base/data_type_histogram.h" |
| 22 #include "components/sync/core/activation_context.h" | 22 #include "components/sync/core/activation_context.h" |
| 23 #include "components/sync/driver/backend_data_type_configurer.h" | 23 #include "components/sync/driver/backend_data_type_configurer.h" |
| 24 #include "components/sync/driver/sync_client.h" | 24 #include "components/sync/driver/sync_client.h" |
| 25 | 25 |
| 26 namespace syncer { | 26 namespace sync_driver_v2 { |
| 27 | 27 |
| 28 NonBlockingDataTypeController::NonBlockingDataTypeController( | 28 NonBlockingDataTypeController::NonBlockingDataTypeController( |
| 29 ModelType type, | 29 syncer::ModelType type, |
| 30 const base::Closure& dump_stack, | 30 const base::Closure& dump_stack, |
| 31 SyncClient* sync_client) | 31 sync_driver::SyncClient* sync_client) |
| 32 : DataTypeController(type, dump_stack), | 32 : sync_driver::DataTypeController(type, dump_stack), |
| 33 sync_client_(sync_client), | 33 sync_client_(sync_client), |
| 34 sync_prefs_(sync_client->GetPrefService()), | 34 sync_prefs_(sync_client->GetPrefService()), |
| 35 state_(NOT_RUNNING) {} | 35 state_(NOT_RUNNING) {} |
| 36 | 36 |
| 37 NonBlockingDataTypeController::~NonBlockingDataTypeController() {} | 37 NonBlockingDataTypeController::~NonBlockingDataTypeController() {} |
| 38 | 38 |
| 39 bool NonBlockingDataTypeController::ShouldLoadModelBeforeConfigure() const { | 39 bool NonBlockingDataTypeController::ShouldLoadModelBeforeConfigure() const { |
| 40 // USS datatypes require loading models because model controls storage where | 40 // USS datatypes require loading models because model controls storage where |
| 41 // data type context and progress marker are persisted. | 41 // data type context and progress marker are persisted. |
| 42 return true; | 42 return true; |
| 43 } | 43 } |
| 44 | 44 |
| 45 void NonBlockingDataTypeController::LoadModels( | 45 void NonBlockingDataTypeController::LoadModels( |
| 46 const ModelLoadCallback& model_load_callback) { | 46 const ModelLoadCallback& model_load_callback) { |
| 47 DCHECK(CalledOnValidThread()); | 47 DCHECK(CalledOnValidThread()); |
| 48 DCHECK(!model_load_callback.is_null()); | 48 DCHECK(!model_load_callback.is_null()); |
| 49 model_load_callback_ = model_load_callback; | 49 model_load_callback_ = model_load_callback; |
| 50 | 50 |
| 51 if (state() != NOT_RUNNING) { | 51 if (state() != NOT_RUNNING) { |
| 52 LoadModelsDone(RUNTIME_ERROR, | 52 LoadModelsDone( |
| 53 SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, | 53 RUNTIME_ERROR, |
| 54 "Model already running", type())); | 54 syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 55 "Model already running", type())); |
| 55 return; | 56 return; |
| 56 } | 57 } |
| 57 | 58 |
| 58 state_ = MODEL_STARTING; | 59 state_ = MODEL_STARTING; |
| 59 | 60 |
| 60 // Callback that posts back to the UI thread. | 61 // Callback that posts back to the UI thread. |
| 61 ModelTypeChangeProcessor::StartCallback callback = BindToCurrentThread( | 62 syncer_v2::ModelTypeChangeProcessor::StartCallback callback = |
| 62 base::Bind(&NonBlockingDataTypeController::OnProcessorStarted, | 63 syncer::BindToCurrentThread( |
| 63 base::AsWeakPtr(this))); | 64 base::Bind(&NonBlockingDataTypeController::OnProcessorStarted, |
| 65 base::AsWeakPtr(this))); |
| 64 | 66 |
| 65 // Start the type processor on the model thread. | 67 // Start the type processor on the model thread. |
| 66 if (!RunOnModelThread( | 68 if (!RunOnModelThread( |
| 67 FROM_HERE, | 69 FROM_HERE, |
| 68 base::Bind(&ModelTypeService::OnSyncStarting, | 70 base::Bind(&syncer_v2::ModelTypeService::OnSyncStarting, |
| 69 sync_client_->GetModelTypeServiceForType(type()), | 71 sync_client_->GetModelTypeServiceForType(type()), |
| 70 base::Passed(CreateErrorHandler()), callback))) { | 72 base::Passed(CreateErrorHandler()), callback))) { |
| 71 LoadModelsDone(UNRECOVERABLE_ERROR, | 73 LoadModelsDone( |
| 72 SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, | 74 UNRECOVERABLE_ERROR, |
| 73 "Failed to post model Start", type())); | 75 syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 76 "Failed to post model Start", type())); |
| 74 } | 77 } |
| 75 } | 78 } |
| 76 | 79 |
| 77 void NonBlockingDataTypeController::GetAllNodes( | 80 void NonBlockingDataTypeController::GetAllNodes( |
| 78 const AllNodesCallback& callback) { | 81 const AllNodesCallback& callback) { |
| 79 base::WeakPtr<ModelTypeService> service = | 82 base::WeakPtr<syncer_v2::ModelTypeService> service = |
| 80 sync_client_->GetModelTypeServiceForType(type()); | 83 sync_client_->GetModelTypeServiceForType(type()); |
| 81 // TODO(gangwu): Casting should happen "near" where the processor factory has | 84 // TODO(gangwu): Casting should happen "near" where the processor factory has |
| 82 // code that instantiates a new processor. | 85 // code that instantiates a new processor. |
| 83 SharedModelTypeProcessor* processor = | 86 syncer_v2::SharedModelTypeProcessor* processor = |
| 84 (SharedModelTypeProcessor*)service->change_processor(); | 87 (syncer_v2::SharedModelTypeProcessor*)service->change_processor(); |
| 85 RunOnModelThread(FROM_HERE, | 88 RunOnModelThread(FROM_HERE, |
| 86 base::Bind(&SharedModelTypeProcessor::GetAllNodes, | 89 base::Bind(&syncer_v2::SharedModelTypeProcessor::GetAllNodes, |
| 87 base::Unretained(processor), | 90 base::Unretained(processor), |
| 88 base::ThreadTaskRunnerHandle::Get(), callback)); | 91 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 89 } | 92 } |
| 90 | 93 |
| 91 void NonBlockingDataTypeController::LoadModelsDone(ConfigureResult result, | 94 void NonBlockingDataTypeController::LoadModelsDone( |
| 92 const SyncError& error) { | 95 ConfigureResult result, |
| 96 const syncer::SyncError& error) { |
| 93 DCHECK(CalledOnValidThread()); | 97 DCHECK(CalledOnValidThread()); |
| 94 | 98 |
| 95 if (state_ == NOT_RUNNING) { | 99 if (state_ == NOT_RUNNING) { |
| 96 // The callback arrived on the UI thread after the type has been already | 100 // The callback arrived on the UI thread after the type has been already |
| 97 // stopped. | 101 // stopped. |
| 98 RecordStartFailure(ABORTED); | 102 RecordStartFailure(ABORTED); |
| 99 return; | 103 return; |
| 100 } | 104 } |
| 101 | 105 |
| 102 if (IsSuccessfulResult(result)) { | 106 if (IsSuccessfulResult(result)) { |
| 103 DCHECK_EQ(MODEL_STARTING, state_); | 107 DCHECK_EQ(MODEL_STARTING, state_); |
| 104 state_ = MODEL_LOADED; | 108 state_ = MODEL_LOADED; |
| 105 } else { | 109 } else { |
| 106 RecordStartFailure(result); | 110 RecordStartFailure(result); |
| 107 } | 111 } |
| 108 | 112 |
| 109 if (!model_load_callback_.is_null()) { | 113 if (!model_load_callback_.is_null()) { |
| 110 model_load_callback_.Run(type(), error); | 114 model_load_callback_.Run(type(), error); |
| 111 } | 115 } |
| 112 } | 116 } |
| 113 | 117 |
| 114 void NonBlockingDataTypeController::OnProcessorStarted( | 118 void NonBlockingDataTypeController::OnProcessorStarted( |
| 115 SyncError error, | 119 syncer::SyncError error, |
| 116 std::unique_ptr<ActivationContext> activation_context) { | 120 std::unique_ptr<syncer_v2::ActivationContext> activation_context) { |
| 117 DCHECK(CalledOnValidThread()); | 121 DCHECK(CalledOnValidThread()); |
| 118 // Hold on to the activation context until ActivateDataType is called. | 122 // Hold on to the activation context until ActivateDataType is called. |
| 119 if (state_ == MODEL_STARTING) { | 123 if (state_ == MODEL_STARTING) { |
| 120 activation_context_ = std::move(activation_context); | 124 activation_context_ = std::move(activation_context); |
| 121 } | 125 } |
| 122 // TODO(stanisc): Figure out if UNRECOVERABLE_ERROR is OK in this case. | 126 // TODO(stanisc): Figure out if UNRECOVERABLE_ERROR is OK in this case. |
| 123 ConfigureResult result = error.IsSet() ? UNRECOVERABLE_ERROR : OK; | 127 ConfigureResult result = error.IsSet() ? UNRECOVERABLE_ERROR : OK; |
| 124 LoadModelsDone(result, error); | 128 LoadModelsDone(result, error); |
| 125 } | 129 } |
| 126 | 130 |
| 127 void NonBlockingDataTypeController::RegisterWithBackend( | 131 void NonBlockingDataTypeController::RegisterWithBackend( |
| 128 BackendDataTypeConfigurer* configurer) { | 132 sync_driver::BackendDataTypeConfigurer* configurer) { |
| 129 DCHECK(CalledOnValidThread()); | 133 DCHECK(CalledOnValidThread()); |
| 130 if (activated_) | 134 if (activated_) |
| 131 return; | 135 return; |
| 132 DCHECK(configurer); | 136 DCHECK(configurer); |
| 133 DCHECK(activation_context_); | 137 DCHECK(activation_context_); |
| 134 DCHECK_EQ(MODEL_LOADED, state_); | 138 DCHECK_EQ(MODEL_LOADED, state_); |
| 135 configurer->ActivateNonBlockingDataType(type(), | 139 configurer->ActivateNonBlockingDataType(type(), |
| 136 std::move(activation_context_)); | 140 std::move(activation_context_)); |
| 137 activated_ = true; | 141 activated_ = true; |
| 138 } | 142 } |
| 139 | 143 |
| 140 void NonBlockingDataTypeController::StartAssociating( | 144 void NonBlockingDataTypeController::StartAssociating( |
| 141 const StartCallback& start_callback) { | 145 const StartCallback& start_callback) { |
| 142 DCHECK(CalledOnValidThread()); | 146 DCHECK(CalledOnValidThread()); |
| 143 DCHECK(!start_callback.is_null()); | 147 DCHECK(!start_callback.is_null()); |
| 144 | 148 |
| 145 state_ = RUNNING; | 149 state_ = RUNNING; |
| 146 | 150 |
| 147 // There is no association, just call back promptly. | 151 // There is no association, just call back promptly. |
| 148 SyncMergeResult merge_result(type()); | 152 syncer::SyncMergeResult merge_result(type()); |
| 149 start_callback.Run(OK, merge_result, merge_result); | 153 start_callback.Run(OK, merge_result, merge_result); |
| 150 } | 154 } |
| 151 | 155 |
| 152 void NonBlockingDataTypeController::ActivateDataType( | 156 void NonBlockingDataTypeController::ActivateDataType( |
| 153 BackendDataTypeConfigurer* configurer) { | 157 sync_driver::BackendDataTypeConfigurer* configurer) { |
| 154 DCHECK(CalledOnValidThread()); | 158 DCHECK(CalledOnValidThread()); |
| 155 DCHECK(configurer); | 159 DCHECK(configurer); |
| 156 DCHECK_EQ(RUNNING, state_); | 160 DCHECK_EQ(RUNNING, state_); |
| 157 // In contrast with directory datatypes, non-blocking data types should be | 161 // In contrast with directory datatypes, non-blocking data types should be |
| 158 // activated in RegisterWithBackend. activation_context_ should be passed | 162 // activated in RegisterWithBackend. activation_context_ should be passed |
| 159 // to backend before call to ActivateDataType. | 163 // to backend before call to ActivateDataType. |
| 160 DCHECK(!activation_context_); | 164 DCHECK(!activation_context_); |
| 161 } | 165 } |
| 162 | 166 |
| 163 void NonBlockingDataTypeController::DeactivateDataType( | 167 void NonBlockingDataTypeController::DeactivateDataType( |
| 164 BackendDataTypeConfigurer* configurer) { | 168 sync_driver::BackendDataTypeConfigurer* configurer) { |
| 165 DCHECK(CalledOnValidThread()); | 169 DCHECK(CalledOnValidThread()); |
| 166 DCHECK(configurer); | 170 DCHECK(configurer); |
| 167 DCHECK(activated_); | 171 DCHECK(activated_); |
| 168 configurer->DeactivateNonBlockingDataType(type()); | 172 configurer->DeactivateNonBlockingDataType(type()); |
| 169 activated_ = false; | 173 activated_ = false; |
| 170 } | 174 } |
| 171 | 175 |
| 172 void NonBlockingDataTypeController::Stop() { | 176 void NonBlockingDataTypeController::Stop() { |
| 173 DCHECK(CalledOnValidThread()); | 177 DCHECK(CalledOnValidThread()); |
| 174 | 178 |
| 175 if (state() == NOT_RUNNING) | 179 if (state() == NOT_RUNNING) |
| 176 return; | 180 return; |
| 177 | 181 |
| 178 // Check preferences if datatype is not in preferred datatypes. Only call | 182 // Check preferences if datatype is not in preferred datatypes. Only call |
| 179 // DisableSync if service is ready to handle it (controller is in loaded | 183 // DisableSync if service is ready to handle it (controller is in loaded |
| 180 // state). | 184 // state). |
| 181 ModelTypeSet preferred_types = | 185 syncer::ModelTypeSet preferred_types = |
| 182 sync_prefs_.GetPreferredDataTypes(ModelTypeSet(type())); | 186 sync_prefs_.GetPreferredDataTypes(syncer::ModelTypeSet(type())); |
| 183 if ((state() == MODEL_LOADED || state() == RUNNING) && | 187 if ((state() == MODEL_LOADED || state() == RUNNING) && |
| 184 (!sync_prefs_.IsFirstSetupComplete() || !preferred_types.Has(type()))) { | 188 (!sync_prefs_.IsFirstSetupComplete() || !preferred_types.Has(type()))) { |
| 185 RunOnModelThread( | 189 RunOnModelThread( |
| 186 FROM_HERE, | 190 FROM_HERE, |
| 187 base::Bind(&ModelTypeService::DisableSync, | 191 base::Bind(&syncer_v2::ModelTypeService::DisableSync, |
| 188 sync_client_->GetModelTypeServiceForType(type()))); | 192 sync_client_->GetModelTypeServiceForType(type()))); |
| 189 } | 193 } |
| 190 | 194 |
| 191 state_ = NOT_RUNNING; | 195 state_ = NOT_RUNNING; |
| 192 } | 196 } |
| 193 | 197 |
| 194 std::string NonBlockingDataTypeController::name() const { | 198 std::string NonBlockingDataTypeController::name() const { |
| 195 // For logging only. | 199 // For logging only. |
| 196 return ModelTypeToString(type()); | 200 return syncer::ModelTypeToString(type()); |
| 197 } | 201 } |
| 198 | 202 |
| 199 DataTypeController::State NonBlockingDataTypeController::state() const { | 203 sync_driver::DataTypeController::State NonBlockingDataTypeController::state() |
| 204 const { |
| 200 return state_; | 205 return state_; |
| 201 } | 206 } |
| 202 | 207 |
| 203 std::unique_ptr<DataTypeErrorHandler> | 208 std::unique_ptr<syncer::DataTypeErrorHandler> |
| 204 NonBlockingDataTypeController::CreateErrorHandler() { | 209 NonBlockingDataTypeController::CreateErrorHandler() { |
| 205 DCHECK(CalledOnValidThread()); | 210 DCHECK(CalledOnValidThread()); |
| 206 return base::MakeUnique<DataTypeErrorHandlerImpl>( | 211 return base::MakeUnique<syncer::DataTypeErrorHandlerImpl>( |
| 207 base::ThreadTaskRunnerHandle::Get(), dump_stack_, | 212 base::ThreadTaskRunnerHandle::Get(), dump_stack_, |
| 208 base::Bind(&NonBlockingDataTypeController::ReportLoadModelError, | 213 base::Bind(&NonBlockingDataTypeController::ReportLoadModelError, |
| 209 base::AsWeakPtr(this))); | 214 base::AsWeakPtr(this))); |
| 210 } | 215 } |
| 211 | 216 |
| 212 void NonBlockingDataTypeController::ReportLoadModelError( | 217 void NonBlockingDataTypeController::ReportLoadModelError( |
| 213 const SyncError& error) { | 218 const syncer::SyncError& error) { |
| 214 DCHECK(CalledOnValidThread()); | 219 DCHECK(CalledOnValidThread()); |
| 215 LoadModelsDone(UNRECOVERABLE_ERROR, error); | 220 LoadModelsDone(UNRECOVERABLE_ERROR, error); |
| 216 } | 221 } |
| 217 | 222 |
| 218 void NonBlockingDataTypeController::RecordStartFailure( | 223 void NonBlockingDataTypeController::RecordStartFailure( |
| 219 ConfigureResult result) const { | 224 ConfigureResult result) const { |
| 220 DCHECK(CalledOnValidThread()); | 225 DCHECK(CalledOnValidThread()); |
| 221 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", | 226 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", |
| 222 ModelTypeToHistogramInt(type()), MODEL_TYPE_COUNT); | 227 ModelTypeToHistogramInt(type()), |
| 228 syncer::MODEL_TYPE_COUNT); |
| 223 #define PER_DATA_TYPE_MACRO(type_str) \ | 229 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 224 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ | 230 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ |
| 225 MAX_CONFIGURE_RESULT); | 231 MAX_CONFIGURE_RESULT); |
| 226 SYNC_DATA_TYPE_HISTOGRAM(type()); | 232 SYNC_DATA_TYPE_HISTOGRAM(type()); |
| 227 #undef PER_DATA_TYPE_MACRO | 233 #undef PER_DATA_TYPE_MACRO |
| 228 } | 234 } |
| 229 | 235 |
| 230 } // namespace syncer | 236 } // namespace sync_driver_v2 |
| OLD | NEW |