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/observer_list.h"
     18 #include "base/prefs/pref_change_registrar.h"
     19 #include "base/threading/platform_thread.h"
     20 #include "base/tuple.h"
     21 #include "chrome/browser/content_settings/content_settings_override_provider.h"
     22 #include "components/content_settings/core/browser/content_settings_observer.h"
     23 #include "components/content_settings/core/common/content_settings.h"
     24 #include "components/content_settings/core/common/content_settings_pattern.h"
     25 #include "components/content_settings/core/common/content_settings_types.h"
     26 
     27 class ExtensionService;
     28 class GURL;
     29 class PrefService;
     30 
     31 namespace base {
     32 class Clock;
     33 class Value;
     34 }
     35 
     36 namespace content_settings {
     37 class OverrideProvider;
     38 class ObservableProvider;
     39 class ProviderInterface;
     40 class PrefProvider;
     41 }
     42 
     43 namespace user_prefs {
     44 class PrefRegistrySyncable;
     45 }
     46 
     47 class HostContentSettingsMap
     48     : public content_settings::Observer,
     49       public base::RefCountedThreadSafe<HostContentSettingsMap> {
     50  public:
     51   enum ProviderType {
     52     // EXTENSION names is a layering violation when this class will move to
     53     // components.
     54     // TODO(mukai): find the solution.
     55     INTERNAL_EXTENSION_PROVIDER = 0,
     56     POLICY_PROVIDER,
     57     CUSTOM_EXTENSION_PROVIDER,
     58     OVERRIDE_PROVIDER,
     59     PREF_PROVIDER,
     60     DEFAULT_PROVIDER,
     61     NUM_PROVIDER_TYPES,
     62   };
     63 
     64   HostContentSettingsMap(PrefService* prefs, bool incognito);
     65 
     66   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
     67 
     68   // Adds a new provider for |type|.
     69   void RegisterProvider(
     70       ProviderType type,
     71       scoped_ptr<content_settings::ObservableProvider> provider);
     72 
     73   // Returns the default setting for a particular content type. If |provider_id|
     74   // is not NULL, the id of the provider which provided the default setting is
     75   // assigned to it.
     76   //
     77   // This may be called on any thread.
     78   ContentSetting GetDefaultContentSetting(ContentSettingsType content_type,
     79                                           std::string* provider_id) const;
     80 
     81   // Returns a single |ContentSetting| which applies to the given URLs.  Note
     82   // that certain internal schemes are whitelisted. For |CONTENT_TYPE_COOKIES|,
     83   // |CookieSettings| should be used instead. For content types that can't be
     84   // converted to a |ContentSetting|, |GetContentSettingValue| should be called.
     85   // If there is no content setting, returns CONTENT_SETTING_DEFAULT.
     86   //
     87   // May be called on any thread.
     88   ContentSetting GetContentSetting(
     89       const GURL& primary_url,
     90       const GURL& secondary_url,
     91       ContentSettingsType content_type,
     92       const std::string& resource_identifier) const;
     93 
     94   // Returns a single content setting |Value| which applies to the given URLs.
     95   // If |info| is not NULL, then the |source| field of |info| is set to the
     96   // source of the returned |Value| (POLICY, EXTENSION, USER, ...) and the
     97   // |primary_pattern| and the |secondary_pattern| fields of |info| are set to
     98   // the patterns of the applying rule.  Note that certain internal schemes are
     99   // whitelisted. For whitelisted schemes the |source| field of |info| is set
    100   // the |SETTING_SOURCE_WHITELIST| and the |primary_pattern| and
    101   // |secondary_pattern| are set to a wildcard pattern.  If there is no content
    102   // setting, NULL is returned and the |source| field of |info| is set to
    103   // |SETTING_SOURCE_NONE|. The pattern fiels of |info| are set to empty
    104   // patterns.
    105   // May be called on any thread.
    106   scoped_ptr<base::Value> GetWebsiteSetting(
    107       const GURL& primary_url,
    108       const GURL& secondary_url,
    109       ContentSettingsType content_type,
    110       const std::string& resource_identifier,
    111       content_settings::SettingInfo* info) const;
    112 
    113   // For a given content type, returns all patterns with a non-default setting,
    114   // mapped to their actual settings, in the precedence order of the rules.
    115   // |settings| must be a non-NULL outparam.
    116   //
    117   // This may be called on any thread.
    118   void GetSettingsForOneType(ContentSettingsType content_type,
    119                              const std::string& resource_identifier,
    120                              ContentSettingsForOneType* settings) const;
    121 
    122   // Sets the default setting for a particular content type. This method must
    123   // not be invoked on an incognito map.
    124   //
    125   // This should only be called on the UI thread.
    126   void SetDefaultContentSetting(ContentSettingsType content_type,
    127                                 ContentSetting setting);
    128 
    129   // Sets the content |setting| for the given patterns, |content_type| and
    130   // |resource_identifier|. Setting the value to CONTENT_SETTING_DEFAULT causes
    131   // the default setting for that type to be used when loading pages matching
    132   // this pattern.
    133   // NOTICE: This is just a convenience method for content types that use
    134   // |CONTENT_SETTING| as their data type. For content types that use other
    135   // data types please use the method SetWebsiteSetting.
    136   //
    137   // This should only be called on the UI thread.
    138   void SetContentSetting(const ContentSettingsPattern& primary_pattern,
    139                          const ContentSettingsPattern& secondary_pattern,
    140                          ContentSettingsType content_type,
    141                          const std::string& resource_identifier,
    142                          ContentSetting setting);
    143 
    144   // Sets the |value| for the given patterns, |content_type| and
    145   // |resource_identifier|. Setting the value to NULL causes the default value
    146   // for that type to be used when loading pages matching this pattern.
    147   //
    148   // Takes ownership of the passed value.
    149   void SetWebsiteSetting(const ContentSettingsPattern& primary_pattern,
    150                          const ContentSettingsPattern& secondary_pattern,
    151                          ContentSettingsType content_type,
    152                          const std::string& resource_identifier,
    153                          base::Value* value);
    154 
    155   // Sets the most specific rule that currently defines the permission for the
    156   // given permission type.
    157   void SetNarrowestWebsiteSetting(
    158       const ContentSettingsPattern& primary_pattern,
    159       const ContentSettingsPattern& secondary_pattern,
    160       ContentSettingsType content_type,
    161       const std::string& resource_identifier,
    162       ContentSetting setting,
    163       content_settings::SettingInfo existing_info);
    164 
    165   // Convenience method to add a content setting for the given URLs, making sure
    166   // that there is no setting overriding it.
    167   //
    168   // This should only be called on the UI thread.
    169   void AddExceptionForURL(const GURL& primary_url,
    170                           const GURL& secondary_url,
    171                           ContentSettingsType content_type,
    172                           ContentSetting setting);
    173 
    174   // Clears all host-specific settings for one content type.
    175   //
    176   // This should only be called on the UI thread.
    177   void ClearSettingsForOneType(ContentSettingsType content_type);
    178 
    179   static bool IsValueAllowedForType(PrefService* prefs,
    180                                     const base::Value* value,
    181                                     ContentSettingsType content_type);
    182   static bool IsSettingAllowedForType(PrefService* prefs,
    183                                       ContentSetting setting,
    184                                       ContentSettingsType content_type);
    185 
    186   // Returns true if the values for content type are of type dictionary/map.
    187   static bool ContentTypeHasCompoundValue(ContentSettingsType type);
    188 
    189   // Detaches the HostContentSettingsMap from all Profile-related objects like
    190   // PrefService. This methods needs to be called before destroying the Profile.
    191   // Afterwards, none of the methods above that should only be called on the UI
    192   // thread should be called anymore.
    193   void ShutdownOnUIThread();
    194 
    195   // content_settings::Observer implementation.
    196   virtual void OnContentSettingChanged(
    197       const ContentSettingsPattern& primary_pattern,
    198       const ContentSettingsPattern& secondary_pattern,
    199       ContentSettingsType content_type,
    200       std::string resource_identifier) OVERRIDE;
    201 
    202   // Returns true if we should allow all content types for this URL.  This is
    203   // true for various internal objects like chrome:// URLs, so UI and other
    204   // things users think of as "not webpages" don't break.
    205   static bool ShouldAllowAllContent(const GURL& primary_url,
    206                                     const GURL& secondary_url,
    207                                     ContentSettingsType content_type);
    208 
    209   // Returns the ProviderType associated with the given source string.
    210   // TODO(estade): I regret adding this. At the moment there are no legitimate
    211   // uses. We should stick to ProviderType rather than string so we don't have
    212   // to convert backwards.
    213   static ProviderType GetProviderTypeFromSource(const std::string& source);
    214 
    215   bool is_off_the_record() const {
    216     return is_off_the_record_;
    217   }
    218 
    219   // Returns a single |ContentSetting| which applies to the given URLs, just as
    220   // |GetContentSetting| does. If the setting is allowed, it also records the
    221   // last usage to preferences.
    222   //
    223   // This should only be called on the UI thread, unlike |GetContentSetting|.
    224   ContentSetting GetContentSettingAndMaybeUpdateLastUsage(
    225       const GURL& primary_url,
    226       const GURL& secondary_url,
    227       ContentSettingsType content_type,
    228       const std::string& resource_identifier);
    229 
    230   // Sets the last time that a given content type has been used for the pattern
    231   // which matches the URLs to the current time.
    232   void UpdateLastUsage(const GURL& primary_url,
    233                        const GURL& secondary_url,
    234                        ContentSettingsType content_type);
    235 
    236   // Sets the last time that a given content type has been used for a pattern
    237   // pair to the current time.
    238   void UpdateLastUsageByPattern(const ContentSettingsPattern& primary_pattern,
    239                                 const ContentSettingsPattern& secondary_pattern,
    240                                 ContentSettingsType content_type);
    241 
    242   // Returns the last time the pattern that matches the URL has requested
    243   // permission for the |content_type| setting.
    244   base::Time GetLastUsage(const GURL& primary_url,
    245                           const GURL& secondary_url,
    246                           ContentSettingsType content_type);
    247 
    248   // Returns the last time the pattern has requested permission for the
    249   // |content_type| setting.
    250   base::Time GetLastUsageByPattern(
    251       const ContentSettingsPattern& primary_pattern,
    252       const ContentSettingsPattern& secondary_pattern,
    253       ContentSettingsType content_type);
    254 
    255   // Returns the content setting without considering the global on/off toggle
    256   // for the content setting that matches the URLs.
    257   ContentSetting GetContentSettingWithoutOverride(
    258       const GURL& primary_url,
    259       const GURL& secondary_url,
    260       ContentSettingsType content_type,
    261       const std::string& resource_identifier);
    262 
    263   // Returns the single content setting |value| without considering the
    264   // global on/off toggle for the content setting that matches the given
    265   // patterns.
    266   scoped_ptr<base::Value> GetWebsiteSettingWithoutOverride(
    267       const GURL& primary_url,
    268       const GURL& secondary_url,
    269       ContentSettingsType content_type,
    270       const std::string& resource_identifier,
    271       content_settings::SettingInfo* info) const;
    272 
    273   // Sets globally if a given |content_type| |is_enabled|.
    274   void SetContentSettingOverride(ContentSettingsType content_type,
    275                                  bool is_enabled);
    276 
    277   // Returns if a given |content_type| is enabled.
    278   bool GetContentSettingOverride(ContentSettingsType content_type);
    279 
    280   // Adds/removes an observer for content settings changes.
    281   void AddObserver(content_settings::Observer* observer);
    282   void RemoveObserver(content_settings::Observer* observer);
    283 
    284   // Passes ownership of |clock|.
    285   void SetPrefClockForTesting(scoped_ptr<base::Clock> clock);
    286 
    287  private:
    288   friend class base::RefCountedThreadSafe<HostContentSettingsMap>;
    289   friend class HostContentSettingsMapTest_NonDefaultSettings_Test;
    290 
    291   typedef std::map<ProviderType, content_settings::ProviderInterface*>
    292       ProviderMap;
    293   typedef ProviderMap::iterator ProviderIterator;
    294   typedef ProviderMap::const_iterator ConstProviderIterator;
    295 
    296   virtual ~HostContentSettingsMap();
    297 
    298   ContentSetting GetDefaultContentSettingFromProvider(
    299       ContentSettingsType content_type,
    300       content_settings::ProviderInterface* provider) const;
    301 
    302   // Migrate the Clear on exit pref into equivalent content settings.
    303   void MigrateObsoleteClearOnExitPref();
    304 
    305   // Adds content settings for |content_type| and |resource_identifier|,
    306   // provided by |provider|, into |settings|. If |incognito| is true, adds only
    307   // the content settings which are applicable to the incognito mode and differ
    308   // from the normal mode. Otherwise, adds the content settings for the normal
    309   // mode.
    310   void AddSettingsForOneType(
    311       const content_settings::ProviderInterface* provider,
    312       ProviderType provider_type,
    313       ContentSettingsType content_type,
    314       const std::string& resource_identifier,
    315       ContentSettingsForOneType* settings,
    316       bool incognito) const;
    317 
    318   // Call UsedContentSettingsProviders() whenever you access
    319   // content_settings_providers_ (apart from initialization and
    320   // teardown), so that we can DCHECK in RegisterExtensionService that
    321   // it is not being called too late.
    322   void UsedContentSettingsProviders() const;
    323 
    324   // Returns the single content setting |value| with a toggle for if it
    325   // takes the global on/off switch into account.
    326   scoped_ptr<base::Value> GetWebsiteSettingInternal(
    327       const GURL& primary_url,
    328       const GURL& secondary_url,
    329       ContentSettingsType content_type,
    330       const std::string& resource_identifier,
    331       content_settings::SettingInfo* info,
    332       bool get_override) const;
    333 
    334   content_settings::PrefProvider* GetPrefProvider();
    335 
    336 #ifndef NDEBUG
    337   // This starts as the thread ID of the thread that constructs this
    338   // object, and remains until used by a different thread, at which
    339   // point it is set to base::kInvalidThreadId. This allows us to
    340   // DCHECK on unsafe usage of content_settings_providers_ (they
    341   // should be set up on a single thread, after which they are
    342   // immutable).
    343   mutable base::PlatformThreadId used_from_thread_id_;
    344 #endif
    345 
    346   // Weak; owned by the Profile.
    347   PrefService* prefs_;
    348 
    349   // Whether this settings map is for an OTR session.
    350   bool is_off_the_record_;
    351 
    352   // Content setting providers. This is only modified at construction
    353   // time and by RegisterExtensionService, both of which should happen
    354   // before any other uses of it.
    355   ProviderMap content_settings_providers_;
    356 
    357   ObserverList<content_settings::Observer> observers_;
    358 
    359   DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap);
    360 };
    361 
    362 #endif  // CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_
    363