diff options
13 files changed, 159 insertions, 149 deletions
diff --git a/chrome/browser/api/webdata/web_data_service_base.h b/chrome/browser/api/webdata/web_data_service_base.h index dc30fc1..1c92550 100644 --- a/chrome/browser/api/webdata/web_data_service_base.h +++ b/chrome/browser/api/webdata/web_data_service_base.h @@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/supports_user_data.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_source.h" #include "sql/init_status.h" @@ -70,8 +71,15 @@ class WebDataServiceBase // DBThread. virtual WebDatabase* GetDatabase(); + // Returns a SupportsUserData objects that may be used to store data + // owned by the DB thread on this object. Should be called only from + // the DB thread, and will be destroyed on the DB thread soon after + // |ShutdownOnUIThread()| is called. + base::SupportsUserData* GetDBUserData(); + protected: virtual ~WebDataServiceBase(); + virtual void ShutdownOnDBThread(); // Our database service. scoped_ptr<WebDatabaseService> wdbs_; @@ -86,6 +94,23 @@ class WebDataServiceBase ProfileErrorCallback profile_error_callback_; + // This makes the destructor public, and thus allows us to aggregate + // SupportsUserData. It is private by default to prevent incorrect + // usage in class hierarchies where it is inherited by + // reference-counted objects. + class SupportsUserDataAggregatable : public base::SupportsUserData { + public: + SupportsUserDataAggregatable() {} + virtual ~SupportsUserDataAggregatable() {} + private: + DISALLOW_COPY_AND_ASSIGN(SupportsUserDataAggregatable); + }; + + // Storage for user data to be accessed only on the DB thread. May + // be used e.g. for SyncableService subclasses that need to be owned + // by this object. Is created on first call to |GetDBUserData()|. + scoped_ptr<SupportsUserDataAggregatable> db_thread_user_data_; + void DBInitFailed(sql::InitStatus sql_status); void NotifyDatabaseLoadedOnUIThread(); void DatabaseInitOnDB(sql::InitStatus status); diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.cc b/chrome/browser/sync/glue/autofill_data_type_controller.cc index 5bff9a8..a611682 100644 --- a/chrome/browser/sync/glue/autofill_data_type_controller.cc +++ b/chrome/browser/sync/glue/autofill_data_type_controller.cc @@ -107,7 +107,7 @@ void AutofillDataTypeController::UpdateAutofillCullingSettings( bool cull_expired_entries) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); AutocompleteSyncableService* service = - web_data_service_->GetAutocompleteSyncableService(); + AutocompleteSyncableService::FromWebDataService(web_data_service_); if (!service) { DVLOG(1) << "Can't update culling, no AutocompleteSyncableService."; return; diff --git a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc index b6cac6a..a9ae8e5 100644 --- a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/bind.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" @@ -60,34 +61,30 @@ class FakeWebDataService : public WebDataService { return is_database_loaded_; } - virtual AutocompleteSyncableService* - GetAutocompleteSyncableService() const OVERRIDE { - return autocomplete_syncable_service_; - } - - void StartSyncableService() { - // The |autofill_profile_syncable_service_| must be constructed on the DB + virtual void ShutdownOnUIThread() OVERRIDE { + // The storage for syncable services must be destructed on the DB // thread. base::RunLoop run_loop; BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE, - base::Bind(&FakeWebDataService::CreateSyncableService, + base::Bind(&FakeWebDataService::ShutdownOnDBThread, base::Unretained(this)), run_loop.QuitClosure()); run_loop.Run(); } - void ShutdownSyncableService() { - // The |autofill_profile_syncable_service_| must be destructed on the DB + void StartSyncableService() { + // The |autofill_profile_syncable_service_| must be constructed on the DB // thread. base::RunLoop run_loop; BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE, - base::Bind(&FakeWebDataService::DestroySyncableService, + base::Bind(&FakeWebDataService::CreateSyncableService, base::Unretained(this)), run_loop.QuitClosure()); run_loop.Run(); } void GetAutofillCullingValue(bool* result) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); - *result = autocomplete_syncable_service_->cull_expired_entries(); + *result = AutocompleteSyncableService::FromWebDataService( + this)->cull_expired_entries(); } bool CheckAutofillCullingValue() { @@ -102,25 +99,14 @@ class FakeWebDataService : public WebDataService { private: virtual ~FakeWebDataService() { - DCHECK(!autocomplete_syncable_service_); } void CreateSyncableService() { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); // These services are deleted in DestroySyncableService(). - autocomplete_syncable_service_ = new AutocompleteSyncableService(this); - } - - void DestroySyncableService() { - ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); - delete autocomplete_syncable_service_; - autocomplete_syncable_service_ = NULL; + AutocompleteSyncableService::CreateForWebDataService(this); } - // We own the syncable services, but don't use a |scoped_ptr| because the - // lifetime must be managed on the DB thread. - AutocompleteSyncableService* autocomplete_syncable_service_; - bool is_database_loaded_; DISALLOW_COPY_AND_ASSIGN(FakeWebDataService); @@ -138,7 +124,7 @@ class MockWebDataServiceWrapperSyncable : public MockWebDataServiceWrapper { void Shutdown() OVERRIDE { static_cast<FakeWebDataService*>( - fake_web_data_service_.get())->ShutdownSyncableService(); + fake_web_data_service_.get())->ShutdownOnUIThread(); } private: diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc index dc447fc..9eaa3c9 100644 --- a/chrome/browser/sync/profile_sync_components_factory_impl.cc +++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc @@ -304,10 +304,11 @@ base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl:: if (!web_data_service_.get()) return base::WeakPtr<syncer::SyncableService>(); if (type == syncer::AUTOFILL) { - return web_data_service_->GetAutocompleteSyncableService()->AsWeakPtr(); + return AutocompleteSyncableService::FromWebDataService( + web_data_service_)->AsWeakPtr(); } else { - return web_data_service_-> - GetAutofillProfileSyncableService()->AsWeakPtr(); + return AutofillProfileSyncableService::FromWebDataService( + web_data_service_)->AsWeakPtr(); } } case syncer::APPS: diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc index 6ffaf1b..f82ba96 100644 --- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc @@ -193,21 +193,7 @@ class WebDataServiceFake : public WebDataService { return 0; } - virtual AutocompleteSyncableService* - GetAutocompleteSyncableService() const OVERRIDE { - EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); - EXPECT_TRUE(autocomplete_syncable_service_); - - return autocomplete_syncable_service_; - } - - virtual AutofillProfileSyncableService* - GetAutofillProfileSyncableService() const OVERRIDE { - EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); - EXPECT_TRUE(autofill_profile_syncable_service_); - - return autofill_profile_syncable_service_; - } + virtual void ShutdownOnUIThread() OVERRIDE {} private: virtual ~WebDataServiceFake() {} @@ -215,25 +201,19 @@ class WebDataServiceFake : public WebDataService { void CreateSyncableService() { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); // These services are deleted in DestroySyncableService(). - autocomplete_syncable_service_ = new AutocompleteSyncableService(this); - autofill_profile_syncable_service_ = - new AutofillProfileSyncableService(this); + AutocompleteSyncableService::CreateForWebDataService(this); + AutofillProfileSyncableService::CreateForWebDataService(this); syncable_service_created_or_destroyed_.Signal(); } void DestroySyncableService() { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); - delete autofill_profile_syncable_service_; - delete autocomplete_syncable_service_; + WebDataServiceBase::ShutdownOnDBThread(); syncable_service_created_or_destroyed_.Signal(); } WebDatabase* web_database_; - // We own the syncable services, but don't use a |scoped_ptr| because the - // lifetime must be managed on the DB thread. - AutocompleteSyncableService* autocomplete_syncable_service_; - AutofillProfileSyncableService* autofill_profile_syncable_service_; WaitableEvent syncable_service_created_or_destroyed_; }; @@ -245,7 +225,7 @@ ACTION_P(MakeAutocompleteSyncComponents, wds) { EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); if (!BrowserThread::CurrentlyOn(BrowserThread::DB)) return base::WeakPtr<syncer::SyncableService>(); - return wds->GetAutocompleteSyncableService()->AsWeakPtr(); + return AutocompleteSyncableService::FromWebDataService(wds)->AsWeakPtr(); } ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) { @@ -274,7 +254,7 @@ ACTION_P(MakeAutofillProfileSyncComponents, wds) { EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); if (!BrowserThread::CurrentlyOn(BrowserThread::DB)) return base::WeakPtr<syncer::SyncableService>();; - return wds->GetAutofillProfileSyncableService()->AsWeakPtr(); + return AutofillProfileSyncableService::FromWebDataService(wds)->AsWeakPtr(); } class AbstractAutofillFactory { diff --git a/chrome/browser/webdata/autocomplete_syncable_service.cc b/chrome/browser/webdata/autocomplete_syncable_service.cc index f039075..e3499c2 100644 --- a/chrome/browser/webdata/autocomplete_syncable_service.cc +++ b/chrome/browser/webdata/autocomplete_syncable_service.cc @@ -79,6 +79,13 @@ bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill, } } +void* UserDataKey() { + // Use the address of a static that COMDAT folding won't ever fold + // with something else. + static int user_data_key = 0; + return reinterpret_cast<void*>(&user_data_key); +} + } // namespace AutocompleteSyncableService::AutocompleteSyncableService( @@ -96,6 +103,20 @@ AutocompleteSyncableService::~AutocompleteSyncableService() { DCHECK(CalledOnValidThread()); } +// static +void AutocompleteSyncableService::CreateForWebDataService( + WebDataService* web_data) { + web_data->GetDBUserData()->SetUserData( + UserDataKey(), new AutocompleteSyncableService(web_data)); +} + +// static +AutocompleteSyncableService* AutocompleteSyncableService::FromWebDataService( + WebDataService* web_data) { + return static_cast<AutocompleteSyncableService*>( + web_data->GetDBUserData()->GetUserData(UserDataKey())); +} + AutocompleteSyncableService::AutocompleteSyncableService() : web_data_service_(NULL), cull_expired_entries_(false) { diff --git a/chrome/browser/webdata/autocomplete_syncable_service.h b/chrome/browser/webdata/autocomplete_syncable_service.h index 3a0a5c9..5b1b91e 100644 --- a/chrome/browser/webdata/autocomplete_syncable_service.h +++ b/chrome/browser/webdata/autocomplete_syncable_service.h @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/supports_user_data.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/webdata/autofill_change.h" #include "chrome/browser/webdata/autofill_entry.h" @@ -40,13 +41,23 @@ class AutofillSpecifics; // TODO(georgey) : remove reliance on the notifications and make it to be called // from web_data_service directly. class AutocompleteSyncableService - : public syncer::SyncableService, + : public base::SupportsUserData::Data, + public syncer::SyncableService, public content::NotificationObserver, public base::NonThreadSafe { public: - explicit AutocompleteSyncableService(WebDataService* web_data_service); virtual ~AutocompleteSyncableService(); + // TODO(joi): Change this to key off AutofillWebDataService instead + // of WebDataService, once it is truly separate. + + // Creates a new AutocompleteSyncableService and hangs it off of + // |web_data|, which takes ownership. + static void CreateForWebDataService(WebDataService* web_data); + // Retrieves the AutocompleteSyncableService stored on |web_data|. + static AutocompleteSyncableService* FromWebDataService( + WebDataService* web_data); + static syncer::ModelType model_type() { return syncer::AUTOFILL; } // syncer::SyncableService implementation. @@ -73,6 +84,8 @@ class AutocompleteSyncableService bool cull_expired_entries() const { return cull_expired_entries_; } protected: + explicit AutocompleteSyncableService(WebDataService* web_data_service); + // Helper to query WebDatabase for the current autocomplete state. // Made virtual for ease of mocking in the unit-test. virtual bool LoadAutofillData(std::vector<AutofillEntry>* entries) const; diff --git a/chrome/browser/webdata/autofill_profile_syncable_service.cc b/chrome/browser/webdata/autofill_profile_syncable_service.cc index 980ca80..2e936dc 100644 --- a/chrome/browser/webdata/autofill_profile_syncable_service.cc +++ b/chrome/browser/webdata/autofill_profile_syncable_service.cc @@ -33,6 +33,13 @@ std::string LimitData(const std::string& data) { return sanitized_value; } +void* UserDataKey() { + // Use the address of a static that COMDAT folding won't ever fold + // with something else. + static int user_data_key = 0; + return reinterpret_cast<void*>(&user_data_key); +} + } // namespace const char kAutofillProfileTag[] = "google_chrome_autofill_profiles"; @@ -52,6 +59,21 @@ AutofillProfileSyncableService::~AutofillProfileSyncableService() { DCHECK(CalledOnValidThread()); } +// static +void AutofillProfileSyncableService::CreateForWebDataService( + WebDataService* web_data) { + web_data->GetDBUserData()->SetUserData( + UserDataKey(), new AutofillProfileSyncableService(web_data)); +} + +// static +AutofillProfileSyncableService* +AutofillProfileSyncableService::FromWebDataService( + WebDataService* service) { + return static_cast<AutofillProfileSyncableService*>( + service->GetDBUserData()->GetUserData(UserDataKey())); +} + AutofillProfileSyncableService::AutofillProfileSyncableService() : web_data_service_(NULL) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); diff --git a/chrome/browser/webdata/autofill_profile_syncable_service.h b/chrome/browser/webdata/autofill_profile_syncable_service.h index c55cec5..2c4b93b 100644 --- a/chrome/browser/webdata/autofill_profile_syncable_service.h +++ b/chrome/browser/webdata/autofill_profile_syncable_service.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_vector.h" +#include "base/supports_user_data.h" #include "base/synchronization/lock.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/webdata/autofill_change.h" @@ -29,6 +30,7 @@ class AutofillTable; class FormGroup; class ProfileSyncServiceAutofillTest; class WebDataService; +class WebDataServiceBase; extern const char kAutofillProfileTag[]; @@ -37,13 +39,23 @@ extern const char kAutofillProfileTag[]; // local->cloud syncs. Then for each cloud change we receive // ProcessSyncChanges() and for each local change Observe() is called. class AutofillProfileSyncableService - : public syncer::SyncableService, + : public base::SupportsUserData::Data, + public syncer::SyncableService, public content::NotificationObserver, public base::NonThreadSafe { public: - explicit AutofillProfileSyncableService(WebDataService* web_data_service); virtual ~AutofillProfileSyncableService(); + // TODO(joi): Change this to key off AutofillWebDataService instead + // of WebDataService, once it is truly separate. + + // Creates a new AutofillProfileSyncableService and hangs it off of + // |web_data|, which takes ownership. + static void CreateForWebDataService(WebDataService* web_data); + // Retrieves the AutofillProfileSyncableService stored on |web_data|. + static AutofillProfileSyncableService* FromWebDataService( + WebDataService* web_data); + static syncer::ModelType model_type() { return syncer::AUTOFILL_PROFILE; } // syncer::SyncableService implementation. @@ -65,6 +77,8 @@ class AutofillProfileSyncableService const content::NotificationDetails& details) OVERRIDE; protected: + explicit AutofillProfileSyncableService(WebDataService* web_data_service); + // A convenience wrapper of a bunch of state we pass around while // associating models, and send to the WebDatabase for persistence. // We do this so we hold the write lock for only a small period. diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc index 9557ef8..894902d 100644 --- a/chrome/browser/webdata/web_data_service.cc +++ b/chrome/browser/webdata/web_data_service.cc @@ -4,11 +4,10 @@ #include "chrome/browser/webdata/web_data_service.h" +#include "base/stl_util.h" #include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/webdata/autocomplete_syncable_service.h" #include "chrome/browser/webdata/autofill_change.h" #include "chrome/browser/webdata/autofill_entry.h" -#include "chrome/browser/webdata/autofill_profile_syncable_service.h" #include "chrome/browser/webdata/autofill_table.h" #include "chrome/browser/webdata/keyword_table.h" #include "chrome/browser/webdata/logins_table.h" @@ -64,9 +63,7 @@ WDKeywordsResult::WDKeywordsResult() WDKeywordsResult::~WDKeywordsResult() {} WebDataService::WebDataService(const ProfileErrorCallback& callback) - : WebDataServiceBase(callback), - autocomplete_syncable_service_(NULL), - autofill_profile_syncable_service_(NULL) { + : WebDataServiceBase(callback) { } // static @@ -83,18 +80,6 @@ void WebDataService::NotifyOfMultipleAutofillChanges( make_scoped_refptr(web_data_service))); } -void WebDataService::ShutdownOnUIThread() { - BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, - Bind(&WebDataService::ShutdownSyncableServices, this)); - WebDataServiceBase::ShutdownOnUIThread(); -} - -void WebDataService::Init(const base::FilePath& path) { - WebDataServiceBase::Init(path); - BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, - Bind(&WebDataService::InitializeSyncableServices, this)); -} - ////////////////////////////////////////////////////////////////////////////// // // Keywords. @@ -277,38 +262,10 @@ void WebDataService::RemoveAutofillProfilesAndCreditCardsModifiedBetween( } WebDataService::WebDataService() - : WebDataServiceBase(ProfileErrorCallback()), - autocomplete_syncable_service_(NULL), - autofill_profile_syncable_service_(NULL) { + : WebDataServiceBase(ProfileErrorCallback()) { } WebDataService::~WebDataService() { - DCHECK(!autocomplete_syncable_service_); - DCHECK(!autofill_profile_syncable_service_); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The following methods are executed on the DB thread. -// -//////////////////////////////////////////////////////////////////////////////// - -void WebDataService::InitializeSyncableServices() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - DCHECK(!autocomplete_syncable_service_); - DCHECK(!autofill_profile_syncable_service_); - - autocomplete_syncable_service_ = new AutocompleteSyncableService(this); - autofill_profile_syncable_service_ = new AutofillProfileSyncableService(this); -} - -void WebDataService::ShutdownSyncableServices() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - - delete autocomplete_syncable_service_; - autocomplete_syncable_service_ = NULL; - delete autofill_profile_syncable_service_; - autofill_profile_syncable_service_ = NULL; } //////////////////////////////////////////////////////////////////////////////// @@ -685,22 +642,6 @@ WebDataService::RemoveAutofillProfilesAndCreditCardsModifiedBetweenImpl( return WebDatabase::COMMIT_NOT_NEEDED; } -AutofillProfileSyncableService* - WebDataService::GetAutofillProfileSyncableService() const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - DCHECK(autofill_profile_syncable_service_); // Make sure we're initialized. - - return autofill_profile_syncable_service_; -} - -AutocompleteSyncableService* WebDataService::GetAutocompleteSyncableService() - const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - DCHECK(autocomplete_syncable_service_); // Make sure we're initialized. - - return autocomplete_syncable_service_; -} - void WebDataService::DestroyAutofillProfileResult(const WDTypedResult* result) { DCHECK(result->GetType() == AUTOFILL_PROFILES_RESULT); const WDResult<std::vector<AutofillProfile*> >* r = diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h index 9eabe67..7db7caf 100644 --- a/chrome/browser/webdata/web_data_service.h +++ b/chrome/browser/webdata/web_data_service.h @@ -109,10 +109,6 @@ class WebDataService explicit WebDataService(const ProfileErrorCallback& callback); - // WebDataServiceBase implementation. - virtual void ShutdownOnUIThread() OVERRIDE; - virtual void Init(const base::FilePath& path) OVERRIDE; - // Notifies listeners on the UI thread that multiple changes have been made to // to Autofill records of the database. // NOTE: This method is intended to be called from the DB thread. It @@ -289,16 +285,6 @@ class WebDataService void RemoveFormElementsAddedBetween(const base::Time& delete_begin, const base::Time& delete_end); - // Returns the syncable service for Autofill addresses and credit cards stored - // in this table. The returned service is owned by |this| object. - virtual AutofillProfileSyncableService* - GetAutofillProfileSyncableService() const; - - // Returns the syncable service for field autocomplete stored in this table. - // The returned service is owned by |this| object. - virtual AutocompleteSyncableService* - GetAutocompleteSyncableService() const; - protected: // TODO(caitkp): We probably don't need these anymore. friend class TemplateURLServiceTest; @@ -311,17 +297,12 @@ class WebDataService virtual ~WebDataService(); + private: ////////////////////////////////////////////////////////////////////////////// // // The following methods are only invoked in the web data service thread. // ////////////////////////////////////////////////////////////////////////////// - private: - // Initialize any syncable services. - void InitializeSyncableServices(); - - // Deletes the syncable services. - void ShutdownSyncableServices(); ////////////////////////////////////////////////////////////////////////////// // @@ -441,14 +422,6 @@ class WebDataService void DestroyAutofillProfileResult(const WDTypedResult* result); void DestroyAutofillCreditCardResult(const WDTypedResult* result); - // Syncable services for the database data. We own the services, but don't - // use |scoped_ptr|s because the lifetimes must be managed on the database - // thread. - // Currently only Autocomplete and Autofill profiles use the new Sync API, but - // all the database data should migrate to this API over time. - AutocompleteSyncableService* autocomplete_syncable_service_; - AutofillProfileSyncableService* autofill_profile_syncable_service_; - DISALLOW_COPY_AND_ASSIGN(WebDataService); }; diff --git a/chrome/browser/webdata/web_data_service_base.cc b/chrome/browser/webdata/web_data_service_base.cc index 68650cf..57891aa 100644 --- a/chrome/browser/webdata/web_data_service_base.cc +++ b/chrome/browser/webdata/web_data_service_base.cc @@ -40,6 +40,9 @@ WebDataServiceBase::WebDataServiceBase(const ProfileErrorCallback& callback) void WebDataServiceBase::ShutdownOnUIThread() { db_loaded_ = false; + BrowserThread::PostTask( + BrowserThread::DB, FROM_HERE, + base::Bind(&WebDataServiceBase::ShutdownOnDBThread, this)); ShutdownDatabase(); } @@ -80,10 +83,23 @@ WebDatabase* WebDataServiceBase::GetDatabase() { return wdbs_->GetDatabaseOnDB(); } +base::SupportsUserData* WebDataServiceBase::GetDBUserData() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + if (!db_thread_user_data_) + db_thread_user_data_.reset(new SupportsUserDataAggregatable()); + return db_thread_user_data_.get(); +} + WebDataServiceBase::~WebDataServiceBase() { + DCHECK(!db_thread_user_data_.get()) << "Forgot to call ShutdownOnUIThread?"; wdbs_.reset(); } +void WebDataServiceBase::ShutdownOnDBThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + db_thread_user_data_.reset(); +} + //////////////////////////////////////////////////////////////////////////////// // // The following methods are executed on the DB thread. diff --git a/chrome/browser/webdata/web_data_service_factory.cc b/chrome/browser/webdata/web_data_service_factory.cc index 25a6af7..c687186 100644 --- a/chrome/browser/webdata/web_data_service_factory.cc +++ b/chrome/browser/webdata/web_data_service_factory.cc @@ -8,11 +8,16 @@ #include "base/files/file_path.h" #include "chrome/browser/profiles/profile_dependency_manager.h" #include "chrome/browser/ui/profile_error_dialog.h" +#include "chrome/browser/webdata/autocomplete_syncable_service.h" +#include "chrome/browser/webdata/autofill_profile_syncable_service.h" #include "chrome/browser/webdata/autofill_web_data_service_impl.h" #include "chrome/common/chrome_constants.h" +#include "content/public/browser/browser_thread.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" +using content::BrowserThread; + namespace { // Callback to show error dialog on profile load error. @@ -22,6 +27,15 @@ void ProfileErrorCallback(sql::InitStatus status) { IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR); } +void InitSyncableServicesOnDBThread(scoped_refptr<WebDataService> web_data) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + + // Currently only Autocomplete and Autofill profiles use the new Sync API, but + // all the database data should migrate to this API over time. + AutocompleteSyncableService::CreateForWebDataService(web_data); + AutofillProfileSyncableService::CreateForWebDataService(web_data); +} + } // namespace WebDataServiceWrapper::WebDataServiceWrapper() {} @@ -31,6 +45,10 @@ WebDataServiceWrapper::WebDataServiceWrapper(Profile* profile) { path = path.Append(chrome::kWebDataFilename); web_data_service_ = new WebDataService(base::Bind(&ProfileErrorCallback)); web_data_service_->Init(path); + + BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, + base::Bind(&InitSyncableServicesOnDBThread, + web_data_service_)); } WebDataServiceWrapper::~WebDataServiceWrapper() { |