diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-16 04:32:31 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-16 04:32:31 +0000 |
commit | abc77243c735ff8b44deac96a5fc81fd9788b2c9 (patch) | |
tree | 108d9a16f4c49161bafe4758db3359aebdd832f6 | |
parent | 85059c375bfd167ba24b51f59fe0b5ed70a53d9b (diff) | |
download | chromium_src-abc77243c735ff8b44deac96a5fc81fd9788b2c9.zip chromium_src-abc77243c735ff8b44deac96a5fc81fd9788b2c9.tar.gz chromium_src-abc77243c735ff8b44deac96a5fc81fd9788b2c9.tar.bz2 |
Profiles: Really fix refcounted services.
Previous attempts to share code between ProfileKeyedServiceFactory and RefcountedProfileKeyedServiceFactory were ill advised. The core logic code must maintain refcounted data in a scoped_refptr<> for the entire lifecycle, across interface and implementation, preventing any real abstraction here.
This removes the common ProfileKeyedBase and splits the two worlds entirely in two. This has quite a bit of exact code with different types now.
Fallout from this is far reaching:
- Since there isn't one common heiarchy, now the testing methods either return ProfileKeyedServices or scoped_refptr<RefcountedProfileKeyedService>s. This is a lot of change.
- Many consumers handled the refcounted ptrs as raw pointers, which probably isn't a good idea.
- There is now a bunch of code duplication.
BUG=118196,77155
R=mirandac,tim
TBR=jhawkins,sky,scottbyer
Review URL: http://codereview.chromium.org/9703038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127104 0039d316-1c4b-4281-b951-d872f2087c98
51 files changed, 386 insertions, 300 deletions
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc index 98d93da..94ec873 100644 --- a/chrome/browser/autofill/autofill_manager_unittest.cc +++ b/chrome/browser/autofill/autofill_manager_unittest.cc @@ -68,7 +68,7 @@ class TestPersonalDataManager : public PersonalDataManager { } // Factory method for keyed service. PersonalDataManager is NULL for testing. - static ProfileKeyedBase* Build(Profile* profile) { + static ProfileKeyedService* Build(Profile* profile) { return NULL; } diff --git a/chrome/browser/content_settings/cookie_settings.cc b/chrome/browser/content_settings/cookie_settings.cc index 46a580e..742cc73 100644 --- a/chrome/browser/content_settings/cookie_settings.cc +++ b/chrome/browser/content_settings/cookie_settings.cc @@ -44,10 +44,11 @@ bool IsAllowed(ContentSetting setting) { } // namespace // static -CookieSettings* CookieSettings::Factory::GetForProfile(Profile* profile) { +scoped_refptr<CookieSettings> CookieSettings::Factory::GetForProfile( + Profile* profile) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); return static_cast<CookieSettings*>( - GetInstance()->GetBaseForProfile(profile, true)); + GetInstance()->GetServiceForProfile(profile, true).get()); } // static @@ -73,7 +74,7 @@ bool CookieSettings::Factory::ServiceRedirectedInIncognito() { return true; } -RefcountedProfileKeyedService* +scoped_refptr<RefcountedProfileKeyedService> CookieSettings::Factory::BuildServiceInstanceFor(Profile* profile) const { return new CookieSettings(profile->GetHostContentSettingsMap(), profile->GetPrefs()); diff --git a/chrome/browser/content_settings/cookie_settings.h b/chrome/browser/content_settings/cookie_settings.h index c8e8c8e..59996ef 100644 --- a/chrome/browser/content_settings/cookie_settings.h +++ b/chrome/browser/content_settings/cookie_settings.h @@ -9,6 +9,7 @@ #include <string> #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "base/synchronization/lock.h" #include "chrome/browser/content_settings/host_content_settings_map.h" @@ -117,7 +118,7 @@ class CookieSettings // Returns the |CookieSettings| associated with the |profile|. // // This should only be called on the UI thread. - static CookieSettings* GetForProfile(Profile* profile); + static scoped_refptr<CookieSettings> GetForProfile(Profile* profile); static Factory* GetInstance(); @@ -130,8 +131,8 @@ class CookieSettings // |ProfileKeyedBaseFactory| methods: virtual void RegisterUserPrefs(PrefService* user_prefs) OVERRIDE; virtual bool ServiceRedirectedInIncognito() OVERRIDE; - virtual RefcountedProfileKeyedService* BuildServiceInstanceFor( - Profile* profile) const OVERRIDE; + virtual scoped_refptr<RefcountedProfileKeyedService> + BuildServiceInstanceFor(Profile* profile) const OVERRIDE; }; private: diff --git a/chrome/browser/extensions/api/browsingdata/browsing_data_api.cc b/chrome/browser/extensions/api/browsingdata/browsing_data_api.cc index 3e330c5..c822ffa 100644 --- a/chrome/browser/extensions/api/browsingdata/browsing_data_api.cc +++ b/chrome/browser/extensions/api/browsingdata/browsing_data_api.cc @@ -146,7 +146,7 @@ bool BrowsingDataExtensionFunction::RunImpl() { base::Bind( &BrowsingDataExtensionFunction::CheckRemovingPluginDataSupported, this, - make_scoped_refptr(PluginPrefs::GetForProfile(profile)))); + PluginPrefs::GetForProfile(profile))); } else { StartRemoving(); } diff --git a/chrome/browser/extensions/app_notify_channel_setup_unittest.cc b/chrome/browser/extensions/app_notify_channel_setup_unittest.cc index b71b3ca..6407243 100644 --- a/chrome/browser/extensions/app_notify_channel_setup_unittest.cc +++ b/chrome/browser/extensions/app_notify_channel_setup_unittest.cc @@ -57,7 +57,7 @@ class MockTokenService : public TokenService { MOCK_CONST_METHOD0(HasOAuthLoginToken, bool()); }; -ProfileKeyedBase* BuildMockTokenService(Profile* profile) { +ProfileKeyedService* BuildMockTokenService(Profile* profile) { return new MockTokenService; } diff --git a/chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.cc b/chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.cc index e6532ef..2743a28 100644 --- a/chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.cc +++ b/chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.cc @@ -25,7 +25,7 @@ class MockWebIntentsRegistry : public WebIntentsRegistry { void(const webkit_glue::WebIntentServiceData&)); }; -ProfileKeyedBase* BuildMockWebIntentsRegistry(Profile* profile) { +ProfileKeyedService* BuildMockWebIntentsRegistry(Profile* profile) { return new MockWebIntentsRegistry; } diff --git a/chrome/browser/password_manager/mock_password_store.cc b/chrome/browser/password_manager/mock_password_store.cc index 7f9d57e..087ad83 100644 --- a/chrome/browser/password_manager/mock_password_store.cc +++ b/chrome/browser/password_manager/mock_password_store.cc @@ -9,7 +9,8 @@ MockPasswordStore::MockPasswordStore() {} MockPasswordStore::~MockPasswordStore() {} // static -ProfileKeyedBase* MockPasswordStore::Build(Profile* profile) { +scoped_refptr<RefcountedProfileKeyedService> MockPasswordStore::Build( + Profile* profile) { return new MockPasswordStore; } diff --git a/chrome/browser/password_manager/mock_password_store.h b/chrome/browser/password_manager/mock_password_store.h index daa940c..5a13964 100644 --- a/chrome/browser/password_manager/mock_password_store.h +++ b/chrome/browser/password_manager/mock_password_store.h @@ -16,7 +16,7 @@ class MockPasswordStore : public PasswordStore { MockPasswordStore(); virtual ~MockPasswordStore(); - static ProfileKeyedBase* Build(Profile* profile); + static scoped_refptr<RefcountedProfileKeyedService> Build(Profile* profile); MOCK_METHOD1(RemoveLogin, void(const webkit::forms::PasswordForm&)); MOCK_METHOD2(GetLogins, int(const webkit::forms::PasswordForm&, diff --git a/chrome/browser/password_manager/password_manager_unittest.cc b/chrome/browser/password_manager/password_manager_unittest.cc index 9216612..029c2e0 100644 --- a/chrome/browser/password_manager/password_manager_unittest.cc +++ b/chrome/browser/password_manager/password_manager_unittest.cc @@ -57,7 +57,7 @@ class PasswordManagerTest : public ChromeRenderViewHostTestHarness { TestingProfile* testing_profile = new TestingProfile; store_ = static_cast<MockPasswordStore*>( PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( - testing_profile, MockPasswordStore::Build)); + testing_profile, MockPasswordStore::Build).get()); browser_context_.reset(testing_profile); ChromeRenderViewHostTestHarness::SetUp(); diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc index 4b161f0..d2f0ef7 100644 --- a/chrome/browser/password_manager/password_store_factory.cc +++ b/chrome/browser/password_manager/password_store_factory.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/environment.h" #include "chrome/browser/password_manager/login_database.h" +#include "chrome/browser/password_manager/password_store.h" #include "chrome/browser/password_manager/password_store_default.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile_dependency_manager.h" @@ -41,7 +42,7 @@ const LocalProfileId kInvalidLocalProfileId = } // namespace #endif -PasswordStore* PasswordStoreFactory::GetForProfile( +scoped_refptr<PasswordStore> PasswordStoreFactory::GetForProfile( Profile* profile, Profile::ServiceAccessType sat) { if (sat == Profile::IMPLICIT_ACCESS && profile->IsOffTheRecord()) { @@ -49,8 +50,8 @@ PasswordStore* PasswordStoreFactory::GetForProfile( return NULL; } - return static_cast<PasswordStore*>(GetInstance()->GetBaseForProfile( - profile, true)); + return static_cast<PasswordStore*>( + GetInstance()->GetServiceForProfile(profile, true).get()); } // static @@ -93,8 +94,8 @@ LocalProfileId PasswordStoreFactory::GetLocalProfileId( } #endif -RefcountedProfileKeyedService* PasswordStoreFactory::BuildServiceInstanceFor( - Profile* profile) const { +scoped_refptr<RefcountedProfileKeyedService> +PasswordStoreFactory::BuildServiceInstanceFor(Profile* profile) const { scoped_refptr<PasswordStore> ps; FilePath login_db_file_path = profile->GetPath(); login_db_file_path = login_db_file_path.Append(chrome::kLoginDataFileName); @@ -186,7 +187,7 @@ RefcountedProfileKeyedService* PasswordStoreFactory::BuildServiceInstanceFor( return NULL; } - return ps.release(); + return ps; } void PasswordStoreFactory::RegisterUserPrefs(PrefService* prefs) { diff --git a/chrome/browser/password_manager/password_store_factory.h b/chrome/browser/password_manager/password_store_factory.h index e18901b..faadb87 100644 --- a/chrome/browser/password_manager/password_store_factory.h +++ b/chrome/browser/password_manager/password_store_factory.h @@ -27,8 +27,8 @@ typedef int LocalProfileId; // the associated PasswordStore. class PasswordStoreFactory : public RefcountedProfileKeyedServiceFactory { public: - static PasswordStore* GetForProfile(Profile* profile, - Profile::ServiceAccessType set); + static scoped_refptr<PasswordStore> GetForProfile( + Profile* profile, Profile::ServiceAccessType set); static PasswordStoreFactory* GetInstance(); @@ -43,7 +43,7 @@ class PasswordStoreFactory : public RefcountedProfileKeyedServiceFactory { #endif // ProfileKeyedServiceFactory: - virtual RefcountedProfileKeyedService* BuildServiceInstanceFor( + virtual scoped_refptr<RefcountedProfileKeyedService> BuildServiceInstanceFor( Profile* profile) const OVERRIDE; virtual void RegisterUserPrefs(PrefService* prefs) OVERRIDE; virtual bool ServiceRedirectedInIncognito() OVERRIDE; diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc index f72e951..087bed7 100644 --- a/chrome/browser/password_manager/password_store_x.cc +++ b/chrome/browser/password_manager/password_store_x.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -30,8 +30,7 @@ PasswordStoreX::PasswordStoreX(LoginDatabase* login_db, backend_(backend), migration_checked_(!backend), allow_fallback_(false) { } -PasswordStoreX::~PasswordStoreX() { -} +PasswordStoreX::~PasswordStoreX() {} void PasswordStoreX::AddLoginImpl(const PasswordForm& form) { CheckMigration(); diff --git a/chrome/browser/plugin_data_remover_helper.cc b/chrome/browser/plugin_data_remover_helper.cc index a53b3b2..558140c 100644 --- a/chrome/browser/plugin_data_remover_helper.cc +++ b/chrome/browser/plugin_data_remover_helper.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -58,7 +58,7 @@ void PluginDataRemoverHelper::Observe( void PluginDataRemoverHelper::StartUpdate() { PluginService::GetInstance()->GetPlugins( base::Bind(&PluginDataRemoverHelper::GotPlugins, factory_.GetWeakPtr(), - make_scoped_refptr(PluginPrefs::GetForProfile(profile_)))); + PluginPrefs::GetForProfile(profile_))); } void PluginDataRemoverHelper::GotPlugins( diff --git a/chrome/browser/plugin_prefs.cc b/chrome/browser/plugin_prefs.cc index 4796b89..6b1264b 100644 --- a/chrome/browser/plugin_prefs.cc +++ b/chrome/browser/plugin_prefs.cc @@ -52,16 +52,16 @@ base::LazyInstance<std::map<FilePath, bool> > g_default_plugin_state = #define kPluginUpdateDelayMs (60 * 1000) // static -PluginPrefs* PluginPrefs::GetForProfile(Profile* profile) { - return PluginPrefsFactory::GetInstance()->GetPrefsForProfile(profile); +scoped_refptr<PluginPrefs> PluginPrefs::GetForProfile(Profile* profile) { + return PluginPrefsFactory::GetPrefsForProfile(profile); } // static -PluginPrefs* PluginPrefs::GetForTestingProfile(Profile* profile) { - ProfileKeyedBase* prefs = +scoped_refptr<PluginPrefs> PluginPrefs::GetForTestingProfile( + Profile* profile) { + return static_cast<PluginPrefs*>( PluginPrefsFactory::GetInstance()->SetTestingFactoryAndUse( - profile, &PluginPrefsFactory::CreatePrefsForProfile); - return static_cast<PluginPrefs*>(prefs); + profile, &PluginPrefsFactory::CreateForTestingProfile).get()); } void PluginPrefs::SetPluginListForTesting( diff --git a/chrome/browser/plugin_prefs.h b/chrome/browser/plugin_prefs.h index f37eac1..678aed2 100644 --- a/chrome/browser/plugin_prefs.h +++ b/chrome/browser/plugin_prefs.h @@ -44,12 +44,12 @@ class PluginPrefs : public RefcountedProfileKeyedService, }; // Returns the instance associated with |profile|, creating it if necessary. - static PluginPrefs* GetForProfile(Profile* profile); + static scoped_refptr<PluginPrefs> GetForProfile(Profile* profile); // Usually the PluginPrefs associated with a TestingProfile is NULL. // This method overrides that for a given TestingProfile, returning the newly // created PluginPrefs object. - static PluginPrefs* GetForTestingProfile(Profile* profile); + static scoped_refptr<PluginPrefs> GetForTestingProfile(Profile* profile); // Sets the plug-in list for tests. void SetPluginListForTesting(webkit::npapi::PluginList* plugin_list); diff --git a/chrome/browser/plugin_prefs_factory.cc b/chrome/browser/plugin_prefs_factory.cc index 804caa0..b43be37 100644 --- a/chrome/browser/plugin_prefs_factory.cc +++ b/chrome/browser/plugin_prefs_factory.cc @@ -19,13 +19,17 @@ PluginPrefsFactory* PluginPrefsFactory::GetInstance() { } // static -ProfileKeyedBase* PluginPrefsFactory::CreatePrefsForProfile( +scoped_refptr<PluginPrefs> PluginPrefsFactory::GetPrefsForProfile( Profile* profile) { - return GetInstance()->BuildServiceInstanceFor(profile); + return static_cast<PluginPrefs*>( + GetInstance()->GetServiceForProfile(profile, true).get()); } -PluginPrefs* PluginPrefsFactory::GetPrefsForProfile(Profile* profile) { - return static_cast<PluginPrefs*>(GetBaseForProfile(profile, true)); +// static +scoped_refptr<RefcountedProfileKeyedService> +PluginPrefsFactory::CreateForTestingProfile(Profile* profile) { + return static_cast<PluginPrefs*>( + GetInstance()->BuildServiceInstanceFor(profile).get()); } PluginPrefsFactory::PluginPrefsFactory() @@ -35,9 +39,9 @@ PluginPrefsFactory::PluginPrefsFactory() PluginPrefsFactory::~PluginPrefsFactory() {} -RefcountedProfileKeyedService* PluginPrefsFactory::BuildServiceInstanceFor( - Profile* profile) const { - PluginPrefs* plugin_prefs = new PluginPrefs(); +scoped_refptr<RefcountedProfileKeyedService> +PluginPrefsFactory::BuildServiceInstanceFor(Profile* profile) const { + scoped_refptr<PluginPrefs> plugin_prefs(new PluginPrefs()); plugin_prefs->set_profile(profile->GetOriginalProfile()); plugin_prefs->SetPrefs(profile->GetPrefs()); return plugin_prefs; diff --git a/chrome/browser/plugin_prefs_factory.h b/chrome/browser/plugin_prefs_factory.h index e29dd9d..c45d9d1 100644 --- a/chrome/browser/plugin_prefs_factory.h +++ b/chrome/browser/plugin_prefs_factory.h @@ -17,20 +17,23 @@ class ProfileKeyedService; class PluginPrefsFactory : public RefcountedProfileKeyedServiceFactory { public: - static PluginPrefsFactory* GetInstance(); - - PluginPrefs* GetPrefsForProfile(Profile* profile); + static scoped_refptr<PluginPrefs> GetPrefsForProfile(Profile* profile); - static ProfileKeyedBase* CreatePrefsForProfile(Profile* profile); + static PluginPrefsFactory* GetInstance(); private: + friend class PluginPrefs; friend struct DefaultSingletonTraits<PluginPrefsFactory>; + // Helper method for PluginPrefs::GetForTestingProfile. + static scoped_refptr<RefcountedProfileKeyedService> CreateForTestingProfile( + Profile* profile); + PluginPrefsFactory(); virtual ~PluginPrefsFactory(); // RefcountedProfileKeyedServiceFactory methods: - virtual RefcountedProfileKeyedService* BuildServiceInstanceFor( + virtual scoped_refptr<RefcountedProfileKeyedService> BuildServiceInstanceFor( Profile* profile) const OVERRIDE; // ProfileKeyedServiceFactory methods: diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc index de1eb3c..7ba4efe 100644 --- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc +++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc @@ -421,7 +421,7 @@ TEST_F(CloudPrintProxyPolicyTest, prefs->GetString(prefs::kCloudPrintEmail)); } -ProfileKeyedBase* TestCloudPrintProxyServiceFactory(Profile* profile) { +ProfileKeyedService* TestCloudPrintProxyServiceFactory(Profile* profile) { TestCloudPrintProxyService* service = new TestCloudPrintProxyService(profile); service->GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc index e38021a..dd641fb 100644 --- a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc +++ b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc @@ -450,7 +450,7 @@ TEST_F(CloudPrintProxyPolicyStartupTest, StartAndShutdown) { ShutdownAndWaitForExitWithTimeout(handle); } -ProfileKeyedBase* CloudPrintProxyServiceFactoryForPolicyTest( +ProfileKeyedService* CloudPrintProxyServiceFactoryForPolicyTest( Profile* profile) { CloudPrintProxyService* service = new CloudPrintProxyService(profile); service->Initialize(); diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc index 9d014f3..e0a278f 100644 --- a/chrome/browser/profiles/profile_dependency_manager.cc +++ b/chrome/browser/profiles/profile_dependency_manager.cc @@ -102,10 +102,10 @@ void ProfileDependencyManager::CreateProfileServices(Profile* profile, } if (is_testing_profile && (*rit)->ServiceIsNULLWhileTesting()) { - (*rit)->SetTestingFactory(profile, NULL); + (*rit)->SetEmptyTestingFactory(profile); } else if ((*rit)->ServiceIsCreatedWithProfile()) { // Create the service. - (*rit)->GetBaseForProfile(profile, true); + (*rit)->CreateServiceNow(profile); } } } diff --git a/chrome/browser/profiles/profile_keyed_base.h b/chrome/browser/profiles/profile_keyed_base.h deleted file mode 100644 index 6a2f2d4..0000000 --- a/chrome/browser/profiles/profile_keyed_base.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012 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_PROFILES_PROFILE_KEYED_BASE_H_ -#define CHROME_BROWSER_PROFILES_PROFILE_KEYED_BASE_H_ - -// A root class used by the ProfileKeyedBaseFactory. -// -// ProfileKeyedBaseFactory is a generalization of dependency and lifetime -// management, leaving the actual implementation of storage and what actually -// happens at lifetime events up to the factory type. -class ProfileKeyedBase { - public: - virtual ~ProfileKeyedBase() {} -}; - -#endif // CHROME_BROWSER_PROFILES_PROFILE_KEYED_BASE_H_ diff --git a/chrome/browser/profiles/profile_keyed_base_factory.cc b/chrome/browser/profiles/profile_keyed_base_factory.cc index 1b63cb9..04423f0 100644 --- a/chrome/browser/profiles/profile_keyed_base_factory.cc +++ b/chrome/browser/profiles/profile_keyed_base_factory.cc @@ -7,35 +7,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_dependency_manager.h" -void ProfileKeyedBaseFactory::SetTestingFactory(Profile* profile, - FactoryFunction factory) { - // Destroying the profile may cause us to lose data about whether |profile| - // has our preferences registered on it (since the profile object itself - // isn't dead). See if we need to readd it once we've gone through normal - // destruction. - bool add_profile = registered_preferences_.find(profile) != - registered_preferences_.end(); - - // We have to go through the shutdown and destroy mechanisms because there - // are unit tests that create a service on a profile and then change the - // testing service mid-test. - ProfileShutdown(profile); - ProfileDestroyed(profile); - - if (add_profile) - registered_preferences_.insert(profile); - - factories_[profile] = factory; -} - -ProfileKeyedBase* ProfileKeyedBaseFactory::SetTestingFactoryAndUse( - Profile* profile, - FactoryFunction factory) { - DCHECK(factory); - SetTestingFactory(profile, factory); - return GetBaseForProfile(profile, true); -} - ProfileKeyedBaseFactory::ProfileKeyedBaseFactory( const char* name, ProfileDependencyManager* manager) : dependency_manager_(manager) @@ -54,6 +25,31 @@ void ProfileKeyedBaseFactory::DependsOn(ProfileKeyedBaseFactory* rhs) { dependency_manager_->AddEdge(rhs, this); } +Profile* ProfileKeyedBaseFactory::GetProfileToUse(Profile* profile) { + DCHECK(CalledOnValidThread()); + +#ifndef NDEBUG + dependency_manager_->AssertProfileWasntDestroyed(profile); +#endif + + // Possibly handle Incognito mode. + if (profile->IsOffTheRecord()) { + if (ServiceRedirectedInIncognito()) { + profile = profile->GetOriginalProfile(); + +#ifndef NDEBUG + dependency_manager_->AssertProfileWasntDestroyed(profile); +#endif + } else if (ServiceHasOwnInstanceInIncognito()) { + // No-op; the pointers are already set correctly. + } else { + return NULL; + } + } + + return profile; +} + void ProfileKeyedBaseFactory::RegisterUserPrefsOnProfile(Profile* profile) { // Safe timing for pref registration is hard. Previously, we made Profile // responsible for all pref registration on every service that used @@ -105,67 +101,20 @@ bool ProfileKeyedBaseFactory::ServiceIsNULLWhileTesting() { return false; } -ProfileKeyedBase* ProfileKeyedBaseFactory::GetBaseForProfile( - Profile* profile, - bool create) { - DCHECK(CalledOnValidThread()); - -#ifndef NDEBUG - dependency_manager_->AssertProfileWasntDestroyed(profile); -#endif - - // Possibly handle Incognito mode. - if (profile->IsOffTheRecord()) { - if (ServiceRedirectedInIncognito()) { - profile = profile->GetOriginalProfile(); - -#ifndef NDEBUG - dependency_manager_->AssertProfileWasntDestroyed(profile); -#endif - } else if (ServiceHasOwnInstanceInIncognito()) { - // No-op; the pointers are already set correctly. - } else { - return NULL; - } - } - - ProfileKeyedBase* service = NULL; - if (GetAssociation(profile, &service)) { - return service; - } else if (create) { - // not found but creation allowed - - // Check to see if we have a per-Profile factory - std::map<Profile*, FactoryFunction>::iterator jt = factories_.find(profile); - if (jt != factories_.end()) { - if (jt->second) { - if (!profile->IsOffTheRecord()) - RegisterUserPrefsOnProfile(profile); - service = jt->second(profile); - } else { - service = NULL; - } - } else { - service = BuildServiceInstanceFor(profile); - } - } else { - // not found, creation forbidden - return NULL; - } - - Associate(profile, service); - return service; -} - void ProfileKeyedBaseFactory::ProfileDestroyed(Profile* profile) { // While object destruction can be customized in ways where the object is // only dereferenced, this still must run on the UI thread. DCHECK(CalledOnValidThread()); - // For unit tests, we also remove the factory function both so we don't - // maintain a big map of dead pointers, but also since we may have a second - // object that lives at the same address (see other comments about unit tests - // in this file). - factories_.erase(profile); registered_preferences_.erase(profile); } + +bool ProfileKeyedBaseFactory::ArePreferencesSetOn(Profile* profile) { + return registered_preferences_.find(profile) != + registered_preferences_.end(); +} + +void ProfileKeyedBaseFactory::MarkPreferencesSetOn(Profile* profile) { + DCHECK(!ArePreferencesSetOn(profile)); + registered_preferences_.insert(profile); +} diff --git a/chrome/browser/profiles/profile_keyed_base_factory.h b/chrome/browser/profiles/profile_keyed_base_factory.h index efd1edd..fd8ef87 100644 --- a/chrome/browser/profiles/profile_keyed_base_factory.h +++ b/chrome/browser/profiles/profile_keyed_base_factory.h @@ -12,37 +12,17 @@ class PrefService; class Profile; -class ProfileKeyedBase; class ProfileDependencyManager; // Base class for Factories that take a Profile object and return some service. // // Unless you're trying to make a new type of Factory, you probably don't want // this class, but its subclasses: ProfileKeyedServiceFactory and -// RefcountedProfileKeyedServiceFactory. This object describes general profile -// dependency management; subclasses react to lifecycle events and implement -// memory management. +// RefcountedProfileKeyedServiceFactory. This object describes general +// dependency management between Factories; subclasses react to lifecycle +// events and implement memory management. class ProfileKeyedBaseFactory : public base::NonThreadSafe { public: - // A function that replaces the (possibly internal) object used by this - // factory. For the majority of cases, this is the object returned to users. - typedef ProfileKeyedBase* (*FactoryFunction)(Profile* profile); - - // Associates |factory| with |profile| so that |factory| is used to create - // the ProfileKeyedService when requested. - // - // |factory| can be NULL to signal that ProfileKeyedService should be NULL. A - // second call to SetTestingFactory() is allowed. If the FactoryFunction is - // changed AND an instance of the PKSF already exists for |profile|, that - // service is destroyed. - void SetTestingFactory(Profile* profile, FactoryFunction factory); - - // Associates |factory| with |profile| and immediately returns the created - // ProfileKeyedService. Since the factory will be used immediately, it may - // not be NULL; - ProfileKeyedBase* SetTestingFactoryAndUse(Profile* profile, - FactoryFunction factory); - // Registers preferences used in this service on the pref service of // |profile|. This is the public interface and is safe to be called multiple // times because testing code can have multiple services of the same type @@ -70,6 +50,9 @@ class ProfileKeyedBaseFactory : public base::NonThreadSafe { // created by factories. void DependsOn(ProfileKeyedBaseFactory* rhs); + // Finds which profile (if any) to use using the Service.*Incognito methods. + Profile* GetProfileToUse(Profile* profile); + // Interface for people building a concrete FooServiceFactory: -------------- // Register any user preferences on this service. This is called during @@ -77,11 +60,6 @@ class ProfileKeyedBaseFactory : public base::NonThreadSafe { // basis. virtual void RegisterUserPrefs(PrefService* user_prefs) {} - // Returns a new instance of the service, casted to our void* equivalent for - // our storage. - virtual ProfileKeyedBase* BuildServiceInstanceFor( - Profile* profile) const = 0; - // By default, if we are asked for a service with an Incognito profile, we // pass back NULL. To redirect to the Incognito's original profile or to // create another instance, even for Incognito windows, override one of the @@ -103,23 +81,6 @@ class ProfileKeyedBaseFactory : public base::NonThreadSafe { // Interface for people building a type of ProfileKeyedFactory: ------------- - // Common implementation that maps |profile| to some object. Deals with - // incognito profiles per subclass instructions with - // ServiceRedirectedInIncognito() and ServiceHasOwnInstanceInIncognito(). - // If |create| is true, the service will be created using - // BuildServiceInstanceFor() if it doesn't already exist. - virtual ProfileKeyedBase* GetBaseForProfile(Profile* profile, - bool create); - - // The base factory is not responsible for storage; the derived factory type - // maintains storage and reacts to lifecycle events. - virtual void Associate(Profile* profile, ProfileKeyedBase* base) = 0; - - // Returns whether there is an object associated with |profile|. If |out| is - // non-NULL, returns said object. - virtual bool GetAssociation(Profile* profile, - ProfileKeyedBase** out) const = 0; - // A helper object actually listens for notifications about Profile // destruction, calculates the order in which things are destroyed and then // does a two pass shutdown. @@ -138,10 +99,28 @@ class ProfileKeyedBaseFactory : public base::NonThreadSafe { virtual void ProfileShutdown(Profile* profile) = 0; virtual void ProfileDestroyed(Profile* profile); + protected: + // Returns whether we've registered the preferences on this profile. + bool ArePreferencesSetOn(Profile* profile); + + // Mark profile as Preferences set. + void MarkPreferencesSetOn(Profile* profile); + private: friend class ProfileDependencyManager; friend class ProfileDependencyManagerUnittests; + // These two methods are for tight integration with the + // ProfileDependencyManager. + + // Because of ServiceIsNULLWhileTesting(), we need a way to tell different + // subclasses that they should disable testing. + virtual void SetEmptyTestingFactory(Profile* profile) = 0; + + // We also need a generalized, non-returning method that generates the object + // now for when we're creating the profile. + virtual void CreateServiceNow(Profile* profile) = 0; + // Which ProfileDependencyManager we should communicate with. In real code, // this will always be ProfileDependencyManager::GetInstance(), but unit // tests will want to use their own copy. @@ -150,9 +129,6 @@ class ProfileKeyedBaseFactory : public base::NonThreadSafe { // Profiles that have this service's preferences registered on them. std::set<Profile*> registered_preferences_; - // The mapping between a Profile and its overridden FactoryFunction. - std::map<Profile*, FactoryFunction> factories_; - #if !defined(NDEBUG) // A static string passed in to our constructor. Should be unique across all // services. This is used only for debugging in debug mode. (We can print diff --git a/chrome/browser/profiles/profile_keyed_service.h b/chrome/browser/profiles/profile_keyed_service.h index 0a39612..ce7baf2 100644 --- a/chrome/browser/profiles/profile_keyed_service.h +++ b/chrome/browser/profiles/profile_keyed_service.h @@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_H_ #define CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_H_ -#include "chrome/browser/profiles/profile_keyed_base.h" +class ProfileKeyedServiceFactory; // Base class for all ProfileKeyedServices to allow for correct destruction // order. @@ -15,11 +15,14 @@ // all services will need this, so there's a default implementation. Only once // every system has been given a chance to drop references do we start deleting // objects. -class ProfileKeyedService : public ProfileKeyedBase { +class ProfileKeyedService { public: // The first pass is to call Shutdown on a ProfileKeyedService. virtual void Shutdown() {} + protected: + friend class ProfileKeyedServiceFactory; + // The second pass is the actual deletion of each object. virtual ~ProfileKeyedService() {} }; diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc index 10e1459..d5ca934 100644 --- a/chrome/browser/profiles/profile_keyed_service_factory.cc +++ b/chrome/browser/profiles/profile_keyed_service_factory.cc @@ -11,6 +11,34 @@ #include "chrome/browser/profiles/profile_dependency_manager.h" #include "chrome/browser/profiles/profile_keyed_service.h" +void ProfileKeyedServiceFactory::SetTestingFactory(Profile* profile, + FactoryFunction factory) { + // Destroying the profile may cause us to lose data about whether |profile| + // has our preferences registered on it (since the profile object itself + // isn't dead). See if we need to readd it once we've gone through normal + // destruction. + bool add_profile = ArePreferencesSetOn(profile); + + // We have to go through the shutdown and destroy mechanisms because there + // are unit tests that create a service on a profile and then change the + // testing service mid-test. + ProfileShutdown(profile); + ProfileDestroyed(profile); + + if (add_profile) + MarkPreferencesSetOn(profile); + + factories_[profile] = factory; +} + +ProfileKeyedService* ProfileKeyedServiceFactory::SetTestingFactoryAndUse( + Profile* profile, + FactoryFunction factory) { + DCHECK(factory); + SetTestingFactory(profile, factory); + return GetServiceForProfile(profile, true); +} + ProfileKeyedServiceFactory::ProfileKeyedServiceFactory( const char* name, ProfileDependencyManager* manager) : ProfileKeyedBaseFactory(name, manager) { @@ -23,28 +51,47 @@ ProfileKeyedServiceFactory::~ProfileKeyedServiceFactory() { ProfileKeyedService* ProfileKeyedServiceFactory::GetServiceForProfile( Profile* profile, bool create) { - return static_cast<ProfileKeyedService*>(GetBaseForProfile(profile, create)); -} - -void ProfileKeyedServiceFactory::Associate(Profile* profile, - ProfileKeyedBase* service) { - DCHECK(mapping_.find(profile) == mapping_.end()); - mapping_.insert(std::make_pair( - profile, static_cast<ProfileKeyedService*>(service))); -} + profile = GetProfileToUse(profile); + if (!profile) + return NULL; -bool ProfileKeyedServiceFactory::GetAssociation( - Profile* profile, - ProfileKeyedBase** out) const { - bool found = false; + // NOTE: If you modify any of the logic below, make sure to update the + // refcounted version in refcounted_profile_keyed_service_factory.cc! + ProfileKeyedService* service = NULL; std::map<Profile*, ProfileKeyedService*>::const_iterator it = mapping_.find(profile); if (it != mapping_.end()) { - found = true; - if (out) - *out = it->second; + return it->second; + } else if (create) { + // Object not found, and we must create it. + // + // Check to see if we have a per-Profile testing factory that we should use + // instead of default behavior. + std::map<Profile*, FactoryFunction>::iterator jt = factories_.find(profile); + if (jt != factories_.end()) { + if (jt->second) { + if (!profile->IsOffTheRecord()) + RegisterUserPrefsOnProfile(profile); + service = jt->second(profile); + } else { + service = NULL; + } + } else { + service = BuildServiceInstanceFor(profile); + } + } else { + // Object not found, and we're forbidden from creating one. + return NULL; } - return found; + + Associate(profile, service); + return service; +} + +void ProfileKeyedServiceFactory::Associate(Profile* profile, + ProfileKeyedService* service) { + DCHECK(mapping_.find(profile) == mapping_.end()); + mapping_.insert(std::make_pair(profile, service)); } void ProfileKeyedServiceFactory::ProfileShutdown(Profile* profile) { @@ -62,5 +109,20 @@ void ProfileKeyedServiceFactory::ProfileDestroyed(Profile* profile) { mapping_.erase(it); } + // For unit tests, we also remove the factory function both so we don't + // maintain a big map of dead pointers, but also since we may have a second + // object that lives at the same address (see other comments about unit tests + // in this file). + factories_.erase(profile); + ProfileKeyedBaseFactory::ProfileDestroyed(profile); } + +void ProfileKeyedServiceFactory::SetEmptyTestingFactory( + Profile* profile) { + SetTestingFactory(profile, NULL); +} + +void ProfileKeyedServiceFactory::CreateServiceNow(Profile* profile) { + GetServiceForProfile(profile, true); +} diff --git a/chrome/browser/profiles/profile_keyed_service_factory.h b/chrome/browser/profiles/profile_keyed_service_factory.h index 16c39ad..b16feeb 100644 --- a/chrome/browser/profiles/profile_keyed_service_factory.h +++ b/chrome/browser/profiles/profile_keyed_service_factory.h @@ -7,6 +7,7 @@ #include <map> +#include "base/basictypes.h" #include "base/compiler_specific.h" #include "chrome/browser/profiles/profile_keyed_base_factory.h" #include "chrome/browser/profiles/profile_keyed_service.h" @@ -24,6 +25,24 @@ class ProfileKeyedService; // shutdown/destruction order. In each derived classes' constructors, the // implementors must explicitly state which services are depended on. class ProfileKeyedServiceFactory : public ProfileKeyedBaseFactory { + public: + // A function that supplies the instance of a ProfileKeyedService for a given + // Profile. This is used primarily for testing, where we want to feed a + // specific mock into the PKSF system. + typedef ProfileKeyedService* (*FactoryFunction)(Profile* profile); + + // Associates |factory| with |profile| so that |factory| is used to create + // the ProfileKeyedService when requested. |factory| can be NULL to signal + // that ProfileKeyedService should be NULL. Multiple calls to + // SetTestingFactory() are allowed; previous services will be shut down. + void SetTestingFactory(Profile* profile, FactoryFunction factory); + + // Associates |factory| with |profile| and immediately returns the created + // ProfileKeyedService. Since the factory will be used immediately, it may + // not be NULL. + ProfileKeyedService* SetTestingFactoryAndUse(Profile* profile, + FactoryFunction factory); + protected: // ProfileKeyedServiceFactories must communicate with a // ProfileDependencyManager. For all non-test code, write your subclass @@ -40,23 +59,20 @@ class ProfileKeyedServiceFactory : public ProfileKeyedBaseFactory { // Common implementation that maps |profile| to some service object. Deals // with incognito profiles per subclass instructions with - // ServiceRedirectedInIncognito() and ServiceHasOwnInstanceInIncognito(). - // If |create| is true, the service will be created using - // BuildServiceInstanceFor() if it doesn't already exist. + // ServiceRedirectedInIncognito() and ServiceHasOwnInstanceInIncognito() + // through the GetProfileToUse() method on the base. If |create| is true, + // the service will be created using BuildServiceInstanceFor() if it doesn't + // already exist. ProfileKeyedService* GetServiceForProfile(Profile* profile, bool create); + // Maps |profile| to |service| with debug checks to prevent duplication. + void Associate(Profile* profile, ProfileKeyedService* service); + // All subclasses of ProfileKeyedServiceFactory must return a // ProfileKeyedService instead of just a ProfileKeyedBase. virtual ProfileKeyedService* BuildServiceInstanceFor( Profile* profile) const = 0; - // Maps |profile| to |provider| with debug checks to prevent duplication. - virtual void Associate(Profile* profile, ProfileKeyedBase* base) OVERRIDE; - - // Returns the previously associated |base| for |profile|, or NULL. - virtual bool GetAssociation(Profile* profile, - ProfileKeyedBase** out) const OVERRIDE; - // A helper object actually listens for notifications about Profile // destruction, calculates the order in which things are destroyed and then // does a two pass shutdown. @@ -71,12 +87,20 @@ class ProfileKeyedServiceFactory : public ProfileKeyedBaseFactory { virtual void ProfileShutdown(Profile* profile) OVERRIDE; virtual void ProfileDestroyed(Profile* profile) OVERRIDE; + virtual void SetEmptyTestingFactory(Profile* profile) OVERRIDE; + virtual void CreateServiceNow(Profile* profile) OVERRIDE; + private: friend class ProfileDependencyManager; friend class ProfileDependencyManagerUnittests; // The mapping between a Profile and its service. std::map<Profile*, ProfileKeyedService*> mapping_; + + // The mapping between a Profile and its overridden FactoryFunction. + std::map<Profile*, FactoryFunction> factories_; + + DISALLOW_COPY_AND_ASSIGN(ProfileKeyedServiceFactory); }; #endif // CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_ diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service.h b/chrome/browser/profiles/refcounted_profile_keyed_service.h index a554284..0db4351 100644 --- a/chrome/browser/profiles/refcounted_profile_keyed_service.h +++ b/chrome/browser/profiles/refcounted_profile_keyed_service.h @@ -6,7 +6,6 @@ #define CHROME_BROWSER_PROFILES_REFCOUNTED_PROFILE_KEYED_SERVICE_H_ #include "base/memory/ref_counted.h" -#include "chrome/browser/profiles/profile_keyed_base.h" #include "content/public/browser/browser_thread.h" class RefcountedProfileKeyedService; @@ -32,8 +31,7 @@ struct RefcountedProfileKeyedServiceTraits { // content::DeleteOnThread<> directly because RefcountedProfileKeyedService // must be one type that RefcountedProfileKeyedServiceFactory can use. class RefcountedProfileKeyedService - : public ProfileKeyedBase, - public base::RefCountedThreadSafe< + : public base::RefCountedThreadSafe< RefcountedProfileKeyedService, impl::RefcountedProfileKeyedServiceTraits> { public: diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc index 8bf694c..d7eab48 100644 --- a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc +++ b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc @@ -5,12 +5,43 @@ #include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.h" #include "base/logging.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_keyed_service.h" #include "chrome/browser/profiles/refcounted_profile_keyed_service.h" #include "content/public/browser/browser_thread.h" using content::BrowserThread; +void RefcountedProfileKeyedServiceFactory::SetTestingFactory( + Profile* profile, + FactoryFunction factory) { + // Destroying the profile may cause us to lose data about whether |profile| + // has our preferences registered on it (since the profile object itself + // isn't dead). See if we need to readd it once we've gone through normal + // destruction. + bool add_profile = ArePreferencesSetOn(profile); + + // We have to go through the shutdown and destroy mechanisms because there + // are unit tests that create a service on a profile and then change the + // testing service mid-test. + ProfileShutdown(profile); + ProfileDestroyed(profile); + + if (add_profile) + MarkPreferencesSetOn(profile); + + factories_[profile] = factory; +} + +scoped_refptr<RefcountedProfileKeyedService> +RefcountedProfileKeyedServiceFactory::SetTestingFactoryAndUse( + Profile* profile, + FactoryFunction factory) { + DCHECK(factory); + SetTestingFactory(profile, factory); + return GetServiceForProfile(profile, true); +} + RefcountedProfileKeyedServiceFactory::RefcountedProfileKeyedServiceFactory( const char* name, ProfileDependencyManager* manager) @@ -21,26 +52,51 @@ RefcountedProfileKeyedServiceFactory::~RefcountedProfileKeyedServiceFactory() { DCHECK(mapping_.empty()); } -void RefcountedProfileKeyedServiceFactory::Associate(Profile* profile, - ProfileKeyedBase* base) { - DCHECK(mapping_.find(profile) == mapping_.end()); - mapping_.insert(std::make_pair( - profile, make_scoped_refptr( - static_cast<RefcountedProfileKeyedService*>(base)))); -} - -bool RefcountedProfileKeyedServiceFactory::GetAssociation( +scoped_refptr<RefcountedProfileKeyedService> +RefcountedProfileKeyedServiceFactory::GetServiceForProfile( Profile* profile, - ProfileKeyedBase** out) const { - bool found = false; + bool create) { + profile = GetProfileToUse(profile); + if (!profile) + return NULL; + + // NOTE: If you modify any of the logic below, make sure to update the + // non-refcounted version in profile_keyed_service_factory.cc! + scoped_refptr<RefcountedProfileKeyedService> service; RefCountedStorage::const_iterator it = mapping_.find(profile); if (it != mapping_.end()) { - found = true; - - if (out) - *out = it->second.get(); + return it->second; + } else if (create) { + // Object not found, and we must create it. + // + // Check to see if we have a per-Profile testing factory that we should use + // instead of default behavior. + std::map<Profile*, FactoryFunction>::iterator jt = factories_.find(profile); + if (jt != factories_.end()) { + if (jt->second) { + if (!profile->IsOffTheRecord()) + RegisterUserPrefsOnProfile(profile); + service = jt->second(profile); + } else { + service = NULL; + } + } else { + service = BuildServiceInstanceFor(profile); + } + } else { + // Object not found, and we're forbidden from creating one. + return NULL; } - return found; + + Associate(profile, service); + return service; +} + +void RefcountedProfileKeyedServiceFactory::Associate( + Profile* profile, + const scoped_refptr<RefcountedProfileKeyedService>& service) { + DCHECK(mapping_.find(profile) == mapping_.end()); + mapping_.insert(std::make_pair(profile, service)); } void RefcountedProfileKeyedServiceFactory::ProfileShutdown(Profile* profile) { @@ -57,5 +113,20 @@ void RefcountedProfileKeyedServiceFactory::ProfileDestroyed(Profile* profile) { mapping_.erase(it); } + // For unit tests, we also remove the factory function both so we don't + // maintain a big map of dead pointers, but also since we may have a second + // object that lives at the same address (see other comments about unit tests + // in this file). + factories_.erase(profile); + ProfileKeyedBaseFactory::ProfileDestroyed(profile); } + +void RefcountedProfileKeyedServiceFactory::SetEmptyTestingFactory( + Profile* profile) { + SetTestingFactory(profile, NULL); +} + +void RefcountedProfileKeyedServiceFactory::CreateServiceNow(Profile* profile) { + GetServiceForProfile(profile, true); +} diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h index 4e9c1b5..cac29d61 100644 --- a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h +++ b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h @@ -24,22 +24,48 @@ class RefcountedProfileKeyedService; // that ShutdownOnUIThread() is called on the UI thread, but actual object // destruction can happen anywhere. class RefcountedProfileKeyedServiceFactory : public ProfileKeyedBaseFactory { + public: + // A function that supplies the instance of a ProfileKeyedService for a given + // Profile. This is used primarily for testing, where we want to feed a + // specific mock into the PKSF system. + typedef scoped_refptr<RefcountedProfileKeyedService> + (*FactoryFunction)(Profile* profile); + + // Associates |factory| with |profile| so that |factory| is used to create + // the ProfileKeyedService when requested. |factory| can be NULL to signal + // that ProfileKeyedService should be NULL. Multiple calls to + // SetTestingFactory() are allowed; previous services will be shut down. + void SetTestingFactory(Profile* profile, FactoryFunction factory); + + // Associates |factory| with |profile| and immediately returns the created + // ProfileKeyedService. Since the factory will be used immediately, it may + // not be NULL. + scoped_refptr<RefcountedProfileKeyedService> SetTestingFactoryAndUse( + Profile* profile, + FactoryFunction factory); + protected: RefcountedProfileKeyedServiceFactory(const char* name, ProfileDependencyManager* manager); virtual ~RefcountedProfileKeyedServiceFactory(); + scoped_refptr<RefcountedProfileKeyedService> GetServiceForProfile( + Profile* profile, + bool create); + + // Maps |profile| to |service| with debug checks to prevent duplication. + void Associate(Profile* profile, + const scoped_refptr<RefcountedProfileKeyedService>& service); + // All subclasses of RefcountedProfileKeyedServiceFactory must return a // RefcountedProfileKeyedService instead of just a ProfileKeyedBase. - virtual RefcountedProfileKeyedService* BuildServiceInstanceFor( + virtual scoped_refptr<RefcountedProfileKeyedService> BuildServiceInstanceFor( Profile* profile) const = 0; - virtual void Associate(Profile* profile, - ProfileKeyedBase* base) OVERRIDE; - virtual bool GetAssociation(Profile* profile, - ProfileKeyedBase** out) const OVERRIDE; virtual void ProfileShutdown(Profile* profile) OVERRIDE; virtual void ProfileDestroyed(Profile* profile) OVERRIDE; + virtual void SetEmptyTestingFactory(Profile* profile) OVERRIDE; + virtual void CreateServiceNow(Profile* profile) OVERRIDE; private: typedef std::map<Profile*, scoped_refptr<RefcountedProfileKeyedService> > @@ -48,6 +74,9 @@ class RefcountedProfileKeyedServiceFactory : public ProfileKeyedBaseFactory { // The mapping between a Profile and its refcounted service. RefCountedStorage mapping_; + // The mapping between a Profile and its overridden FactoryFunction. + std::map<Profile*, FactoryFunction> factories_; + DISALLOW_COPY_AND_ASSIGN(RefcountedProfileKeyedServiceFactory); }; diff --git a/chrome/browser/protector/mock_protector_service.cc b/chrome/browser/protector/mock_protector_service.cc index 971ea28..a8caacb 100644 --- a/chrome/browser/protector/mock_protector_service.cc +++ b/chrome/browser/protector/mock_protector_service.cc @@ -11,7 +11,7 @@ namespace protector { namespace { -ProfileKeyedBase* BuildMockProtectorService(Profile* profile) { +ProfileKeyedService* BuildMockProtectorService(Profile* profile) { return new MockProtectorService(profile); } diff --git a/chrome/browser/search_engines/template_url_service_test_util.cc b/chrome/browser/search_engines/template_url_service_test_util.cc index 732fdbc..dc6d867 100644 --- a/chrome/browser/search_engines/template_url_service_test_util.cc +++ b/chrome/browser/search_engines/template_url_service_test_util.cc @@ -75,7 +75,7 @@ class TemplateURLServiceTestingProfile : public TestingProfile { // SetKeywordSearchTermsForURL. class TestingTemplateURLService : public TemplateURLService { public: - static ProfileKeyedBase* Build(Profile* profile) { + static ProfileKeyedService* Build(Profile* profile) { return new TestingTemplateURLService(profile); } diff --git a/chrome/browser/signin/signin_manager_fake.cc b/chrome/browser/signin/signin_manager_fake.cc index 5ac6e1c..0eae17d 100644 --- a/chrome/browser/signin/signin_manager_fake.cc +++ b/chrome/browser/signin/signin_manager_fake.cc @@ -20,6 +20,6 @@ void FakeSigninManager::SignOut() { } // static -ProfileKeyedBase* FakeSigninManager::Build(Profile* profile) { +ProfileKeyedService* FakeSigninManager::Build(Profile* profile) { return new FakeSigninManager(); } diff --git a/chrome/browser/signin/signin_manager_fake.h b/chrome/browser/signin/signin_manager_fake.h index f991d8f..a1e1c42 100644 --- a/chrome/browser/signin/signin_manager_fake.h +++ b/chrome/browser/signin/signin_manager_fake.h @@ -28,7 +28,7 @@ class FakeSigninManager : public SigninManager { virtual void SignOut() OVERRIDE; // Helper function to be used with ProfileKeyedService::SetTestingFactory(). - static ProfileKeyedBase* Build(Profile* profile); + static ProfileKeyedService* Build(Profile* profile); }; #endif // CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_FAKE_H_ diff --git a/chrome/browser/signin/signin_tracker_unittest.cc b/chrome/browser/signin/signin_tracker_unittest.cc index 9d70257..8ae1235 100644 --- a/chrome/browser/signin/signin_tracker_unittest.cc +++ b/chrome/browser/signin/signin_tracker_unittest.cc @@ -35,7 +35,7 @@ class MockTokenService : public TokenService { MOCK_CONST_METHOD1(HasTokenForService, bool(const char*)); }; -ProfileKeyedBase* BuildMockTokenService(Profile* profile) { +ProfileKeyedService* BuildMockTokenService(Profile* profile) { return new MockTokenService; } diff --git a/chrome/browser/spellchecker/spellcheck_profile_unittest.cc b/chrome/browser/spellchecker/spellcheck_profile_unittest.cc index bf4e9b5..e44d7cd 100644 --- a/chrome/browser/spellchecker/spellcheck_profile_unittest.cc +++ b/chrome/browser/spellchecker/spellcheck_profile_unittest.cc @@ -65,7 +65,7 @@ class TestingSpellCheckProfile : public SpellCheckProfile { scoped_ptr<SpellCheckHost> returning_from_create_; }; -ProfileKeyedBase* BuildTestingSpellCheckProfile(Profile* profile) { +ProfileKeyedService* BuildTestingSpellCheckProfile(Profile* profile) { return new TestingSpellCheckProfile(profile); } diff --git a/chrome/browser/sync/abstract_profile_sync_service_test.cc b/chrome/browser/sync/abstract_profile_sync_service_test.cc index e7e3ddf..992e07f 100644 --- a/chrome/browser/sync/abstract_profile_sync_service_test.cc +++ b/chrome/browser/sync/abstract_profile_sync_service_test.cc @@ -123,7 +123,7 @@ bool AbstractProfileSyncServiceTest::CreateRoot(ModelType model_type) { } // static -ProfileKeyedBase* AbstractProfileSyncServiceTest::BuildTokenService( +ProfileKeyedService* AbstractProfileSyncServiceTest::BuildTokenService( Profile* profile) { return new TokenService; } diff --git a/chrome/browser/sync/abstract_profile_sync_service_test.h b/chrome/browser/sync/abstract_profile_sync_service_test.h index 1df23f6..066e88a 100644 --- a/chrome/browser/sync/abstract_profile_sync_service_test.h +++ b/chrome/browser/sync/abstract_profile_sync_service_test.h @@ -59,7 +59,7 @@ class AbstractProfileSyncServiceTest : public testing::Test { bool CreateRoot(syncable::ModelType model_type); - static ProfileKeyedBase* BuildTokenService(Profile* profile); + static ProfileKeyedService* BuildTokenService(Profile* profile); protected: MessageLoopForUI ui_loop_; content::TestBrowserThread ui_thread_; diff --git a/chrome/browser/sync/glue/password_model_worker.cc b/chrome/browser/sync/glue/password_model_worker.cc index 84c95e4..a915634 100644 --- a/chrome/browser/sync/glue/password_model_worker.cc +++ b/chrome/browser/sync/glue/password_model_worker.cc @@ -13,7 +13,8 @@ using base::WaitableEvent; namespace browser_sync { -PasswordModelWorker::PasswordModelWorker(PasswordStore* password_store) +PasswordModelWorker::PasswordModelWorker( + const scoped_refptr<PasswordStore>& password_store) : password_store_(password_store) { DCHECK(password_store); } diff --git a/chrome/browser/sync/glue/password_model_worker.h b/chrome/browser/sync/glue/password_model_worker.h index 2e10a8c..5b0cbcb95 100644 --- a/chrome/browser/sync/glue/password_model_worker.h +++ b/chrome/browser/sync/glue/password_model_worker.h @@ -26,7 +26,8 @@ namespace browser_sync { // which is the DB thread on Linux and Windows. class PasswordModelWorker : public browser_sync::ModelSafeWorker { public: - explicit PasswordModelWorker(PasswordStore* password_store); + explicit PasswordModelWorker( + const scoped_refptr<PasswordStore>& password_store); virtual ~PasswordModelWorker(); // ModelSafeWorker implementation. Called on syncapi SyncerThread. diff --git a/chrome/browser/sync/glue/sync_backend_registrar.cc b/chrome/browser/sync/glue/sync_backend_registrar.cc index e3e5164..4417746 100644 --- a/chrome/browser/sync/glue/sync_backend_registrar.cc +++ b/chrome/browser/sync/glue/sync_backend_registrar.cc @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/message_loop.h" +#include "chrome/browser/password_manager/password_store.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/glue/browser_thread_model_worker.h" @@ -87,9 +88,9 @@ SyncBackendRegistrar::SyncBackendRegistrar( routing_info_.erase(syncable::TYPED_URLS); } - PasswordStore* password_store = + scoped_refptr<PasswordStore> password_store = PasswordStoreFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS); - if (password_store) { + if (password_store.get()) { workers_[GROUP_PASSWORD] = new PasswordModelWorker(password_store); } else { LOG_IF(WARNING, initial_types.Has(syncable::PASSWORDS)) diff --git a/chrome/browser/sync/glue/theme_util_unittest.cc b/chrome/browser/sync/glue/theme_util_unittest.cc index 467dbad..ff96f05 100644 --- a/chrome/browser/sync/glue/theme_util_unittest.cc +++ b/chrome/browser/sync/glue/theme_util_unittest.cc @@ -30,7 +30,7 @@ class MockThemeService : public ThemeService { MOCK_CONST_METHOD0(GetThemeID, std::string()); }; -ProfileKeyedBase* BuildMockThemeService(Profile* profile) { +ProfileKeyedService* BuildMockThemeService(Profile* profile) { return new MockThemeService; } diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc index 1c53525..7974c58 100644 --- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc @@ -326,7 +326,7 @@ class AutofillProfileFactory : public AbstractAutofillFactory { class PersonalDataManagerMock: public PersonalDataManager { public: - static ProfileKeyedBase* Build(Profile* profile) { + static ProfileKeyedService* Build(Profile* profile) { return new PersonalDataManagerMock; } diff --git a/chrome/browser/sync/profile_sync_service_mock.cc b/chrome/browser/sync/profile_sync_service_mock.cc index 421de3a..694753a 100644 --- a/chrome/browser/sync/profile_sync_service_mock.cc +++ b/chrome/browser/sync/profile_sync_service_mock.cc @@ -43,7 +43,7 @@ TestingProfile* ProfileSyncServiceMock::MakeSignedInTestingProfile() { } // static -ProfileKeyedBase* ProfileSyncServiceMock::BuildMockProfileSyncService( +ProfileKeyedService* ProfileSyncServiceMock::BuildMockProfileSyncService( Profile* profile) { return new ProfileSyncServiceMock(profile); } diff --git a/chrome/browser/sync/profile_sync_service_mock.h b/chrome/browser/sync/profile_sync_service_mock.h index dd019a4..dbe94da 100644 --- a/chrome/browser/sync/profile_sync_service_mock.h +++ b/chrome/browser/sync/profile_sync_service_mock.h @@ -32,7 +32,7 @@ class ProfileSyncServiceMock : public ProfileSyncService { // Helper routine to be used in conjunction with // ProfileKeyedServiceFactory::SetTestingFactory(). - static ProfileKeyedBase* BuildMockProfileSyncService(Profile* profile); + static ProfileKeyedService* BuildMockProfileSyncService(Profile* profile); MOCK_METHOD0(DisableForUser, void()); MOCK_METHOD2(OnBackendInitialized, diff --git a/chrome/browser/sync/profile_sync_service_password_unittest.cc b/chrome/browser/sync/profile_sync_service_password_unittest.cc index 0acf315..4c5b474 100644 --- a/chrome/browser/sync/profile_sync_service_password_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_password_unittest.cc @@ -159,7 +159,7 @@ class ProfileSyncServicePasswordTest : public AbstractProfileSyncServiceTest { profile_.CreateRequestContext(); password_store_ = static_cast<MockPasswordStore*>( PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( - &profile_, MockPasswordStore::Build)); + &profile_, MockPasswordStore::Build).get()); registrar_.Add(&observer_, chrome::NOTIFICATION_SYNC_CONFIGURE_DONE, diff --git a/chrome/browser/sync/sync_setup_wizard_unittest.cc b/chrome/browser/sync/sync_setup_wizard_unittest.cc index 5519528..4744993 100644 --- a/chrome/browser/sync/sync_setup_wizard_unittest.cc +++ b/chrome/browser/sync/sync_setup_wizard_unittest.cc @@ -96,12 +96,12 @@ class ProfileSyncServiceForWizardTest : public ProfileSyncService { public: virtual ~ProfileSyncServiceForWizardTest() {} - static ProfileKeyedBase* BuildManual(Profile* profile) { + static ProfileKeyedService* BuildManual(Profile* profile) { return new ProfileSyncServiceForWizardTest(profile, ProfileSyncService::MANUAL_START); } - static ProfileKeyedBase* BuildAuto(Profile* profile) { + static ProfileKeyedService* BuildAuto(Profile* profile) { return new ProfileSyncServiceForWizardTest(profile, ProfileSyncService::AUTO_START); } diff --git a/chrome/browser/tabs/pinned_tab_service_unittest.cc b/chrome/browser/tabs/pinned_tab_service_unittest.cc index 0296c40..6f00338 100644 --- a/chrome/browser/tabs/pinned_tab_service_unittest.cc +++ b/chrome/browser/tabs/pinned_tab_service_unittest.cc @@ -17,7 +17,7 @@ namespace { -ProfileKeyedBase* BuildPinnedTabService(Profile* profile) { +ProfileKeyedService* BuildPinnedTabService(Profile* profile) { return new PinnedTabService(profile); } diff --git a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc index f38249b..5651fab 100644 --- a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc +++ b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc @@ -120,7 +120,7 @@ class SigninManagerMock : public FakeSigninManager { std::string captcha_; }; -static ProfileKeyedBase* BuildSigninManagerMock(Profile* profile) { +static ProfileKeyedService* BuildSigninManagerMock(Profile* profile) { return new SigninManagerMock(); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 855d2b1e..1da0e71 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1809,7 +1809,6 @@ 'browser/profiles/profile_info_util.h', 'browser/profiles/profile_io_data.cc', 'browser/profiles/profile_io_data.h', - 'browser/profiles/profile_keyed_base.h', 'browser/profiles/profile_keyed_base_factory.h', 'browser/profiles/profile_keyed_base_factory.cc', 'browser/profiles/profile_keyed_service.h', diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 8a829b4..1615b71 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -120,7 +120,7 @@ class TestExtensionURLRequestContextGetter scoped_refptr<net::URLRequestContext> context_; }; -ProfileKeyedBase* CreateTestDesktopNotificationService(Profile* profile) { +ProfileKeyedService* CreateTestDesktopNotificationService(Profile* profile) { return new DesktopNotificationService(profile, NULL); } @@ -364,7 +364,7 @@ void TestingProfile::CreateTemplateURLFetcher() { template_url_fetcher_.reset(new TemplateURLFetcher(this)); } -static ProfileKeyedBase* BuildTemplateURLService(Profile* profile) { +static ProfileKeyedService* BuildTemplateURLService(Profile* profile) { return new TemplateURLService(profile); } diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index ffaa68b..6e372a9 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt @@ -5778,26 +5778,6 @@ fun:_ZN3net16HostResolverImpl3Job18OnProcTaskCompleteEiRKNS_11AddressListE } { - bug_118196_a - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN3sql10Connection18GetCachedStatementERKNS_11StatementIDEPKc - ... - fun:_ZN*13LoginDatabase* - ... - fun:_ZN*PasswordStore* -} -{ - bug_118196_b - Memcheck:Leak - fun:_Znw* - ... - fun:_ZNK20PasswordStoreFactory23BuildServiceInstanceForEP7Profile - fun:_ZN23ProfileKeyedBaseFactory17GetBaseForProfileEP7Profileb - fun:_ZN20PasswordStoreFactory13GetForProfileEP7ProfileNS0_17ServiceAccessTypeE -} -{ bug_118203 Memcheck:Leak fun:_Znw* |