Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: chrome/browser/sync/glue/non_frontend_data_type_controller.cc

Issue 8274020: Revert 105404 - [Sync] Refactor non-frontend DTC to handle new API properly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/non_frontend_data_type_controller.h" 5 #include "chrome/browser/sync/glue/non_frontend_data_type_controller.h"
6 6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/logging.h" 7 #include "base/logging.h"
10 #include "chrome/browser/profiles/profile.h" 8 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/api/sync_error.h" 9 #include "chrome/browser/sync/api/sync_error.h"
12 #include "chrome/browser/sync/glue/change_processor.h" 10 #include "chrome/browser/sync/glue/change_processor.h"
13 #include "chrome/browser/sync/glue/model_associator.h" 11 #include "chrome/browser/sync/glue/model_associator.h"
14 #include "chrome/browser/sync/profile_sync_factory.h" 12 #include "chrome/browser/sync/profile_sync_factory.h"
15 #include "chrome/browser/sync/profile_sync_service.h" 13 #include "chrome/browser/sync/profile_sync_service.h"
16 #include "chrome/browser/sync/syncable/model_type.h" 14 #include "chrome/browser/sync/syncable/model_type.h"
17 #include "content/browser/browser_thread.h" 15 #include "content/browser/browser_thread.h"
18 16
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 delete start_callback; 53 delete start_callback;
56 return; 54 return;
57 } 55 }
58 56
59 start_callback_.reset(start_callback); 57 start_callback_.reset(start_callback);
60 abort_association_ = false; 58 abort_association_ = false;
61 59
62 state_ = MODEL_STARTING; 60 state_ = MODEL_STARTING;
63 if (!StartModels()) { 61 if (!StartModels()) {
64 // If we are waiting for some external service to load before associating 62 // If we are waiting for some external service to load before associating
65 // or we failed to start the models, we exit early. 63 // or we failed to start the models, we exit early. state_ will control
64 // what we perform next.
66 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); 65 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING);
67 return; 66 return;
68 } 67 }
69 68
70 // Kick off association on the thread the datatype resides on. 69 // Kick off association on the thread the datatype resides on.
71 state_ = ASSOCIATING; 70 state_ = ASSOCIATING;
72 if (!StartAssociationAsync()) { 71 if (!StartAssociationAsync()) {
73 SyncError error(FROM_HERE, "Failed to post StartAssociation", type()); 72 SyncError error(FROM_HERE, "Failed to post StartAssociation", type());
74 StartDoneImpl(ASSOCIATION_FAILED, DISABLED, error); 73 StartDoneImpl(ASSOCIATION_FAILED, DISABLED, error);
75 } 74 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 base::TimeTicks start_time = base::TimeTicks::Now(); 109 base::TimeTicks start_time = base::TimeTicks::Now();
111 SyncError error; 110 SyncError error;
112 bool merge_success = model_associator_->AssociateModels(&error); 111 bool merge_success = model_associator_->AssociateModels(&error);
113 RecordAssociationTime(base::TimeTicks::Now() - start_time); 112 RecordAssociationTime(base::TimeTicks::Now() - start_time);
114 if (!merge_success) { 113 if (!merge_success) {
115 StartFailed(ASSOCIATION_FAILED, error); 114 StartFailed(ASSOCIATION_FAILED, error);
116 return; 115 return;
117 } 116 }
118 117
119 profile_sync_service_->ActivateDataType(type(), model_safe_group(), 118 profile_sync_service_->ActivateDataType(type(), model_safe_group(),
120 change_processor()); 119 change_processor_.get());
121 StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, SyncError()); 120 StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, SyncError());
122 } 121 }
123 122
124 void NonFrontendDataTypeController::StartFailed(StartResult result, 123 void NonFrontendDataTypeController::StartFailed(StartResult result,
125 const SyncError& error) { 124 const SyncError& error) {
126 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 125 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
127 model_associator_.reset(); 126 model_associator_.reset();
128 change_processor_.reset(); 127 change_processor_.reset();
129 StartDone(result, 128 StartDone(result,
130 result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING, 129 result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING,
131 error); 130 error);
132 } 131 }
133 132
134 void NonFrontendDataTypeController::StartDone( 133 void NonFrontendDataTypeController::StartDone(
135 DataTypeController::StartResult result, 134 DataTypeController::StartResult result,
136 DataTypeController::State new_state, 135 DataTypeController::State new_state,
137 const SyncError& error) { 136 const SyncError& error) {
138 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 137 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
139 abort_association_complete_.Signal(); 138 abort_association_complete_.Signal();
140 base::AutoLock lock(abort_association_lock_); 139 base::AutoLock lock(abort_association_lock_);
141 if (!abort_association_) { 140 if (!abort_association_) {
142 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 141 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
143 base::Bind(&NonFrontendDataTypeController::StartDoneImpl, 142 NewRunnableMethod(
144 this, 143 this,
145 result, 144 &NonFrontendDataTypeController::StartDoneImpl,
146 new_state, 145 result,
147 error)); 146 new_state,
147 error));
148 } 148 }
149 } 149 }
150 150
151 void NonFrontendDataTypeController::StartDoneImpl( 151 void NonFrontendDataTypeController::StartDoneImpl(
152 DataTypeController::StartResult result, 152 DataTypeController::StartResult result,
153 DataTypeController::State new_state, 153 DataTypeController::State new_state,
154 const SyncError& error) { 154 const SyncError& error) {
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
156 // It's possible to have StartDoneImpl called first from the UI thread 156
157 // (due to Stop being called) and then posted from the non-UI thread. In
158 // this case, we drop the second call because we've already been stopped.
159 if (state_ == NOT_RUNNING) { 157 if (state_ == NOT_RUNNING) {
158 // During stop it is possible startdoneimpl can be called twice. Once from
159 // the |StartDone| method and once from the |Stop| method.
160 DCHECK(!start_callback_.get()); 160 DCHECK(!start_callback_.get());
161 return; 161 return;
162 } 162 }
163
164 state_ = new_state; 163 state_ = new_state;
165 if (state_ != RUNNING) { 164 if (state_ != RUNNING) {
166 // Start failed. 165 // Start failed.
167 StopModels(); 166 StopModels();
168 RecordStartFailure(result); 167 RecordStartFailure(result);
169 } 168 }
170 169
171 // We have to release the callback before we call it, since it's possible 170 // We have to release the callback before we call it, since it's possible
172 // invoking the callback will trigger a call to STOP(), which will get 171 // invoking the callback will trigger a call to STOP(), which will get
173 // confused by the non-NULL start_callback_. 172 // confused by the non-NULL start_callback_.
174 scoped_ptr<StartCallback> callback(start_callback_.release()); 173 scoped_ptr<StartCallback> callback(start_callback_.release());
175 callback->Run(result, error); 174 callback->Run(result, error);
176 } 175 }
177 176
178 // TODO(sync): Blocking the UI thread at shutdown is bad. The new API avoids 177 // TODO(sync): Blocking the UI thread at shutdown is bad. If we had a way of
179 // this. Once all non-frontend datatypes use the new API, we can get rid of this 178 // distinguishing chrome shutdown from sync shutdown, we should be able to avoid
180 // locking (see implementation in AutofillProfileDataTypeController). 179 // this (http://crbug.com/55662).
181 void NonFrontendDataTypeController::Stop() { 180 void NonFrontendDataTypeController::Stop() {
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
183 // If Stop() is called while Start() is waiting for association to 182 // If Stop() is called while Start() is waiting for association to
184 // complete, we need to abort the association and wait for the DB 183 // complete, we need to abort the association and wait for the DB
185 // thread to finish the StartImpl() task. 184 // thread to finish the StartImpl() task.
186 if (state_ == ASSOCIATING) { 185 if (state_ == ASSOCIATING) {
187 state_ = STOPPING; 186 state_ = STOPPING;
188 { 187 {
189 base::AutoLock lock(abort_association_lock_); 188 base::AutoLock lock(abort_association_lock_);
190 abort_association_ = true; 189 abort_association_ = true;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 246
248 DataTypeController::State NonFrontendDataTypeController::state() const { 247 DataTypeController::State NonFrontendDataTypeController::state() const {
249 return state_; 248 return state_;
250 } 249 }
251 250
252 void NonFrontendDataTypeController::OnUnrecoverableError( 251 void NonFrontendDataTypeController::OnUnrecoverableError(
253 const tracked_objects::Location& from_here, 252 const tracked_objects::Location& from_here,
254 const std::string& message) { 253 const std::string& message) {
255 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 254 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
256 RecordUnrecoverableError(from_here, message); 255 RecordUnrecoverableError(from_here, message);
257 BrowserThread::PostTask(BrowserThread::UI, from_here, 256 BrowserThread::PostTask(BrowserThread::UI, from_here, NewRunnableMethod(this,
258 base::Bind(&NonFrontendDataTypeController::OnUnrecoverableErrorImpl, 257 &NonFrontendDataTypeController::OnUnrecoverableErrorImpl, from_here,
259 this, 258 message));
260 from_here,
261 message));
262 } 259 }
263 260
264 void NonFrontendDataTypeController::OnUnrecoverableErrorImpl( 261 void NonFrontendDataTypeController::OnUnrecoverableErrorImpl(
265 const tracked_objects::Location& from_here, 262 const tracked_objects::Location& from_here,
266 const std::string& message) { 263 const std::string& message) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
268 profile_sync_service_->OnUnrecoverableError(from_here, message); 265 profile_sync_service_->OnUnrecoverableError(from_here, message);
269 } 266 }
270 267
271 ProfileSyncFactory* NonFrontendDataTypeController::profile_sync_factory() 268 ProfileSyncFactory* NonFrontendDataTypeController::profile_sync_factory()
272 const { 269 const {
273 return profile_sync_factory_; 270 return profile_sync_factory_;
274 } 271 }
275 272
276 Profile* NonFrontendDataTypeController::profile() const { 273 Profile* NonFrontendDataTypeController::profile() const {
277 return profile_; 274 return profile_;
278 } 275 }
279 276
280 ProfileSyncService* NonFrontendDataTypeController::profile_sync_service() 277 ProfileSyncService* NonFrontendDataTypeController::profile_sync_service()
281 const { 278 const {
282 return profile_sync_service_; 279 return profile_sync_service_;
283 } 280 }
284 281
285 void NonFrontendDataTypeController::set_start_callback(
286 StartCallback* callback) {
287 start_callback_.reset(callback);
288 }
289 void NonFrontendDataTypeController::set_state(State state) { 282 void NonFrontendDataTypeController::set_state(State state) {
290 state_ = state; 283 state_ = state;
291 } 284 }
292 285
293 AssociatorInterface* NonFrontendDataTypeController::associator() const {
294 return model_associator_.get();
295 }
296
297 void NonFrontendDataTypeController::set_model_associator( 286 void NonFrontendDataTypeController::set_model_associator(
298 AssociatorInterface* associator) { 287 AssociatorInterface* associator) {
299 model_associator_.reset(associator); 288 model_associator_.reset(associator);
300 } 289 }
301 290
302 ChangeProcessor* NonFrontendDataTypeController::change_processor() const {
303 return change_processor_.get();
304 }
305
306 void NonFrontendDataTypeController::set_change_processor( 291 void NonFrontendDataTypeController::set_change_processor(
307 ChangeProcessor* change_processor) { 292 ChangeProcessor* change_processor) {
308 change_processor_.reset(change_processor); 293 change_processor_.reset(change_processor);
309 } 294 }
310 295
311 } // namespace browser_sync 296 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698