Home | History | Annotate | Download | only in content_settings
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Maps hostnames to custom content settings.  Written on the UI thread and read
      6 // on any thread.  One instance per profile.
      7 
      8 #ifndef CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_
      9 #define CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_
     10 
     11 #include <map>
     12 #include <string>
     13 #include <vector>
     14 
     15 #include "base/basictypes.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/prefs/pref_change_registrar.h"
     18 #include "base/threading/platform_thread.h"
     19 #include "base/tuple.h"
     20 #include "chrome/browser/content_settings/content_settings_observer.h"
     21 #include "chrome/common/content_settings.h"
     22 #include "chrome/common/content_settings_pattern.h"
     23 #include "chrome/common/content_settings_types.h"
     24 
     25 class ExtensionService;
     26 class GURL;
     27 class PrefService;
     28 
     29 namespace base {
     30 class Value;
     31 }
     32 
     33 namespace content_settings {
     34 class ProviderInterface;
     35 }
     36 
     37 namespace user_prefs {
     38 class PrefRegistrySyncable;
     39 }
     40 
     41 class HostContentSettingsMap
     42     : public content_settings::Observer,
     43       public base::RefCountedThreadSafe<HostContentSettingsMap> {
     44  public:
     45   enum ProviderType {
     46     INTERNAL_EXTENSION_PROVIDER = 0,
     47     POLICY_PROVIDER,
     48     CUSTOM_EXTENSION_PROVIDER,
     49     PREF_PROVIDER,
     50     DEFAULT_PROVIDER,
     51     NUM_PROVIDER_TYPES,
     52   };
     53 
     54   HostContentSettingsMap(PrefService* prefs, bool incognito);
     55 
     56 #if defined(ENABLE_EXTENSIONS)
     57   // In some cases, the ExtensionService is not available at the time the
     58   // HostContentSettingsMap is constructed. In these cases, we register the
     59   // service once it's available.
     60   void RegisterExtensionService(ExtensionService* extension_service);
     61 #endif
     62 
     63   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
     64 
     65   // Returns the default setting for a particular content type. If |provider_id|
     66   // is not NULL, the id of the provider which provided the default setting is
     67   // assigned to it.
     68   //
     69   // This may be called on any thread.
     70   ContentSetting GetDefaultContentSetting(ContentSettingsType content_type,
     71                                           std::string* provider_id) const;
     72 
     73   // Returns a single |ContentSetting| which applies to the given URLs.  Note
     74   // that certain internal schemes are whitelisted. For |CONTENT_TYPE_COOKIES|,
     75   // |CookieSettings| should be used instead. For content types that can't be
     76   // converted to a |ContentSetting|, |GetContentSettingValue| should be called.
     77   // If there is no content setting, returns CONTENT_SETTING_DEFAULT.
     78   //
     79   // May be called on any thread.
     80   ContentSetting GetContentSetting(
     81       const GURL& primary_url,
     82       const GURL& secondary_url,
     83       ContentSettingsType content_type,
     84       const std::string& resource_identifier) const;
     85 
     86   // Returns a single content setting |Value| which applies to the given URLs.
     87   // If |info| is not NULL, then the |source| field of |info| is set to the
     88   // source of the returned |Value| (POLICY, EXTENSION, USER, ...) and the
     89   // |primary_pattern| and the |secondary_pattern| fields of |info| are set to
     90   // the patterns of the applying rule.  Note that certain internal schemes are
     91   // whitelisted. For whitelisted schemes the |source| field of |info| is set
     92   // the |SETTING_SOURCE_WHITELIST| and the |primary_pattern| and
     93   // |secondary_pattern| are set to a wildcard pattern.  If there is no content
     94   // setting, NULL is returned and the |source| field of |info| is set to
     95   // |SETTING_SOURCE_NONE|. The pattern fiels of |info| are set to empty
     96   // patterns.
     97   // The ownership of the resulting |Value| is transfered to the caller.
     98   // May be called on any thread.
     99   base::Value* GetWebsiteSetting(
    100       const GURL& primary_url,
    101       const GURL& secondary_url,
    102       ContentSettingsType content_type,
    103       const std::string& resource_identifier,
    104       content_settings::SettingInfo* info) const;
    105 
    106   // For a given content type, returns all patterns with a non-default setting,
    107   // mapped to their actual settings, in the precedence order of the rules.
    108   // |settings| must be a non-NULL outparam.
    109   //
    110   // This may be called on any thread.
    111   void GetSettingsForOneType(ContentSettingsType content_type,
    112                              const std::string& resource_identifier,
    113                              ContentSettingsForOneType* settings) const;
    114 
    115   // Sets the default setting for a particular content type. This method must
    116   // not be invoked on an incognito map.
    117   //
    118   // This should only be called on the UI thread.
    119   void SetDefaultContentSetting(ContentSettingsType content_type,
    120                                 ContentSetting setting);
    121 
    122   // Sets the content |setting| for the given patterns, |content_type| and
    123   // |resource_identifier|. Setting the value to CONTENT_SETTING_DEFAULT causes
    124   // the default setting for that type to be used when loading pages matching
    125   // this pattern.
    126   // NOTICE: This is just a convenience method for content types that use
    127   // |CONTENT_SETTING| as their data type. For content types that use other
    128   // data types please use the method SetWebsiteSetting.
    129   //
    130   // This should only be called on the UI thread.
    131   void SetContentSetting(const ContentSettingsPattern& primary_pattern,
    132                          const ContentSettingsPattern& secondary_pattern,
    133                          ContentSettingsType content_type,
    134                          const std::string& resource_identifier,
    135                          ContentSetting setting);
    136 
    137   // Sets the |value| for the given patterns, |content_type| and
    138   // |resource_identifier|. Setting the value to NULL causes the default value
    139   // for that type to be used when loading pages matching this pattern.
    140   //
    141   // Takes ownership of the passed value.
    142   void SetWebsiteSetting(const ContentSettingsPattern& primary_pattern,
    143                          const ContentSettingsPattern& secondary_pattern,
    144                          ContentSettingsType content_type,
    145                          const std::string& resource_identifier,
    146                          base::Value* value);
    147 
    148   // Convenience method to add a content setting for the given URLs, making sure
    149   // that there is no setting overriding it.
    150   //
    151   // This should only be called on the UI thread.
    152   void AddExceptionForURL(const GURL& primary_url,
    153                           const GURL& secondary_url,
    154                           ContentSettingsType content_type,
    155                           ContentSetting setting);
    156 
    157   // Clears all host-specific settings for one content type.
    158   //
    159   // This should only be called on the UI thread.
    160   void ClearSettingsForOneType(ContentSettingsType content_type);
    161 
    162   static bool IsValueAllowedForType(PrefService* prefs,
    163                                     const base::Value* value,
    164                                     ContentSettingsType content_type);
    165   static bool IsSettingAllowedForType(PrefService* prefs,
    166                                       ContentSetting setting,
    167                                       ContentSettingsType content_type);
    168 
    169   // Returns true if the values for content type are of type dictionary/map.
    170   static bool ContentTypeHasCompoundValue(ContentSettingsType type);
    171 
    172   // Detaches the HostContentSettingsMap from all Profile-related objects like
    173   // PrefService. This methods needs to be called before destroying the Profile.
    174   // Afterwards, none of the methods above that should only be called on the UI
    175   // thread should be called anymore.
    176   void ShutdownOnUIThread();
    177 
    178   // content_settings::Observer implementation.
    179   virtual void OnContentSettingChanged(
    180       const ContentSettingsPattern& primary_pattern,
    181       const ContentSettingsPattern& secondary_pattern,
    182       ContentSettingsType content_type,
    183       std::string resource_identifier) OVERRIDE;
    184 
    185   // Returns true if we should allow all content types for this URL.  This is
    186   // true for various internal objects like chrome:// URLs, so UI and other
    187   // things users think of as "not webpages" don't break.
    188   static bool ShouldAllowAllContent(const GURL& primary_url,
    189                                     const GURL& secondary_url,
    190                                     ContentSettingsType content_type);
    191 
    192   // Returns the ProviderType associated with the given source string.
    193   // TODO(estade): I regret adding this. At the moment there are no legitimate
    194   // uses. We should stick to ProviderType rather than string so we don't have
    195   // to convert backwards.
    196   static ProviderType GetProviderTypeFromSource(const std::string& source);
    197 
    198   bool is_off_the_record() const {
    199     return is_off_the_record_;
    200   }
    201 
    202  private:
    203   friend class base::RefCountedThreadSafe<HostContentSettingsMap>;
    204   friend class HostContentSettingsMapTest_NonDefaultSettings_Test;
    205 
    206   typedef std::map<ProviderType, content_settings::ProviderInterface*>
    207       ProviderMap;
    208   typedef ProviderMap::iterator ProviderIterator;
    209   typedef ProviderMap::const_iterator ConstProviderIterator;
    210 
    211   virtual ~HostContentSettingsMap();
    212 
    213   ContentSetting GetDefaultContentSettingFromProvider(
    214       ContentSettingsType content_type,
    215       content_settings::ProviderInterface* provider) const;
    216 
    217   // Migrate the Clear on exit pref into equivalent content settings.
    218   void MigrateObsoleteClearOnExitPref();
    219 
    220   // Adds content settings for |content_type| and |resource_identifier|,
    221   // provided by |provider|, into |settings|. If |incognito| is true, adds only
    222   // the content settings which are applicable to the incognito mode and differ
    223   // from the normal mode. Otherwise, adds the content settings for the normal
    224   // mode.
    225   void AddSettingsForOneType(
    226       const content_settings::ProviderInterface* provider,
    227       ProviderType provider_type,
    228       ContentSettingsType content_type,
    229       const std::string& resource_identifier,
    230       ContentSettingsForOneType* settings,
    231       bool incognito) const;
    232 
    233   // Call UsedContentSettingsProviders() whenever you access
    234   // content_settings_providers_ (apart from initialization and
    235   // teardown), so that we can DCHECK in RegisterExtensionService that
    236   // it is not being called too late.
    237   void UsedContentSettingsProviders() const;
    238 
    239 #ifndef NDEBUG
    240   // This starts as the thread ID of the thread that constructs this
    241   // object, and remains until used by a different thread, at which
    242   // point it is set to base::kInvalidThreadId. This allows us to
    243   // DCHECK on unsafe usage of content_settings_providers_ (they
    244   // should be set up on a single thread, after which they are
    245   // immutable).
    246   mutable base::PlatformThreadId used_from_thread_id_;
    247 #endif
    248 
    249   // Weak; owned by the Profile.
    250   PrefService* prefs_;
    251 
    252   // Whether this settings map is for an OTR session.
    253   bool is_off_the_record_;
    254 
    255   // Content setting providers. This is only modified at construction
    256   // time and by RegisterExtensionService, both of which should happen
    257   // before any other uses of it.
    258   ProviderMap content_settings_providers_;
    259 
    260   DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap);
    261 };
    262 
    263 #endif  // CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_
    264