diff options
13 files changed, 174 insertions, 74 deletions
diff --git a/chrome/browser/content_settings/host_content_settings_map_factory.cc b/chrome/browser/content_settings/host_content_settings_map_factory.cc new file mode 100644 index 0000000..79d2395 --- /dev/null +++ b/chrome/browser/content_settings/host_content_settings_map_factory.cc @@ -0,0 +1,98 @@ +// Copyright 2015 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/content_settings/host_content_settings_map_factory.h" + +#include "chrome/browser/profiles/off_the_record_profile_impl.h" +#include "chrome/browser/profiles/profile.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_thread.h" + +#if defined(ENABLE_EXTENSIONS) +#include "chrome/browser/extensions/extension_service.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_system_provider.h" +#include "extensions/browser/extensions_browser_client.h" +#endif + +#if defined(ENABLE_SUPERVISED_USERS) +#include "chrome/browser/content_settings/content_settings_supervised_provider.h" +#include "chrome/browser/supervised_user/supervised_user_settings_service.h" +#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" +#endif + +HostContentSettingsMapFactory::HostContentSettingsMapFactory() + : RefcountedBrowserContextKeyedServiceFactory( + "HostContentSettingsMap", + BrowserContextDependencyManager::GetInstance()) { +#if defined(ENABLE_SUPERVISED_USERS) + DependsOn(SupervisedUserSettingsServiceFactory::GetInstance()); +#endif +#if defined(ENABLE_EXTENSIONS) + DependsOn( + extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); +#endif +} + +HostContentSettingsMapFactory::~HostContentSettingsMapFactory() { +} + +// static +HostContentSettingsMap* HostContentSettingsMapFactory::GetForProfile( + Profile* profile) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + return static_cast<HostContentSettingsMap*>( + GetInstance()->GetServiceForBrowserContext(profile, true).get()); +} + +// static +HostContentSettingsMapFactory* HostContentSettingsMapFactory::GetInstance() { + return Singleton<HostContentSettingsMapFactory>::get(); +} + +scoped_refptr<RefcountedKeyedService> + HostContentSettingsMapFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + Profile* profile = static_cast<Profile*>(context); + bool off_the_record = profile->GetProfileType() == Profile::INCOGNITO_PROFILE; + + // If off the record, retrieve the host content settings map of the parent + // profile in order to ensure the preferences have been migrated. + if (off_the_record) + GetForProfile(profile->GetOriginalProfile()); + + scoped_refptr<HostContentSettingsMap> settings_map( + new HostContentSettingsMap(profile->GetPrefs(), off_the_record)); + +#if defined(ENABLE_EXTENSIONS) + ExtensionService *ext_service = + extensions::ExtensionSystem::Get(profile)->extension_service(); + // This may be null in testing or when the extenion_service hasn't been + // initialized, in which case it will be registered then. + if (ext_service) + ext_service->RegisterContentSettings(settings_map.get()); +#endif // defined(ENABLE_EXTENSIONS) +#if defined(ENABLE_SUPERVISED_USERS) + SupervisedUserSettingsService* supervised_service = + SupervisedUserSettingsServiceFactory::GetForProfile(profile); + // This may be null in testing. + if (supervised_service) { + scoped_ptr<content_settings::SupervisedProvider> supervised_provider( + new content_settings::SupervisedProvider(supervised_service)); + settings_map->RegisterProvider(HostContentSettingsMap::SUPERVISED_PROVIDER, + supervised_provider.Pass()); + } +#endif // defined(ENABLE_SUPERVISED_USERS) + + return settings_map; +} + +content::BrowserContext* HostContentSettingsMapFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return context; +} diff --git a/chrome/browser/content_settings/host_content_settings_map_factory.h b/chrome/browser/content_settings/host_content_settings_map_factory.h new file mode 100644 index 0000000..26f6d89 --- /dev/null +++ b/chrome/browser/content_settings/host_content_settings_map_factory.h @@ -0,0 +1,36 @@ +// Copyright 2015 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_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_FACTORY_H_ +#define CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_FACTORY_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/singleton.h" +#include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h" + +class HostContentSettingsMap; +class Profile; + +class HostContentSettingsMapFactory + : public RefcountedBrowserContextKeyedServiceFactory { + public: + static HostContentSettingsMap* GetForProfile(Profile* profile); + static HostContentSettingsMapFactory* GetInstance(); + + private: + friend struct DefaultSingletonTraits<HostContentSettingsMapFactory>; + + HostContentSettingsMapFactory(); + ~HostContentSettingsMapFactory() override; + + // RefcountedBrowserContextKeyedServiceFactory methods: + scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMapFactory); +}; + +#endif // CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_FACTORY_H_ diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index c51506d..f36892e 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc @@ -11,6 +11,7 @@ #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/chrome_browser_main.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" #include "chrome/browser/domain_reliability/service_factory.h" @@ -233,6 +234,7 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() { #if defined(ENABLE_EXTENSIONS) HotwordServiceFactory::GetInstance(); #endif + HostContentSettingsMapFactory::GetInstance(); InMemoryURLIndexFactory::GetInstance(); invalidation::ProfileInvalidationProviderFactory::GetInstance(); InstantServiceFactory::GetInstance(); diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index c2f4863..6ef4704 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc @@ -15,6 +15,7 @@ #include "build/build_config.h" #include "chrome/browser/background/background_contents_service_factory.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/dom_distiller/profile_utils.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_service.h" @@ -183,9 +184,6 @@ OffTheRecordProfileImpl::~OffTheRecordProfileImpl() { base::Bind(&NotifyOTRProfileDestroyedOnIOThread, profile_, this)); #endif - if (host_content_settings_map_.get()) - host_content_settings_map_->ShutdownOnUIThread(); - if (pref_proxy_config_tracker_) pref_proxy_config_tracker_->DetachFromPrefService(); @@ -376,31 +374,10 @@ net::SSLConfigService* OffTheRecordProfileImpl::GetSSLConfigService() { } HostContentSettingsMap* OffTheRecordProfileImpl::GetHostContentSettingsMap() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Retrieve the host content settings map of the parent profile in order to - // ensure the preferences have been migrated. - profile_->GetHostContentSettingsMap(); - if (!host_content_settings_map_.get()) { - host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), true); -#if defined(ENABLE_EXTENSIONS) - ExtensionService* extension_service = - extensions::ExtensionSystem::Get(this)->extension_service(); - if (extension_service) { - extension_service->RegisterContentSettings( - host_content_settings_map_.get()); - } -#endif -#if defined(ENABLE_SUPERVISED_USERS) - SupervisedUserSettingsService* supervised_service = - SupervisedUserSettingsServiceFactory::GetForProfile(this); - scoped_ptr<content_settings::SupervisedProvider> supervised_provider( - new content_settings::SupervisedProvider(supervised_service)); - host_content_settings_map_->RegisterProvider( - HostContentSettingsMap::SUPERVISED_PROVIDER, - supervised_provider.Pass()); -#endif - } - return host_content_settings_map_.get(); + // TODO(peconn): Once HostContentSettingsMapFactory works for TestingProfiles + // remove Profile::GetHostContentSettingsMap and replace all references to it. + // Don't forget to remove the #include "host_content_settings_map_factory"! + return HostContentSettingsMapFactory::GetForProfile(this); } content::BrowserPluginGuestManager* OffTheRecordProfileImpl::GetGuestManager() { diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h index 32c094b..2a42058 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.h +++ b/chrome/browser/profiles/off_the_record_profile_impl.h @@ -134,9 +134,6 @@ class OffTheRecordProfileImpl : public Profile { parent_default_zoom_level_subscription_; scoped_ptr<OffTheRecordProfileIOData::Handle> io_data_; - // We use a non-persistent content settings map for OTR. - scoped_refptr<HostContentSettingsMap> host_content_settings_map_; - // Time we were started. Time start_time_; diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index e338384..9ee9a80 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -33,6 +33,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/dom_distiller/profile_utils.h" #include "chrome/browser/domain_reliability/service_factory.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" @@ -369,7 +370,6 @@ ProfileImpl::ProfileImpl( : path_(path), pref_registry_(new user_prefs::PrefRegistrySyncable), io_data_(this), - host_content_settings_map_(NULL), last_session_exit_type_(EXIT_NORMAL), start_time_(Time::Now()), delegate_(delegate), @@ -688,9 +688,6 @@ ProfileImpl::~ProfileImpl() { if (pref_proxy_config_tracker_) pref_proxy_config_tracker_->DetachFromPrefService(); - if (host_content_settings_map_.get()) - host_content_settings_map_->ShutdownOnUIThread(); - // This causes the Preferences file to be written to disk. if (prefs_loaded) SetExitType(EXIT_NORMAL); @@ -992,20 +989,10 @@ net::SSLConfigService* ProfileImpl::GetSSLConfigService() { } HostContentSettingsMap* ProfileImpl::GetHostContentSettingsMap() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!host_content_settings_map_.get()) { - host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false); -#if defined(ENABLE_SUPERVISED_USERS) - SupervisedUserSettingsService* supervised_user_settings = - SupervisedUserSettingsServiceFactory::GetForProfile(this); - scoped_ptr<content_settings::SupervisedProvider> supervised_provider( - new content_settings::SupervisedProvider(supervised_user_settings)); - host_content_settings_map_->RegisterProvider( - HostContentSettingsMap::SUPERVISED_PROVIDER, - supervised_provider.Pass()); -#endif - } - return host_content_settings_map_.get(); + // TODO(peconn): Once HostContentSettingsMapFactory works for TestingProfiles + // remove Profile::GetHostContentSettingsMap and replace all references to it. + // Don't forget to remove the #include "host_content_settings_map_factory"! + return HostContentSettingsMapFactory::GetForProfile(this); } content::BrowserPluginGuestManager* ProfileImpl::GetGuestManager() { diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 8a39d2a..ec4cedc 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -233,7 +233,6 @@ class ProfileImpl : public Profile { #endif scoped_ptr<NetPrefObserver> net_pref_observer_; scoped_ptr<SSLConfigServiceManager> ssl_config_service_manager_; - scoped_refptr<HostContentSettingsMap> host_content_settings_map_; scoped_refptr<ShortcutsBackend> shortcuts_backend_; // Exit type the last time the profile was opened. This is set only once from diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 1337b66..40f9bd7 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc @@ -24,6 +24,7 @@ #include "chrome/browser/bookmarks/startup_task_runner_service_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/download/download_service.h" #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" @@ -1055,13 +1056,23 @@ void ProfileManager::DoFinalInitForServices(Profile* profile, #if defined(ENABLE_EXTENSIONS) ProfileInfoCache& cache = GetProfileInfoCache(); + + // Ensure that the HostContentSettingsMap has been created before the + // ExtensionSystem is initialized otherwise the ExtensionSystem will be + // registered twice + HostContentSettingsMap* content_settings_map = + HostContentSettingsMapFactory::GetForProfile(profile); + extensions::ExtensionSystem::Get(profile)->InitForRegularProfile( !go_off_the_record); // During tests, when |profile| is an instance of TestingProfile, // ExtensionSystem might not create an ExtensionService. + // This block is duplicated in the HostContentSettingsMapFactory + // ::BuildServiceInstanceFor method, it should be called once when both the + // HostContentSettingsMap and the extension_service are set up. if (extensions::ExtensionSystem::Get(profile)->extension_service()) { extensions::ExtensionSystem::Get(profile)->extension_service()-> - RegisterContentSettings(profile->GetHostContentSettingsMap()); + RegisterContentSettings(content_settings_map); } // Set the block extensions bit on the ExtensionService. There likely are no // blockable extensions to block. diff --git a/chrome/browser/push_messaging/push_messaging_service_factory.cc b/chrome/browser/push_messaging/push_messaging_service_factory.cc index 1ed640c..d8b36caa 100644 --- a/chrome/browser/push_messaging/push_messaging_service_factory.cc +++ b/chrome/browser/push_messaging/push_messaging_service_factory.cc @@ -4,6 +4,7 @@ #include "chrome/browser/push_messaging/push_messaging_service_factory.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/push_messaging/push_messaging_service_impl.h" @@ -33,6 +34,7 @@ PushMessagingServiceFactory::PushMessagingServiceFactory() "PushMessagingProfileService", BrowserContextDependencyManager::GetInstance()) { DependsOn(gcm::GCMProfileServiceFactory::GetInstance()); + DependsOn(HostContentSettingsMapFactory::GetInstance()); } PushMessagingServiceFactory::~PushMessagingServiceFactory() { diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index 1e593af..f5b7bcd 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc @@ -14,6 +14,7 @@ #include "base/metrics/histogram.h" #include "base/prefs/pref_service.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/permissions/permission_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" @@ -129,11 +130,10 @@ PushMessagingServiceImpl::PushMessagingServiceImpl(Profile* profile) #endif weak_factory_(this) { DCHECK(profile); - profile_->GetHostContentSettingsMap()->AddObserver(this); + HostContentSettingsMapFactory::GetForProfile(profile_)->AddObserver(this); } PushMessagingServiceImpl::~PushMessagingServiceImpl() { - profile_->GetHostContentSettingsMap()->RemoveObserver(this); } void PushMessagingServiceImpl::IncreasePushSubscriptionCount(int add, @@ -745,6 +745,7 @@ void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting( void PushMessagingServiceImpl::Shutdown() { GetGCMDriver()->RemoveAppHandler(kPushMessagingAppIdentifierPrefix); + profile_->GetHostContentSettingsMap()->RemoveObserver(this); #if defined(ENABLE_BACKGROUND) // TODO(mvanouwerkerk): Ensure Push API unregisters correctly from Background // Mode - crbug.com/527036. diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c238226..0a1ecdc 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1430,6 +1430,8 @@ 'browser/content_settings/chrome_content_settings_utils.h', 'browser/content_settings/cookie_settings_factory.cc', 'browser/content_settings/cookie_settings_factory.h', + 'browser/content_settings/host_content_settings_map_factory.cc', + 'browser/content_settings/host_content_settings_map_factory.h', 'browser/content_settings/local_shared_objects_container.cc', 'browser/content_settings/local_shared_objects_container.h', 'browser/content_settings/tab_specific_content_settings.cc', diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 527305c..77e2165 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -21,6 +21,7 @@ #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/favicon/chrome_fallback_icon_client_factory.h" #include "chrome/browser/favicon/fallback_icon_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" @@ -856,19 +857,9 @@ content::ResourceContext* TestingProfile::GetResourceContext() { } HostContentSettingsMap* TestingProfile::GetHostContentSettingsMap() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!host_content_settings_map_.get()) { - host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false); -#if defined(ENABLE_EXTENSIONS) - ExtensionService* extension_service = - extensions::ExtensionSystem::Get(this)->extension_service(); - if (extension_service) { - extension_service->RegisterContentSettings( - host_content_settings_map_.get()); - } -#endif - } - return host_content_settings_map_.get(); + // TODO(peconn): Get rid of this function + // Don't forget to remove the #include "host_content_settings_map_factory"! + return HostContentSettingsMapFactory::GetForProfile(this); } content::BrowserPluginGuestManager* TestingProfile::GetGuestManager() { diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h index a4d5144..04a204d 100644 --- a/components/content_settings/core/browser/host_content_settings_map.h +++ b/components/content_settings/core/browser/host_content_settings_map.h @@ -22,6 +22,7 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_types.h" +#include "components/keyed_service/core/refcounted_keyed_service.h" class ExtensionService; class GURL; @@ -42,9 +43,8 @@ namespace user_prefs { class PrefRegistrySyncable; } -class HostContentSettingsMap - : public content_settings::Observer, - public base::RefCountedThreadSafe<HostContentSettingsMap> { +class HostContentSettingsMap : public content_settings::Observer, + public RefcountedKeyedService { public: enum ProviderType { // EXTENSION names is a layering violation when this class will move to @@ -189,11 +189,8 @@ class HostContentSettingsMap // Returns true if the values for content type are of type dictionary/map. static bool ContentTypeHasCompoundValue(ContentSettingsType type); - // Detaches the HostContentSettingsMap from all Profile-related objects like - // PrefService. This methods needs to be called before destroying the Profile. - // Afterwards, none of the methods above that should only be called on the UI - // thread should be called anymore. - void ShutdownOnUIThread(); + // RefcountedKeyedService implementation. + void ShutdownOnUIThread() override; // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, |