content_settings_utils.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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#include "chrome/browser/content_settings/content_settings_utils.h"
6
7#include <vector>
8
9#include "base/command_line.h"
10#include "base/logging.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/scoped_vector.h"
13#include "base/strings/string_split.h"
14#include "base/values.h"
15#include "chrome/browser/content_settings/content_settings_provider.h"
16#include "chrome/browser/content_settings/content_settings_rule.h"
17#include "chrome/browser/content_settings/host_content_settings_map.h"
18#include "chrome/common/chrome_switches.h"
19#include "chrome/common/content_settings_pattern.h"
20#include "url/gurl.h"
21
22namespace {
23
24// The names of the ContentSettingsType values, for use with dictionary prefs.
25const char* kTypeNames[] = {
26  "cookies",
27  "images",
28  "javascript",
29  "plugins",
30  "popups",
31  "geolocation",
32  "notifications",
33  "auto-select-certificate",
34  "fullscreen",
35  "mouselock",
36  "mixed-script",
37  "media-stream",
38  "media-stream-mic",
39  "media-stream-camera",
40  "register-protocol-handler",
41  "ppapi-broker",
42  "multiple-automatic-downloads",
43  "midi-sysex",
44  "save-password",
45#if defined(OS_WIN)
46  "metro-switch-to-desktop",
47#elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
48  "protected-media-identifier",
49#endif
50};
51COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES,
52               type_names_incorrect_size);
53
54const char kPatternSeparator[] = ",";
55
56}  // namespace
57
58namespace content_settings {
59
60std::string GetTypeName(ContentSettingsType type) {
61  return std::string(kTypeNames[type]);
62}
63
64std::string CreatePatternString(
65    const ContentSettingsPattern& item_pattern,
66    const ContentSettingsPattern& top_level_frame_pattern) {
67  return item_pattern.ToString()
68         + std::string(kPatternSeparator)
69         + top_level_frame_pattern.ToString();
70}
71
72PatternPair ParsePatternString(const std::string& pattern_str) {
73  std::vector<std::string> pattern_str_list;
74  base::SplitString(pattern_str, kPatternSeparator[0], &pattern_str_list);
75
76  // If the |pattern_str| is an empty string then the |pattern_string_list|
77  // contains a single empty string. In this case the empty string will be
78  // removed to signal an invalid |pattern_str|. Invalid pattern strings are
79  // handle by the "if"-statment below. So the order of the if statements here
80  // must be preserved.
81  if (pattern_str_list.size() == 1) {
82    if (pattern_str_list[0].empty()) {
83      pattern_str_list.pop_back();
84    } else {
85      pattern_str_list.push_back("*");
86    }
87  }
88
89  if (pattern_str_list.size() > 2 ||
90      pattern_str_list.size() == 0) {
91    return PatternPair(ContentSettingsPattern(),
92                       ContentSettingsPattern());
93  }
94
95  PatternPair pattern_pair;
96  pattern_pair.first =
97      ContentSettingsPattern::FromString(pattern_str_list[0]);
98  pattern_pair.second =
99      ContentSettingsPattern::FromString(pattern_str_list[1]);
100  return pattern_pair;
101}
102
103ContentSetting ValueToContentSetting(const base::Value* value) {
104  ContentSetting setting = CONTENT_SETTING_DEFAULT;
105  bool valid = ParseContentSettingValue(value, &setting);
106  DCHECK(valid);
107  return setting;
108}
109
110bool ParseContentSettingValue(const base::Value* value,
111                              ContentSetting* setting) {
112  if (!value) {
113    *setting = CONTENT_SETTING_DEFAULT;
114    return true;
115  }
116  int int_value = -1;
117  if (!value->GetAsInteger(&int_value))
118    return false;
119  *setting = IntToContentSetting(int_value);
120  return *setting != CONTENT_SETTING_DEFAULT;
121}
122
123base::Value* GetContentSettingValueAndPatterns(
124    const ProviderInterface* provider,
125    const GURL& primary_url,
126    const GURL& secondary_url,
127    ContentSettingsType content_type,
128    const std::string& resource_identifier,
129    bool include_incognito,
130    ContentSettingsPattern* primary_pattern,
131    ContentSettingsPattern* secondary_pattern) {
132  if (include_incognito) {
133    // Check incognito-only specific settings. It's essential that the
134    // |RuleIterator| gets out of scope before we get a rule iterator for the
135    // normal mode.
136    scoped_ptr<RuleIterator> incognito_rule_iterator(
137        provider->GetRuleIterator(content_type, resource_identifier, true));
138    base::Value* value = GetContentSettingValueAndPatterns(
139        incognito_rule_iterator.get(), primary_url, secondary_url,
140        primary_pattern, secondary_pattern);
141    if (value)
142      return value;
143  }
144  // No settings from the incognito; use the normal mode.
145  scoped_ptr<RuleIterator> rule_iterator(
146      provider->GetRuleIterator(content_type, resource_identifier, false));
147  return GetContentSettingValueAndPatterns(
148      rule_iterator.get(), primary_url, secondary_url,
149      primary_pattern, secondary_pattern);
150}
151
152base::Value* GetContentSettingValueAndPatterns(
153    RuleIterator* rule_iterator,
154    const GURL& primary_url,
155    const GURL& secondary_url,
156    ContentSettingsPattern* primary_pattern,
157    ContentSettingsPattern* secondary_pattern) {
158  while (rule_iterator->HasNext()) {
159    const Rule& rule = rule_iterator->Next();
160    if (rule.primary_pattern.Matches(primary_url) &&
161        rule.secondary_pattern.Matches(secondary_url)) {
162      if (primary_pattern)
163        *primary_pattern = rule.primary_pattern;
164      if (secondary_pattern)
165        *secondary_pattern = rule.secondary_pattern;
166      return rule.value.get()->DeepCopy();
167    }
168  }
169  return NULL;
170}
171
172base::Value* GetContentSettingValue(const ProviderInterface* provider,
173                                    const GURL& primary_url,
174                                    const GURL& secondary_url,
175                                    ContentSettingsType content_type,
176                                    const std::string& resource_identifier,
177                                    bool include_incognito) {
178  return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url,
179                               content_type, resource_identifier,
180                               include_incognito, NULL, NULL);
181}
182
183ContentSetting GetContentSetting(const ProviderInterface* provider,
184                                 const GURL& primary_url,
185                                 const GURL& secondary_url,
186                                 ContentSettingsType content_type,
187                                 const std::string& resource_identifier,
188                                 bool include_incognito) {
189  scoped_ptr<base::Value> value(
190      GetContentSettingValue(provider, primary_url, secondary_url,
191                             content_type, resource_identifier,
192                             include_incognito));
193  return ValueToContentSetting(value.get());
194}
195
196void GetRendererContentSettingRules(const HostContentSettingsMap* map,
197                                    RendererContentSettingRules* rules) {
198  map->GetSettingsForOneType(
199      CONTENT_SETTINGS_TYPE_IMAGES, std::string(), &(rules->image_rules));
200  map->GetSettingsForOneType(
201      CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string(), &(rules->script_rules));
202}
203
204}  // namespace content_settings
205