summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-13 20:47:58 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-13 20:47:58 +0000
commit67e79990f0ea1d003b0f46d9e2621658b20bae92 (patch)
tree05610f1533e900e7df9db6eb81a7b9c819262f46
parent78f000819426067d2c36529fde366174e3fd2e65 (diff)
downloadchromium_src-67e79990f0ea1d003b0f46d9e2621658b20bae92.zip
chromium_src-67e79990f0ea1d003b0f46d9e2621658b20bae92.tar.gz
chromium_src-67e79990f0ea1d003b0f46d9e2621658b20bae92.tar.bz2
Profiles: Generalize ProfileKeyedServiceFactory into a base class and the part that deals with memory storage.
This patch rips apart the dependency tracking parts of ProfileKeyedServiceFactory into a base class. Derived classes from ProfileKeyedBaseFactory now exist to deal with memory management and lifecycle events. ProfileKeyedBase is the most generic thing that can be tracked (it is simply a virtual destructor). For example, I've created RefcountedKeyedServiceFactory, which derives from ProfileKeyedBaseFactory. Everything tracked via that Factory must be a RefcountedProfileKeyedService. The storage layer uses scoped_refptr<>s in a map instead of normal pointers. This patch converts CookieSettings over (I'm ignoring the rest that could be ported due to how large the patch would be). Other than some minor changes to the testing interface, this doesn't change ProfileKeyedServiceFactory usage. BUG=77155 R=mirandac, jochen, sky, jhawkins TBR=tim Review URL: http://codereview.chromium.org/9360008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121727 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/autofill/autofill_manager_unittest.cc2
-rw-r--r--chrome/browser/autofill/autofill_metrics_unittest.cc9
-rw-r--r--chrome/browser/content_settings/content_settings_browsertest.cc6
-rw-r--r--chrome/browser/content_settings/cookie_settings.cc58
-rw-r--r--chrome/browser/content_settings/cookie_settings.h31
-rw-r--r--chrome/browser/content_settings/cookie_settings_unittest.cc38
-rw-r--r--chrome/browser/content_settings/host_content_settings_map_unittest.cc3
-rw-r--r--chrome/browser/cookies_tree_model_unittest.cc5
-rw-r--r--chrome/browser/extensions/extension_content_settings_api.cc6
-rw-r--r--chrome/browser/extensions/extension_content_settings_apitest.cc4
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy_unittest.cc5
-rw-r--r--chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.cc4
-rw-r--r--chrome/browser/plugin_prefs.cc2
-rw-r--r--chrome/browser/plugin_prefs_factory.cc2
-rw-r--r--chrome/browser/plugin_prefs_factory.h4
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc2
-rw-r--r--chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc2
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc32
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.h24
-rw-r--r--chrome/browser/profiles/profile_impl.cc4
-rw-r--r--chrome/browser/profiles/profile_io_data.cc4
-rw-r--r--chrome/browser/profiles/profile_keyed_base.h18
-rw-r--r--chrome/browser/profiles/profile_keyed_base_factory.cc154
-rw-r--r--chrome/browser/profiles/profile_keyed_base_factory.h149
-rw-r--r--chrome/browser/profiles/profile_keyed_service.h7
-rw-r--r--chrome/browser/profiles/profile_keyed_service_factory.cc151
-rw-r--r--chrome/browser/profiles/profile_keyed_service_factory.h94
-rw-r--r--chrome/browser/profiles/refcounted_profile_keyed_service.cc8
-rw-r--r--chrome/browser/profiles/refcounted_profile_keyed_service.h33
-rw-r--r--chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc60
-rw-r--r--chrome/browser/profiles/refcounted_profile_keyed_service_factory.h51
-rw-r--r--chrome/browser/protector/mock_protector_service.cc2
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.cc2
-rw-r--r--chrome/browser/search_engines/template_url_service_test_util.cc4
-rw-r--r--chrome/browser/signin/signin_manager_fake.cc2
-rw-r--r--chrome/browser/signin/signin_manager_fake.h2
-rw-r--r--chrome/browser/spellchecker/spellcheck_profile_unittest.cc2
-rw-r--r--chrome/browser/sync/glue/theme_util_unittest.cc2
-rw-r--r--chrome/browser/sync/profile_sync_service_autofill_unittest.cc2
-rw-r--r--chrome/browser/sync/sync_setup_wizard_unittest.cc4
-rw-r--r--chrome/browser/tabs/pinned_tab_service_unittest.cc2
-rw-r--r--chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm6
-rw-r--r--chrome/browser/ui/content_settings/content_setting_bubble_model.cc5
-rw-r--r--chrome/browser/ui/gtk/collected_cookies_gtk.cc4
-rw-r--r--chrome/browser/ui/views/collected_cookies_views.cc4
-rw-r--r--chrome/browser/ui/webui/collected_cookies_ui_delegate.cc4
-rw-r--r--chrome/chrome_browser.gypi8
-rw-r--r--chrome/test/base/testing_profile.cc4
48 files changed, 663 insertions, 368 deletions
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc
index 3d1e400..522bc9d 100644
--- a/chrome/browser/autofill/autofill_manager_unittest.cc
+++ b/chrome/browser/autofill/autofill_manager_unittest.cc
@@ -67,7 +67,7 @@ class TestPersonalDataManager : public PersonalDataManager {
}
// Factory method for keyed service. PersonalDataManager is NULL for testing.
- static ProfileKeyedService* Build(Profile* profile) {
+ static ProfileKeyedBase* Build(Profile* profile) {
return NULL;
}
diff --git a/chrome/browser/autofill/autofill_metrics_unittest.cc b/chrome/browser/autofill/autofill_metrics_unittest.cc
index b588c8c..ba2a6ae 100644
--- a/chrome/browser/autofill/autofill_metrics_unittest.cc
+++ b/chrome/browser/autofill/autofill_metrics_unittest.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.
@@ -85,11 +85,6 @@ class TestPersonalDataManager : public PersonalDataManager {
CreateTestAutofillProfiles(&web_profiles_);
}
- // Factory method for keyed service. PersonalDataManager is NULL for testing.
- static ProfileKeyedService* Build(Profile* profile) {
- return NULL;
- }
-
// Overridden to avoid a trip to the database. This should be a no-op except
// for the side-effect of logging the profile count.
virtual void LoadProfiles() OVERRIDE {
@@ -297,7 +292,7 @@ void AutofillMetricsTest::SetUp() {
Profile* profile = new TestingProfile();
browser_context_.reset(profile);
PersonalDataManagerFactory::GetInstance()->SetTestingFactory(
- profile, TestPersonalDataManager::Build);
+ profile, NULL);
TabContentsWrapperTestHarness::SetUp();
autofill_manager_ = new TestAutofillManager(contents_wrapper(),
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index ff1e3a3a..12744ff 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.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.
@@ -21,7 +21,7 @@ IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, RedirectLoopCookies) {
GURL test_url = test_server()->GetURL("files/redirect-loop.html");
- CookieSettings::GetForProfile(browser()->profile())->
+ CookieSettings::Factory::GetForProfile(browser()->profile())->
SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
ui_test_utils::NavigateToURL(browser(), test_url);
@@ -62,7 +62,7 @@ IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, RedirectCrossOrigin) {
host_port.port()));
GURL test_url = test_server()->GetURL("server-redirect?" + redirect);
- CookieSettings::GetForProfile(browser()->profile())->
+ CookieSettings::Factory::GetForProfile(browser()->profile())->
SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
ui_test_utils::NavigateToURL(browser(), test_url);
diff --git a/chrome/browser/content_settings/cookie_settings.cc b/chrome/browser/content_settings/cookie_settings.cc
index 6a18498..11aa2bc 100644
--- a/chrome/browser/content_settings/cookie_settings.cc
+++ b/chrome/browser/content_settings/cookie_settings.cc
@@ -43,47 +43,34 @@ bool IsAllowed(ContentSetting setting) {
} // namespace
-// |ProfileKeyedFactory| is the owner of the |ProfileKeyedService|s. This
-// wrapper class allows others to hold shared pointers to CookieSettings.
-class CookieSettingsWrapper : public ProfileKeyedService {
- public:
- explicit CookieSettingsWrapper(scoped_refptr<CookieSettings> cookie_settings)
- : cookie_settings_(cookie_settings) {}
- virtual ~CookieSettingsWrapper() {}
-
- CookieSettings* cookie_settings() { return cookie_settings_.get(); }
-
- private:
- // ProfileKeyedService methods:
- virtual void Shutdown() OVERRIDE {
- cookie_settings_->ShutdownOnUIThread();
- }
-
- scoped_refptr<CookieSettings> cookie_settings_;
-};
+// static
+CookieSettings* CookieSettings::Factory::GetForProfile(Profile* profile) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return static_cast<CookieSettings*>(
+ GetInstance()->GetBaseForProfile(profile, true));
+}
// static
CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
return Singleton<CookieSettings::Factory>::get();
}
-CookieSettingsWrapper* CookieSettings::Factory::GetWrapperForProfile(
- Profile* profile) {
- return static_cast<CookieSettingsWrapper*>(
- GetServiceForProfile(profile, true));
+CookieSettings::Factory::Factory()
+ : RefcountedProfileKeyedServiceFactory(
+ "CookieSettings",
+ ProfileDependencyManager::GetInstance()) {
}
-CookieSettings::Factory::Factory()
- : ProfileKeyedServiceFactory("CookieSettings",
- ProfileDependencyManager::GetInstance()) {
+CookieSettings::Factory::~Factory() {}
+
+bool CookieSettings::Factory::ServiceRedirectedInIncognito() {
+ return true;
}
-ProfileKeyedService* CookieSettings::Factory::BuildServiceInstanceFor(
- Profile* profile) const {
- scoped_refptr<CookieSettings> cookie_settings = new CookieSettings(
- profile->GetHostContentSettingsMap(),
- profile->GetPrefs());
- return new CookieSettingsWrapper(cookie_settings);
+RefcountedProfileKeyedService*
+CookieSettings::Factory::BuildServiceInstanceFor(Profile* profile) const {
+ return new CookieSettings(profile->GetHostContentSettingsMap(),
+ profile->GetPrefs());
}
CookieSettings::CookieSettings(
@@ -107,15 +94,6 @@ CookieSettings::CookieSettings(
CookieSettings::~CookieSettings() {
}
-// static
-CookieSettings* CookieSettings::GetForProfile(Profile* profile) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- CookieSettings* cookie_settings =
- Factory::GetInstance()->GetWrapperForProfile(profile)->cookie_settings();
- DCHECK(cookie_settings);
- return cookie_settings;
-}
-
ContentSetting
CookieSettings::GetDefaultCookieSetting(std::string* provider_id) const {
return host_content_settings_map_->GetDefaultContentSetting(
diff --git a/chrome/browser/content_settings/cookie_settings.h b/chrome/browser/content_settings/cookie_settings.h
index 394d7b6..1c87c81 100644
--- a/chrome/browser/content_settings/cookie_settings.h
+++ b/chrome/browser/content_settings/cookie_settings.h
@@ -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.
@@ -9,12 +9,12 @@
#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"
#include "chrome/browser/prefs/pref_change_registrar.h"
-#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+#include "chrome/browser/profiles/refcounted_profile_keyed_service.h"
+#include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.h"
#include "chrome/common/content_settings.h"
#include "content/public/browser/notification_observer.h"
@@ -30,7 +30,7 @@ class Profile;
class CookieSettings
: public content::NotificationObserver,
- public base::RefCountedThreadSafe<CookieSettings> {
+ public RefcountedProfileKeyedService {
public:
CookieSettings(
HostContentSettingsMap* host_content_settings_map,
@@ -38,11 +38,6 @@ class CookieSettings
virtual ~CookieSettings();
- // Returns the |CookieSettings| associated with the |profile|.
- //
- // This should only be called on the UI thread.
- static CookieSettings* GetForProfile(Profile* profile);
-
// Returns the default content setting (CONTENT_SETTING_ALLOW,
// CONTENT_SETTING_BLOCK, or CONTENT_SETTING_SESSION_ONLY) for cookies. If
// |provider_id| is not NULL, the id of the provider which provided the
@@ -106,7 +101,7 @@ class CookieSettings
// Detaches the |CookieSettings| from all |Profile|-related objects like
// |PrefService|. This methods needs to be called before destroying the
// |Profile|. Afterwards, only const methods can be called.
- void ShutdownOnUIThread();
+ virtual void ShutdownOnUIThread() OVERRIDE;
// A helper for applying third party cookie blocking rules.
ContentSetting GetCookieSetting(
@@ -117,21 +112,27 @@ class CookieSettings
static void RegisterUserPrefs(PrefService* prefs);
- class Factory : public ProfileKeyedServiceFactory {
+ class Factory : public RefcountedProfileKeyedServiceFactory {
public:
+ // Returns the |CookieSettings| associated with the |profile|.
+ //
+ // This should only be called on the UI thread.
+ static CookieSettings* GetForProfile(Profile* profile);
+
static Factory* GetInstance();
- CookieSettingsWrapper* GetWrapperForProfile(Profile* profile);
private:
friend struct DefaultSingletonTraits<Factory>;
Factory();
- virtual ~Factory() {}
+ virtual ~Factory();
// |ProfileKeyedServiceFactory| methods:
- virtual ProfileKeyedService* BuildServiceInstanceFor(
+ virtual bool ServiceRedirectedInIncognito() OVERRIDE;
+
+ // |RefcountedProfileKeyedServiceFactory| methods:
+ virtual RefcountedProfileKeyedService* BuildServiceInstanceFor(
Profile* profile) const OVERRIDE;
- virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; }
};
private:
diff --git a/chrome/browser/content_settings/cookie_settings_unittest.cc b/chrome/browser/content_settings/cookie_settings_unittest.cc
index fe482d6..a7e6e30 100644
--- a/chrome/browser/content_settings/cookie_settings_unittest.cc
+++ b/chrome/browser/content_settings/cookie_settings_unittest.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.
@@ -42,7 +42,8 @@ class CookieSettingsTest : public testing::Test {
TEST_F(CookieSettingsTest, CookiesBlockSingle) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kBlockedSite),
ContentSettingsPattern::Wildcard(),
@@ -53,7 +54,8 @@ TEST_F(CookieSettingsTest, CookiesBlockSingle) {
TEST_F(CookieSettingsTest, CookiesBlockThirdParty) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
profile.GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true);
EXPECT_FALSE(cookie_settings->IsReadingCookieAllowed(
kBlockedSite, kFirstPartySite));
@@ -73,7 +75,8 @@ TEST_F(CookieSettingsTest, CookiesBlockThirdParty) {
TEST_F(CookieSettingsTest, CookiesAllowThirdParty) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
EXPECT_TRUE(cookie_settings->IsReadingCookieAllowed(
kBlockedSite, kFirstPartySite));
EXPECT_TRUE(cookie_settings->IsSettingCookieAllowed(
@@ -83,7 +86,8 @@ TEST_F(CookieSettingsTest, CookiesAllowThirdParty) {
TEST_F(CookieSettingsTest, CookiesExplicitBlockSingleThirdParty) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kBlockedSite),
ContentSettingsPattern::Wildcard(),
@@ -98,7 +102,8 @@ TEST_F(CookieSettingsTest, CookiesExplicitBlockSingleThirdParty) {
TEST_F(CookieSettingsTest, CookiesExplicitSessionOnly) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kBlockedSite),
ContentSettingsPattern::Wildcard(),
@@ -119,7 +124,8 @@ TEST_F(CookieSettingsTest, CookiesExplicitSessionOnly) {
TEST_F(CookieSettingsTest, CookiesThirdPartyBlockedExplicitAllow) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kAllowedSite),
ContentSettingsPattern::Wildcard(),
@@ -146,7 +152,8 @@ TEST_F(CookieSettingsTest, CookiesThirdPartyBlockedExplicitAllow) {
TEST_F(CookieSettingsTest, CookiesBlockEverything) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
EXPECT_FALSE(cookie_settings->IsReadingCookieAllowed(
@@ -159,7 +166,8 @@ TEST_F(CookieSettingsTest, CookiesBlockEverything) {
TEST_F(CookieSettingsTest, CookiesBlockEverythingExceptAllowed) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kAllowedSite),
@@ -182,7 +190,8 @@ TEST_F(CookieSettingsTest, CookiesBlockEverythingExceptAllowed) {
TEST_F(CookieSettingsTest, CookiesBlockSingleFirstParty) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kAllowedSite),
ContentSettingsPattern::FromURL(kFirstPartySite),
@@ -228,7 +237,8 @@ TEST_F(CookieSettingsTest, CookiesBlockSingleFirstParty) {
TEST_F(CookieSettingsTest, ExtensionsRegularSettings) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetCookieSetting(
ContentSettingsPattern::FromURL(kBlockedSite),
ContentSettingsPattern::Wildcard(),
@@ -241,7 +251,8 @@ TEST_F(CookieSettingsTest, ExtensionsRegularSettings) {
TEST_F(CookieSettingsTest, ExtensionsOwnCookies) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
// Extensions can always use cookies (and site data) in their own origin.
@@ -251,7 +262,8 @@ TEST_F(CookieSettingsTest, ExtensionsOwnCookies) {
TEST_F(CookieSettingsTest, ExtensionsThirdParty) {
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
profile.GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true);
// XHRs stemming from extensions are exempt from third-party cookie blocking
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
index 51e923e..ac059af 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -399,7 +399,8 @@ TEST_F(HostContentSettingsMapTest, HostTrimEndingDotCheck) {
TestingProfile profile;
HostContentSettingsMap* host_content_settings_map =
profile.GetHostContentSettingsMap();
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
ContentSettingsPattern pattern =
ContentSettingsPattern::FromString("[*.]example.com");
diff --git a/chrome/browser/cookies_tree_model_unittest.cc b/chrome/browser/cookies_tree_model_unittest.cc
index 5d4dd6d..6dde8ea 100644
--- a/chrome/browser/cookies_tree_model_unittest.cc
+++ b/chrome/browser/cookies_tree_model_unittest.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.
@@ -952,7 +952,8 @@ TEST_F(CookiesTreeModelTest, ContentSettings) {
TestingProfile profile;
HostContentSettingsMap* content_settings =
profile.GetHostContentSettingsMap();
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
MockSettingsObserver observer;
CookieTreeRootNode* root =
diff --git a/chrome/browser/extensions/extension_content_settings_api.cc b/chrome/browser/extensions/extension_content_settings_api.cc
index 730e8dd..d08b250 100644
--- a/chrome/browser/extensions/extension_content_settings_api.cc
+++ b/chrome/browser/extensions/extension_content_settings_api.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.
@@ -141,11 +141,11 @@ bool GetContentSettingFunction::RunImpl() {
return false;
}
map = profile()->GetOffTheRecordProfile()->GetHostContentSettingsMap();
- cookie_settings = CookieSettings::GetForProfile(
+ cookie_settings = CookieSettings::Factory::GetForProfile(
profile()->GetOffTheRecordProfile());
} else {
map = profile()->GetHostContentSettingsMap();
- cookie_settings = CookieSettings::GetForProfile(profile());
+ cookie_settings = CookieSettings::Factory::GetForProfile(profile());
}
ContentSetting setting;
diff --git a/chrome/browser/extensions/extension_content_settings_apitest.cc b/chrome/browser/extensions/extension_content_settings_apitest.cc
index e0b7955..f7ad22b 100644
--- a/chrome/browser/extensions/extension_content_settings_apitest.cc
+++ b/chrome/browser/extensions/extension_content_settings_apitest.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.
@@ -23,7 +23,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentSettings) {
HostContentSettingsMap* map =
browser()->profile()->GetHostContentSettingsMap();
CookieSettings* cookie_settings =
- CookieSettings::GetForProfile(browser()->profile());
+ CookieSettings::Factory::GetForProfile(browser()->profile());
// Check default content settings by using an unknown URL.
GURL example_url("http://www.example.com");
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
index 5c62841..60ab2e3 100644
--- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.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.
@@ -224,7 +224,8 @@ TEST_F(ExtensionSpecialStoragePolicyTest, HasSessionOnlyOrigins) {
content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
TestingProfile profile;
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(&profile);
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(&profile);
scoped_refptr<ExtensionSpecialStoragePolicy> policy(
new ExtensionSpecialStoragePolicy(cookie_settings));
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 d308b73..15c2594 100644
--- a/chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.cc
+++ b/chrome/browser/intents/register_intent_handler_infobar_delegate_unittest.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.
@@ -25,7 +25,7 @@ class MockWebIntentsRegistry : public WebIntentsRegistry {
void(const webkit_glue::WebIntentServiceData&));
};
-ProfileKeyedService* BuildMockWebIntentsRegistry(Profile* profile) {
+ProfileKeyedBase* BuildMockWebIntentsRegistry(Profile* profile) {
return new MockWebIntentsRegistry;
}
diff --git a/chrome/browser/plugin_prefs.cc b/chrome/browser/plugin_prefs.cc
index 51be80b..bd88413 100644
--- a/chrome/browser/plugin_prefs.cc
+++ b/chrome/browser/plugin_prefs.cc
@@ -62,7 +62,7 @@ PluginPrefs* PluginPrefs::GetForProfile(Profile* profile) {
// static
PluginPrefs* PluginPrefs::GetForTestingProfile(Profile* profile) {
- ProfileKeyedService* wrapper =
+ ProfileKeyedBase* wrapper =
PluginPrefsFactory::GetInstance()->SetTestingFactoryAndUse(
profile, &PluginPrefsFactory::CreateWrapperForProfile);
return static_cast<PluginPrefsWrapper*>(wrapper)->plugin_prefs();
diff --git a/chrome/browser/plugin_prefs_factory.cc b/chrome/browser/plugin_prefs_factory.cc
index 588f974..8671a90 100644
--- a/chrome/browser/plugin_prefs_factory.cc
+++ b/chrome/browser/plugin_prefs_factory.cc
@@ -38,7 +38,7 @@ PluginPrefsWrapper* PluginPrefsFactory::GetWrapperForProfile(
}
// static
-ProfileKeyedService* PluginPrefsFactory::CreateWrapperForProfile(
+ProfileKeyedBase* PluginPrefsFactory::CreateWrapperForProfile(
Profile* profile) {
return GetInstance()->BuildServiceInstanceFor(profile);
}
diff --git a/chrome/browser/plugin_prefs_factory.h b/chrome/browser/plugin_prefs_factory.h
index edb28a5..566f39b 100644
--- a/chrome/browser/plugin_prefs_factory.h
+++ b/chrome/browser/plugin_prefs_factory.h
@@ -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.
@@ -42,7 +42,7 @@ class PluginPrefsFactory : public ProfileKeyedServiceFactory {
// Factory function for use with
// ProfileKeyedServiceFactory::SetTestingFactory.
- static ProfileKeyedService* CreateWrapperForProfile(Profile* profile);
+ static ProfileKeyedBase* CreateWrapperForProfile(Profile* profile);
// Some unit tests that deal with PluginPrefs don't run with a Profile. Let
// them still register their preferences.
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 7ba4efe..de1eb3c 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));
}
-ProfileKeyedService* TestCloudPrintProxyServiceFactory(Profile* profile) {
+ProfileKeyedBase* 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 a06c168..b567d76 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);
}
-ProfileKeyedService* CloudPrintProxyServiceFactoryForPolicyTest(
+ProfileKeyedBase* 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 12344b7..00edb13 100644
--- a/chrome/browser/profiles/profile_dependency_manager.cc
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -44,13 +44,13 @@
class Profile;
void ProfileDependencyManager::AddComponent(
- ProfileKeyedServiceFactory* component) {
+ ProfileKeyedBaseFactory* component) {
all_components_.push_back(component);
destruction_order_.clear();
}
void ProfileDependencyManager::RemoveComponent(
- ProfileKeyedServiceFactory* component) {
+ ProfileKeyedBaseFactory* component) {
all_components_.erase(std::remove(all_components_.begin(),
all_components_.end(),
component),
@@ -69,8 +69,8 @@ void ProfileDependencyManager::RemoveComponent(
destruction_order_.clear();
}
-void ProfileDependencyManager::AddEdge(ProfileKeyedServiceFactory* depended,
- ProfileKeyedServiceFactory* dependee) {
+void ProfileDependencyManager::AddEdge(ProfileKeyedBaseFactory* depended,
+ ProfileKeyedBaseFactory* dependee) {
edges_.insert(std::make_pair(depended, dependee));
destruction_order_.clear();
}
@@ -90,7 +90,7 @@ void ProfileDependencyManager::CreateProfileServices(Profile* profile,
BuildDestructionOrder(profile);
// Iterate in reverse destruction order for creation.
- for (std::vector<ProfileKeyedServiceFactory*>::reverse_iterator rit =
+ for (std::vector<ProfileKeyedBaseFactory*>::reverse_iterator rit =
destruction_order_.rbegin(); rit != destruction_order_.rend();
++rit) {
if (!profile->IsOffTheRecord()) {
@@ -103,7 +103,7 @@ void ProfileDependencyManager::CreateProfileServices(Profile* profile,
(*rit)->SetTestingFactory(profile, NULL);
} else if ((*rit)->ServiceIsCreatedWithProfile()) {
// Create the service.
- (*rit)->GetServiceForProfile(profile, true);
+ (*rit)->GetBaseForProfile(profile, true);
}
}
}
@@ -112,7 +112,7 @@ void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
if (destruction_order_.empty())
BuildDestructionOrder(profile);
- for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
+ for (std::vector<ProfileKeyedBaseFactory*>::const_iterator it =
destruction_order_.begin(); it != destruction_order_.end(); ++it) {
(*it)->ProfileShutdown(profile);
}
@@ -122,7 +122,7 @@ void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
dead_profile_pointers_.insert(profile);
#endif
- for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
+ for (std::vector<ProfileKeyedBaseFactory*>::const_iterator it =
destruction_order_.begin(); it != destruction_order_.end(); ++it) {
(*it)->ProfileDestroyed(profile);
}
@@ -204,12 +204,12 @@ void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {
#endif
// Step 1: Build a set of nodes with no incoming edges.
- std::deque<ProfileKeyedServiceFactory*> queue;
+ std::deque<ProfileKeyedBaseFactory*> queue;
std::copy(all_components_.begin(),
all_components_.end(),
std::back_inserter(queue));
- std::deque<ProfileKeyedServiceFactory*>::iterator queue_end = queue.end();
+ std::deque<ProfileKeyedBaseFactory*>::iterator queue_end = queue.end();
for (EdgeMap::const_iterator it = edges_.begin();
it != edges_.end(); ++it) {
queue_end = std::remove(queue.begin(), queue_end, it->second);
@@ -217,10 +217,10 @@ void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {
queue.erase(queue_end, queue.end());
// Step 2: Do the Kahn topological sort.
- std::vector<ProfileKeyedServiceFactory*> output;
+ std::vector<ProfileKeyedBaseFactory*> output;
EdgeMap edges(edges_);
while (!queue.empty()) {
- ProfileKeyedServiceFactory* node = queue.front();
+ ProfileKeyedBaseFactory* node = queue.front();
queue.pop_front();
output.push_back(node);
@@ -228,7 +228,7 @@ void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {
edges.equal_range(node);
EdgeMap::iterator it = range.first;
while (it != range.second) {
- ProfileKeyedServiceFactory* dest = it->second;
+ ProfileKeyedBaseFactory* dest = it->second;
EdgeMap::iterator temp = it;
it++;
edges.erase(temp);
@@ -260,14 +260,14 @@ std::string ProfileDependencyManager::DumpGraphvizDependency() {
std::string result("digraph {\n");
// Make a copy of all components.
- std::deque<ProfileKeyedServiceFactory*> components;
+ std::deque<ProfileKeyedBaseFactory*> components;
std::copy(all_components_.begin(),
all_components_.end(),
std::back_inserter(components));
// State all dependencies and remove |second| so we don't generate an
// implicit dependency on the Profile hard coded node.
- std::deque<ProfileKeyedServiceFactory*>::iterator components_end =
+ std::deque<ProfileKeyedBaseFactory*>::iterator components_end =
components.end();
result.append(" /* Dependencies */\n");
for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
@@ -285,7 +285,7 @@ std::string ProfileDependencyManager::DumpGraphvizDependency() {
// Every node that doesn't depend on anything else will implicitly depend on
// the Profile.
result.append("\n /* Toplevel attachments */\n");
- for (std::deque<ProfileKeyedServiceFactory*>::const_iterator it =
+ for (std::deque<ProfileKeyedBaseFactory*>::const_iterator it =
components.begin(); it != components.end(); ++it) {
result.append(" ");
result.append((*it)->name());
diff --git a/chrome/browser/profiles/profile_dependency_manager.h b/chrome/browser/profiles/profile_dependency_manager.h
index 3ad0634..56458367 100644
--- a/chrome/browser/profiles/profile_dependency_manager.h
+++ b/chrome/browser/profiles/profile_dependency_manager.h
@@ -16,26 +16,26 @@
#endif
class Profile;
-class ProfileKeyedServiceFactory;
+class ProfileKeyedBaseFactory;
// A singleton that listens for profile destruction notifications and
-// rebroadcasts them to each ProfileKeyedServiceFactory in a safe order based
+// rebroadcasts them to each ProfileKeyedBaseFactory in a safe order based
// on the stated dependencies by each service.
class ProfileDependencyManager {
public:
// Adds/Removes a component from our list of live components. Removing will
// also remove live dependency links.
- void AddComponent(ProfileKeyedServiceFactory* component);
- void RemoveComponent(ProfileKeyedServiceFactory* component);
+ void AddComponent(ProfileKeyedBaseFactory* component);
+ void RemoveComponent(ProfileKeyedBaseFactory* component);
// Adds a dependency between two factories.
- void AddEdge(ProfileKeyedServiceFactory* depended,
- ProfileKeyedServiceFactory* dependee);
+ void AddEdge(ProfileKeyedBaseFactory* depended,
+ ProfileKeyedBaseFactory* dependee);
// Called by each Profile to alert us of its creation. Several services want
// to be started when a profile is created. Testing configuration is also
// done at this time. (If you want your ProfileKeyedService to be started
- // with the Profile, override ProfileKeyedServiceFactory::
+ // with the Profile, override ProfileKeyedBaseFactory::
// ServiceIsCreatedWithProfile() to return true.)
void CreateProfileServices(Profile* profile, bool is_testing_profile);
@@ -64,8 +64,8 @@ class ProfileDependencyManager {
friend class ProfileDependencyManagerUnittests;
friend struct DefaultSingletonTraits<ProfileDependencyManager>;
- typedef std::multimap<ProfileKeyedServiceFactory*,
- ProfileKeyedServiceFactory*> EdgeMap;
+ typedef std::multimap<ProfileKeyedBaseFactory*,
+ ProfileKeyedBaseFactory*> EdgeMap;
ProfileDependencyManager();
virtual ~ProfileDependencyManager();
@@ -75,7 +75,7 @@ class ProfileDependencyManager {
void AssertFactoriesBuilt();
// Using the dependency graph defined in |edges_|, fills |destruction_order_|
- // so that Observe() can notify each ProfileKeyedServiceFactory in order.
+ // so that Observe() can notify each ProfileKeyedBaseFactory in order.
void BuildDestructionOrder(Profile* profile);
#ifndef NDEBUG
@@ -83,11 +83,11 @@ class ProfileDependencyManager {
std::string DumpGraphvizDependency();
#endif
- std::vector<ProfileKeyedServiceFactory*> all_components_;
+ std::vector<ProfileKeyedBaseFactory*> all_components_;
EdgeMap edges_;
- std::vector<ProfileKeyedServiceFactory*> destruction_order_;
+ std::vector<ProfileKeyedBaseFactory*> destruction_order_;
// Whether AssertFactoriesBuilt has been done.
bool built_factories_;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index ef54f1c..5900233 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -729,8 +729,8 @@ ExtensionEventRouter* ProfileImpl::GetExtensionEventRouter() {
ExtensionSpecialStoragePolicy*
ProfileImpl::GetExtensionSpecialStoragePolicy() {
if (!extension_special_storage_policy_.get()) {
- extension_special_storage_policy_ =
- new ExtensionSpecialStoragePolicy(CookieSettings::GetForProfile(this));
+ extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(
+ CookieSettings::Factory::GetForProfile(this));
}
return extension_special_storage_policy_.get();
}
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 312f9d2..ea45c55 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.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.
@@ -222,7 +222,7 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) {
params->audio_manager = g_browser_process->audio_manager();
params->host_content_settings_map = profile->GetHostContentSettingsMap();
- params->cookie_settings = CookieSettings::GetForProfile(profile);
+ params->cookie_settings = CookieSettings::Factory::GetForProfile(profile);
params->host_zoom_map = profile->GetHostZoomMap();
params->ssl_config_service = profile->GetSSLConfigService();
base::Callback<Profile*(void)> profile_getter =
diff --git a/chrome/browser/profiles/profile_keyed_base.h b/chrome/browser/profiles/profile_keyed_base.h
new file mode 100644
index 0000000..6a2f2d4
--- /dev/null
+++ b/chrome/browser/profiles/profile_keyed_base.h
@@ -0,0 +1,18 @@
+// 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
new file mode 100644
index 0000000..19a1383
--- /dev/null
+++ b/chrome/browser/profiles/profile_keyed_base_factory.cc
@@ -0,0 +1,154 @@
+// 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.
+
+#include "chrome/browser/profiles/profile_keyed_base_factory.h"
+
+#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;
+}
+
+ProfileKeyedBaseFactory::ProfileKeyedBaseFactory(
+ const char* name, ProfileDependencyManager* manager)
+ : dependency_manager_(manager)
+#ifndef NDEBUG
+ , service_name_(name)
+#endif
+{
+ dependency_manager_->AddComponent(this);
+}
+
+ProfileKeyedBaseFactory::~ProfileKeyedBaseFactory() {
+ dependency_manager_->RemoveComponent(this);
+}
+
+
+void ProfileKeyedBaseFactory::DependsOn(ProfileKeyedBaseFactory* rhs) {
+ dependency_manager_->AddEdge(rhs, this);
+}
+
+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
+ // Profile. Now we don't and there are timing issues.
+ //
+ // With normal profiles, prefs can simply be registered at
+ // ProfileDependencyManager::CreateProfileServices time. With incognito
+ // profiles, we just never register since incognito profiles share the same
+ // pref services with their parent profiles.
+ //
+ // TestingProfiles throw a wrench into the mix, in that some tests will
+ // swap out the PrefService after we've registered user prefs on the original
+ // PrefService. Test code that does this is responsible for either manually
+ // invoking RegisterUserPrefs() on the appropriate ProfileKeyedServiceFactory
+ // associated with the prefs they need, or they can use SetTestingFactory()
+ // and create a service (since service creation with a factory method causes
+ // registration to happen at service creation time).
+ //
+ // Now that services are responsible for declaring their preferences, we have
+ // to enforce a uniquenes check here because some tests create one profile and
+ // multiple services of the same type attached to that profile (serially, not
+ // parallel) and we don't want to register multiple times on the same profile.
+ DCHECK(!profile->IsOffTheRecord());
+
+ std::set<Profile*>::iterator it = registered_preferences_.find(profile);
+ if (it == registered_preferences_.end()) {
+ RegisterUserPrefs(profile->GetPrefs());
+ registered_preferences_.insert(profile);
+ }
+}
+
+bool ProfileKeyedBaseFactory::ServiceRedirectedInIncognito() {
+ return false;
+}
+
+bool ProfileKeyedBaseFactory::ServiceHasOwnInstanceInIncognito() {
+ return false;
+}
+
+bool ProfileKeyedBaseFactory::ServiceIsCreatedWithProfile() {
+ return false;
+}
+
+bool ProfileKeyedBaseFactory::ServiceIsNULLWhileTesting() {
+ return false;
+}
+
+ProfileKeyedBase* ProfileKeyedBaseFactory::GetBaseForProfile(
+ Profile* profile,
+ bool create) {
+#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) {
+ // 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);
+}
diff --git a/chrome/browser/profiles/profile_keyed_base_factory.h b/chrome/browser/profiles/profile_keyed_base_factory.h
new file mode 100644
index 0000000..3c4f092
--- /dev/null
+++ b/chrome/browser/profiles/profile_keyed_base_factory.h
@@ -0,0 +1,149 @@
+// 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_FACTORY_H_
+#define CHROME_BROWSER_PROFILES_PROFILE_KEYED_BASE_FACTORY_H_
+
+#include <map>
+#include <set>
+
+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.
+class ProfileKeyedBaseFactory {
+ 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);
+
+ // 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
+ // attached to a single |profile|.
+ void RegisterUserPrefsOnProfile(Profile* profile);
+
+#ifndef NDEBUG
+ // Returns our name. We don't keep track of this in release mode.
+ const char* name() const { return service_name_; }
+#endif
+
+ protected:
+ ProfileKeyedBaseFactory(const char* name,
+ ProfileDependencyManager* manager);
+ virtual ~ProfileKeyedBaseFactory();
+
+ // The main public interface for declaring dependencies between services
+ // created by factories.
+ void DependsOn(ProfileKeyedBaseFactory* rhs);
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Register any user preferences on this service. This is called during
+ // CreateProfileService() since preferences are registered on a per Profile
+ // 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
+ // following methods:
+ virtual bool ServiceRedirectedInIncognito();
+ virtual bool ServiceHasOwnInstanceInIncognito();
+
+ // By default, we create instances of a service lazily and wait until
+ // GetForProfile() is called on our subclass. Some services need to be
+ // created as soon as the Profile has been brought up.
+ virtual bool ServiceIsCreatedWithProfile();
+
+ // By default, TestingProfiles will be treated like normal profiles. You can
+ // override this so that by default, the service associated with the
+ // TestingProfile is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our profiles don't directly refer to the
+ // services they use.)
+ virtual bool ServiceIsNULLWhileTesting();
+
+ // 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.
+ //
+ // It is up to the individual factory types to determine what this two pass
+ // shutdown means. The general framework guarantees the following:
+ //
+ // - Each ProfileShutdown() is called in dependency order (and you may reach
+ // out to other services during this phase).
+ //
+ // - Each ProfileDestroyed() is called in dependency order. We will
+ // NOTREACHED() if you attempt to GetForProfile() any other service. You
+ // should delete/deref/do other final memory management things during this
+ // phase. You must also call the base class method as the last thing you
+ // do.
+ virtual void ProfileShutdown(Profile* profile) = 0;
+ virtual void ProfileDestroyed(Profile* profile);
+
+ private:
+ friend class ProfileDependencyManager;
+ friend class ProfileDependencyManagerUnittests;
+
+ // 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.
+ ProfileDependencyManager* dependency_manager_;
+
+ // 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
+ // pretty graphs with GraphViz with this information.)
+ const char* service_name_;
+#endif
+};
+
+#endif // CHROME_BROWSER_PROFILES_PROFILE_KEYED_BASE_FACTORY_H_
diff --git a/chrome/browser/profiles/profile_keyed_service.h b/chrome/browser/profiles/profile_keyed_service.h
index f03e186..0a39612 100644
--- a/chrome/browser/profiles/profile_keyed_service.h
+++ b/chrome/browser/profiles/profile_keyed_service.h
@@ -1,10 +1,12 @@
-// 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.
#ifndef CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_H_
#define CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_H_
+#include "chrome/browser/profiles/profile_keyed_base.h"
+
// Base class for all ProfileKeyedServices to allow for correct destruction
// order.
//
@@ -13,7 +15,7 @@
// 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 {
+class ProfileKeyedService : public ProfileKeyedBase {
public:
// The first pass is to call Shutdown on a ProfileKeyedService.
virtual void Shutdown() {}
@@ -23,4 +25,3 @@ class ProfileKeyedService {
};
#endif // CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_H_
-
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc
index 07a6d6d..e2e6fcf 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory.cc
@@ -11,27 +11,6 @@
#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 = 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;
-}
-
ProfileKeyedService* ProfileKeyedServiceFactory::SetTestingFactoryAndUse(
Profile* profile,
FactoryFunction factory) {
@@ -40,129 +19,40 @@ ProfileKeyedService* ProfileKeyedServiceFactory::SetTestingFactoryAndUse(
return GetServiceForProfile(profile, true);
}
-void ProfileKeyedServiceFactory::RegisterUserPrefsOnProfile(Profile* profile) {
- // Safe timing for pref registration is hard. Previously, we made Profile
- // responsible for all pref registration on every service that used
- // Profile. Now we don't and there are timing issues.
- //
- // With normal profiles, prefs can simply be registered at
- // ProfileDependencyManager::CreateProfileServices time. With incognito
- // profiles, we just never register since incognito profiles share the same
- // pref services with their parent profiles.
- //
- // TestingProfiles throw a wrench into the mix, in that some tests will
- // swap out the PrefService after we've registered user prefs on the original
- // PrefService. Test code that does this is responsible for either manually
- // invoking RegisterUserPrefs() on the appropriate ProfileKeyedServiceFactory
- // associated with the prefs they need, or they can use SetTestingFactory()
- // and create a service (since service creation with a factory method causes
- // registration to happen at service creation time).
- //
- // Now that services are responsible for declaring their preferences, we have
- // to enforce a uniquenes check here because some tests create one profile and
- // multiple services of the same type attached to that profile (serially, not
- // parallel) and we don't want to register multiple times on the same profile.
- DCHECK(!profile->IsOffTheRecord());
-
- std::set<Profile*>::iterator it = registered_preferences_.find(profile);
- if (it == registered_preferences_.end()) {
- RegisterUserPrefs(profile->GetPrefs());
- registered_preferences_.insert(profile);
- }
-}
-
ProfileKeyedServiceFactory::ProfileKeyedServiceFactory(
const char* name, ProfileDependencyManager* manager)
- : dependency_manager_(manager)
-#ifndef NDEBUG
- , service_name_(name)
-#endif
-{
- dependency_manager_->AddComponent(this);
+ : ProfileKeyedBaseFactory(name, manager) {
}
ProfileKeyedServiceFactory::~ProfileKeyedServiceFactory() {
- dependency_manager_->RemoveComponent(this);
DCHECK(mapping_.empty());
}
ProfileKeyedService* ProfileKeyedServiceFactory::GetServiceForProfile(
Profile* profile,
bool create) {
-#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;
- }
- }
-
- ProfileKeyedService* service;
-
- std::map<Profile*, ProfileKeyedService*>::iterator it =
- mapping_.find(profile);
- if (it != mapping_.end()) {
- return it->second;
- } 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 ProfileKeyedServiceFactory::DependsOn(ProfileKeyedServiceFactory* rhs) {
- dependency_manager_->AddEdge(rhs, this);
+ return static_cast<ProfileKeyedService*>(GetBaseForProfile(profile, create));
}
void ProfileKeyedServiceFactory::Associate(Profile* profile,
- ProfileKeyedService* service) {
+ ProfileKeyedBase* service) {
DCHECK(mapping_.find(profile) == mapping_.end());
- mapping_.insert(std::make_pair(profile, service));
-}
-
-bool ProfileKeyedServiceFactory::ServiceRedirectedInIncognito() {
- return false;
+ mapping_.insert(std::make_pair(
+ profile, static_cast<ProfileKeyedService*>(service)));
}
-bool ProfileKeyedServiceFactory::ServiceHasOwnInstanceInIncognito() {
- return false;
-}
-
-bool ProfileKeyedServiceFactory::ServiceIsCreatedWithProfile() {
- return false;
-}
-
-bool ProfileKeyedServiceFactory::ServiceIsNULLWhileTesting() {
- return false;
+bool ProfileKeyedServiceFactory::GetAssociation(
+ Profile* profile,
+ ProfileKeyedBase** out) const {
+ bool found = false;
+ std::map<Profile*, ProfileKeyedService*>::const_iterator it =
+ mapping_.find(profile);
+ if (it != mapping_.end()) {
+ found = true;
+ if (out)
+ *out = it->second;
+ }
+ return found;
}
void ProfileKeyedServiceFactory::ProfileShutdown(Profile* profile) {
@@ -180,10 +70,5 @@ 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);
- registered_preferences_.erase(profile);
+ ProfileKeyedBaseFactory::ProfileDestroyed(profile);
}
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.h b/chrome/browser/profiles/profile_keyed_service_factory.h
index 30c99c1..3aa58ee 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.h
+++ b/chrome/browser/profiles/profile_keyed_service_factory.h
@@ -6,9 +6,11 @@
#define CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_
#include <map>
-#include <set>
-class PrefService;
+#include "base/compiler_specific.h"
+#include "chrome/browser/profiles/profile_keyed_base_factory.h"
+#include "chrome/browser/profiles/profile_keyed_service.h"
+
class Profile;
class ProfileDependencyManager;
class ProfileKeyedService;
@@ -21,36 +23,14 @@ class ProfileKeyedService;
// We do this because services depend on each other and we need to control
// shutdown/destruction order. In each derived classes' constructors, the
// implementors must explicitly state which services are depended on.
-class ProfileKeyedServiceFactory {
+class ProfileKeyedServiceFactory : public ProfileKeyedBaseFactory {
public:
- 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. 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;
ProfileKeyedService* 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
- // attached to a single |profile|.
- void RegisterUserPrefsOnProfile(Profile* profile);
-
-#ifndef NDEBUG
- // Returns our name. We don't keep track of this in release mode.
- const char* name() const { return service_name_; }
-#endif
-
protected:
// ProfileKeyedServiceFactories must communicate with a
// ProfileDependencyManager. For all non-test code, write your subclass
@@ -61,8 +41,8 @@ class ProfileKeyedServiceFactory {
// "MyService",
// ProfileDependencyManager::GetInstance())
// {}
- explicit ProfileKeyedServiceFactory(const char* name,
- ProfileDependencyManager* manager);
+ ProfileKeyedServiceFactory(const char* name,
+ ProfileDependencyManager* manager);
virtual ~ProfileKeyedServiceFactory();
// Common implementation that maps |profile| to some service object. Deals
@@ -72,41 +52,17 @@ class ProfileKeyedServiceFactory {
// BuildServiceInstanceFor() if it doesn't already exist.
ProfileKeyedService* GetServiceForProfile(Profile* profile, bool create);
- // The main public interface for declaring dependencies between services
- // created by factories.
- void DependsOn(ProfileKeyedServiceFactory* rhs);
-
- // Maps |profile| to |provider| with debug checks to prevent duplication.
- void Associate(Profile* profile, ProfileKeyedService* service);
-
- // Returns a new instance of the service, casted to void* for our common
- // storage.
+ // All subclasses of ProfileKeyedServiceFactory must return a
+ // ProfileKeyedService instead of just a ProfileKeyedBase.
virtual ProfileKeyedService* BuildServiceInstanceFor(
Profile* profile) const = 0;
- // Register any user preferences on this service. This is called during
- // CreateProfileService() since preferences are registered on a per Profile
- // basis.
- virtual void RegisterUserPrefs(PrefService* user_prefs) {}
-
- // 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
- // following methods:
- virtual bool ServiceRedirectedInIncognito();
- virtual bool ServiceHasOwnInstanceInIncognito();
-
- // By default, we create instances of a service lazily and wait until
- // GetForProfile() is called on our subclass. Some services need to be
- // created as soon as the Profile has been brought up.
- virtual bool ServiceIsCreatedWithProfile();
+ // Maps |profile| to |provider| with debug checks to prevent duplication.
+ virtual void Associate(Profile* profile, ProfileKeyedBase* base) OVERRIDE;
- // By default, TestingProfiles will be treated like normal profiles. You can
- // override this so that by default, the service associated with the
- // TestingProfile is NULL. (This is just a shortcut around
- // SetTestingFactory() to make sure our profiles don't directly refer to the
- // services they use.)
- virtual bool ServiceIsNULLWhileTesting();
+ // 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
@@ -119,8 +75,8 @@ class ProfileKeyedServiceFactory {
//
// Secondly, ProfileDestroyed() is called on every ServiceFactory and the
// default implementation removes it from |mapping_| and deletes the pointer.
- virtual void ProfileShutdown(Profile* profile);
- virtual void ProfileDestroyed(Profile* profile);
+ virtual void ProfileShutdown(Profile* profile) OVERRIDE;
+ virtual void ProfileDestroyed(Profile* profile) OVERRIDE;
private:
friend class ProfileDependencyManager;
@@ -128,24 +84,6 @@ class ProfileKeyedServiceFactory {
// 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_;
-
- // Profiles that have this service's preferences registered on them.
- std::set<Profile*> registered_preferences_;
-
- // 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.
- ProfileDependencyManager* dependency_manager_;
-
-#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
- // pretty graphs with GraphViz with this information.)
- const char* service_name_;
-#endif
};
#endif // CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_
diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service.cc b/chrome/browser/profiles/refcounted_profile_keyed_service.cc
new file mode 100644
index 0000000..b9e757c
--- /dev/null
+++ b/chrome/browser/profiles/refcounted_profile_keyed_service.cc
@@ -0,0 +1,8 @@
+// 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.
+
+#include "chrome/browser/profiles/refcounted_profile_keyed_service.h"
+
+RefcountedProfileKeyedService::~RefcountedProfileKeyedService() {}
+
diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service.h b/chrome/browser/profiles/refcounted_profile_keyed_service.h
new file mode 100644
index 0000000..562e113
--- /dev/null
+++ b/chrome/browser/profiles/refcounted_profile_keyed_service.h
@@ -0,0 +1,33 @@
+// 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_REFCOUNTED_PROFILE_KEYED_SERVICE_H_
+#define CHROME_BROWSER_PROFILES_REFCOUNTED_PROFILE_KEYED_SERVICE_H_
+
+#include "base/memory/ref_counted.h"
+#include "chrome/browser/profiles/profile_keyed_base.h"
+
+// Base class for refcounted objects that hang off the Profile.
+//
+// The two pass shutdown described in ProfileKeyedService works a bit
+// differently because there could be outstanding references on other
+// threads. ShutdownOnUIThread() will be called on the UI thread, and then the
+// destructor will run when the last reference is dropped, which may or may not
+// be after the corresponding Profile has been destroyed.
+class RefcountedProfileKeyedService
+ : public ProfileKeyedBase,
+ public base::RefCountedThreadSafe<RefcountedProfileKeyedService> {
+ public:
+ // Unlike ProfileKeyedService, ShutdownOnUI is not optional. You must do
+ // something to drop references during the first pass Shutdown() because this
+ // is the only point where you are guaranteed that something is running on
+ // the UI thread. The PKSF framework will ensure that this is only called on
+ // the UI thread; you do not need to check for that yourself.
+ virtual void ShutdownOnUIThread() = 0;
+
+ // This second pass can happen anywhere.
+ virtual ~RefcountedProfileKeyedService();
+};
+
+#endif // CHROME_BROWSER_PROFILES_REFCOUNTED_PROFILE_KEYED_SERVICE_H_
diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc
new file mode 100644
index 0000000..56a273a
--- /dev/null
+++ b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc
@@ -0,0 +1,60 @@
+// 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.
+
+#include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.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;
+
+RefcountedProfileKeyedServiceFactory::RefcountedProfileKeyedServiceFactory(
+ const char* name,
+ ProfileDependencyManager* manager)
+ : ProfileKeyedBaseFactory(name, manager) {
+}
+
+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(
+ Profile* profile,
+ ProfileKeyedBase** out) const {
+ bool found = false;
+ RefCountedStorage::const_iterator it = mapping_.find(profile);
+ if (it != mapping_.end()) {
+ found = true;
+
+ if (out)
+ *out = it->second.get();
+ }
+ return found;
+}
+
+void RefcountedProfileKeyedServiceFactory::ProfileShutdown(Profile* profile) {
+ RefCountedStorage::iterator it = mapping_.find(profile);
+ if (it != mapping_.end() && it->second)
+ it->second->ShutdownOnUIThread();
+}
+
+void RefcountedProfileKeyedServiceFactory::ProfileDestroyed(Profile* profile) {
+ RefCountedStorage::iterator it = mapping_.find(profile);
+ if (it != mapping_.end()) {
+ // We "merely" drop our reference to the service. Hopefully this will cause
+ // the service to be destroyed. If not, oh well.
+ mapping_.erase(it);
+ }
+
+ ProfileKeyedBaseFactory::ProfileDestroyed(profile);
+}
diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h
new file mode 100644
index 0000000..93e1d47
--- /dev/null
+++ b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h
@@ -0,0 +1,51 @@
+// 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_REFCOUNTED_PROFILE_KEYED_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_PROFILES_REFCOUNTED_PROFILE_KEYED_SERVICE_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+#include "chrome/browser/profiles/refcounted_profile_keyed_service.h"
+
+class Profile;
+class RefcountedProfileKeyedService;
+
+// A specialized ProfileKeyedServiceFactory that manages a
+// RefcountedThreadSafe<>.
+//
+// Implementers of RefcountedProfileKeyedService should note that we guarantee
+// that ShutdownOnUIThread() is called on the UI thread, but actual object
+// destruction can happen anywhere.
+class RefcountedProfileKeyedServiceFactory : public ProfileKeyedBaseFactory {
+ protected:
+ RefcountedProfileKeyedServiceFactory(const char* name,
+ ProfileDependencyManager* manager);
+ virtual ~RefcountedProfileKeyedServiceFactory();
+
+ // All subclasses of RefcountedProfileKeyedServiceFactory must return a
+ // RefcountedProfileKeyedService instead of just a ProfileKeyedBase.
+ virtual 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;
+
+ private:
+ typedef std::map<Profile*, scoped_refptr<RefcountedProfileKeyedService> >
+ RefCountedStorage;
+
+ // The mapping between a Profile and its refcounted service.
+ RefCountedStorage mapping_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefcountedProfileKeyedServiceFactory);
+};
+
+#endif // CHROME_BROWSER_PROFILES_REFCOUNTED_PROFILE_KEYED_SERVICE_FACTORY_H_
diff --git a/chrome/browser/protector/mock_protector_service.cc b/chrome/browser/protector/mock_protector_service.cc
index a8caacb..971ea28 100644
--- a/chrome/browser/protector/mock_protector_service.cc
+++ b/chrome/browser/protector/mock_protector_service.cc
@@ -11,7 +11,7 @@ namespace protector {
namespace {
-ProfileKeyedService* BuildMockProtectorService(Profile* profile) {
+ProfileKeyedBase* BuildMockProtectorService(Profile* profile) {
return new MockProtectorService(profile);
}
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index 6e4ff09..5dff4e0 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -55,7 +55,7 @@ ChromeRenderMessageFilter::ChromeRenderMessageFilter(
profile_(profile),
request_context_(request_context),
extension_info_map_(profile->GetExtensionInfoMap()),
- cookie_settings_(CookieSettings::GetForProfile(profile)),
+ cookie_settings_(CookieSettings::Factory::GetForProfile(profile)),
weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
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 098e50c..732fdbc 100644
--- a/chrome/browser/search_engines/template_url_service_test_util.cc
+++ b/chrome/browser/search_engines/template_url_service_test_util.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.
@@ -75,7 +75,7 @@ class TemplateURLServiceTestingProfile : public TestingProfile {
// SetKeywordSearchTermsForURL.
class TestingTemplateURLService : public TemplateURLService {
public:
- static ProfileKeyedService* Build(Profile* profile) {
+ static ProfileKeyedBase* 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 0eae17d..5ac6e1c 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
-ProfileKeyedService* FakeSigninManager::Build(Profile* profile) {
+ProfileKeyedBase* 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 a1e1c42..f991d8f 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 ProfileKeyedService* Build(Profile* profile);
+ static ProfileKeyedBase* Build(Profile* profile);
};
#endif // CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_FAKE_H_
diff --git a/chrome/browser/spellchecker/spellcheck_profile_unittest.cc b/chrome/browser/spellchecker/spellcheck_profile_unittest.cc
index e44d7cd..bf4e9b5 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_;
};
-ProfileKeyedService* BuildTestingSpellCheckProfile(Profile* profile) {
+ProfileKeyedBase* BuildTestingSpellCheckProfile(Profile* profile) {
return new TestingSpellCheckProfile(profile);
}
diff --git a/chrome/browser/sync/glue/theme_util_unittest.cc b/chrome/browser/sync/glue/theme_util_unittest.cc
index b1dad81..e1a8222 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());
};
-ProfileKeyedService* BuildMockThemeService(Profile* profile) {
+ProfileKeyedBase* 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 31eaecc..2390313 100644
--- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
@@ -328,7 +328,7 @@ class AutofillProfileFactory : public AbstractAutofillFactory {
class PersonalDataManagerMock: public PersonalDataManager {
public:
- static ProfileKeyedService* Build(Profile* profile) {
+ static ProfileKeyedBase* Build(Profile* profile) {
return new PersonalDataManagerMock;
}
diff --git a/chrome/browser/sync/sync_setup_wizard_unittest.cc b/chrome/browser/sync/sync_setup_wizard_unittest.cc
index 5f0f98f..2c2b859 100644
--- a/chrome/browser/sync/sync_setup_wizard_unittest.cc
+++ b/chrome/browser/sync/sync_setup_wizard_unittest.cc
@@ -93,12 +93,12 @@ class ProfileSyncServiceForWizardTest : public ProfileSyncService {
public:
virtual ~ProfileSyncServiceForWizardTest() {}
- static ProfileKeyedService* BuildManual(Profile* profile) {
+ static ProfileKeyedBase* BuildManual(Profile* profile) {
return new ProfileSyncServiceForWizardTest(profile,
ProfileSyncService::MANUAL_START);
}
- static ProfileKeyedService* BuildAuto(Profile* profile) {
+ static ProfileKeyedBase* 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 6f00338..0296c40 100644
--- a/chrome/browser/tabs/pinned_tab_service_unittest.cc
+++ b/chrome/browser/tabs/pinned_tab_service_unittest.cc
@@ -17,7 +17,7 @@
namespace {
-ProfileKeyedService* BuildPinnedTabService(Profile* profile) {
+ProfileKeyedBase* BuildPinnedTabService(Profile* profile) {
return new PinnedTabService(profile);
}
diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
index 582ab9b..8b514fd 100644
--- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
+++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
@@ -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.
@@ -246,8 +246,8 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) {
Profile* profile = wrapper_->profile();
CookieTreeOriginNode* origin_node =
static_cast<CookieTreeOriginNode*>(cookie);
- origin_node->CreateContentException(CookieSettings::GetForProfile(profile),
- setting);
+ origin_node->CreateContentException(
+ CookieSettings::Factory::GetForProfile(profile), setting);
if (!lastDomain.empty())
multipleDomainsChanged = YES;
lastDomain = origin_node->GetTitle();
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index fb07eb2..4a0a639 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.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.
@@ -261,7 +261,8 @@ class ContentSettingSingleRadioGroup
radio_group.radio_items.push_back(radio_allow_label);
radio_group.radio_items.push_back(radio_block_label);
HostContentSettingsMap* map = profile()->GetHostContentSettingsMap();
- CookieSettings* cookie_settings = CookieSettings::GetForProfile(profile());
+ CookieSettings* cookie_settings =
+ CookieSettings::Factory::GetForProfile(profile());
ContentSetting most_restrictive_setting;
SettingSource most_restrictive_setting_source = SETTING_SOURCE_NONE;
diff --git a/chrome/browser/ui/gtk/collected_cookies_gtk.cc b/chrome/browser/ui/gtk/collected_cookies_gtk.cc
index a2fa8c7..43bc94e 100644
--- a/chrome/browser/ui/gtk/collected_cookies_gtk.cc
+++ b/chrome/browser/ui/gtk/collected_cookies_gtk.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.
@@ -461,7 +461,7 @@ void CollectedCookiesGtk::AddExceptions(GtkTreeSelection* selection,
last_domain_name = origin_node->GetTitle();
Profile* profile = wrapper_->profile();
origin_node->CreateContentException(
- CookieSettings::GetForProfile(profile), setting);
+ CookieSettings::Factory::GetForProfile(profile), setting);
}
}
g_list_foreach(paths, reinterpret_cast<GFunc>(gtk_tree_path_free), NULL);
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index 95c2b2d..ab1ab8c 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -481,8 +481,8 @@ void CollectedCookiesViews::AddContentException(views::TreeView* tree_view,
CookieTreeOriginNode* origin_node =
static_cast<CookieTreeOriginNode*>(tree_view->GetSelectedNode());
Profile* profile = wrapper_->profile();
- origin_node->CreateContentException(CookieSettings::GetForProfile(profile),
- setting);
+ origin_node->CreateContentException(
+ CookieSettings::Factory::GetForProfile(profile), setting);
infobar_->UpdateVisibility(true, setting, origin_node->GetTitle());
status_changed_ = true;
}
diff --git a/chrome/browser/ui/webui/collected_cookies_ui_delegate.cc b/chrome/browser/ui/webui/collected_cookies_ui_delegate.cc
index fa3c2f1..dc9a858 100644
--- a/chrome/browser/ui/webui/collected_cookies_ui_delegate.cc
+++ b/chrome/browser/ui/webui/collected_cookies_ui_delegate.cc
@@ -244,8 +244,8 @@ void CollectedCookiesUIDelegate::AddContentException(
CookieTreeOriginNode* origin_node, ContentSetting setting) {
if (origin_node->CanCreateContentException()) {
Profile* profile = wrapper_->profile();
- origin_node->CreateContentException(CookieSettings::GetForProfile(profile),
- setting);
+ origin_node->CreateContentException(
+ CookieSettings::Factory::GetForProfile(profile), setting);
SetInfobarLabel(GetInfobarLabel(setting, origin_node->GetTitle()));
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 99664e5..4c82a96 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2062,6 +2062,10 @@
'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',
'browser/profiles/profile_keyed_service_factory.cc',
'browser/profiles/profile_keyed_service_factory.h',
'browser/profiles/profile_manager.cc',
@@ -2070,6 +2074,10 @@
'browser/profiles/profile_metrics.h',
'browser/profiles/profile_shortcut_manager_win.cc',
'browser/profiles/profile_shortcut_manager_win.h',
+ 'browser/profiles/refcounted_profile_keyed_service.h',
+ 'browser/profiles/refcounted_profile_keyed_service.cc',
+ 'browser/profiles/refcounted_profile_keyed_service_factory.h',
+ 'browser/profiles/refcounted_profile_keyed_service_factory.cc',
'browser/protector/base_setting_change.cc',
'browser/protector/base_setting_change.h',
'browser/protector/default_search_provider_change.cc',
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 4f61359..0ff506c 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -123,7 +123,7 @@ class TestExtensionURLRequestContextGetter
scoped_refptr<net::URLRequestContext> context_;
};
-ProfileKeyedService* CreateTestDesktopNotificationService(Profile* profile) {
+ProfileKeyedBase* CreateTestDesktopNotificationService(Profile* profile) {
return new DesktopNotificationService(profile, NULL);
}
@@ -376,7 +376,7 @@ void TestingProfile::CreateTemplateURLFetcher() {
template_url_fetcher_.reset(new TemplateURLFetcher(this));
}
-static ProfileKeyedService* BuildTemplateURLService(Profile* profile) {
+static ProfileKeyedBase* BuildTemplateURLService(Profile* profile) {
return new TemplateURLService(profile);
}