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
27class ExtensionService;
28class GURL;
29class PrefService;
30
31namespace base {
32class Clock;
33class Value;
34}
35
36namespace content_settings {
37class OverrideProvider;
38class ObservableProvider;
39class ProviderInterface;
40class PrefProvider;
41}
42
43namespace user_prefs {
44class PrefRegistrySyncable;
45}
46
47class 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