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 |