content_settings_utils.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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 "googleurl/src/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#if defined(OS_WIN)
43  "metro-switch-to-desktop",
44#endif
45};
46COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES,
47               type_names_incorrect_size);
48
49const char kPatternSeparator[] = ",";
50
51}  // namespace
52
53namespace content_settings {
54
55std::string GetTypeName(ContentSettingsType type) {
56  return std::string(kTypeNames[type]);
57}
58
59std::string CreatePatternString(
60    const ContentSettingsPattern& item_pattern,
61    const ContentSettingsPattern& top_level_frame_pattern) {
62  return item_pattern.ToString()
63         + std::string(kPatternSeparator)
64         + top_level_frame_pattern.ToString();
65}
66
67PatternPair ParsePatternString(const std::string& pattern_str) {
68  std::vector<std::string> pattern_str_list;
69  base::SplitString(pattern_str, kPatternSeparator[0], &pattern_str_list);
70
71  // If the |pattern_str| is an empty string then the |pattern_string_list|
72  // contains a single empty string. In this case the empty string will be
73  // removed to signal an invalid |pattern_str|. Invalid pattern strings are
74  // handle by the "if"-statment below. So the order of the if statements here
75  // must be preserved.
76  if (pattern_str_list.size() == 1) {
77    if (pattern_str_list[0].empty()) {
78      pattern_str_list.pop_back();
79    } else {
80      pattern_str_list.push_back("*");
81    }
82  }
83
84  if (pattern_str_list.size() > 2 ||
85      pattern_str_list.size() == 0) {
86    return PatternPair(ContentSettingsPattern(),
87                       ContentSettingsPattern());
88  }
89
90  PatternPair pattern_pair;
91  pattern_pair.first =
92      ContentSettingsPattern::FromString(pattern_str_list[0]);
93  pattern_pair.second =
94      ContentSettingsPattern::FromString(pattern_str_list[1]);
95  return pattern_pair;
96}
97
98ContentSetting ValueToContentSetting(const base::Value* value) {
99  ContentSetting setting = CONTENT_SETTING_DEFAULT;
100  bool valid = ParseContentSettingValue(value, &setting);
101  DCHECK(valid);
102  return setting;
103}
104
105bool ParseContentSettingValue(const base::Value* value,
106                              ContentSetting* setting) {
107  if (!value) {
108    *setting = CONTENT_SETTING_DEFAULT;
109    return true;
110  }
111  int int_value = -1;
112  if (!value->GetAsInteger(&int_value))
113    return false;
114  *setting = IntToContentSetting(int_value);
115  return *setting != CONTENT_SETTING_DEFAULT;
116}
117
118base::Value* GetContentSettingValueAndPatterns(
119    const ProviderInterface* provider,
120    const GURL& primary_url,
121    const GURL& secondary_url,
122    ContentSettingsType content_type,
123    const std::string& resource_identifier,
124    bool include_incognito,
125    ContentSettingsPattern* primary_pattern,
126    ContentSettingsPattern* secondary_pattern) {
127  if (include_incognito) {
128    // Check incognito-only specific settings. It's essential that the
129    // |RuleIterator| gets out of scope before we get a rule iterator for the
130    // normal mode.
131    scoped_ptr<RuleIterator> incognito_rule_iterator(
132        provider->GetRuleIterator(content_type, resource_identifier, true));
133    base::Value* value = GetContentSettingValueAndPatterns(
134        incognito_rule_iterator.get(), primary_url, secondary_url,
135        primary_pattern, secondary_pattern);
136    if (value)
137      return value;
138  }
139  // No settings from the incognito; use the normal mode.
140  scoped_ptr<RuleIterator> rule_iterator(
141      provider->GetRuleIterator(content_type, resource_identifier, false));
142  return GetContentSettingValueAndPatterns(
143      rule_iterator.get(), primary_url, secondary_url,
144      primary_pattern, secondary_pattern);
145}
146
147base::Value* GetContentSettingValueAndPatterns(
148    RuleIterator* rule_iterator,
149    const GURL& primary_url,
150    const GURL& secondary_url,
151    ContentSettingsPattern* primary_pattern,
152    ContentSettingsPattern* secondary_pattern) {
153  while (rule_iterator->HasNext()) {
154    const Rule& rule = rule_iterator->Next();
155    if (rule.primary_pattern.Matches(primary_url) &&
156        rule.secondary_pattern.Matches(secondary_url)) {
157      if (primary_pattern)
158        *primary_pattern = rule.primary_pattern;
159      if (secondary_pattern)
160        *secondary_pattern = rule.secondary_pattern;
161      return rule.value.get()->DeepCopy();
162    }
163  }
164  return NULL;
165}
166
167base::Value* GetContentSettingValue(const ProviderInterface* provider,
168                                    const GURL& primary_url,
169                                    const GURL& secondary_url,
170                                    ContentSettingsType content_type,
171                                    const std::string& resource_identifier,
172                                    bool include_incognito) {
173  return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url,
174                               content_type, resource_identifier,
175                               include_incognito, NULL, NULL);
176}
177
178ContentSetting GetContentSetting(const ProviderInterface* provider,
179                                 const GURL& primary_url,
180                                 const GURL& secondary_url,
181                                 ContentSettingsType content_type,
182                                 const std::string& resource_identifier,
183                                 bool include_incognito) {
184  scoped_ptr<base::Value> value(
185      GetContentSettingValue(provider, primary_url, secondary_url,
186                             content_type, resource_identifier,
187                             include_incognito));
188  return ValueToContentSetting(value.get());
189}
190
191void GetRendererContentSettingRules(const HostContentSettingsMap* map,
192                                    RendererContentSettingRules* rules) {
193  map->GetSettingsForOneType(
194      CONTENT_SETTINGS_TYPE_IMAGES, std::string(), &(rules->image_rules));
195  map->GetSettingsForOneType(
196      CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string(), &(rules->script_rules));
197}
198
199}  // namespace content_settings
200