diff options
Diffstat (limited to 'chrome')
34 files changed, 828 insertions, 957 deletions
diff --git a/chrome/browser/sync/glue/app_data_type_controller.cc b/chrome/browser/sync/glue/app_data_type_controller.cc index 9902334..713de10 100644 --- a/chrome/browser/sync/glue/app_data_type_controller.cc +++ b/chrome/browser/sync/glue/app_data_type_controller.cc @@ -5,13 +5,8 @@ #include "chrome/browser/sync/glue/app_data_type_controller.h" #include "base/metrics/histogram.h" -#include "base/logging.h" -#include "base/time.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory.h" -#include "chrome/browser/sync/unrecoverable_error_handler.h" -#include "content/browser/browser_thread.h" namespace browser_sync { @@ -19,120 +14,42 @@ AppDataTypeController::AppDataTypeController( ProfileSyncFactory* profile_sync_factory, Profile* profile, ProfileSyncService* sync_service) - : profile_sync_factory_(profile_sync_factory), - profile_(profile), - sync_service_(sync_service), - state_(NOT_RUNNING) { - DCHECK(profile_sync_factory); - DCHECK(sync_service); + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service) { } AppDataTypeController::~AppDataTypeController() { } -void AppDataTypeController::Start(StartCallback* start_callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(start_callback); - if (state_ != NOT_RUNNING) { - start_callback->Run(BUSY, FROM_HERE); - delete start_callback; - return; - } - - start_callback_.reset(start_callback); +syncable::ModelType AppDataTypeController::type() const { + return syncable::APPS; +} +bool AppDataTypeController::StartModels() { profile_->InitExtensions(); + return true; +} + +void AppDataTypeController::CreateSyncComponents() { ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_->CreateAppSyncComponents(sync_service_, this); model_associator_.reset(sync_components.model_associator); change_processor_.reset(sync_components.change_processor); - - if (!model_associator_->CryptoReadyIfNecessary()) { - StartFailed(NEEDS_CRYPTO, FROM_HERE); - return; - } - - bool sync_has_nodes = false; - if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); - return; - } - - base::TimeTicks start_time = base::TimeTicks::Now(); - bool merge_success = model_associator_->AssociateModels(); - UMA_HISTOGRAM_TIMES("Sync.AppAssociationTime", - base::TimeTicks::Now() - start_time); - if (!merge_success) { - StartFailed(ASSOCIATION_FAILED, FROM_HERE); - return; - } - - sync_service_->ActivateDataType(this, change_processor_.get()); - state_ = RUNNING; - FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK, FROM_HERE); -} - -void AppDataTypeController::Stop() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (state_ == MODEL_STARTING || state_ == ASSOCIATING) - FinishStart(ABORTED, FROM_HERE); - DCHECK(!start_callback_.get()); - - if (change_processor_ != NULL) - sync_service_->DeactivateDataType(this, change_processor_.get()); - - if (model_associator_ != NULL) - model_associator_->DisassociateModels(); - - change_processor_.reset(); - model_associator_.reset(); - - state_ = NOT_RUNNING; -} - -bool AppDataTypeController::enabled() { - return true; -} - -syncable::ModelType AppDataTypeController::type() { - return syncable::APPS; -} - -browser_sync::ModelSafeGroup AppDataTypeController::model_safe_group() { - return browser_sync::GROUP_UI; -} - -const char* AppDataTypeController::name() const { - // For logging only. - return "app"; -} - -DataTypeController::State AppDataTypeController::state() { - return state_; } -void AppDataTypeController::OnUnrecoverableError( +void AppDataTypeController::RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); UMA_HISTOGRAM_COUNTS("Sync.AppRunFailures", 1); - sync_service_->OnUnrecoverableError(from_here, message); } -void AppDataTypeController::FinishStart(StartResult result, - const tracked_objects::Location& location) { - start_callback_->Run(result, location); - start_callback_.reset(); +void AppDataTypeController::RecordAssociationTime(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("Sync.AppAssociationTime", time); } -void AppDataTypeController::StartFailed(StartResult result, - const tracked_objects::Location& location) { - model_associator_.reset(); - change_processor_.reset(); - start_callback_->Run(result, location); - start_callback_.reset(); +void AppDataTypeController::RecordStartFailure(StartResult result) { UMA_HISTOGRAM_ENUMERATION("Sync.AppStartFailures", result, MAX_START_RESULT); diff --git a/chrome/browser/sync/glue/app_data_type_controller.h b/chrome/browser/sync/glue/app_data_type_controller.h index 173308d..93bd517 100644 --- a/chrome/browser/sync/glue/app_data_type_controller.h +++ b/chrome/browser/sync/glue/app_data_type_controller.h @@ -8,20 +8,11 @@ #include <string> -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/sync/glue/data_type_controller.h" - -class Profile; -class ProfileSyncFactory; -class ProfileSyncService; +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" namespace browser_sync { -class AssociatorInterface; -class ChangeProcessor; - -class AppDataTypeController : public DataTypeController { +class AppDataTypeController : public FrontendDataTypeController { public: AppDataTypeController( ProfileSyncFactory* profile_sync_factory, @@ -30,43 +21,17 @@ class AppDataTypeController : public DataTypeController { virtual ~AppDataTypeController(); // DataTypeController implementation. - virtual void Start(StartCallback* start_callback); - - virtual void Stop(); - - virtual bool enabled(); - - virtual syncable::ModelType type(); - - virtual browser_sync::ModelSafeGroup model_safe_group(); - - virtual const char* name() const; - - virtual State state(); + virtual syncable::ModelType type() const; - // UnrecoverableErrorHandler interface. - virtual void OnUnrecoverableError( + private: + // DataTypeController implementations. + virtual bool StartModels(); + virtual void CreateSyncComponents(); + virtual void RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message); - - private: - // Helper method to run the stashed start callback with a given result. - void FinishStart(StartResult result, - const tracked_objects::Location& location); - - // Cleans up state and calls callback when start fails. - void StartFailed(StartResult result, - const tracked_objects::Location& location); - - ProfileSyncFactory* profile_sync_factory_; - Profile* profile_; - ProfileSyncService* sync_service_; - - State state_; - - scoped_ptr<StartCallback> start_callback_; - scoped_ptr<AssociatorInterface> model_associator_; - scoped_ptr<ChangeProcessor> change_processor_; + virtual void RecordAssociationTime(base::TimeDelta time); + virtual void RecordStartFailure(StartResult result); DISALLOW_COPY_AND_ASSIGN(AppDataTypeController); }; diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.cc b/chrome/browser/sync/glue/autofill_data_type_controller.cc index 48eb549..fa5dde4 100644 --- a/chrome/browser/sync/glue/autofill_data_type_controller.cc +++ b/chrome/browser/sync/glue/autofill_data_type_controller.cc @@ -165,20 +165,21 @@ bool AutofillDataTypeController::enabled() { return true; } -syncable::ModelType AutofillDataTypeController::type() { +syncable::ModelType AutofillDataTypeController::type() const { return syncable::AUTOFILL; } -browser_sync::ModelSafeGroup AutofillDataTypeController::model_safe_group() { +browser_sync::ModelSafeGroup AutofillDataTypeController::model_safe_group() + const { return browser_sync::GROUP_DB; } -const char* AutofillDataTypeController::name() const { +std::string AutofillDataTypeController::name() const { // For logging only. return "autofill"; } -DataTypeController::State AutofillDataTypeController::state() { +DataTypeController::State AutofillDataTypeController::state() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); return state_; } diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.h b/chrome/browser/sync/glue/autofill_data_type_controller.h index 198ff22..8df5fb8 100644 --- a/chrome/browser/sync/glue/autofill_data_type_controller.h +++ b/chrome/browser/sync/glue/autofill_data_type_controller.h @@ -43,13 +43,13 @@ class AutofillDataTypeController : public DataTypeController, virtual bool enabled(); - virtual syncable::ModelType type(); + virtual syncable::ModelType type() const; - virtual browser_sync::ModelSafeGroup model_safe_group(); + virtual browser_sync::ModelSafeGroup model_safe_group() const; - virtual const char* name() const; + virtual std::string name() const; - virtual State state(); + virtual State state() const; // UnrecoverableHandler implementation virtual void OnUnrecoverableError(const tracked_objects::Location& from_here, diff --git a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc index 1b5214b..2203197 100644 --- a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc +++ b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc @@ -19,11 +19,11 @@ AutofillProfileDataTypeController::AutofillProfileDataTypeController( AutofillProfileDataTypeController::~AutofillProfileDataTypeController() {} -syncable::ModelType AutofillProfileDataTypeController::type() { +syncable::ModelType AutofillProfileDataTypeController::type() const { return syncable::AUTOFILL_PROFILE; } -const char* AutofillProfileDataTypeController::name() const { +std::string AutofillProfileDataTypeController::name() const { // For logging only. return "autofill_profile"; } diff --git a/chrome/browser/sync/glue/autofill_profile_data_type_controller.h b/chrome/browser/sync/glue/autofill_profile_data_type_controller.h index 83cafc3..d97a904 100644 --- a/chrome/browser/sync/glue/autofill_profile_data_type_controller.h +++ b/chrome/browser/sync/glue/autofill_profile_data_type_controller.h @@ -19,9 +19,9 @@ class AutofillProfileDataTypeController : public AutofillDataTypeController { ProfileSyncService* sync_service); virtual ~AutofillProfileDataTypeController(); - virtual syncable::ModelType type(); + virtual syncable::ModelType type() const; - virtual const char* name() const; + virtual std::string name() const; protected: virtual ProfileSyncFactory::SyncComponents CreateSyncComponents( diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller.cc b/chrome/browser/sync/glue/bookmark_data_type_controller.cc index c16bb35..8cd3d5b 100644 --- a/chrome/browser/sync/glue/bookmark_data_type_controller.cc +++ b/chrome/browser/sync/glue/bookmark_data_type_controller.cc @@ -4,13 +4,9 @@ #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" -#include "base/logging.h" #include "base/metrics/histogram.h" -#include "base/time.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/glue/bookmark_change_processor.h" -#include "chrome/browser/sync/glue/bookmark_model_associator.h" #include "chrome/browser/sync/profile_sync_factory.h" #include "chrome/browser/sync/profile_sync_service.h" #include "content/browser/browser_thread.h" @@ -24,96 +20,31 @@ BookmarkDataTypeController::BookmarkDataTypeController( ProfileSyncFactory* profile_sync_factory, Profile* profile, ProfileSyncService* sync_service) - : profile_sync_factory_(profile_sync_factory), - profile_(profile), - sync_service_(sync_service), - state_(NOT_RUNNING) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(profile_sync_factory); - DCHECK(profile); - DCHECK(sync_service); + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service) { } BookmarkDataTypeController::~BookmarkDataTypeController() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } -void BookmarkDataTypeController::Start(StartCallback* start_callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(start_callback); - if (state_ != NOT_RUNNING) { - start_callback->Run(BUSY, FROM_HERE); - delete start_callback; - return; - } - - start_callback_.reset(start_callback); - - if (!enabled()) { - FinishStart(NOT_ENABLED); - return; - } - - state_ = MODEL_STARTING; - +// We want to start the bookmark model before we begin associating. +bool BookmarkDataTypeController::StartModels() { // If the bookmarks model is loaded, continue with association. BookmarkModel* bookmark_model = profile_->GetBookmarkModel(); if (bookmark_model && bookmark_model->IsLoaded()) { - Associate(); - return; + return true; // Continue to Associate(). } // Add an observer and continue when the bookmarks model is loaded. registrar_.Add(this, NotificationType::BOOKMARK_MODEL_LOADED, Source<Profile>(sync_service_->profile())); + return false; // Don't continue Start. } -void BookmarkDataTypeController::Stop() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // If Stop() is called while Start() is waiting for the bookmark - // model to load, abort the start. - if (state_ == MODEL_STARTING) - FinishStart(ABORTED); - +// Cleanup for our extra registrar usage. +void BookmarkDataTypeController::CleanupState() { registrar_.RemoveAll(); - if (change_processor_ != NULL) - sync_service_->DeactivateDataType(this, change_processor_.get()); - - if (model_associator_ != NULL) - model_associator_->DisassociateModels(); - - change_processor_.reset(); - model_associator_.reset(); - - state_ = NOT_RUNNING; -} - -bool BookmarkDataTypeController::enabled() { - return true; -} - -syncable::ModelType BookmarkDataTypeController::type() { - return syncable::BOOKMARKS; -} - -browser_sync::ModelSafeGroup BookmarkDataTypeController::model_safe_group() { - return browser_sync::GROUP_UI; -} - -const char* BookmarkDataTypeController::name() const { - // For logging only. - return "bookmark"; -} - -DataTypeController::State BookmarkDataTypeController::state() { - return state_; -} - -void BookmarkDataTypeController::OnUnrecoverableError( - const tracked_objects::Location& from_here, const std::string& message) { - // The ProfileSyncService will invoke our Stop() method in response to this. - UMA_HISTOGRAM_COUNTS("Sync.BookmarkRunFailures", 1); - sync_service_->OnUnrecoverableError(from_here, message); } void BookmarkDataTypeController::Observe(NotificationType type, @@ -122,58 +53,33 @@ void BookmarkDataTypeController::Observe(NotificationType type, DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK_EQ(NotificationType::BOOKMARK_MODEL_LOADED, type.value); registrar_.RemoveAll(); + DCHECK_EQ(state_, MODEL_STARTING); + state_ = ASSOCIATING; Associate(); } -void BookmarkDataTypeController::Associate() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK_EQ(state_, MODEL_STARTING); - state_ = ASSOCIATING; +syncable::ModelType BookmarkDataTypeController::type() const { + return syncable::BOOKMARKS; +} - ProfileSyncFactory::SyncComponents sync_components = - profile_sync_factory_->CreateBookmarkSyncComponents(sync_service_, this); +void BookmarkDataTypeController::CreateSyncComponents() { + ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_-> + CreateBookmarkSyncComponents(sync_service_, this); model_associator_.reset(sync_components.model_associator); change_processor_.reset(sync_components.change_processor); +} - if (!model_associator_->CryptoReadyIfNecessary()) { - StartFailed(NEEDS_CRYPTO, FROM_HERE); - return; - } - - bool sync_has_nodes = false; - if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); - return; - } - - base::TimeTicks start_time = base::TimeTicks::Now(); - bool merge_success = model_associator_->AssociateModels(); - UMA_HISTOGRAM_TIMES("Sync.BookmarkAssociationTime", - base::TimeTicks::Now() - start_time); - if (!merge_success) { - StartFailed(ASSOCIATION_FAILED, FROM_HERE); - return; - } - - sync_service_->ActivateDataType(this, change_processor_.get()); - state_ = RUNNING; - FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK); +void BookmarkDataTypeController::RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message) { + UMA_HISTOGRAM_COUNTS("Sync.BookmarkRunFailures", 1); } -void BookmarkDataTypeController::FinishStart(StartResult result) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - start_callback_->Run(result, FROM_HERE); - start_callback_.reset(); +void BookmarkDataTypeController::RecordAssociationTime(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("Sync.BookmarkAssociationTime", time); } -void BookmarkDataTypeController::StartFailed(StartResult result, - const tracked_objects::Location& location) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - model_associator_.reset(); - change_processor_.reset(); - state_ = NOT_RUNNING; - start_callback_->Run(result, location); - start_callback_.reset(); +void BookmarkDataTypeController::RecordStartFailure(StartResult result) { UMA_HISTOGRAM_ENUMERATION("Sync.BookmarkStartFailures", result, MAX_START_RESULT); diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller.h b/chrome/browser/sync/glue/bookmark_data_type_controller.h index 1c6d769..8741e84 100644 --- a/chrome/browser/sync/glue/bookmark_data_type_controller.h +++ b/chrome/browser/sync/glue/bookmark_data_type_controller.h @@ -8,26 +8,18 @@ #include <string> -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/sync/glue/data_type_controller.h" +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" #include "content/common/notification_observer.h" #include "content/common/notification_registrar.h" class NotificationDetails; class NotificationType; class NotificationSource; -class Profile; -class ProfileSyncService; -class ProfileSyncFactory; namespace browser_sync { -class AssociatorInterface; -class ChangeProcessor; - // A class that manages the startup and shutdown of bookmark sync. -class BookmarkDataTypeController : public DataTypeController, +class BookmarkDataTypeController : public FrontendDataTypeController, public NotificationObserver { public: BookmarkDataTypeController( @@ -36,24 +28,8 @@ class BookmarkDataTypeController : public DataTypeController, ProfileSyncService* sync_service); virtual ~BookmarkDataTypeController(); - // DataTypeController interface. - virtual void Start(StartCallback* start_callback); - - virtual void Stop(); - - virtual bool enabled(); - - virtual syncable::ModelType type(); - - virtual browser_sync::ModelSafeGroup model_safe_group(); - - virtual const char* name() const; - - virtual State state(); - - // UnrecoverableErrorHandler interface. - virtual void OnUnrecoverableError(const tracked_objects::Location& from_here, - const std::string& message); + // FrontendDataTypeController interface. + virtual syncable::ModelType type() const; // NotificationObserver interface. virtual void Observe(NotificationType type, @@ -61,25 +37,16 @@ class BookmarkDataTypeController : public DataTypeController, const NotificationDetails& details); private: - // Runs model association and change processor registration. - void Associate(); - - // Helper method to run the stashed start callback with a given result. - void FinishStart(StartResult result); - - // Cleans up state and calls callback when star fails. - void StartFailed(StartResult result, - const tracked_objects::Location& location); - - ProfileSyncFactory* profile_sync_factory_; - Profile* profile_; - ProfileSyncService* sync_service_; - - State state_; + // FrontendDataTypeController interface. + virtual bool StartModels(); + virtual void CleanupState(); + virtual void CreateSyncComponents(); + virtual void RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message); + virtual void RecordAssociationTime(base::TimeDelta time); + virtual void RecordStartFailure(StartResult result); - scoped_ptr<StartCallback> start_callback_; - scoped_ptr<AssociatorInterface> model_associator_; - scoped_ptr<ChangeProcessor> change_processor_; NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(BookmarkDataTypeController); diff --git a/chrome/browser/sync/glue/data_type_controller.h b/chrome/browser/sync/glue/data_type_controller.h index f174241..3108310 100644 --- a/chrome/browser/sync/glue/data_type_controller.h +++ b/chrome/browser/sync/glue/data_type_controller.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__ #pragma once +#include <string> #include <map> #include "base/callback.h" @@ -73,23 +74,19 @@ class DataTypeController // result. virtual void Stop() = 0; - // Returns true if the user has indicated that they want this data - // type to be enabled. - virtual bool enabled() = 0; - // Unique model type for this data type controller. - virtual syncable::ModelType type() = 0; + virtual syncable::ModelType type() const = 0; // Name of this data type. For logging purposes only. - virtual const char* name() const = 0; + virtual std::string name() const = 0; // The model safe group of this data type. This should reflect the // thread that should be used to modify the data type's native // model. - virtual browser_sync::ModelSafeGroup model_safe_group() = 0; + virtual browser_sync::ModelSafeGroup model_safe_group() const = 0; // Current state of the data type controller. - virtual State state() = 0; + virtual State state() const = 0; protected: friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; diff --git a/chrome/browser/sync/glue/data_type_controller_mock.h b/chrome/browser/sync/glue/data_type_controller_mock.h index 83d0b6b..afde5cb 100644 --- a/chrome/browser/sync/glue/data_type_controller_mock.h +++ b/chrome/browser/sync/glue/data_type_controller_mock.h @@ -19,10 +19,10 @@ class DataTypeControllerMock : public DataTypeController { MOCK_METHOD1(Start, void(StartCallback* start_callback)); MOCK_METHOD0(Stop, void()); MOCK_METHOD0(enabled, bool()); - MOCK_METHOD0(type, syncable::ModelType()); - MOCK_CONST_METHOD0(name, const char*()); - MOCK_METHOD0(model_safe_group, browser_sync::ModelSafeGroup()); - MOCK_METHOD0(state, State()); + MOCK_CONST_METHOD0(type, syncable::ModelType()); + MOCK_CONST_METHOD0(name, std::string()); + MOCK_CONST_METHOD0(model_safe_group, browser_sync::ModelSafeGroup()); + MOCK_CONST_METHOD0(state, State()); MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&, const std::string&)); }; diff --git a/chrome/browser/sync/glue/extension_data_type_controller.cc b/chrome/browser/sync/glue/extension_data_type_controller.cc index f3561be..1177eab 100644 --- a/chrome/browser/sync/glue/extension_data_type_controller.cc +++ b/chrome/browser/sync/glue/extension_data_type_controller.cc @@ -4,14 +4,9 @@ #include "chrome/browser/sync/glue/extension_data_type_controller.h" -#include "base/logging.h" #include "base/metrics/histogram.h" -#include "base/time.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory.h" -#include "chrome/browser/sync/unrecoverable_error_handler.h" -#include "content/browser/browser_thread.h" namespace browser_sync { @@ -19,120 +14,42 @@ ExtensionDataTypeController::ExtensionDataTypeController( ProfileSyncFactory* profile_sync_factory, Profile* profile, ProfileSyncService* sync_service) - : profile_sync_factory_(profile_sync_factory), - profile_(profile), - sync_service_(sync_service), - state_(NOT_RUNNING) { - DCHECK(profile_sync_factory); - DCHECK(sync_service); + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service) { } ExtensionDataTypeController::~ExtensionDataTypeController() { } -void ExtensionDataTypeController::Start(StartCallback* start_callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(start_callback); - if (state_ != NOT_RUNNING) { - start_callback->Run(BUSY, FROM_HERE); - delete start_callback; - return; - } - - start_callback_.reset(start_callback); +syncable::ModelType ExtensionDataTypeController::type() const { + return syncable::EXTENSIONS; +} +bool ExtensionDataTypeController::StartModels() { profile_->InitExtensions(); + return true; +} + +void ExtensionDataTypeController::CreateSyncComponents() { ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_->CreateExtensionSyncComponents(sync_service_, - this); + this); model_associator_.reset(sync_components.model_associator); change_processor_.reset(sync_components.change_processor); - - if (!model_associator_->CryptoReadyIfNecessary()) { - StartFailed(NEEDS_CRYPTO, FROM_HERE); - return; - } - - bool sync_has_nodes = false; - if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); - return; - } - - base::TimeTicks start_time = base::TimeTicks::Now(); - bool merge_success = model_associator_->AssociateModels(); - UMA_HISTOGRAM_TIMES("Sync.ExtensionAssociationTime", - base::TimeTicks::Now() - start_time); - if (!merge_success) { - StartFailed(ASSOCIATION_FAILED, FROM_HERE); - return; - } - - sync_service_->ActivateDataType(this, change_processor_.get()); - state_ = RUNNING; - FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK, FROM_HERE); -} - -void ExtensionDataTypeController::Stop() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (state_ == MODEL_STARTING || state_ == ASSOCIATING) - FinishStart(ABORTED, FROM_HERE); - DCHECK(!start_callback_.get()); - - if (change_processor_ != NULL) - sync_service_->DeactivateDataType(this, change_processor_.get()); - - if (model_associator_ != NULL) - model_associator_->DisassociateModels(); - - change_processor_.reset(); - model_associator_.reset(); - - state_ = NOT_RUNNING; -} - -bool ExtensionDataTypeController::enabled() { - return true; -} - -syncable::ModelType ExtensionDataTypeController::type() { - return syncable::EXTENSIONS; -} - -browser_sync::ModelSafeGroup ExtensionDataTypeController::model_safe_group() { - return browser_sync::GROUP_UI; -} - -const char* ExtensionDataTypeController::name() const { - // For logging only. - return "extension"; -} - -DataTypeController::State ExtensionDataTypeController::state() { - return state_; } -void ExtensionDataTypeController::OnUnrecoverableError( +void ExtensionDataTypeController::RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); UMA_HISTOGRAM_COUNTS("Sync.ExtensionRunFailures", 1); - sync_service_->OnUnrecoverableError(from_here, message); } -void ExtensionDataTypeController::FinishStart(StartResult result, - const tracked_objects::Location& location) { - start_callback_->Run(result, location); - start_callback_.reset(); +void ExtensionDataTypeController::RecordAssociationTime(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("Sync.ExtensionAssociationTime", time); } -void ExtensionDataTypeController::StartFailed(StartResult result, - const tracked_objects::Location& location) { - model_associator_.reset(); - change_processor_.reset(); - start_callback_->Run(result, location); - start_callback_.reset(); +void ExtensionDataTypeController::RecordStartFailure(StartResult result) { UMA_HISTOGRAM_ENUMERATION("Sync.ExtensionStartFailures", result, MAX_START_RESULT); diff --git a/chrome/browser/sync/glue/extension_data_type_controller.h b/chrome/browser/sync/glue/extension_data_type_controller.h index 5cd5d66..761db08 100644 --- a/chrome/browser/sync/glue/extension_data_type_controller.h +++ b/chrome/browser/sync/glue/extension_data_type_controller.h @@ -8,20 +8,11 @@ #include <string> -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/sync/glue/data_type_controller.h" - -class Profile; -class ProfileSyncFactory; -class ProfileSyncService; +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" namespace browser_sync { -class AssociatorInterface; -class ChangeProcessor; - -class ExtensionDataTypeController : public DataTypeController { +class ExtensionDataTypeController : public FrontendDataTypeController { public: ExtensionDataTypeController( ProfileSyncFactory* profile_sync_factory, @@ -30,43 +21,17 @@ class ExtensionDataTypeController : public DataTypeController { virtual ~ExtensionDataTypeController(); // DataTypeController implementation. - virtual void Start(StartCallback* start_callback); - - virtual void Stop(); - - virtual bool enabled(); - - virtual syncable::ModelType type(); - - virtual browser_sync::ModelSafeGroup model_safe_group(); - - virtual const char* name() const; - - virtual State state(); + virtual syncable::ModelType type() const; - // UnrecoverableErrorHandler interface. - virtual void OnUnrecoverableError( + private: + // DataTypeController implementations. + virtual bool StartModels(); + virtual void CreateSyncComponents(); + virtual void RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message); - - private: - // Helper method to run the stashed start callback with a given result. - void FinishStart(StartResult result, - const tracked_objects::Location& location); - - // Cleans up state and calls callback when start fails. - void StartFailed(StartResult result, - const tracked_objects::Location& location); - - ProfileSyncFactory* profile_sync_factory_; - Profile* profile_; - ProfileSyncService* sync_service_; - - State state_; - - scoped_ptr<StartCallback> start_callback_; - scoped_ptr<AssociatorInterface> model_associator_; - scoped_ptr<ChangeProcessor> change_processor_; + virtual void RecordAssociationTime(base::TimeDelta time); + virtual void RecordStartFailure(StartResult result); DISALLOW_COPY_AND_ASSIGN(ExtensionDataTypeController); }; diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.cc b/chrome/browser/sync/glue/frontend_data_type_controller.cc new file mode 100644 index 0000000..5e324f9 --- /dev/null +++ b/chrome/browser/sync/glue/frontend_data_type_controller.cc @@ -0,0 +1,172 @@ +// 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/glue/frontend_data_type_controller.h" + +#include "base/logging.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/glue/change_processor.h" +#include "chrome/browser/sync/glue/model_associator.h" +#include "chrome/browser/sync/profile_sync_factory.h" +#include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/sync/syncable/model_type.h" +#include "content/browser/browser_thread.h" + +namespace browser_sync { + +FrontendDataTypeController::FrontendDataTypeController() + : profile_sync_factory_(NULL), + profile_(NULL), + sync_service_(NULL) {} + +FrontendDataTypeController::FrontendDataTypeController( + ProfileSyncFactory* profile_sync_factory, + Profile* profile, + ProfileSyncService* sync_service) + : profile_sync_factory_(profile_sync_factory), + profile_(profile), + sync_service_(sync_service), + state_(NOT_RUNNING) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(profile_sync_factory); + DCHECK(profile); + DCHECK(sync_service); +} + +FrontendDataTypeController::~FrontendDataTypeController() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +} + +void FrontendDataTypeController::Start(StartCallback* start_callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(start_callback); + if (state_ != NOT_RUNNING) { + start_callback->Run(BUSY, FROM_HERE); + delete start_callback; + return; + } + + start_callback_.reset(start_callback); + + state_ = MODEL_STARTING; + if (!StartModels()) { + // If we are waiting for some external service to load before associating + // or we failed to start the models, we exit early. state_ will control + // what we perform next. + DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); + return; + } + + state_ = ASSOCIATING; + if (!Associate()) { + // We failed to associate and are aborting. + DCHECK_EQ(state_, NOT_RUNNING); + return; + } + DCHECK_EQ(state_, RUNNING); +} + +bool FrontendDataTypeController::StartModels() { + DCHECK_EQ(state_, MODEL_STARTING); + // By default, no additional services need to be started before we can proceed + // with model association. + return true; +} + +bool FrontendDataTypeController::Associate() { + DCHECK_EQ(state_, ASSOCIATING); + CreateSyncComponents(); + + if (!model_associator_->CryptoReadyIfNecessary()) { + StartFailed(NEEDS_CRYPTO, FROM_HERE); + return false; + } + + bool sync_has_nodes = false; + if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { + StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); + return false; + } + + base::TimeTicks start_time = base::TimeTicks::Now(); + bool merge_success = model_associator_->AssociateModels(); + RecordAssociationTime(base::TimeTicks::Now() - start_time); + if (!merge_success) { + StartFailed(ASSOCIATION_FAILED, FROM_HERE); + return false; + } + + sync_service_->ActivateDataType(this, change_processor_.get()); + state_ = RUNNING; + FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK, FROM_HERE); + return true; +} + +void FrontendDataTypeController::Stop() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // If Stop() is called while Start() is waiting for the datatype model to + // load, abort the start. + if (state_ == MODEL_STARTING) + FinishStart(ABORTED, FROM_HERE); + DCHECK(!start_callback_.get()); + + CleanupState(); + + if (change_processor_ != NULL) + sync_service_->DeactivateDataType(this, change_processor_.get()); + + if (model_associator_ != NULL) + model_associator_->DisassociateModels(); + + change_processor_.reset(); + model_associator_.reset(); + + state_ = NOT_RUNNING; +} + +void FrontendDataTypeController::CleanupState() { + // Do nothing by default. +} + +browser_sync::ModelSafeGroup FrontendDataTypeController::model_safe_group() + const { + return browser_sync::GROUP_UI; +} + +std::string FrontendDataTypeController::name() const { + // For logging only. + return syncable::ModelTypeToString(type()); +} + +DataTypeController::State FrontendDataTypeController::state() const { + return state_; +} + +void FrontendDataTypeController::OnUnrecoverableError( + const tracked_objects::Location& from_here, const std::string& message) { + // The ProfileSyncService will invoke our Stop() method in response to this. + RecordUnrecoverableError(from_here, message); + sync_service_->OnUnrecoverableError(from_here, message); +} + +void FrontendDataTypeController::FinishStart(StartResult result, + const tracked_objects::Location& location) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + start_callback_->Run(result, location); + start_callback_.reset(); +} + +void FrontendDataTypeController::StartFailed(StartResult result, + const tracked_objects::Location& location) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + CleanupState(); + model_associator_.reset(); + change_processor_.reset(); + state_ = NOT_RUNNING; + start_callback_->Run(result, location); + start_callback_.reset(); + RecordStartFailure(result); +} + +} // namespace browser_sync diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.h b/chrome/browser/sync/glue/frontend_data_type_controller.h new file mode 100644 index 0000000..eafbcad --- /dev/null +++ b/chrome/browser/sync/glue/frontend_data_type_controller.h @@ -0,0 +1,113 @@ +// 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_GLUE_FRONTEND_DATA_TYPE_CONTROLLER_H__ +#define CHROME_BROWSER_SYNC_GLUE_FRONTEND_DATA_TYPE_CONTROLLER_H__ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/sync/glue/data_type_controller.h" + +class Profile; +class ProfileSyncService; +class ProfileSyncFactory; + +namespace base { class TimeDelta; } +namespace browser_sync { + +class AssociatorInterface; +class ChangeProcessor; + +// Implementation for datatypes that reside on the frontend thread +// (UI thread). This is the same thread we perform initialization on, so we +// don't have to worry about thread safety. The main start/stop funtionality is +// implemented by default. +// Derived classes must implement (at least): +// syncable::ModelType type() const +// void CreateSyncComponents(); +// void RecordUnrecoverableError( +// const tracked_objects::Location& from_here, +// const std::string& message); +// void RecordAssociationTime(base::TimeDelta time); +// void RecordStartFailure(StartResult result); +class FrontendDataTypeController : public DataTypeController { + public: + FrontendDataTypeController( + ProfileSyncFactory* profile_sync_factory, + Profile* profile, + ProfileSyncService* sync_service); + virtual ~FrontendDataTypeController(); + + // DataTypeController interface. + virtual void Start(StartCallback* start_callback); + + virtual void Stop(); + + virtual syncable::ModelType type() const = 0; + + browser_sync::ModelSafeGroup model_safe_group() const; + + virtual std::string name() const; + + virtual State state() const; + + // UnrecoverableErrorHandler interface. + virtual void OnUnrecoverableError(const tracked_objects::Location& from_here, + const std::string& message); + protected: + // For testing only. + FrontendDataTypeController(); + + // Kick off any dependent services that need to be running before we can + // associate models. The default implementation is a no-op. + virtual bool StartModels(); + + // Build sync components and associate models. + virtual bool Associate(); + + // Perform any DataType controller specific state cleanup before stopping + // the datatype controller. The default implementation is a no-op. + virtual void CleanupState(); + + // Helper method to run the stashed start callback with a given result. + virtual void FinishStart(StartResult result, + const tracked_objects::Location& from_here); + + // Cleans up state and calls callback when start fails. + virtual void StartFailed(StartResult result, + const tracked_objects::Location& from_here); + + // Datatype specific creation of sync components. + virtual void CreateSyncComponents() = 0; + + // DataType specific histogram methods. Because histograms use static's, the + // specific datatype controllers must implement this themselves. + // Record unrecoverable errors. + virtual void RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message) = 0; + // Record association time. + virtual void RecordAssociationTime(base::TimeDelta time) = 0; + // Record causes of start failure. + virtual void RecordStartFailure(StartResult result) = 0; + + ProfileSyncFactory* const profile_sync_factory_; + Profile* const profile_; + ProfileSyncService* const sync_service_; + + State state_; + + scoped_ptr<StartCallback> start_callback_; + scoped_ptr<AssociatorInterface> model_associator_; + scoped_ptr<ChangeProcessor> change_processor_; + + DISALLOW_COPY_AND_ASSIGN(FrontendDataTypeController); +}; + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_GLUE_FRONTEND_DATA_TYPE_CONTROLLER_H__ diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_mock.cc b/chrome/browser/sync/glue/frontend_data_type_controller_mock.cc new file mode 100644 index 0000000..405d328 --- /dev/null +++ b/chrome/browser/sync/glue/frontend_data_type_controller_mock.cc @@ -0,0 +1,13 @@ +// 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/glue/frontend_data_type_controller_mock.h" + +namespace browser_sync { + +FrontendDataTypeControllerMock::FrontendDataTypeControllerMock() {} + +FrontendDataTypeControllerMock::~FrontendDataTypeControllerMock() {} + +} // namespace browser_sync diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_mock.h b/chrome/browser/sync/glue/frontend_data_type_controller_mock.h new file mode 100644 index 0000000..fd19263e --- /dev/null +++ b/chrome/browser/sync/glue/frontend_data_type_controller_mock.h @@ -0,0 +1,47 @@ +// 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_GLUE_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ +#define CHROME_BROWSER_SYNC_GLUE_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ +#pragma once + +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace browser_sync { + +class FrontendDataTypeControllerMock : public FrontendDataTypeController { + public: + FrontendDataTypeControllerMock(); + virtual ~FrontendDataTypeControllerMock(); + + // DataTypeController mocks. + MOCK_METHOD1(Start, void(StartCallback* start_callback)); + MOCK_METHOD0(Stop, void()); + MOCK_METHOD0(enabled, bool()); + MOCK_CONST_METHOD0(type, syncable::ModelType()); + MOCK_CONST_METHOD0(name, std::string()); + MOCK_CONST_METHOD0(model_safe_group, browser_sync::ModelSafeGroup()); + MOCK_CONST_METHOD0(state, State()); + MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&, + const std::string&)); + + // FrontendDataTypeController mocks. + MOCK_METHOD0(StartModels, bool()); + MOCK_METHOD0(Associate, bool()); + MOCK_METHOD0(CleanupState, void()); + MOCK_METHOD2(FinishStart, void(StartCallback* start_callback, + const tracked_objects::Location& from_here)); + MOCK_METHOD2(StartFailed, void(StartCallback* start_callback, + const tracked_objects::Location& from_here)); + MOCK_METHOD0(CreateSyncComponents, void()); + MOCK_METHOD2(RecordUnrecoverableError, void(const tracked_objects::Location&, + const std::string&)); + MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time)); + MOCK_METHOD1(RecordStartFailure, void(StartResult result)); +}; + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_GLUE_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc new file mode 100644 index 0000000..c0c2290 --- /dev/null +++ b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc @@ -0,0 +1,242 @@ +// 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 "testing/gtest/include/gtest/gtest.h" + +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "base/task.h" +#include "base/tracked_objects.h" +#include "chrome/browser/sync/glue/change_processor_mock.h" +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" +#include "chrome/browser/sync/glue/frontend_data_type_controller_mock.h" +#include "chrome/browser/sync/glue/model_associator_mock.h" +#include "chrome/browser/sync/profile_sync_factory_mock.h" +#include "chrome/browser/sync/profile_sync_service_mock.h" +#include "chrome/test/profile_mock.h" +#include "content/browser/browser_thread.h" + +using browser_sync::ChangeProcessorMock; +using browser_sync::DataTypeController; +using browser_sync::FrontendDataTypeController; +using browser_sync::FrontendDataTypeControllerMock; +using browser_sync::ModelAssociatorMock; +using testing::_; +using testing::DoAll; +using testing::InvokeWithoutArgs; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +class StartCallback { + public: + MOCK_METHOD2(Run, void(DataTypeController::StartResult result, + const tracked_objects::Location& from_here)); +}; + +class FrontendDataTypeControllerFake : public FrontendDataTypeController { + public: + FrontendDataTypeControllerFake( + ProfileSyncFactory* profile_sync_factory, + Profile* profile, + ProfileSyncService* sync_service, + FrontendDataTypeControllerMock* mock) + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service), + mock_(mock) {} + virtual syncable::ModelType type() const { return syncable::BOOKMARKS; } + + private: + virtual void CreateSyncComponents() { + ProfileSyncFactory::SyncComponents sync_components = + profile_sync_factory_-> + CreateBookmarkSyncComponents(sync_service_, this); + model_associator_.reset(sync_components.model_associator); + change_processor_.reset(sync_components.change_processor); + } + + // We mock the following methods because their default implementations do + // nothing, but we still want to make sure they're called appropriately. + virtual bool StartModels() { + return mock_->StartModels(); + } + virtual void CleanupState() { + mock_->CleanupState(); + } + virtual void RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message) { + mock_->RecordUnrecoverableError(from_here, message); + } + virtual void RecordAssociationTime(base::TimeDelta time) { + mock_->RecordAssociationTime(time); + } + virtual void RecordStartFailure(DataTypeController::StartResult result) { + mock_->RecordStartFailure(result); + } + private: + FrontendDataTypeControllerMock* mock_; +}; + +class FrontendDataTypeControllerTest : public testing::Test { + public: + FrontendDataTypeControllerTest() + : ui_thread_(BrowserThread::UI, &message_loop_) {} + + virtual void SetUp() { + profile_sync_factory_.reset(new ProfileSyncFactoryMock()); + dtc_mock_ = new StrictMock<FrontendDataTypeControllerMock>(); + frontend_dtc_ = + new FrontendDataTypeControllerFake(profile_sync_factory_.get(), + &profile_, + &service_, + dtc_mock_.get()); + } + + protected: + void SetStartExpectations() { + EXPECT_CALL(*dtc_mock_, StartModels()).WillOnce(Return(true)); + model_associator_ = new ModelAssociatorMock(); + change_processor_ = new ChangeProcessorMock(); + EXPECT_CALL(*profile_sync_factory_, CreateBookmarkSyncComponents(_, _)). + WillOnce(Return(ProfileSyncFactory::SyncComponents(model_associator_, + change_processor_))); + } + + void SetAssociateExpectations() { + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). + WillOnce(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). + WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*model_associator_, AssociateModels()). + WillOnce(Return(true)); + EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_)); + } + + void SetActivateExpectations(DataTypeController::StartResult result) { + EXPECT_CALL(service_, ActivateDataType(_, _)); + EXPECT_CALL(start_callback_, Run(result,_)); + } + + void SetStopExpectations() { + EXPECT_CALL(*dtc_mock_, CleanupState()); + EXPECT_CALL(service_, DeactivateDataType(_, _)); + EXPECT_CALL(*model_associator_, DisassociateModels()); + } + + void SetStartFailExpectations(DataTypeController::StartResult result) { + EXPECT_CALL(*dtc_mock_, CleanupState()); + EXPECT_CALL(*dtc_mock_, RecordStartFailure(result)); + EXPECT_CALL(start_callback_, Run(result,_)); + } + + MessageLoopForUI message_loop_; + BrowserThread ui_thread_; + scoped_refptr<FrontendDataTypeControllerFake> frontend_dtc_; + scoped_ptr<ProfileSyncFactoryMock> profile_sync_factory_; + scoped_refptr<FrontendDataTypeControllerMock> dtc_mock_; + ProfileMock profile_; + ProfileSyncServiceMock service_; + ModelAssociatorMock* model_associator_; + ChangeProcessorMock* change_processor_; + StartCallback start_callback_; +}; + +TEST_F(FrontendDataTypeControllerTest, StartOk) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); +} + +TEST_F(FrontendDataTypeControllerTest, StartFirstRun) { + SetStartExpectations(); + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). + WillOnce(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). + WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); + EXPECT_CALL(*model_associator_, AssociateModels()). + WillOnce(Return(true)); + EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_)); + SetActivateExpectations(DataTypeController::OK_FIRST_RUN); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); +} + +TEST_F(FrontendDataTypeControllerTest, StartAssociationFailed) { + SetStartExpectations(); + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). + WillOnce(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). + WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*model_associator_, AssociateModels()). + WillOnce(Return(false)); + EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_)); + SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); + // Set up association to fail with an association failed error. + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(FrontendDataTypeControllerTest, + StartAssociationTriggersUnrecoverableError) { + SetStartExpectations(); + SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); + // Set up association to fail with an unrecoverable error. + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). + WillRepeatedly(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). + WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(FrontendDataTypeControllerTest, StartAssociationCryptoNotReady) { + SetStartExpectations(); + SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); + // Set up association to fail with a NEEDS_CRYPTO error. + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). + WillRepeatedly(Return(false)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(FrontendDataTypeControllerTest, Stop) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + SetStopExpectations(); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); + frontend_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(FrontendDataTypeControllerTest, OnUnrecoverableError) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + EXPECT_CALL(*dtc_mock_, RecordUnrecoverableError(_, "Test")); + EXPECT_CALL(service_, OnUnrecoverableError(_,_)). + WillOnce(InvokeWithoutArgs(frontend_dtc_.get(), + &FrontendDataTypeController::Stop)); + SetStopExpectations(); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); + // This should cause frontend_dtc_->Stop() to be called. + frontend_dtc_->OnUnrecoverableError(FROM_HERE, "Test"); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} diff --git a/chrome/browser/sync/glue/password_data_type_controller.cc b/chrome/browser/sync/glue/password_data_type_controller.cc index ff9bd51..2589861 100644 --- a/chrome/browser/sync/glue/password_data_type_controller.cc +++ b/chrome/browser/sync/glue/password_data_type_controller.cc @@ -107,20 +107,21 @@ bool PasswordDataTypeController::enabled() { return true; } -syncable::ModelType PasswordDataTypeController::type() { +syncable::ModelType PasswordDataTypeController::type() const { return syncable::PASSWORDS; } -browser_sync::ModelSafeGroup PasswordDataTypeController::model_safe_group() { +browser_sync::ModelSafeGroup PasswordDataTypeController::model_safe_group() + const { return browser_sync::GROUP_PASSWORD; } -const char* PasswordDataTypeController::name() const { +std::string PasswordDataTypeController::name() const { // For logging only. return "password"; } -DataTypeController::State PasswordDataTypeController::state() { +DataTypeController::State PasswordDataTypeController::state() const { return state_; } diff --git a/chrome/browser/sync/glue/password_data_type_controller.h b/chrome/browser/sync/glue/password_data_type_controller.h index 988a482..1a3a9e41 100644 --- a/chrome/browser/sync/glue/password_data_type_controller.h +++ b/chrome/browser/sync/glue/password_data_type_controller.h @@ -41,13 +41,13 @@ class PasswordDataTypeController : public DataTypeController { virtual bool enabled(); - virtual syncable::ModelType type(); + virtual syncable::ModelType type() const; - virtual browser_sync::ModelSafeGroup model_safe_group(); + virtual browser_sync::ModelSafeGroup model_safe_group() const; - virtual const char* name() const; + virtual std::string name() const; - virtual State state(); + virtual State state() const; // UnrecoverableHandler implementation virtual void OnUnrecoverableError(const tracked_objects::Location& from_here, diff --git a/chrome/browser/sync/glue/preference_data_type_controller.cc b/chrome/browser/sync/glue/preference_data_type_controller.cc index a88dc24..3331bd3 100644 --- a/chrome/browser/sync/glue/preference_data_type_controller.cc +++ b/chrome/browser/sync/glue/preference_data_type_controller.cc @@ -4,141 +4,44 @@ #include "chrome/browser/sync/glue/preference_data_type_controller.h" -#include <string> - -#include "base/logging.h" #include "base/metrics/histogram.h" -#include "base/time.h" -#include "chrome/browser/sync/glue/preference_change_processor.h" -#include "chrome/browser/sync/glue/preference_model_associator.h" -#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory.h" -#include "chrome/browser/sync/unrecoverable_error_handler.h" -#include "content/browser/browser_thread.h" namespace browser_sync { PreferenceDataTypeController::PreferenceDataTypeController( ProfileSyncFactory* profile_sync_factory, + Profile* profile, ProfileSyncService* sync_service) - : profile_sync_factory_(profile_sync_factory), - sync_service_(sync_service), - state_(NOT_RUNNING) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(profile_sync_factory); - DCHECK(sync_service); -} - -PreferenceDataTypeController::~PreferenceDataTypeController() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); -} - -void PreferenceDataTypeController::Start(StartCallback* start_callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(start_callback); - if (state_ != NOT_RUNNING) { - start_callback->Run(BUSY, FROM_HERE); - delete start_callback; - return; - } - - start_callback_.reset(start_callback); - - // No additional services need to be started before we can proceed - // with model association. - ProfileSyncFactory::SyncComponents sync_components = - profile_sync_factory_->CreatePreferenceSyncComponents(sync_service_, - this); - model_associator_.reset(sync_components.model_associator); - change_processor_.reset(sync_components.change_processor); - - if (!model_associator_->CryptoReadyIfNecessary()) { - StartFailed(NEEDS_CRYPTO, FROM_HERE); - return; - } - - bool sync_has_nodes = false; - if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); - return; - } - - base::TimeTicks start_time = base::TimeTicks::Now(); - bool merge_success = model_associator_->AssociateModels(); - UMA_HISTOGRAM_TIMES("Sync.PreferenceAssociationTime", - base::TimeTicks::Now() - start_time); - if (!merge_success) { - StartFailed(ASSOCIATION_FAILED, FROM_HERE); - return; - } - - sync_service_->ActivateDataType(this, change_processor_.get()); - state_ = RUNNING; - FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK, FROM_HERE); + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service) { } -void PreferenceDataTypeController::Stop() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (state_ == MODEL_STARTING || state_ == ASSOCIATING) - FinishStart(ABORTED, FROM_HERE); - DCHECK(!start_callback_.get()); +PreferenceDataTypeController::~PreferenceDataTypeController() {} - if (change_processor_ != NULL) - sync_service_->DeactivateDataType(this, change_processor_.get()); - - if (model_associator_ != NULL) - model_associator_->DisassociateModels(); - - change_processor_.reset(); - model_associator_.reset(); - - state_ = NOT_RUNNING; -} - -bool PreferenceDataTypeController::enabled() { - return true; -} - -syncable::ModelType PreferenceDataTypeController::type() { +syncable::ModelType PreferenceDataTypeController::type() const { return syncable::PREFERENCES; } -browser_sync::ModelSafeGroup PreferenceDataTypeController::model_safe_group() { - return browser_sync::GROUP_UI; -} - -const char* PreferenceDataTypeController::name() const { - // For logging only. - return "preference"; -} - -DataTypeController::State PreferenceDataTypeController::state() { - return state_; +void PreferenceDataTypeController::CreateSyncComponents() { + ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_-> + CreatePreferenceSyncComponents(sync_service_, this); + model_associator_.reset(sync_components.model_associator); + change_processor_.reset(sync_components.change_processor); } -void PreferenceDataTypeController::OnUnrecoverableError( +void PreferenceDataTypeController::RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); UMA_HISTOGRAM_COUNTS("Sync.PreferenceRunFailures", 1); - sync_service_->OnUnrecoverableError(from_here, message); } -void PreferenceDataTypeController::FinishStart(StartResult result, - const tracked_objects::Location& location) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - start_callback_->Run(result, location); - start_callback_.reset(); +void PreferenceDataTypeController::RecordAssociationTime(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("Sync.PreferenceAssociationTime", time); } -void PreferenceDataTypeController::StartFailed(StartResult result, - const tracked_objects::Location& location) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - model_associator_.reset(); - change_processor_.reset(); - start_callback_->Run(result, location); - start_callback_.reset(); +void PreferenceDataTypeController::RecordStartFailure(StartResult result) { UMA_HISTOGRAM_ENUMERATION("Sync.PreferenceStartFailures", result, MAX_START_RESULT); diff --git a/chrome/browser/sync/glue/preference_data_type_controller.h b/chrome/browser/sync/glue/preference_data_type_controller.h index 05894d09..3f375b15 100644 --- a/chrome/browser/sync/glue/preference_data_type_controller.h +++ b/chrome/browser/sync/glue/preference_data_type_controller.h @@ -6,60 +6,31 @@ #define CHROME_BROWSER_SYNC_GLUE_PREFERENCE_DATA_TYPE_CONTROLLER_H__ #pragma once -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/sync/glue/data_type_controller.h" +#include <string> -class ProfileSyncFactory; -class ProfileSyncService; +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" namespace browser_sync { -class AssociatorInterface; -class ChangeProcessor; - -class PreferenceDataTypeController : public DataTypeController { +class PreferenceDataTypeController : public FrontendDataTypeController { public: PreferenceDataTypeController( ProfileSyncFactory* profile_sync_factory, + Profile* profile, ProfileSyncService* sync_service); virtual ~PreferenceDataTypeController(); - virtual void Start(StartCallback* start_callback); - - virtual void Stop(); - - virtual bool enabled(); - - virtual syncable::ModelType type(); - - virtual browser_sync::ModelSafeGroup model_safe_group(); - - virtual const char* name() const; - - virtual State state(); - - // UnrecoverableErrorHandler interface. - virtual void OnUnrecoverableError(const tracked_objects::Location& from_here, - const std::string& message); + // FrontendDataTypeController implementation. + virtual syncable::ModelType type() const; private: - // Helper method to run the stashed start callback with a given result. - void FinishStart(StartResult result, - const tracked_objects::Location& location); - - // Cleans up state and calls callback when start fails. - void StartFailed(StartResult result, - const tracked_objects::Location& location); - - ProfileSyncFactory* profile_sync_factory_; - ProfileSyncService* sync_service_; - - State state_; - - scoped_ptr<StartCallback> start_callback_; - scoped_ptr<AssociatorInterface> model_associator_; - scoped_ptr<ChangeProcessor> change_processor_; + // FrontendDataTypeController implementations. + virtual void CreateSyncComponents(); + virtual void RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message); + virtual void RecordAssociationTime(base::TimeDelta time); + virtual void RecordStartFailure(StartResult result); DISALLOW_COPY_AND_ASSIGN(PreferenceDataTypeController); }; diff --git a/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc b/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc index 0ddc05d..4df8b3f 100644 --- a/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc @@ -14,6 +14,7 @@ #include "chrome/browser/sync/glue/model_associator_mock.h" #include "chrome/browser/sync/profile_sync_factory_mock.h" #include "chrome/browser/sync/profile_sync_service_mock.h" +#include "chrome/test/profile_mock.h" #include "content/browser/browser_thread.h" using browser_sync::PreferenceDataTypeController; @@ -41,6 +42,7 @@ class PreferenceDataTypeControllerTest : public testing::Test { profile_sync_factory_.reset(new ProfileSyncFactoryMock()); preference_dtc_ = new PreferenceDataTypeController(profile_sync_factory_.get(), + &profile_, &service_); } @@ -75,6 +77,7 @@ class PreferenceDataTypeControllerTest : public testing::Test { BrowserThread ui_thread_; scoped_refptr<PreferenceDataTypeController> preference_dtc_; scoped_ptr<ProfileSyncFactoryMock> profile_sync_factory_; + ProfileMock profile_; ProfileSyncServiceMock service_; ModelAssociatorMock* model_associator_; ChangeProcessorMock* change_processor_; diff --git a/chrome/browser/sync/glue/session_data_type_controller.cc b/chrome/browser/sync/glue/session_data_type_controller.cc index f0373e2..68186cb 100644 --- a/chrome/browser/sync/glue/session_data_type_controller.cc +++ b/chrome/browser/sync/glue/session_data_type_controller.cc @@ -5,137 +5,47 @@ #include "chrome/browser/sync/glue/session_data_type_controller.h" #include "base/metrics/histogram.h" -#include "base/logging.h" -#include "base/time.h" -#include "chrome/browser/sync/glue/session_change_processor.h" -#include "chrome/browser/sync/glue/session_model_associator.h" -#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory.h" -#include "chrome/browser/sync/unrecoverable_error_handler.h" -#include "content/browser/browser_thread.h" namespace browser_sync { SessionDataTypeController::SessionDataTypeController( ProfileSyncFactory* profile_sync_factory, + Profile* profile, ProfileSyncService* sync_service) - : profile_sync_factory_(profile_sync_factory), - sync_service_(sync_service), - state_(NOT_RUNNING) { - DCHECK(profile_sync_factory); - DCHECK(sync_service); + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service) { } -SessionDataTypeController::~SessionDataTypeController() { -} - -void SessionDataTypeController::Start(StartCallback* start_callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(start_callback); - if (state_ != NOT_RUNNING) { - start_callback->Run(BUSY, FROM_HERE); - delete start_callback; - return; - } - - start_callback_.reset(start_callback); - - ProfileSyncFactory::SyncComponents sync_components = - profile_sync_factory_->CreateSessionSyncComponents(sync_service_, - this); - model_associator_.reset(sync_components.model_associator); - change_processor_.reset(sync_components.change_processor); - - if (!model_associator_->CryptoReadyIfNecessary()) { - StartFailed(NEEDS_CRYPTO, FROM_HERE); - return; - } - - bool sync_has_nodes = false; - if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); - return; - } - - base::TimeTicks start_time = base::TimeTicks::Now(); - bool success = model_associator_->AssociateModels(); - UMA_HISTOGRAM_TIMES("Sync.SessionAssociationTime", - base::TimeTicks::Now() - start_time); - if (!success) { - StartFailed(ASSOCIATION_FAILED, FROM_HERE); - return; - } - - sync_service_->ActivateDataType(this, change_processor_.get()); - state_ = RUNNING; - FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK, FROM_HERE); -} - -void SessionDataTypeController::Stop() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (state_ == MODEL_STARTING || state_ == ASSOCIATING) - FinishStart(ABORTED, FROM_HERE); - DCHECK(!start_callback_.get()); +SessionDataTypeController::~SessionDataTypeController() {} - if (change_processor_ != NULL) - sync_service_->DeactivateDataType(this, change_processor_.get()); - - if (model_associator_ != NULL) - model_associator_->DisassociateModels(); - - change_processor_.reset(); - model_associator_.reset(); - - state_ = NOT_RUNNING; +SessionModelAssociator* SessionDataTypeController::GetModelAssociator() { + return reinterpret_cast<SessionModelAssociator*>(model_associator_.get()); } -bool SessionDataTypeController::enabled() { - return true; -} - -syncable::ModelType SessionDataTypeController::type() { +syncable::ModelType SessionDataTypeController::type() const { return syncable::SESSIONS; } -browser_sync::ModelSafeGroup SessionDataTypeController::model_safe_group() { - return browser_sync::GROUP_UI; -} - -const char* SessionDataTypeController::name() const { - // For logging only. - return "session"; -} - -DataTypeController::State SessionDataTypeController::state() { - return state_; +void SessionDataTypeController::CreateSyncComponents() { + ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_-> + CreateSessionSyncComponents(sync_service_, this); + model_associator_.reset(sync_components.model_associator); + change_processor_.reset(sync_components.change_processor); } -void SessionDataTypeController::OnUnrecoverableError( +void SessionDataTypeController::RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); UMA_HISTOGRAM_COUNTS("Sync.SessionRunFailures", 1); - sync_service_->OnUnrecoverableError(from_here, message); -} - -browser_sync::SessionModelAssociator* - SessionDataTypeController::GetModelAssociator() { - return static_cast<SessionModelAssociator*>(model_associator_.get()); } -void SessionDataTypeController::FinishStart(StartResult result, - const tracked_objects::Location& location) { - start_callback_->Run(result, location); - start_callback_.reset(); +void SessionDataTypeController::RecordAssociationTime(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("Sync.SessionAssociationTime", time); } -void SessionDataTypeController::StartFailed(StartResult result, - const tracked_objects::Location& location) { - model_associator_.reset(); - change_processor_.reset(); - start_callback_->Run(result, location); - start_callback_.reset(); +void SessionDataTypeController::RecordStartFailure(StartResult result) { UMA_HISTOGRAM_ENUMERATION("Sync.SessionStartFailures", result, MAX_START_RESULT); diff --git a/chrome/browser/sync/glue/session_data_type_controller.h b/chrome/browser/sync/glue/session_data_type_controller.h index 002ba69..4ee284a 100644 --- a/chrome/browser/sync/glue/session_data_type_controller.h +++ b/chrome/browser/sync/glue/session_data_type_controller.h @@ -8,65 +8,37 @@ #include <string> -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/sync/glue/data_type_controller.h" -#include "chrome/browser/sync/glue/session_model_associator.h" - -class ProfileSyncFactory; -class ProfileSyncService; +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" namespace browser_sync { -class AssociatorInterface; -class ChangeProcessor; +class SessionModelAssociator; -class SessionDataTypeController : public DataTypeController { +class SessionDataTypeController : public FrontendDataTypeController { public: SessionDataTypeController( ProfileSyncFactory* profile_sync_factory, + Profile* profile, ProfileSyncService* sync_service); virtual ~SessionDataTypeController(); - // DataTypeController implementation. - virtual void Start(StartCallback* start_callback); - - virtual void Stop(); - - virtual bool enabled(); - - virtual syncable::ModelType type(); - - virtual browser_sync::ModelSafeGroup model_safe_group(); - - virtual const char* name() const; + SessionModelAssociator* GetModelAssociator(); - virtual State state(); + // FrontendDataTypeController implementation. + virtual syncable::ModelType type() const; - // UnrecoverableErrorHandler interface. - virtual void OnUnrecoverableError( + private: + // FrontendDataTypeController implementations. + // Datatype specific creation of sync components. + virtual void CreateSyncComponents(); + // Record unrecoverable errors. + virtual void RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message); - - SessionModelAssociator* GetModelAssociator(); - - private: - // Helper method to run the stashed start callback with a given result. - void FinishStart(StartResult result, - const tracked_objects::Location& location); - - // Cleans up state and calls callback when start fails. - void StartFailed(StartResult result, - const tracked_objects::Location& location); - - ProfileSyncFactory* profile_sync_factory_; - ProfileSyncService* sync_service_; - - State state_; - - scoped_ptr<StartCallback> start_callback_; - scoped_ptr<AssociatorInterface> model_associator_; - scoped_ptr<ChangeProcessor> change_processor_; + // Record association time. + virtual void RecordAssociationTime(base::TimeDelta time); + // Record causes of start failure. + virtual void RecordStartFailure(StartResult result); DISALLOW_COPY_AND_ASSIGN(SessionDataTypeController); }; diff --git a/chrome/browser/sync/glue/theme_data_type_controller.cc b/chrome/browser/sync/glue/theme_data_type_controller.cc index 5a2fa79..c2aa400 100644 --- a/chrome/browser/sync/glue/theme_data_type_controller.cc +++ b/chrome/browser/sync/glue/theme_data_type_controller.cc @@ -5,15 +5,8 @@ #include "chrome/browser/sync/glue/theme_data_type_controller.h" #include "base/metrics/histogram.h" -#include "base/logging.h" -#include "base/time.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/glue/theme_change_processor.h" -#include "chrome/browser/sync/glue/theme_model_associator.h" -#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory.h" -#include "chrome/browser/sync/unrecoverable_error_handler.h" -#include "content/browser/browser_thread.h" namespace browser_sync { @@ -21,121 +14,42 @@ ThemeDataTypeController::ThemeDataTypeController( ProfileSyncFactory* profile_sync_factory, Profile* profile, ProfileSyncService* sync_service) - : profile_sync_factory_(profile_sync_factory), - profile_(profile), - sync_service_(sync_service), - state_(NOT_RUNNING) { - DCHECK(profile_sync_factory); - DCHECK(sync_service); + : FrontendDataTypeController(profile_sync_factory, + profile, + sync_service) { } ThemeDataTypeController::~ThemeDataTypeController() { } -void ThemeDataTypeController::Start(StartCallback* start_callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(start_callback); - if (state_ != NOT_RUNNING) { - start_callback->Run(BUSY, FROM_HERE); - delete start_callback; - return; - } - - start_callback_.reset(start_callback); +syncable::ModelType ThemeDataTypeController::type() const { + return syncable::THEMES; +} +bool ThemeDataTypeController::StartModels() { profile_->InitExtensions(); + return true; +} + +void ThemeDataTypeController::CreateSyncComponents() { ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_->CreateThemeSyncComponents(sync_service_, - this); + this); model_associator_.reset(sync_components.model_associator); change_processor_.reset(sync_components.change_processor); - - if (!model_associator_->CryptoReadyIfNecessary()) { - StartFailed(NEEDS_CRYPTO, FROM_HERE); - return; - } - - bool sync_has_nodes = false; - if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - StartFailed(UNRECOVERABLE_ERROR, FROM_HERE); - return; - } - - base::TimeTicks start_time = base::TimeTicks::Now(); - bool merge_success = model_associator_->AssociateModels(); - UMA_HISTOGRAM_TIMES("Sync.ThemeAssociationTime", - base::TimeTicks::Now() - start_time); - if (!merge_success) { - StartFailed(ASSOCIATION_FAILED, FROM_HERE); - return; - } - - sync_service_->ActivateDataType(this, change_processor_.get()); - state_ = RUNNING; - FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK, FROM_HERE); } -void ThemeDataTypeController::Stop() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (state_ == MODEL_STARTING || state_ == ASSOCIATING) - FinishStart(ABORTED, FROM_HERE); - DCHECK(!start_callback_.get()); - - if (change_processor_ != NULL) - sync_service_->DeactivateDataType(this, change_processor_.get()); - - if (model_associator_ != NULL) - model_associator_->DisassociateModels(); - - change_processor_.reset(); - model_associator_.reset(); - - state_ = NOT_RUNNING; -} - -bool ThemeDataTypeController::enabled() { - return true; - } - -syncable::ModelType ThemeDataTypeController::type() { - return syncable::THEMES; -} - -browser_sync::ModelSafeGroup ThemeDataTypeController::model_safe_group() { - return browser_sync::GROUP_UI; -} - -const char* ThemeDataTypeController::name() const { - // For logging only. - return "theme"; -} - -DataTypeController::State ThemeDataTypeController::state() { - return state_; -} - - -void ThemeDataTypeController::OnUnrecoverableError( +void ThemeDataTypeController::RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); UMA_HISTOGRAM_COUNTS("Sync.ThemeRunFailures", 1); - sync_service_->OnUnrecoverableError(from_here, message); } -void ThemeDataTypeController::FinishStart(StartResult result, - const tracked_objects::Location& location) { - start_callback_->Run(result, location); - start_callback_.reset(); +void ThemeDataTypeController::RecordAssociationTime(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("Sync.ThemeAssociationTime", time); } -void ThemeDataTypeController::StartFailed(StartResult result, - const tracked_objects::Location& location) { - model_associator_.reset(); - change_processor_.reset(); - start_callback_->Run(result, location); - start_callback_.reset(); +void ThemeDataTypeController::RecordStartFailure(StartResult result) { UMA_HISTOGRAM_ENUMERATION("Sync.ThemeStartFailures", result, MAX_START_RESULT); diff --git a/chrome/browser/sync/glue/theme_data_type_controller.h b/chrome/browser/sync/glue/theme_data_type_controller.h index c4c103b..37f5ceb 100644 --- a/chrome/browser/sync/glue/theme_data_type_controller.h +++ b/chrome/browser/sync/glue/theme_data_type_controller.h @@ -8,20 +8,11 @@ #include <string> -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/sync/glue/data_type_controller.h" - -class Profile; -class ProfileSyncFactory; -class ProfileSyncService; +#include "chrome/browser/sync/glue/frontend_data_type_controller.h" namespace browser_sync { -class AssociatorInterface; -class ChangeProcessor; - -class ThemeDataTypeController : public DataTypeController { +class ThemeDataTypeController : public FrontendDataTypeController { public: ThemeDataTypeController( ProfileSyncFactory* profile_sync_factory, @@ -30,44 +21,17 @@ class ThemeDataTypeController : public DataTypeController { virtual ~ThemeDataTypeController(); // DataTypeController implementation. - virtual void Start(StartCallback* start_callback); - - virtual void Stop(); - - virtual bool enabled(); - - virtual syncable::ModelType type(); - - virtual browser_sync::ModelSafeGroup model_safe_group(); - - virtual const char* name() const; - - virtual State state(); + virtual syncable::ModelType type() const; - // UnrecoverableErrorHandler interface. - virtual void OnUnrecoverableError( + private: + // DataTypeController implementations. + virtual bool StartModels(); + virtual void CreateSyncComponents(); + virtual void RecordUnrecoverableError( const tracked_objects::Location& from_here, const std::string& message); - - private: - // Helper method to run the stashed start callback with a given result. - void FinishStart(StartResult result, - const tracked_objects::Location& location); - - // Cleans up state and calls callback when start fails. - void StartFailed(StartResult result, - const tracked_objects::Location& location); - - ProfileSyncFactory* profile_sync_factory_; - Profile* profile_; - ProfileSyncService* sync_service_; - - State state_; - - scoped_ptr<StartCallback> start_callback_; - scoped_ptr<AssociatorInterface> model_associator_; - scoped_ptr<ChangeProcessor> change_processor_; - + virtual void RecordAssociationTime(base::TimeDelta time); + virtual void RecordStartFailure(StartResult result); DISALLOW_COPY_AND_ASSIGN(ThemeDataTypeController); }; diff --git a/chrome/browser/sync/glue/typed_url_data_type_controller.cc b/chrome/browser/sync/glue/typed_url_data_type_controller.cc index 2a12081..93be84d 100644 --- a/chrome/browser/sync/glue/typed_url_data_type_controller.cc +++ b/chrome/browser/sync/glue/typed_url_data_type_controller.cc @@ -148,20 +148,21 @@ bool TypedUrlDataTypeController::enabled() { return true; } -syncable::ModelType TypedUrlDataTypeController::type() { +syncable::ModelType TypedUrlDataTypeController::type() const { return syncable::TYPED_URLS; } -browser_sync::ModelSafeGroup TypedUrlDataTypeController::model_safe_group() { +browser_sync::ModelSafeGroup TypedUrlDataTypeController::model_safe_group() + const { return browser_sync::GROUP_HISTORY; } -const char* TypedUrlDataTypeController::name() const { +std::string TypedUrlDataTypeController::name() const { // For logging only. return "typed_url"; } -DataTypeController::State TypedUrlDataTypeController::state() { +DataTypeController::State TypedUrlDataTypeController::state() const { return state_; } diff --git a/chrome/browser/sync/glue/typed_url_data_type_controller.h b/chrome/browser/sync/glue/typed_url_data_type_controller.h index 5b9435b..386a01d 100644 --- a/chrome/browser/sync/glue/typed_url_data_type_controller.h +++ b/chrome/browser/sync/glue/typed_url_data_type_controller.h @@ -53,13 +53,13 @@ class TypedUrlDataTypeController : public DataTypeController, virtual bool enabled(); - virtual syncable::ModelType type(); + virtual syncable::ModelType type() const; - virtual browser_sync::ModelSafeGroup model_safe_group(); + virtual browser_sync::ModelSafeGroup model_safe_group() const; - virtual const char* name() const; + virtual std::string name() const; - virtual State state(); + virtual State state() const; // UnrecoverableHandler implementation virtual void OnUnrecoverableError(const tracked_objects::Location& from_here, diff --git a/chrome/browser/sync/profile_sync_factory_impl.cc b/chrome/browser/sync/profile_sync_factory_impl.cc index 1a31c09..430941c 100644 --- a/chrome/browser/sync/profile_sync_factory_impl.cc +++ b/chrome/browser/sync/profile_sync_factory_impl.cc @@ -127,7 +127,7 @@ ProfileSyncService* ProfileSyncFactoryImpl::CreateProfileSyncService( // disabled. if (!command_line_->HasSwitch(switches::kDisableSyncPreferences)) { pss->RegisterDataTypeController( - new PreferenceDataTypeController(this, pss)); + new PreferenceDataTypeController(this, profile_, pss)); } // Theme sync is enabled by default. Register unless explicitly disabled. @@ -147,7 +147,7 @@ ProfileSyncService* ProfileSyncFactoryImpl::CreateProfileSyncService( // enabled. if (command_line_->HasSwitch(switches::kEnableSyncSessions)) { pss->RegisterDataTypeController( - new SessionDataTypeController(this, pss)); + new SessionDataTypeController(this, profile_, pss)); } if (!command_line_->HasSwitch(switches::kDisableSyncAutofillProfile)) { diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 102d4ee..dde2a0e 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -32,6 +32,8 @@ #include "chrome/browser/sync/js_arg_list.h" #include "chrome/browser/sync/profile_sync_factory.h" #include "chrome/browser/sync/signin_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/net/gaia/gaia_constants.h" #include "chrome/common/pref_names.h" diff --git a/chrome/browser/sync/profile_sync_service_preference_unittest.cc b/chrome/browser/sync/profile_sync_service_preference_unittest.cc index e3ae3f7..1739d69 100644 --- a/chrome/browser/sync/profile_sync_service_preference_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_preference_unittest.cc @@ -84,6 +84,7 @@ class ProfileSyncServicePreferenceTest service_->RegisterDataTypeController( new PreferenceDataTypeController(&factory_, + profile_.get(), service_.get())); profile_->GetTokenService()->IssueAuthTokenForTest( GaiaConstants::kSyncService, "token"); @@ -116,12 +117,12 @@ class ProfileSyncServicePreferenceTest return reader.JsonToValue(specifics.value(), false, false); } - int64 WriteSyncedValue(sync_api::WriteNode& node, - const std::string& name, - const Value& value) { - if (!PreferenceModelAssociator::WritePreferenceToNode(name, value, &node)) + int64 WriteSyncedValue(const std::string& name, + const Value& value, + sync_api::WriteNode* node) { + if (!PreferenceModelAssociator::WritePreferenceToNode(name, value, node)) return sync_api::kInvalidId; - return node.GetId(); + return node->GetId(); } int64 SetSyncedValue(const std::string& name, const Value& value) { @@ -136,11 +137,11 @@ class ProfileSyncServicePreferenceTest int64 node_id = model_associator_->GetSyncIdFromChromeId(name); if (node_id == sync_api::kInvalidId) { if (tag_node.InitByClientTagLookup(syncable::PREFERENCES, name)) - return WriteSyncedValue(tag_node, name, value); + return WriteSyncedValue(name, value, &tag_node); if (node.InitUniqueByCreation(syncable::PREFERENCES, root, name)) - return WriteSyncedValue(node, name, value); + return WriteSyncedValue(name, value, &node); } else if (node.InitByIdLookup(node_id)) { - return WriteSyncedValue(node, name, value); + return WriteSyncedValue(name, value, &node); } return sync_api::kInvalidId; } diff --git a/chrome/browser/sync/profile_sync_service_session_unittest.cc b/chrome/browser/sync/profile_sync_service_session_unittest.cc index cd1337b..ed08d52 100644 --- a/chrome/browser/sync/profile_sync_service_session_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_session_unittest.cc @@ -115,7 +115,9 @@ class ProfileSyncServiceSessionTest EXPECT_CALL(factory_, CreateDataTypeManager(_, _)). WillOnce(ReturnNewDataTypeManager()); sync_service_->RegisterDataTypeController( - new SessionDataTypeController(&factory_, sync_service_.get())); + new SessionDataTypeController(&factory_, + profile(), + sync_service_.get())); profile()->GetTokenService()->IssueAuthTokenForTest( GaiaConstants::kSyncService, "token"); sync_service_->Initialize(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b9fe9cd..33ac815 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1874,6 +1874,8 @@ 'browser/sync/glue/extension_util.h', 'browser/sync/glue/foreign_session_tracker.cc', 'browser/sync/glue/foreign_session_tracker.h', + 'browser/sync/glue/frontend_data_type_controller.cc', + 'browser/sync/glue/frontend_data_type_controller.h', 'browser/sync/glue/history_model_worker.cc', 'browser/sync/glue/history_model_worker.h', 'browser/sync/glue/http_bridge.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 50f3d47..50db52e 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1527,6 +1527,9 @@ 'browser/sync/glue/extension_data_unittest.cc', 'browser/sync/glue/extension_data_type_controller_unittest.cc', 'browser/sync/glue/extension_util_unittest.cc', + 'browser/sync/glue/frontend_data_type_controller_mock.cc', + 'browser/sync/glue/frontend_data_type_controller_mock.h', + 'browser/sync/glue/frontend_data_type_controller_unittest.cc', 'browser/sync/glue/http_bridge_unittest.cc', 'browser/sync/glue/model_associator_mock.cc', 'browser/sync/glue/model_associator_mock.h', |