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 "chrome/browser/sync/glue/new_non_frontend_data_type_controller.h" | 5 #include "chrome/browser/sync/glue/new_non_frontend_data_type_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "chrome/browser/sync/glue/shared_change_processor_ref.h" | 8 #include "chrome/browser/sync/glue/shared_change_processor_ref.h" |
9 #include "chrome/browser/sync/profile_sync_components_factory.h" | 9 #include "chrome/browser/sync/profile_sync_components_factory.h" |
10 #include "chrome/browser/sync/profile_sync_service.h" | 10 #include "chrome/browser/sync/profile_sync_service.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 ProfileSyncService* sync_service) | 23 ProfileSyncService* sync_service) |
24 : NonFrontendDataTypeController(profile_sync_factory, | 24 : NonFrontendDataTypeController(profile_sync_factory, |
25 profile, | 25 profile, |
26 sync_service) {} | 26 sync_service) {} |
27 | 27 |
28 void NewNonFrontendDataTypeController::LoadModels( | 28 void NewNonFrontendDataTypeController::LoadModels( |
29 const ModelLoadCallback& model_load_callback) { | 29 const ModelLoadCallback& model_load_callback) { |
30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
31 DCHECK(!model_load_callback.is_null()); | 31 DCHECK(!model_load_callback.is_null()); |
32 if (state() != NOT_RUNNING) { | 32 if (state() != NOT_RUNNING) { |
33 model_load_callback.Run(type(), SyncError(FROM_HERE, | 33 model_load_callback.Run(type(), csync::SyncError(FROM_HERE, |
34 "Model already running", | 34 "Model already running", |
35 type())); | 35 type())); |
36 return; | 36 return; |
37 } | 37 } |
38 | 38 |
39 set_state(MODEL_STARTING); | 39 set_state(MODEL_STARTING); |
40 | 40 |
41 // Since we can't be called multiple times before Stop() is called, | 41 // Since we can't be called multiple times before Stop() is called, |
42 // |shared_change_processor_| must be NULL here. | 42 // |shared_change_processor_| must be NULL here. |
43 DCHECK(!shared_change_processor_.get()); | 43 DCHECK(!shared_change_processor_.get()); |
(...skipping 12 matching lines...) Expand all Loading... |
56 OnModelLoaded(); | 56 OnModelLoaded(); |
57 } | 57 } |
58 | 58 |
59 void NewNonFrontendDataTypeController::OnModelLoaded() { | 59 void NewNonFrontendDataTypeController::OnModelLoaded() { |
60 DCHECK_EQ(state_, MODEL_STARTING); | 60 DCHECK_EQ(state_, MODEL_STARTING); |
61 DCHECK(!model_load_callback_.is_null()); | 61 DCHECK(!model_load_callback_.is_null()); |
62 set_state(MODEL_LOADED); | 62 set_state(MODEL_LOADED); |
63 | 63 |
64 ModelLoadCallback model_load_callback = model_load_callback_; | 64 ModelLoadCallback model_load_callback = model_load_callback_; |
65 model_load_callback_.Reset(); | 65 model_load_callback_.Reset(); |
66 model_load_callback.Run(type(), SyncError()); | 66 model_load_callback.Run(type(), csync::SyncError()); |
67 } | 67 } |
68 | 68 |
69 void NewNonFrontendDataTypeController::StartAssociating( | 69 void NewNonFrontendDataTypeController::StartAssociating( |
70 const StartCallback& start_callback) { | 70 const StartCallback& start_callback) { |
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
72 DCHECK(!start_callback.is_null()); | 72 DCHECK(!start_callback.is_null()); |
73 DCHECK_EQ(state_, MODEL_LOADED); | 73 DCHECK_EQ(state_, MODEL_LOADED); |
74 set_state(ASSOCIATING); | 74 set_state(ASSOCIATING); |
75 | 75 |
76 set_start_callback(start_callback); | 76 set_start_callback(start_callback); |
77 if (!StartAssociationAsync()) { | 77 if (!StartAssociationAsync()) { |
78 SyncError error(FROM_HERE, "Failed to post StartAssociation", type()); | 78 csync::SyncError error( |
| 79 FROM_HERE, "Failed to post StartAssociation", type()); |
79 StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, error); | 80 StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, error); |
80 // StartDoneImpl should have called ClearSharedChangeProcessor(); | 81 // StartDoneImpl should have called ClearSharedChangeProcessor(); |
81 DCHECK(!shared_change_processor_.get()); | 82 DCHECK(!shared_change_processor_.get()); |
82 return; | 83 return; |
83 } | 84 } |
84 } | 85 } |
85 | 86 |
86 void NewNonFrontendDataTypeController::Stop() { | 87 void NewNonFrontendDataTypeController::Stop() { |
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
88 if (state() == NOT_RUNNING) { | 89 if (state() == NOT_RUNNING) { |
89 // Stop() should never be called for datatypes that are already stopped. | 90 // Stop() should never be called for datatypes that are already stopped. |
90 NOTREACHED(); | 91 NOTREACHED(); |
91 return; | 92 return; |
92 } | 93 } |
93 | 94 |
94 // Disconnect the change processor. At this point, the | 95 // Disconnect the change processor. At this point, the |
95 // SyncableService can no longer interact with the Syncer, even if | 96 // csync::SyncableService can no longer interact with the Syncer, even if |
96 // it hasn't finished MergeDataAndStartSyncing. | 97 // it hasn't finished MergeDataAndStartSyncing. |
97 ClearSharedChangeProcessor(); | 98 ClearSharedChangeProcessor(); |
98 | 99 |
99 // If we haven't finished starting, we need to abort the start. | 100 // If we haven't finished starting, we need to abort the start. |
100 switch (state()) { | 101 switch (state()) { |
101 case MODEL_STARTING: | 102 case MODEL_STARTING: |
102 set_state(STOPPING); | 103 set_state(STOPPING); |
103 AbortModelStarting(); | 104 AbortModelStarting(); |
104 return; // The datatype was never activated, we're done. | 105 return; // The datatype was never activated, we're done. |
105 case ASSOCIATING: | 106 case ASSOCIATING: |
106 set_state(STOPPING); | 107 set_state(STOPPING); |
107 StartDoneImpl(ABORTED, NOT_RUNNING, SyncError()); | 108 StartDoneImpl(ABORTED, NOT_RUNNING, csync::SyncError()); |
108 // We continue on to deactivate the datatype and stop the local service. | 109 // We continue on to deactivate the datatype and stop the local service. |
109 break; | 110 break; |
110 case DISABLED: | 111 case DISABLED: |
111 // If we're disabled we never succeded associating and never activated the | 112 // If we're disabled we never succeded associating and never activated the |
112 // datatype. We would have already stopped the local service in | 113 // datatype. We would have already stopped the local service in |
113 // StartDoneImpl(..). | 114 // StartDoneImpl(..). |
114 set_state(NOT_RUNNING); | 115 set_state(NOT_RUNNING); |
115 StopModels(); | 116 StopModels(); |
116 return; | 117 return; |
117 default: | 118 default: |
(...skipping 16 matching lines...) Expand all Loading... |
134 set_state(NOT_RUNNING); | 135 set_state(NOT_RUNNING); |
135 } | 136 } |
136 | 137 |
137 NewNonFrontendDataTypeController::NewNonFrontendDataTypeController() {} | 138 NewNonFrontendDataTypeController::NewNonFrontendDataTypeController() {} |
138 | 139 |
139 NewNonFrontendDataTypeController::~NewNonFrontendDataTypeController() {} | 140 NewNonFrontendDataTypeController::~NewNonFrontendDataTypeController() {} |
140 | 141 |
141 void NewNonFrontendDataTypeController::StartDone( | 142 void NewNonFrontendDataTypeController::StartDone( |
142 DataTypeController::StartResult result, | 143 DataTypeController::StartResult result, |
143 DataTypeController::State new_state, | 144 DataTypeController::State new_state, |
144 const SyncError& error) { | 145 const csync::SyncError& error) { |
145 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); | 146 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
146 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 147 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
147 base::Bind( | 148 base::Bind( |
148 &NewNonFrontendDataTypeController::StartDoneImpl, | 149 &NewNonFrontendDataTypeController::StartDoneImpl, |
149 this, | 150 this, |
150 result, | 151 result, |
151 new_state, | 152 new_state, |
152 error)); | 153 error)); |
153 } | 154 } |
154 | 155 |
155 void NewNonFrontendDataTypeController::StartDoneImpl( | 156 void NewNonFrontendDataTypeController::StartDoneImpl( |
156 DataTypeController::StartResult result, | 157 DataTypeController::StartResult result, |
157 DataTypeController::State new_state, | 158 DataTypeController::State new_state, |
158 const SyncError& error) { | 159 const csync::SyncError& error) { |
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
160 // If we failed to start up, and we haven't been stopped yet, we need to | 161 // If we failed to start up, and we haven't been stopped yet, we need to |
161 // ensure we clean up the local service and shared change processor properly. | 162 // ensure we clean up the local service and shared change processor properly. |
162 if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) { | 163 if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) { |
163 ClearSharedChangeProcessor(); | 164 ClearSharedChangeProcessor(); |
164 StopLocalServiceAsync(); | 165 StopLocalServiceAsync(); |
165 } | 166 } |
166 NonFrontendDataTypeController::StartDoneImpl(result, new_state, error); | 167 NonFrontendDataTypeController::StartDoneImpl(result, new_state, error); |
167 } | 168 } |
168 | 169 |
169 void NewNonFrontendDataTypeController::AbortModelStarting() { | 170 void NewNonFrontendDataTypeController::AbortModelStarting() { |
170 set_state(NOT_RUNNING); | 171 set_state(NOT_RUNNING); |
171 StopModels(); | 172 StopModels(); |
172 ModelLoadCallback model_load_callback = model_load_callback_; | 173 ModelLoadCallback model_load_callback = model_load_callback_; |
173 model_load_callback_.Reset(); | 174 model_load_callback_.Reset(); |
174 model_load_callback.Run(type(), SyncError(FROM_HERE, | 175 model_load_callback.Run(type(), csync::SyncError(FROM_HERE, |
175 "ABORTED", | 176 "ABORTED", |
176 type())); | 177 type())); |
177 } | 178 } |
178 | 179 |
179 bool NewNonFrontendDataTypeController::StartAssociationAsync() { | 180 bool NewNonFrontendDataTypeController::StartAssociationAsync() { |
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
181 DCHECK_EQ(state(), ASSOCIATING); | 182 DCHECK_EQ(state(), ASSOCIATING); |
182 return PostTaskOnBackendThread( | 183 return PostTaskOnBackendThread( |
183 FROM_HERE, | 184 FROM_HERE, |
184 base::Bind( | 185 base::Bind( |
185 &NewNonFrontendDataTypeController:: | 186 &NewNonFrontendDataTypeController:: |
186 StartAssociationWithSharedChangeProcessor, | 187 StartAssociationWithSharedChangeProcessor, |
187 this, | 188 this, |
188 shared_change_processor_)); | 189 shared_change_processor_)); |
189 } | 190 } |
190 | 191 |
191 // This method can execute after we've already stopped (and possibly even | 192 // This method can execute after we've already stopped (and possibly even |
192 // destroyed) both the Syncer and the SyncableService. As a result, all actions | 193 // destroyed) both the Syncer and the SyncableService. As a result, all actions |
193 // must either have no side effects outside of the DTC or must be protected | 194 // must either have no side effects outside of the DTC or must be protected |
194 // by |shared_change_processor|, which is guaranteed to have been Disconnected | 195 // by |shared_change_processor|, which is guaranteed to have been Disconnected |
195 // if the syncer shut down. | 196 // if the syncer shut down. |
196 void NewNonFrontendDataTypeController:: | 197 void NewNonFrontendDataTypeController:: |
197 StartAssociationWithSharedChangeProcessor( | 198 StartAssociationWithSharedChangeProcessor( |
198 const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { | 199 const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { |
199 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); | 200 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
200 DCHECK(shared_change_processor.get()); | 201 DCHECK(shared_change_processor.get()); |
201 | 202 |
202 // Connect |shared_change_processor| to the syncer and get the | 203 // Connect |shared_change_processor| to the syncer and get the |
203 // SyncableService associated with type(). | 204 // csync::SyncableService associated with type(). |
204 // Note that it's possible the shared_change_processor has already been | 205 // Note that it's possible the shared_change_processor has already been |
205 // disconnected at this point, so all our accesses to the syncer from this | 206 // disconnected at this point, so all our accesses to the syncer from this |
206 // point on are through it. | 207 // point on are through it. |
207 local_service_ = shared_change_processor->Connect(profile_sync_factory(), | 208 local_service_ = shared_change_processor->Connect(profile_sync_factory(), |
208 profile_sync_service(), | 209 profile_sync_service(), |
209 this, | 210 this, |
210 type()); | 211 type()); |
211 if (!local_service_.get()) { | 212 if (!local_service_.get()) { |
212 SyncError error(FROM_HERE, "Failed to connect to syncer.", type()); | 213 csync::SyncError error(FROM_HERE, "Failed to connect to syncer.", type()); |
213 StartFailed(UNRECOVERABLE_ERROR, error); | 214 StartFailed(UNRECOVERABLE_ERROR, error); |
214 return; | 215 return; |
215 } | 216 } |
216 | 217 |
217 if (!shared_change_processor->CryptoReadyIfNecessary()) { | 218 if (!shared_change_processor->CryptoReadyIfNecessary()) { |
218 StartFailed(NEEDS_CRYPTO, SyncError()); | 219 StartFailed(NEEDS_CRYPTO, csync::SyncError()); |
219 return; | 220 return; |
220 } | 221 } |
221 | 222 |
222 bool sync_has_nodes = false; | 223 bool sync_has_nodes = false; |
223 if (!shared_change_processor->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { | 224 if (!shared_change_processor->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { |
224 SyncError error(FROM_HERE, "Failed to load sync nodes", type()); | 225 csync::SyncError error(FROM_HERE, "Failed to load sync nodes", type()); |
225 StartFailed(UNRECOVERABLE_ERROR, error); | 226 StartFailed(UNRECOVERABLE_ERROR, error); |
226 return; | 227 return; |
227 } | 228 } |
228 | 229 |
229 base::TimeTicks start_time = base::TimeTicks::Now(); | 230 base::TimeTicks start_time = base::TimeTicks::Now(); |
230 SyncError error; | 231 csync::SyncError error; |
231 SyncDataList initial_sync_data; | 232 csync::SyncDataList initial_sync_data; |
232 error = shared_change_processor->GetSyncData(&initial_sync_data); | 233 error = shared_change_processor->GetSyncData(&initial_sync_data); |
233 if (error.IsSet()) { | 234 if (error.IsSet()) { |
234 StartFailed(ASSOCIATION_FAILED, error); | 235 StartFailed(ASSOCIATION_FAILED, error); |
235 return; | 236 return; |
236 } | 237 } |
237 // Passes a reference to |shared_change_processor|. | 238 // Passes a reference to |shared_change_processor|. |
238 error = local_service_->MergeDataAndStartSyncing( | 239 error = local_service_->MergeDataAndStartSyncing( |
239 type(), | 240 type(), |
240 initial_sync_data, | 241 initial_sync_data, |
241 scoped_ptr<SyncChangeProcessor>( | 242 scoped_ptr<csync::SyncChangeProcessor>( |
242 new SharedChangeProcessorRef(shared_change_processor)), | 243 new SharedChangeProcessorRef(shared_change_processor)), |
243 scoped_ptr<SyncErrorFactory>( | 244 scoped_ptr<csync::SyncErrorFactory>( |
244 new SharedChangeProcessorRef(shared_change_processor))); | 245 new SharedChangeProcessorRef(shared_change_processor))); |
245 RecordAssociationTime(base::TimeTicks::Now() - start_time); | 246 RecordAssociationTime(base::TimeTicks::Now() - start_time); |
246 if (error.IsSet()) { | 247 if (error.IsSet()) { |
247 StartFailed(ASSOCIATION_FAILED, error); | 248 StartFailed(ASSOCIATION_FAILED, error); |
248 return; | 249 return; |
249 } | 250 } |
250 | 251 |
251 // If we've been disconnected, profile_sync_service() may return an invalid | 252 // If we've been disconnected, profile_sync_service() may return an invalid |
252 // pointer, but |shared_change_processor| protects us from attempting to | 253 // pointer, but |shared_change_processor| protects us from attempting to |
253 // access it. | 254 // access it. |
254 // Note: This must be done on the datatype's thread to ensure local_service_ | 255 // Note: This must be done on the datatype's thread to ensure local_service_ |
255 // doesn't start trying to push changes from its thread before we activate | 256 // doesn't start trying to push changes from its thread before we activate |
256 // the datatype. | 257 // the datatype. |
257 shared_change_processor->ActivateDataType(model_safe_group()); | 258 shared_change_processor->ActivateDataType(model_safe_group()); |
258 StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, SyncError()); | 259 StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, csync::SyncError()); |
259 } | 260 } |
260 | 261 |
261 void NewNonFrontendDataTypeController::ClearSharedChangeProcessor() { | 262 void NewNonFrontendDataTypeController::ClearSharedChangeProcessor() { |
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
263 // |shared_change_processor_| can already be NULL if Stop() is | 264 // |shared_change_processor_| can already be NULL if Stop() is |
264 // called after StartDoneImpl(_, DISABLED, _). | 265 // called after StartDoneImpl(_, DISABLED, _). |
265 if (shared_change_processor_.get()) { | 266 if (shared_change_processor_.get()) { |
266 shared_change_processor_->Disconnect(); | 267 shared_change_processor_->Disconnect(); |
267 shared_change_processor_ = NULL; | 268 shared_change_processor_ = NULL; |
268 } | 269 } |
(...skipping 11 matching lines...) Expand all Loading... |
280 if (local_service_.get()) | 281 if (local_service_.get()) |
281 local_service_->StopSyncing(type()); | 282 local_service_->StopSyncing(type()); |
282 local_service_.reset(); | 283 local_service_.reset(); |
283 } | 284 } |
284 | 285 |
285 void NewNonFrontendDataTypeController::CreateSyncComponents() { | 286 void NewNonFrontendDataTypeController::CreateSyncComponents() { |
286 NOTIMPLEMENTED(); | 287 NOTIMPLEMENTED(); |
287 } | 288 } |
288 | 289 |
289 } // namepsace browser_sync | 290 } // namepsace browser_sync |
OLD | NEW |