| Index: chrome/browser/sync/glue/ui_data_type_controller.cc
|
| diff --git a/chrome/browser/sync/glue/ui_data_type_controller.cc b/chrome/browser/sync/glue/ui_data_type_controller.cc
|
| index e4475dbc85a3375cf8974c373068c2a6a16738da..b2d3b2990bf6de0100265f510b0ea7d1bec7d08b 100644
|
| --- a/chrome/browser/sync/glue/ui_data_type_controller.cc
|
| +++ b/chrome/browser/sync/glue/ui_data_type_controller.cc
|
| @@ -8,7 +8,7 @@
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/sync/api/sync_error.h"
|
| #include "chrome/browser/sync/api/syncable_service.h"
|
| -#include "chrome/browser/sync/glue/generic_change_processor.h"
|
| +#include "chrome/browser/sync/glue/shared_change_processor_ref.h"
|
| #include "chrome/browser/sync/profile_sync_components_factory.h"
|
| #include "chrome/browser/sync/profile_sync_service.h"
|
| #include "content/public/browser/browser_thread.h"
|
| @@ -59,6 +59,13 @@ void UIDataTypeController::Start(const StartCallback& start_callback) {
|
|
|
| start_callback_ = start_callback;
|
|
|
| + // Since we can't be called multiple times before Stop() is called,
|
| + // |shared_change_processor_| must be NULL here.
|
| + DCHECK(!shared_change_processor_.get());
|
| + shared_change_processor_ =
|
| + profile_sync_factory_->CreateSharedChangeProcessor();
|
| + DCHECK(shared_change_processor_.get());
|
| +
|
| state_ = MODEL_STARTING;
|
| if (!StartModels()) {
|
| // If we are waiting for some external service to load before associating
|
| @@ -84,58 +91,54 @@ bool UIDataTypeController::StartModels() {
|
|
|
| void UIDataTypeController::Associate() {
|
| DCHECK_EQ(state_, ASSOCIATING);
|
| - local_service_ = profile_sync_factory_->GetSyncableServiceForType(type());
|
| +
|
| + // Connect |shared_change_processor_| to the syncer and get the
|
| + // SyncableService associated with type().
|
| + local_service_ = shared_change_processor_->Connect(profile_sync_factory_,
|
| + sync_service_,
|
| + this,
|
| + type());
|
| if (!local_service_.get()) {
|
| - SyncError error(FROM_HERE, "Failed to connect to syncable service.",
|
| - type());
|
| + SyncError error(FROM_HERE, "Failed to connect to syncer.", type());
|
| StartFailed(UNRECOVERABLE_ERROR, error);
|
| return;
|
| }
|
|
|
| - // We maintain ownership until MergeDataAndStartSyncing is called.
|
| - scoped_ptr<GenericChangeProcessor> sync_processor(
|
| - profile_sync_factory_->CreateGenericChangeProcessor(
|
| - sync_service_, this, local_service_));
|
| -
|
| - if (!sync_processor->CryptoReadyIfNecessary(type())) {
|
| + if (!shared_change_processor_->CryptoReadyIfNecessary()) {
|
| StartFailed(NEEDS_CRYPTO, SyncError());
|
| return;
|
| }
|
|
|
| bool sync_has_nodes = false;
|
| - if (!sync_processor->SyncModelHasUserCreatedNodes(type(), &sync_has_nodes)) {
|
| + if (!shared_change_processor_->SyncModelHasUserCreatedNodes(
|
| + &sync_has_nodes)) {
|
| SyncError error(FROM_HERE, "Failed to load sync nodes", type());
|
| StartFailed(UNRECOVERABLE_ERROR, error);
|
| return;
|
| }
|
|
|
| base::TimeTicks start_time = base::TimeTicks::Now();
|
| + SyncError error;
|
| SyncDataList initial_sync_data;
|
| - SyncError error = sync_processor->GetSyncDataForType(
|
| - type(), &initial_sync_data);
|
| + error = shared_change_processor_->GetSyncData(&initial_sync_data);
|
| if (error.IsSet()) {
|
| StartFailed(ASSOCIATION_FAILED, error);
|
| return;
|
| }
|
|
|
| - // TODO(zea): this should use scoped_ptr<T>::Pass semantics.
|
| - GenericChangeProcessor* saved_sync_processor = sync_processor.get();
|
| - // Takes ownership of sync_processor.
|
| - error = local_service_->MergeDataAndStartSyncing(type(),
|
| - initial_sync_data,
|
| - sync_processor.release());
|
| + // Passes a reference to |shared_change_processor_|.
|
| + error = local_service_->MergeDataAndStartSyncing(
|
| + type(),
|
| + initial_sync_data,
|
| + scoped_ptr<SyncChangeProcessor>(
|
| + new SharedChangeProcessorRef(shared_change_processor_)));
|
| + RecordAssociationTime(base::TimeTicks::Now() - start_time);
|
| if (error.IsSet()) {
|
| StartFailed(ASSOCIATION_FAILED, error);
|
| return;
|
| }
|
| - RecordAssociationTime(base::TimeTicks::Now() - start_time);
|
| -
|
| - sync_service_->ActivateDataType(type(), model_safe_group(),
|
| - saved_sync_processor);
|
|
|
| - // StartDone(..) invokes the DataTypeManager callback, which can lead to a
|
| - // call to Stop() if one of the other data types being started generates an
|
| - // error.
|
| + shared_change_processor_->ActivateDataType(model_safe_group());
|
| state_ = RUNNING;
|
| StartDone(sync_has_nodes ? OK : OK_FIRST_RUN);
|
| }
|
| @@ -153,6 +156,11 @@ void UIDataTypeController::StartFailed(StartResult result,
|
| }
|
| RecordStartFailure(result);
|
|
|
| + if (shared_change_processor_.get()) {
|
| + shared_change_processor_->Disconnect();
|
| + shared_change_processor_ = NULL;
|
| + }
|
| +
|
| // We have to release the callback before we call it, since it's possible
|
| // invoking the callback will trigger a call to Stop(), which will get
|
| // confused by the non-NULL start_callback_.
|
| @@ -175,6 +183,12 @@ void UIDataTypeController::StartDone(StartResult result) {
|
| void UIDataTypeController::Stop() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| DCHECK(syncable::IsRealDataType(type_));
|
| +
|
| + if (shared_change_processor_.get()) {
|
| + shared_change_processor_->Disconnect();
|
| + shared_change_processor_ = NULL;
|
| + }
|
| +
|
| // If Stop() is called while Start() is waiting for the datatype model to
|
| // load, abort the start.
|
| if (state_ == MODEL_STARTING) {
|
|
|