// 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. // Maps hostnames to custom content settings. Written on the UI thread and read // on any thread. One instance per profile. #ifndef CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_ #define CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_ #include <map> #include <string> #include <vector> #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/prefs/pref_change_registrar.h" #include "base/threading/platform_thread.h" #include "base/tuple.h" #include "chrome/browser/content_settings/content_settings_observer.h" #include "chrome/common/content_settings.h" #include "chrome/common/content_settings_pattern.h" #include "chrome/common/content_settings_types.h" class ExtensionService; class GURL; class PrefService; namespace base { class Value; } namespace content_settings { class ProviderInterface; } namespace user_prefs { class PrefRegistrySyncable; } class HostContentSettingsMap : public content_settings::Observer, public base::RefCountedThreadSafe<HostContentSettingsMap> { public: enum ProviderType { INTERNAL_EXTENSION_PROVIDER = 0, POLICY_PROVIDER, CUSTOM_EXTENSION_PROVIDER, PREF_PROVIDER, DEFAULT_PROVIDER, NUM_PROVIDER_TYPES, }; HostContentSettingsMap(PrefService* prefs, bool incognito); #if defined(ENABLE_EXTENSIONS) // In some cases, the ExtensionService is not available at the time the // HostContentSettingsMap is constructed. In these cases, we register the // service once it's available. void RegisterExtensionService(ExtensionService* extension_service); #endif static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); // Returns the default setting for a particular content type. If |provider_id| // is not NULL, the id of the provider which provided the default setting is // assigned to it. // // This may be called on any thread. ContentSetting GetDefaultContentSetting(ContentSettingsType content_type, std::string* provider_id) const; // Returns a single |ContentSetting| which applies to the given URLs. Note // that certain internal schemes are whitelisted. For |CONTENT_TYPE_COOKIES|, // |CookieSettings| should be used instead. For content types that can't be // converted to a |ContentSetting|, |GetContentSettingValue| should be called. // If there is no content setting, returns CONTENT_SETTING_DEFAULT. // // May be called on any thread. ContentSetting GetContentSetting( const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type, const std::string& resource_identifier) const; // Returns a single content setting |Value| which applies to the given URLs. // If |info| is not NULL, then the |source| field of |info| is set to the // source of the returned |Value| (POLICY, EXTENSION, USER, ...) and the // |primary_pattern| and the |secondary_pattern| fields of |info| are set to // the patterns of the applying rule. Note that certain internal schemes are // whitelisted. For whitelisted schemes the |source| field of |info| is set // the |SETTING_SOURCE_WHITELIST| and the |primary_pattern| and // |secondary_pattern| are set to a wildcard pattern. If there is no content // setting, NULL is returned and the |source| field of |info| is set to // |SETTING_SOURCE_NONE|. The pattern fiels of |info| are set to empty // patterns. // The ownership of the resulting |Value| is transfered to the caller. // May be called on any thread. base::Value* GetWebsiteSetting( const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type, const std::string& resource_identifier, content_settings::SettingInfo* info) const; // For a given content type, returns all patterns with a non-default setting, // mapped to their actual settings, in the precedence order of the rules. // |settings| must be a non-NULL outparam. // // This may be called on any thread. void GetSettingsForOneType(ContentSettingsType content_type, const std::string& resource_identifier, ContentSettingsForOneType* settings) const; // Sets the default setting for a particular content type. This method must // not be invoked on an incognito map. // // This should only be called on the UI thread. void SetDefaultContentSetting(ContentSettingsType content_type, ContentSetting setting); // Sets the content |setting| for the given patterns, |content_type| and // |resource_identifier|. Setting the value to CONTENT_SETTING_DEFAULT causes // the default setting for that type to be used when loading pages matching // this pattern. // NOTICE: This is just a convenience method for content types that use // |CONTENT_SETTING| as their data type. For content types that use other // data types please use the method SetWebsiteSetting. // // This should only be called on the UI thread. void SetContentSetting(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, const std::string& resource_identifier, ContentSetting setting); // Sets the |value| for the given patterns, |content_type| and // |resource_identifier|. Setting the value to NULL causes the default value // for that type to be used when loading pages matching this pattern. // // Takes ownership of the passed value. void SetWebsiteSetting(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, const std::string& resource_identifier, base::Value* value); // Convenience method to add a content setting for the given URLs, making sure // that there is no setting overriding it. // // This should only be called on the UI thread. void AddExceptionForURL(const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type, ContentSetting setting); // Clears all host-specific settings for one content type. // // This should only be called on the UI thread. void ClearSettingsForOneType(ContentSettingsType content_type); static bool IsValueAllowedForType(PrefService* prefs, const base::Value* value, ContentSettingsType content_type); static bool IsSettingAllowedForType(PrefService* prefs, ContentSetting setting, ContentSettingsType content_type); // 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(); // content_settings::Observer implementation. virtual void OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, std::string resource_identifier) OVERRIDE; // Returns true if we should allow all content types for this URL. This is // true for various internal objects like chrome:// URLs, so UI and other // things users think of as "not webpages" don't break. static bool ShouldAllowAllContent(const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type); // Returns the ProviderType associated with the given source string. // TODO(estade): I regret adding this. At the moment there are no legitimate // uses. We should stick to ProviderType rather than string so we don't have // to convert backwards. static ProviderType GetProviderTypeFromSource(const std::string& source); bool is_off_the_record() const { return is_off_the_record_; } private: friend class base::RefCountedThreadSafe<HostContentSettingsMap>; friend class HostContentSettingsMapTest_NonDefaultSettings_Test; typedef std::map<ProviderType, content_settings::ProviderInterface*> ProviderMap; typedef ProviderMap::iterator ProviderIterator; typedef ProviderMap::const_iterator ConstProviderIterator; virtual ~HostContentSettingsMap(); ContentSetting GetDefaultContentSettingFromProvider( ContentSettingsType content_type, content_settings::ProviderInterface* provider) const; // Migrate the Clear on exit pref into equivalent content settings. void MigrateObsoleteClearOnExitPref(); // Adds content settings for |content_type| and |resource_identifier|, // provided by |provider|, into |settings|. If |incognito| is true, adds only // the content settings which are applicable to the incognito mode and differ // from the normal mode. Otherwise, adds the content settings for the normal // mode. void AddSettingsForOneType( const content_settings::ProviderInterface* provider, ProviderType provider_type, ContentSettingsType content_type, const std::string& resource_identifier, ContentSettingsForOneType* settings, bool incognito) const; // Call UsedContentSettingsProviders() whenever you access // content_settings_providers_ (apart from initialization and // teardown), so that we can DCHECK in RegisterExtensionService that // it is not being called too late. void UsedContentSettingsProviders() const; #ifndef NDEBUG // This starts as the thread ID of the thread that constructs this // object, and remains until used by a different thread, at which // point it is set to base::kInvalidThreadId. This allows us to // DCHECK on unsafe usage of content_settings_providers_ (they // should be set up on a single thread, after which they are // immutable). mutable base::PlatformThreadId used_from_thread_id_; #endif // Weak; owned by the Profile. PrefService* prefs_; // Whether this settings map is for an OTR session. bool is_off_the_record_; // Content setting providers. This is only modified at construction // time and by RegisterExtensionService, both of which should happen // before any other uses of it. ProviderMap content_settings_providers_; DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap); }; #endif // CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_