summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync')
-rw-r--r--chrome/browser/sync/api/fake_syncable_service.cc5
-rw-r--r--chrome/browser/sync/api/fake_syncable_service.h2
-rw-r--r--chrome/browser/sync/api/syncable_service.h5
-rw-r--r--chrome/browser/sync/api/syncable_service_mock.cc9
-rw-r--r--chrome/browser/sync/api/syncable_service_mock.h30
-rw-r--r--chrome/browser/sync/glue/app_notification_data_type_controller_unittest.cc13
-rw-r--r--chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc3
-rw-r--r--chrome/browser/sync/glue/new_non_frontend_data_type_controller_unittest.cc17
-rw-r--r--chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc12
-rw-r--r--chrome/browser/sync/glue/shared_change_processor_unittest.cc17
-rw-r--r--chrome/browser/sync/glue/ui_data_type_controller.cc66
-rw-r--r--chrome/browser/sync/glue/ui_data_type_controller.h18
-rw-r--r--chrome/browser/sync/glue/ui_data_type_controller_unittest.cc13
-rw-r--r--chrome/browser/sync/profile_sync_service_preference_unittest.cc8
14 files changed, 120 insertions, 98 deletions
diff --git a/chrome/browser/sync/api/fake_syncable_service.cc b/chrome/browser/sync/api/fake_syncable_service.cc
index 9823dbd..2f7d948 100644
--- a/chrome/browser/sync/api/fake_syncable_service.cc
+++ b/chrome/browser/sync/api/fake_syncable_service.cc
@@ -30,8 +30,8 @@ bool FakeSyncableService::syncing() const {
SyncError FakeSyncableService::MergeDataAndStartSyncing(
syncable::ModelType type,
const SyncDataList& initial_sync_data,
- SyncChangeProcessor* sync_processor) {
- sync_processor_.reset(sync_processor);
+ scoped_ptr<SyncChangeProcessor> sync_processor) {
+ sync_processor_ = sync_processor.Pass();
type_ = type;
if (!merge_data_and_start_syncing_error_.IsSet()) {
syncing_ = true;
@@ -41,6 +41,7 @@ SyncError FakeSyncableService::MergeDataAndStartSyncing(
void FakeSyncableService::StopSyncing(syncable::ModelType type) {
syncing_ = false;
+ sync_processor_.reset();
}
SyncDataList FakeSyncableService::GetAllSyncData(
diff --git a/chrome/browser/sync/api/fake_syncable_service.h b/chrome/browser/sync/api/fake_syncable_service.h
index 9229665..724985c 100644
--- a/chrome/browser/sync/api/fake_syncable_service.h
+++ b/chrome/browser/sync/api/fake_syncable_service.h
@@ -27,7 +27,7 @@ class FakeSyncableService : public SyncableService {
virtual SyncError MergeDataAndStartSyncing(
syncable::ModelType type,
const SyncDataList& initial_sync_data,
- SyncChangeProcessor* sync_processor) OVERRIDE;
+ scoped_ptr<SyncChangeProcessor> sync_processor) OVERRIDE;
virtual void StopSyncing(syncable::ModelType type) OVERRIDE;
virtual SyncDataList GetAllSyncData(syncable::ModelType type) const OVERRIDE;
virtual SyncError ProcessSyncChanges(
diff --git a/chrome/browser/sync/api/syncable_service.h b/chrome/browser/sync/api/syncable_service.h
index 6b5152b..1e1e6a2 100644
--- a/chrome/browser/sync/api/syncable_service.h
+++ b/chrome/browser/sync/api/syncable_service.h
@@ -9,14 +9,13 @@
#include <vector>
#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/sync/api/sync_change_processor.h"
#include "chrome/browser/sync/api/sync_data.h"
#include "chrome/browser/sync/api/sync_error.h"
#include "sync/syncable/model_type.h"
-class SyncData;
-
typedef std::vector<SyncData> SyncDataList;
// TODO(zea): remove SupportsWeakPtr in favor of having all SyncableService
@@ -37,7 +36,7 @@ class SyncableService : public SyncChangeProcessor,
virtual SyncError MergeDataAndStartSyncing(
syncable::ModelType type,
const SyncDataList& initial_sync_data,
- SyncChangeProcessor* sync_processor) = 0;
+ scoped_ptr<SyncChangeProcessor> sync_processor) = 0;
// Stop syncing the specified type and reset state.
virtual void StopSyncing(syncable::ModelType type) = 0;
diff --git a/chrome/browser/sync/api/syncable_service_mock.cc b/chrome/browser/sync/api/syncable_service_mock.cc
deleted file mode 100644
index 0f4c300..0000000
--- a/chrome/browser/sync/api/syncable_service_mock.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/api/syncable_service_mock.h"
-
-SyncableServiceMock::SyncableServiceMock() {}
-
-SyncableServiceMock::~SyncableServiceMock() {}
diff --git a/chrome/browser/sync/api/syncable_service_mock.h b/chrome/browser/sync/api/syncable_service_mock.h
deleted file mode 100644
index 2575183..0000000
--- a/chrome/browser/sync/api/syncable_service_mock.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_API_SYNCABLE_SERVICE_MOCK_H_
-#define CHROME_BROWSER_SYNC_API_SYNCABLE_SERVICE_MOCK_H_
-#pragma once
-
-#include "base/location.h"
-#include "chrome/browser/sync/api/syncable_service.h"
-#include "chrome/browser/sync/api/sync_change.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-class SyncableServiceMock : public SyncableService {
- public:
- SyncableServiceMock();
- virtual ~SyncableServiceMock();
-
- MOCK_METHOD3(MergeDataAndStartSyncing,
- SyncError(syncable::ModelType,
- const SyncDataList&,
- SyncChangeProcessor* sync_processor));
- MOCK_METHOD1(StopSyncing, void(syncable::ModelType));
- MOCK_CONST_METHOD1(GetAllSyncData, SyncDataList(syncable::ModelType type));
- MOCK_METHOD2(ProcessSyncChanges,
- SyncError(const tracked_objects::Location&,
- const SyncChangeList&));
-};
-
-#endif // CHROME_BROWSER_SYNC_API_SYNCABLE_SERVICE_MOCK_H_
diff --git a/chrome/browser/sync/glue/app_notification_data_type_controller_unittest.cc b/chrome/browser/sync/glue/app_notification_data_type_controller_unittest.cc
index b63ef7c..f24a469 100644
--- a/chrome/browser/sync/glue/app_notification_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/app_notification_data_type_controller_unittest.cc
@@ -31,6 +31,10 @@ using testing::SetArgumentPointee;
namespace browser_sync {
namespace {
+ACTION(MakeSharedChangeProcessor) {
+ return new SharedChangeProcessor();
+}
+
ACTION_P(ReturnAndRelease, change_processor) {
return change_processor->release();
}
@@ -78,7 +82,12 @@ class SyncAppNotificationDataTypeControllerTest
SetStartExpectations();
}
- virtual void TearDown() { }
+ virtual void TearDown() {
+ // Must be done before we pump the loop.
+ syncable_service_.StopSyncing(syncable::APP_NOTIFICATIONS);
+ app_notif_dtc_ = NULL;
+ PumpLoop();
+ }
protected:
// Waits until the file thread executes all tasks queued up so far.
@@ -111,6 +120,8 @@ class SyncAppNotificationDataTypeControllerTest
EXPECT_CALL(*profile_sync_factory_,
GetSyncableServiceForType(syncable::APP_NOTIFICATIONS)).
WillOnce(Return(syncable_service_.AsWeakPtr()));
+ EXPECT_CALL(*profile_sync_factory_, CreateSharedChangeProcessor()).
+ WillOnce(MakeSharedChangeProcessor());
EXPECT_CALL(*profile_sync_factory_, CreateGenericChangeProcessor(_, _, _)).
WillOnce(ReturnAndRelease(&change_processor_));
}
diff --git a/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
index add06f8..fc74e61 100644
--- a/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
@@ -128,7 +128,8 @@ void NewNonFrontendDataTypeController::
error = local_service_->MergeDataAndStartSyncing(
type(),
initial_sync_data,
- new SharedChangeProcessorRef(shared_change_processor));
+ scoped_ptr<SyncChangeProcessor>(
+ new SharedChangeProcessorRef(shared_change_processor)));
RecordAssociationTime(base::TimeTicks::Now() - start_time);
if (error.IsSet()) {
StartFailed(ASSOCIATION_FAILED, error);
diff --git a/chrome/browser/sync/glue/new_non_frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/new_non_frontend_data_type_controller_unittest.cc
index 59f7cc7..8a702fd 100644
--- a/chrome/browser/sync/glue/new_non_frontend_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/new_non_frontend_data_type_controller_unittest.cc
@@ -13,7 +13,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/tracked_objects.h"
-#include "chrome/browser/sync/api/syncable_service_mock.h"
+#include "chrome/browser/sync/api/fake_syncable_service.h"
#include "chrome/browser/sync/glue/data_type_controller_mock.h"
#include "chrome/browser/sync/glue/new_non_frontend_data_type_controller_mock.h"
#include "chrome/browser/sync/glue/shared_change_processor_mock.h"
@@ -204,9 +204,6 @@ class SyncNewNonFrontendDataTypeControllerTest : public testing::Test {
WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
EXPECT_CALL(*change_processor_, GetSyncData(_)).
WillOnce(Return(SyncError()));
- EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_,_,_)).
- WillOnce(DoAll(SaveChangeProcessor(&saved_change_processor_),
- Return(SyncError())));
EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_));
}
@@ -218,11 +215,9 @@ class SyncNewNonFrontendDataTypeControllerTest : public testing::Test {
EXPECT_CALL(*dtc_mock_, StopModels());
EXPECT_CALL(*change_processor_, Disconnect()).WillOnce(Return(true));
EXPECT_CALL(service_, DeactivateDataType(_));
- EXPECT_CALL(syncable_service_, StopSyncing(_));
}
void SetStartFailExpectations(DataTypeController::StartResult result) {
- EXPECT_CALL(syncable_service_, StopSyncing(_));
EXPECT_CALL(*dtc_mock_, StopModels()).Times(AtLeast(1));
if (DataTypeController::IsUnrecoverableResult(result))
EXPECT_CALL(*dtc_mock_, RecordUnrecoverableError(_, _));
@@ -242,7 +237,7 @@ class SyncNewNonFrontendDataTypeControllerTest : public testing::Test {
StrictMock<ProfileSyncServiceMock> service_;
StartCallbackMock start_callback_;
// Must be destroyed after new_non_frontend_dtc_.
- SyncableServiceMock syncable_service_;
+ FakeSyncableService syncable_service_;
scoped_refptr<NewNonFrontendDataTypeControllerFake> new_non_frontend_dtc_;
scoped_refptr<NewNonFrontendDataTypeControllerMock> dtc_mock_;
scoped_refptr<SharedChangeProcessorMock> change_processor_;
@@ -270,9 +265,6 @@ TEST_F(SyncNewNonFrontendDataTypeControllerTest, StartFirstRun) {
WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true)));
EXPECT_CALL(*change_processor_, GetSyncData(_)).
WillOnce(Return(SyncError()));
- EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_,_,_)).
- WillOnce(DoAll(SaveChangeProcessor(&saved_change_processor_),
- Return(SyncError())));
EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_));
SetActivateExpectations(DataTypeController::OK_FIRST_RUN);
EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
@@ -314,13 +306,12 @@ TEST_F(SyncNewNonFrontendDataTypeControllerTest, StartAssociationFailed) {
WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
EXPECT_CALL(*change_processor_, GetSyncData(_)).
WillOnce(Return(SyncError()));
- EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_,_,_)).
- WillOnce(DoAll(SaveChangeProcessor(&saved_change_processor_),
- Return(SyncError(FROM_HERE, "failed", AUTOFILL_PROFILE))));
EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_));
SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED);
// Set up association to fail with an association failed error.
EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
+ syncable_service_.set_merge_data_and_start_syncing_error(
+ SyncError(FROM_HERE, "Sync Error", new_non_frontend_dtc_->type()));
new_non_frontend_dtc_->Start(
base::Bind(&StartCallbackMock::Run, base::Unretained(&start_callback_)));
WaitForDTC();
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
index 311f869..897bfe6 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
@@ -29,6 +29,10 @@ using testing::SetArgumentPointee;
namespace browser_sync {
namespace {
+ACTION(MakeSharedChangeProcessor) {
+ return new SharedChangeProcessor();
+}
+
ACTION_P(ReturnAndRelease, change_processor) {
return change_processor->release();
}
@@ -51,6 +55,9 @@ class SyncSearchEngineDataTypeControllerTest : public testing::Test {
}
virtual void TearDown() {
+ // Must be done before we pump the loop.
+ syncable_service_.StopSyncing(syncable::SEARCH_ENGINES);
+ search_engine_dtc_ = NULL;
test_util_.TearDown();
}
@@ -65,6 +72,8 @@ class SyncSearchEngineDataTypeControllerTest : public testing::Test {
EXPECT_CALL(*profile_sync_factory_,
GetSyncableServiceForType(syncable::SEARCH_ENGINES)).
WillOnce(Return(syncable_service_.AsWeakPtr()));
+ EXPECT_CALL(*profile_sync_factory_, CreateSharedChangeProcessor()).
+ WillOnce(MakeSharedChangeProcessor());
EXPECT_CALL(*profile_sync_factory_, CreateGenericChangeProcessor(_, _, _)).
WillOnce(ReturnAndRelease(&change_processor_));
}
@@ -194,6 +203,9 @@ TEST_F(SyncSearchEngineDataTypeControllerTest, OnUnrecoverableError) {
base::Bind(&StartCallbackMock::Run, base::Unretained(&start_callback_)));
// This should cause search_engine_dtc_->Stop() to be called.
search_engine_dtc_->OnUnrecoverableError(FROM_HERE, "Test");
+ test_util_.PumpLoop();
+ EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
+ EXPECT_FALSE(syncable_service_.syncing());
}
} // namespace
diff --git a/chrome/browser/sync/glue/shared_change_processor_unittest.cc b/chrome/browser/sync/glue/shared_change_processor_unittest.cc
index 4a6f5fa..8279cdf 100644
--- a/chrome/browser/sync/glue/shared_change_processor_unittest.cc
+++ b/chrome/browser/sync/glue/shared_change_processor_unittest.cc
@@ -10,7 +10,7 @@
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/message_loop.h"
-#include "chrome/browser/sync/api/syncable_service_mock.h"
+#include "chrome/browser/sync/api/fake_syncable_service.h"
#include "chrome/browser/sync/profile_sync_components_factory_mock.h"
#include "chrome/browser/sync/glue/data_type_error_handler_mock.h"
#include "chrome/browser/sync/profile_sync_components_factory_impl.h"
@@ -41,7 +41,7 @@ class SyncSharedChangeProcessorTest : public testing::Test {
db_syncable_service_(NULL) {}
virtual ~SyncSharedChangeProcessorTest() {
- EXPECT_FALSE(db_syncable_service_);
+ EXPECT_FALSE(db_syncable_service_.get());
}
protected:
@@ -85,16 +85,15 @@ class SyncSharedChangeProcessorTest : public testing::Test {
// Used by SetUp().
void SetUpDBSyncableService() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- DCHECK(!db_syncable_service_);
- db_syncable_service_ = new NiceMock<SyncableServiceMock>();
+ DCHECK(!db_syncable_service_.get());
+ db_syncable_service_.reset(new FakeSyncableService());
}
// Used by TearDown().
void TearDownDBSyncableService() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- DCHECK(db_syncable_service_);
- delete db_syncable_service_;
- db_syncable_service_ = NULL;
+ DCHECK(db_syncable_service_.get());
+ db_syncable_service_.reset();
}
// Used by Connect(). The SharedChangeProcessor is passed in
@@ -104,7 +103,7 @@ class SyncSharedChangeProcessorTest : public testing::Test {
const scoped_refptr<SharedChangeProcessor>& shared_change_processor) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
EXPECT_CALL(sync_factory_, GetSyncableServiceForType(syncable::AUTOFILL)).
- WillOnce(GetWeakPtrToSyncableService(db_syncable_service_));
+ WillOnce(GetWeakPtrToSyncableService(db_syncable_service_.get()));
EXPECT_TRUE(shared_change_processor->Connect(&sync_factory_,
&sync_service_,
&error_handler_,
@@ -121,7 +120,7 @@ class SyncSharedChangeProcessorTest : public testing::Test {
StrictMock<DataTypeErrorHandlerMock> error_handler_;
// Used only on DB thread.
- NiceMock<SyncableServiceMock>* db_syncable_service_;
+ scoped_ptr<FakeSyncableService> db_syncable_service_;
};
// Simply connect the shared change processor. It should succeed, and
diff --git a/chrome/browser/sync/glue/ui_data_type_controller.cc b/chrome/browser/sync/glue/ui_data_type_controller.cc
index e4475db..b2d3b29 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) {
diff --git a/chrome/browser/sync/glue/ui_data_type_controller.h b/chrome/browser/sync/glue/ui_data_type_controller.h
index 857e50f..ba378ce 100644
--- a/chrome/browser/sync/glue/ui_data_type_controller.h
+++ b/chrome/browser/sync/glue/ui_data_type_controller.h
@@ -13,6 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/sync/glue/data_type_controller.h"
+#include "chrome/browser/sync/glue/shared_change_processor.h"
class Profile;
class ProfileSyncService;
@@ -91,6 +92,23 @@ class UIDataTypeController : public DataTypeController {
// The sync datatype being controlled.
syncable::ModelType type_;
+ // Sync's interface to the datatype. All sync changes for |type_| are pushed
+ // through it to the datatype as well as vice versa.
+ //
+ // Lifetime: it gets created when Start()) is called, and a reference to it
+ // is passed to |local_service_| during Associate(). We release our reference
+ // when Stop() or StartFailed() is called, and |local_service_| releases its
+ // reference when local_service_->StopSyncing() is called or when it is
+ // destroyed.
+ //
+ // Note: we use refcounting here primarily so that we can keep a uniform
+ // SyncableService API, whether the datatype lives on the UI thread or not
+ // (a SyncableService takes ownership of its SyncChangeProcessor when
+ // MergeDataAndStartSyncing is called). This will help us eventually merge the
+ // two datatype controller implementations (for ui and non-ui thread
+ // datatypes).
+ scoped_refptr<SharedChangeProcessor> shared_change_processor_;
+
// A weak pointer to the actual local syncable service, which performs all the
// real work. We do not own the object.
base::WeakPtr<SyncableService> local_service_;
diff --git a/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc b/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc
index a9ed7b0..4a99e9b 100644
--- a/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc
@@ -25,6 +25,10 @@ using testing::Return;
namespace browser_sync {
namespace {
+ACTION(MakeSharedChangeProcessor) {
+ return new SharedChangeProcessor();
+}
+
ACTION_P(ReturnAndRelease, change_processor) {
return change_processor->release();
}
@@ -50,12 +54,21 @@ class SyncUIDataTypeControllerTest : public testing::Test {
SetStartExpectations();
}
+ virtual void TearDown() {
+ // Must be done before we pump the loop.
+ syncable_service_.StopSyncing(type_);
+ preference_dtc_ = NULL;
+ PumpLoop();
+ }
+
protected:
void SetStartExpectations() {
// Ownership gets passed to caller of CreateGenericChangeProcessor.
change_processor_.reset(new FakeGenericChangeProcessor());
EXPECT_CALL(*profile_sync_factory_, GetSyncableServiceForType(type_)).
WillOnce(Return(syncable_service_.AsWeakPtr()));
+ EXPECT_CALL(*profile_sync_factory_, CreateSharedChangeProcessor()).
+ WillOnce(MakeSharedChangeProcessor());
EXPECT_CALL(*profile_sync_factory_, CreateGenericChangeProcessor(_, _, _)).
WillOnce(ReturnAndRelease(&change_processor_));
}
diff --git a/chrome/browser/sync/profile_sync_service_preference_unittest.cc b/chrome/browser/sync/profile_sync_service_preference_unittest.cc
index e72818d..b22406a 100644
--- a/chrome/browser/sync/profile_sync_service_preference_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_preference_unittest.cc
@@ -41,8 +41,8 @@
using base::JSONReader;
using browser_sync::GenericChangeProcessor;
+using browser_sync::SharedChangeProcessor;
using browser_sync::UIDataTypeController;
-using browser_sync::SyncBackendHost;
using sync_api::ChangeRecord;
using testing::_;
using testing::Invoke;
@@ -134,8 +134,10 @@ class ProfileSyncServicePreferenceTest
factory,
profile_.get(),
service_.get());
- EXPECT_CALL(*factory, CreateGenericChangeProcessor(_, _, _)).
- WillOnce(CreateAndSaveChangeProcessor(&change_processor_));
+ EXPECT_CALL(*factory, CreateSharedChangeProcessor()).
+ WillOnce(Return(new SharedChangeProcessor()));
+ EXPECT_CALL(*factory, CreateGenericChangeProcessor(_, _, _)).
+ WillOnce(CreateAndSaveChangeProcessor(&change_processor_));
service_->RegisterDataTypeController(dtc_);
TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
GaiaConstants::kSyncService, "token");