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_ui_data_type_controller.h" | 5 #include "components/sync/driver/non_ui_data_type_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/threading/thread_task_runner_handle.h" | 8 #include "base/threading/thread_task_runner_handle.h" |
9 #include "components/sync/api/data_type_error_handler_impl.h" | 9 #include "components/sync/api/data_type_error_handler_impl.h" |
10 #include "components/sync/api/sync_error.h" | 10 #include "components/sync/api/sync_error.h" |
11 #include "components/sync/api/sync_merge_result.h" | 11 #include "components/sync/api/sync_merge_result.h" |
12 #include "components/sync/api/syncable_service.h" | 12 #include "components/sync/api/syncable_service.h" |
13 #include "components/sync/base/bind_to_task_runner.h" | 13 #include "components/sync/base/bind_to_task_runner.h" |
14 #include "components/sync/base/data_type_histogram.h" | 14 #include "components/sync/base/data_type_histogram.h" |
15 #include "components/sync/base/model_type.h" | 15 #include "components/sync/base/model_type.h" |
16 #include "components/sync/driver/generic_change_processor_factory.h" | 16 #include "components/sync/driver/generic_change_processor_factory.h" |
17 #include "components/sync/driver/sync_api_component_factory.h" | 17 #include "components/sync/driver/sync_api_component_factory.h" |
18 #include "components/sync/driver/sync_client.h" | 18 #include "components/sync/driver/sync_client.h" |
19 #include "components/sync/driver/sync_service.h" | 19 #include "components/sync/driver/sync_service.h" |
20 | 20 |
21 namespace sync_driver { | 21 namespace syncer { |
22 | 22 |
23 SharedChangeProcessor* NonUIDataTypeController::CreateSharedChangeProcessor() { | 23 SharedChangeProcessor* NonUIDataTypeController::CreateSharedChangeProcessor() { |
24 return new SharedChangeProcessor(type()); | 24 return new SharedChangeProcessor(type()); |
25 } | 25 } |
26 | 26 |
27 NonUIDataTypeController::NonUIDataTypeController( | 27 NonUIDataTypeController::NonUIDataTypeController( |
28 syncer::ModelType type, | 28 ModelType type, |
29 const base::Closure& dump_stack, | 29 const base::Closure& dump_stack, |
30 SyncClient* sync_client) | 30 SyncClient* sync_client) |
31 : DirectoryDataTypeController(type, dump_stack, sync_client), | 31 : DirectoryDataTypeController(type, dump_stack, sync_client), |
32 state_(NOT_RUNNING) {} | 32 state_(NOT_RUNNING) {} |
33 | 33 |
34 void NonUIDataTypeController::LoadModels( | 34 void NonUIDataTypeController::LoadModels( |
35 const ModelLoadCallback& model_load_callback) { | 35 const ModelLoadCallback& model_load_callback) { |
36 DCHECK(CalledOnValidThread()); | 36 DCHECK(CalledOnValidThread()); |
37 model_load_callback_ = model_load_callback; | 37 model_load_callback_ = model_load_callback; |
38 if (state() != NOT_RUNNING) { | 38 if (state() != NOT_RUNNING) { |
39 model_load_callback.Run( | 39 model_load_callback.Run(type(), |
40 type(), syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 40 SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, |
41 "Model already running", type())); | 41 "Model already running", type())); |
42 return; | 42 return; |
43 } | 43 } |
44 | 44 |
45 state_ = MODEL_STARTING; | 45 state_ = MODEL_STARTING; |
46 // Since we can't be called multiple times before Stop() is called, | 46 // Since we can't be called multiple times before Stop() is called, |
47 // |shared_change_processor_| must be NULL here. | 47 // |shared_change_processor_| must be NULL here. |
48 DCHECK(!shared_change_processor_.get()); | 48 DCHECK(!shared_change_processor_.get()); |
49 shared_change_processor_ = CreateSharedChangeProcessor(); | 49 shared_change_processor_ = CreateSharedChangeProcessor(); |
50 DCHECK(shared_change_processor_.get()); | 50 DCHECK(shared_change_processor_.get()); |
51 if (!StartModels()) { | 51 if (!StartModels()) { |
52 // If we are waiting for some external service to load before associating | 52 // If we are waiting for some external service to load before associating |
53 // or we failed to start the models, we exit early. | 53 // or we failed to start the models, we exit early. |
54 DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING); | 54 DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING); |
55 return; | 55 return; |
56 } | 56 } |
57 | 57 |
58 OnModelLoaded(); | 58 OnModelLoaded(); |
59 } | 59 } |
60 | 60 |
61 void NonUIDataTypeController::OnModelLoaded() { | 61 void NonUIDataTypeController::OnModelLoaded() { |
62 DCHECK(CalledOnValidThread()); | 62 DCHECK(CalledOnValidThread()); |
63 DCHECK_EQ(state_, MODEL_STARTING); | 63 DCHECK_EQ(state_, MODEL_STARTING); |
64 state_ = MODEL_LOADED; | 64 state_ = MODEL_LOADED; |
65 model_load_callback_.Run(type(), syncer::SyncError()); | 65 model_load_callback_.Run(type(), SyncError()); |
66 } | 66 } |
67 | 67 |
68 bool NonUIDataTypeController::StartModels() { | 68 bool NonUIDataTypeController::StartModels() { |
69 DCHECK(CalledOnValidThread()); | 69 DCHECK(CalledOnValidThread()); |
70 DCHECK_EQ(state_, MODEL_STARTING); | 70 DCHECK_EQ(state_, MODEL_STARTING); |
71 // By default, no additional services need to be started before we can proceed | 71 // By default, no additional services need to be started before we can proceed |
72 // with model association. | 72 // with model association. |
73 return true; | 73 return true; |
74 } | 74 } |
75 | 75 |
76 void NonUIDataTypeController::StopModels() { | 76 void NonUIDataTypeController::StopModels() { |
77 DCHECK(CalledOnValidThread()); | 77 DCHECK(CalledOnValidThread()); |
78 } | 78 } |
79 | 79 |
80 void NonUIDataTypeController::StartAssociating( | 80 void NonUIDataTypeController::StartAssociating( |
81 const StartCallback& start_callback) { | 81 const StartCallback& start_callback) { |
82 DCHECK(CalledOnValidThread()); | 82 DCHECK(CalledOnValidThread()); |
83 DCHECK(!start_callback.is_null()); | 83 DCHECK(!start_callback.is_null()); |
84 DCHECK_EQ(state_, MODEL_LOADED); | 84 DCHECK_EQ(state_, MODEL_LOADED); |
85 state_ = ASSOCIATING; | 85 state_ = ASSOCIATING; |
86 | 86 |
87 // Store UserShare now while on UI thread to avoid potential race | 87 // Store UserShare now while on UI thread to avoid potential race |
88 // condition in StartAssociationWithSharedChangeProcessor. | 88 // condition in StartAssociationWithSharedChangeProcessor. |
89 DCHECK(sync_client_->GetSyncService()); | 89 DCHECK(sync_client_->GetSyncService()); |
90 user_share_ = sync_client_->GetSyncService()->GetUserShare(); | 90 user_share_ = sync_client_->GetSyncService()->GetUserShare(); |
91 | 91 |
92 start_callback_ = start_callback; | 92 start_callback_ = start_callback; |
93 if (!StartAssociationAsync()) { | 93 if (!StartAssociationAsync()) { |
94 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 94 SyncError error(FROM_HERE, SyncError::DATATYPE_ERROR, |
95 "Failed to post StartAssociation", type()); | 95 "Failed to post StartAssociation", type()); |
96 syncer::SyncMergeResult local_merge_result(type()); | 96 SyncMergeResult local_merge_result(type()); |
97 local_merge_result.set_error(error); | 97 local_merge_result.set_error(error); |
98 StartDone(ASSOCIATION_FAILED, local_merge_result, | 98 StartDone(ASSOCIATION_FAILED, local_merge_result, SyncMergeResult(type())); |
99 syncer::SyncMergeResult(type())); | |
100 // StartDone should have cleared the SharedChangeProcessor. | 99 // StartDone should have cleared the SharedChangeProcessor. |
101 DCHECK(!shared_change_processor_.get()); | 100 DCHECK(!shared_change_processor_.get()); |
102 return; | 101 return; |
103 } | 102 } |
104 } | 103 } |
105 | 104 |
106 void NonUIDataTypeController::Stop() { | 105 void NonUIDataTypeController::Stop() { |
107 DCHECK(CalledOnValidThread()); | 106 DCHECK(CalledOnValidThread()); |
108 | 107 |
109 if (state() == NOT_RUNNING) | 108 if (state() == NOT_RUNNING) |
110 return; | 109 return; |
111 | 110 |
112 // Disconnect the change processor. At this point, the | 111 // Disconnect the change processor. At this point, the |
113 // syncer::SyncableService can no longer interact with the Syncer, even if | 112 // SyncableService can no longer interact with the Syncer, even if |
114 // it hasn't finished MergeDataAndStartSyncing. | 113 // it hasn't finished MergeDataAndStartSyncing. |
115 DisconnectSharedChangeProcessor(); | 114 DisconnectSharedChangeProcessor(); |
116 | 115 |
117 // If we haven't finished starting, we need to abort the start. | 116 // If we haven't finished starting, we need to abort the start. |
118 bool service_started = state() == ASSOCIATING || state() == RUNNING; | 117 bool service_started = state() == ASSOCIATING || state() == RUNNING; |
119 state_ = service_started ? STOPPING : NOT_RUNNING; | 118 state_ = service_started ? STOPPING : NOT_RUNNING; |
120 StopModels(); | 119 StopModels(); |
121 | 120 |
122 if (service_started) | 121 if (service_started) |
123 StopSyncableService(); | 122 StopSyncableService(); |
124 | 123 |
125 shared_change_processor_ = nullptr; | 124 shared_change_processor_ = nullptr; |
126 state_ = NOT_RUNNING; | 125 state_ = NOT_RUNNING; |
127 } | 126 } |
128 | 127 |
129 std::string NonUIDataTypeController::name() const { | 128 std::string NonUIDataTypeController::name() const { |
130 // For logging only. | 129 // For logging only. |
131 return syncer::ModelTypeToString(type()); | 130 return ModelTypeToString(type()); |
132 } | 131 } |
133 | 132 |
134 DataTypeController::State NonUIDataTypeController::state() const { | 133 DataTypeController::State NonUIDataTypeController::state() const { |
135 return state_; | 134 return state_; |
136 } | 135 } |
137 | 136 |
138 NonUIDataTypeController::NonUIDataTypeController() | 137 NonUIDataTypeController::NonUIDataTypeController() |
139 : DirectoryDataTypeController(syncer::UNSPECIFIED, | 138 : DirectoryDataTypeController(UNSPECIFIED, base::Closure(), nullptr) {} |
140 base::Closure(), | |
141 nullptr) {} | |
142 | 139 |
143 NonUIDataTypeController::~NonUIDataTypeController() {} | 140 NonUIDataTypeController::~NonUIDataTypeController() {} |
144 | 141 |
145 void NonUIDataTypeController::StartDone( | 142 void NonUIDataTypeController::StartDone( |
146 DataTypeController::ConfigureResult start_result, | 143 DataTypeController::ConfigureResult start_result, |
147 const syncer::SyncMergeResult& local_merge_result, | 144 const SyncMergeResult& local_merge_result, |
148 const syncer::SyncMergeResult& syncer_merge_result) { | 145 const SyncMergeResult& syncer_merge_result) { |
149 DCHECK(CalledOnValidThread()); | 146 DCHECK(CalledOnValidThread()); |
150 | 147 |
151 DataTypeController::State new_state; | 148 DataTypeController::State new_state; |
152 if (IsSuccessfulResult(start_result)) { | 149 if (IsSuccessfulResult(start_result)) { |
153 new_state = RUNNING; | 150 new_state = RUNNING; |
154 } else { | 151 } else { |
155 new_state = (start_result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING); | 152 new_state = (start_result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING); |
156 } | 153 } |
157 | 154 |
158 // If we failed to start up, and we haven't been stopped yet, we need to | 155 // If we failed to start up, and we haven't been stopped yet, we need to |
(...skipping 17 matching lines...) Expand all Loading... |
176 StopModels(); | 173 StopModels(); |
177 RecordStartFailure(start_result); | 174 RecordStartFailure(start_result); |
178 } | 175 } |
179 | 176 |
180 start_callback_.Run(start_result, local_merge_result, syncer_merge_result); | 177 start_callback_.Run(start_result, local_merge_result, syncer_merge_result); |
181 } | 178 } |
182 | 179 |
183 void NonUIDataTypeController::RecordStartFailure(ConfigureResult result) { | 180 void NonUIDataTypeController::RecordStartFailure(ConfigureResult result) { |
184 DCHECK(CalledOnValidThread()); | 181 DCHECK(CalledOnValidThread()); |
185 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", | 182 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", |
186 ModelTypeToHistogramInt(type()), | 183 ModelTypeToHistogramInt(type()), MODEL_TYPE_COUNT); |
187 syncer::MODEL_TYPE_COUNT); | |
188 #define PER_DATA_TYPE_MACRO(type_str) \ | 184 #define PER_DATA_TYPE_MACRO(type_str) \ |
189 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ | 185 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ |
190 MAX_CONFIGURE_RESULT); | 186 MAX_CONFIGURE_RESULT); |
191 SYNC_DATA_TYPE_HISTOGRAM(type()); | 187 SYNC_DATA_TYPE_HISTOGRAM(type()); |
192 #undef PER_DATA_TYPE_MACRO | 188 #undef PER_DATA_TYPE_MACRO |
193 } | 189 } |
194 | 190 |
195 void NonUIDataTypeController::DisableImpl(const syncer::SyncError& error) { | 191 void NonUIDataTypeController::DisableImpl(const SyncError& error) { |
196 DCHECK(CalledOnValidThread()); | 192 DCHECK(CalledOnValidThread()); |
197 if (!model_load_callback_.is_null()) { | 193 if (!model_load_callback_.is_null()) { |
198 model_load_callback_.Run(type(), error); | 194 model_load_callback_.Run(type(), error); |
199 } | 195 } |
200 } | 196 } |
201 | 197 |
202 bool NonUIDataTypeController::StartAssociationAsync() { | 198 bool NonUIDataTypeController::StartAssociationAsync() { |
203 DCHECK(CalledOnValidThread()); | 199 DCHECK(CalledOnValidThread()); |
204 DCHECK_EQ(state(), ASSOCIATING); | 200 DCHECK_EQ(state(), ASSOCIATING); |
205 return PostTaskOnBackendThread( | 201 return PostTaskOnBackendThread( |
206 FROM_HERE, | 202 FROM_HERE, |
207 base::Bind( | 203 base::Bind( |
208 &SharedChangeProcessor::StartAssociation, shared_change_processor_, | 204 &SharedChangeProcessor::StartAssociation, shared_change_processor_, |
209 syncer::BindToCurrentThread(base::Bind( | 205 BindToCurrentThread(base::Bind(&NonUIDataTypeController::StartDone, |
210 &NonUIDataTypeController::StartDone, base::AsWeakPtr(this))), | 206 base::AsWeakPtr(this))), |
211 sync_client_, user_share_, base::Passed(CreateErrorHandler()))); | 207 sync_client_, user_share_, base::Passed(CreateErrorHandler()))); |
212 } | 208 } |
213 | 209 |
214 ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const { | 210 ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const { |
215 DCHECK(CalledOnValidThread()); | 211 DCHECK(CalledOnValidThread()); |
216 DCHECK_EQ(state_, RUNNING); | 212 DCHECK_EQ(state_, RUNNING); |
217 return shared_change_processor_->generic_change_processor(); | 213 return shared_change_processor_->generic_change_processor(); |
218 } | 214 } |
219 | 215 |
220 void NonUIDataTypeController::DisconnectSharedChangeProcessor() { | 216 void NonUIDataTypeController::DisconnectSharedChangeProcessor() { |
221 DCHECK(CalledOnValidThread()); | 217 DCHECK(CalledOnValidThread()); |
222 // |shared_change_processor_| can already be NULL if Stop() is | 218 // |shared_change_processor_| can already be NULL if Stop() is |
223 // called after StartDone(_, DISABLED, _). | 219 // called after StartDone(_, DISABLED, _). |
224 if (shared_change_processor_.get()) { | 220 if (shared_change_processor_.get()) { |
225 shared_change_processor_->Disconnect(); | 221 shared_change_processor_->Disconnect(); |
226 } | 222 } |
227 } | 223 } |
228 | 224 |
229 void NonUIDataTypeController::StopSyncableService() { | 225 void NonUIDataTypeController::StopSyncableService() { |
230 DCHECK(CalledOnValidThread()); | 226 DCHECK(CalledOnValidThread()); |
231 if (shared_change_processor_.get()) { | 227 if (shared_change_processor_.get()) { |
232 PostTaskOnBackendThread(FROM_HERE, | 228 PostTaskOnBackendThread(FROM_HERE, |
233 base::Bind(&SharedChangeProcessor::StopLocalService, | 229 base::Bind(&SharedChangeProcessor::StopLocalService, |
234 shared_change_processor_)); | 230 shared_change_processor_)); |
235 } | 231 } |
236 } | 232 } |
237 | 233 |
238 std::unique_ptr<syncer::DataTypeErrorHandler> | 234 std::unique_ptr<DataTypeErrorHandler> |
239 NonUIDataTypeController::CreateErrorHandler() { | 235 NonUIDataTypeController::CreateErrorHandler() { |
240 DCHECK(CalledOnValidThread()); | 236 DCHECK(CalledOnValidThread()); |
241 return base::MakeUnique<syncer::DataTypeErrorHandlerImpl>( | 237 return base::MakeUnique<DataTypeErrorHandlerImpl>( |
242 base::ThreadTaskRunnerHandle::Get(), dump_stack_, | 238 base::ThreadTaskRunnerHandle::Get(), dump_stack_, |
243 base::Bind(&NonUIDataTypeController::DisableImpl, base::AsWeakPtr(this))); | 239 base::Bind(&NonUIDataTypeController::DisableImpl, base::AsWeakPtr(this))); |
244 } | 240 } |
245 | 241 |
246 } // namespace sync_driver | 242 } // namespace syncer |
OLD | NEW |