Revert 285173 "Removed InProcessBrowserTest::CleanUpOnMainThread()"
[chromium-blink-merge.git] / chrome / browser / extensions / api / content_settings / content_settings_api.cc
blob99f7fc0be134af984eb1423388679a2ea7a3ce2d
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.
5 #include "chrome/browser/extensions/api/content_settings/content_settings_api.h"
7 #include <set>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/values.h"
14 #include "chrome/browser/content_settings/cookie_settings.h"
15 #include "chrome/browser/content_settings/host_content_settings_map.h"
16 #include "chrome/browser/extensions/api/content_settings/content_settings_api_constants.h"
17 #include "chrome/browser/extensions/api/content_settings/content_settings_helpers.h"
18 #include "chrome/browser/extensions/api/content_settings/content_settings_service.h"
19 #include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
20 #include "chrome/browser/extensions/api/preference/preference_api_constants.h"
21 #include "chrome/browser/extensions/api/preference/preference_helpers.h"
22 #include "chrome/browser/plugins/plugin_finder.h"
23 #include "chrome/browser/plugins/plugin_installer.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/extensions/api/content_settings.h"
27 #include "content/public/browser/plugin_service.h"
28 #include "extensions/browser/extension_prefs_scope.h"
29 #include "extensions/common/error_utils.h"
31 using content::BrowserThread;
32 using content::PluginService;
34 namespace Clear = extensions::api::content_settings::ContentSetting::Clear;
35 namespace Get = extensions::api::content_settings::ContentSetting::Get;
36 namespace Set = extensions::api::content_settings::ContentSetting::Set;
37 namespace pref_helpers = extensions::preference_helpers;
38 namespace pref_keys = extensions::preference_api_constants;
40 namespace {
42 bool RemoveContentType(base::ListValue* args,
43 ContentSettingsType* content_type) {
44 std::string content_type_str;
45 if (!args->GetString(0, &content_type_str))
46 return false;
47 // We remove the ContentSettingsType parameter since this is added by the
48 // renderer, and is not part of the JSON schema.
49 args->Remove(0, NULL);
50 *content_type =
51 extensions::content_settings_helpers::StringToContentSettingsType(
52 content_type_str);
53 return *content_type != CONTENT_SETTINGS_TYPE_DEFAULT;
56 } // namespace
58 namespace extensions {
60 namespace helpers = content_settings_helpers;
61 namespace keys = content_settings_api_constants;
63 bool ContentSettingsContentSettingClearFunction::RunSync() {
64 ContentSettingsType content_type;
65 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
67 scoped_ptr<Clear::Params> params(Clear::Params::Create(*args_));
68 EXTENSION_FUNCTION_VALIDATE(params.get());
70 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular;
71 bool incognito = false;
72 if (params->details.scope ==
73 Clear::Params::Details::SCOPE_INCOGNITO_SESSION_ONLY) {
74 scope = kExtensionPrefsScopeIncognitoSessionOnly;
75 incognito = true;
78 if (incognito) {
79 // We don't check incognito permissions here, as an extension should be
80 // always allowed to clear its own settings.
81 } else {
82 // Incognito profiles can't access regular mode ever, they only exist in
83 // split mode.
84 if (GetProfile()->IsOffTheRecord()) {
85 error_ = keys::kIncognitoContextError;
86 return false;
90 ContentSettingsStore* store =
91 ContentSettingsService::Get(GetProfile())->content_settings_store();
92 store->ClearContentSettingsForExtension(extension_id(), scope);
94 return true;
97 bool ContentSettingsContentSettingGetFunction::RunSync() {
98 ContentSettingsType content_type;
99 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
101 scoped_ptr<Get::Params> params(Get::Params::Create(*args_));
102 EXTENSION_FUNCTION_VALIDATE(params.get());
104 GURL primary_url(params->details.primary_url);
105 if (!primary_url.is_valid()) {
106 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
107 params->details.primary_url);
108 return false;
111 GURL secondary_url(primary_url);
112 if (params->details.secondary_url.get()) {
113 secondary_url = GURL(*params->details.secondary_url);
114 if (!secondary_url.is_valid()) {
115 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
116 *params->details.secondary_url);
117 return false;
121 std::string resource_identifier;
122 if (params->details.resource_identifier.get())
123 resource_identifier = params->details.resource_identifier->id;
125 bool incognito = false;
126 if (params->details.incognito.get())
127 incognito = *params->details.incognito;
128 if (incognito && !include_incognito()) {
129 error_ = pref_keys::kIncognitoErrorMessage;
130 return false;
133 HostContentSettingsMap* map;
134 CookieSettings* cookie_settings;
135 if (incognito) {
136 if (!GetProfile()->HasOffTheRecordProfile()) {
137 // TODO(bauerb): Allow reading incognito content settings
138 // outside of an incognito session.
139 error_ = keys::kIncognitoSessionOnlyError;
140 return false;
142 map = GetProfile()->GetOffTheRecordProfile()->GetHostContentSettingsMap();
143 cookie_settings = CookieSettings::Factory::GetForProfile(
144 GetProfile()->GetOffTheRecordProfile()).get();
145 } else {
146 map = GetProfile()->GetHostContentSettingsMap();
147 cookie_settings =
148 CookieSettings::Factory::GetForProfile(GetProfile()).get();
151 ContentSetting setting;
152 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES) {
153 // TODO(jochen): Do we return the value for setting or for reading cookies?
154 bool setting_cookie = false;
155 setting = cookie_settings->GetCookieSetting(primary_url, secondary_url,
156 setting_cookie, NULL);
157 } else {
158 setting = map->GetContentSetting(primary_url, secondary_url, content_type,
159 resource_identifier);
162 base::DictionaryValue* result = new base::DictionaryValue();
163 result->SetString(keys::kContentSettingKey,
164 helpers::ContentSettingToString(setting));
166 SetResult(result);
168 return true;
171 bool ContentSettingsContentSettingSetFunction::RunSync() {
172 ContentSettingsType content_type;
173 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
175 scoped_ptr<Set::Params> params(Set::Params::Create(*args_));
176 EXTENSION_FUNCTION_VALIDATE(params.get());
178 std::string primary_error;
179 ContentSettingsPattern primary_pattern =
180 helpers::ParseExtensionPattern(params->details.primary_pattern,
181 &primary_error);
182 if (!primary_pattern.IsValid()) {
183 error_ = primary_error;
184 return false;
187 ContentSettingsPattern secondary_pattern = ContentSettingsPattern::Wildcard();
188 if (params->details.secondary_pattern.get()) {
189 std::string secondary_error;
190 secondary_pattern =
191 helpers::ParseExtensionPattern(*params->details.secondary_pattern,
192 &secondary_error);
193 if (!secondary_pattern.IsValid()) {
194 error_ = secondary_error;
195 return false;
199 std::string resource_identifier;
200 if (params->details.resource_identifier.get())
201 resource_identifier = params->details.resource_identifier->id;
203 std::string setting_str;
204 EXTENSION_FUNCTION_VALIDATE(
205 params->details.setting->GetAsString(&setting_str));
206 ContentSetting setting;
207 EXTENSION_FUNCTION_VALIDATE(
208 helpers::StringToContentSetting(setting_str, &setting));
209 EXTENSION_FUNCTION_VALIDATE(HostContentSettingsMap::IsSettingAllowedForType(
210 GetProfile()->GetPrefs(), setting, content_type));
212 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular;
213 bool incognito = false;
214 if (params->details.scope ==
215 Set::Params::Details::SCOPE_INCOGNITO_SESSION_ONLY) {
216 scope = kExtensionPrefsScopeIncognitoSessionOnly;
217 incognito = true;
220 if (incognito) {
221 // Regular profiles can't access incognito unless include_incognito is true.
222 if (!GetProfile()->IsOffTheRecord() && !include_incognito()) {
223 error_ = pref_keys::kIncognitoErrorMessage;
224 return false;
226 } else {
227 // Incognito profiles can't access regular mode ever, they only exist in
228 // split mode.
229 if (GetProfile()->IsOffTheRecord()) {
230 error_ = keys::kIncognitoContextError;
231 return false;
235 if (scope == kExtensionPrefsScopeIncognitoSessionOnly &&
236 !GetProfile()->HasOffTheRecordProfile()) {
237 error_ = pref_keys::kIncognitoSessionOnlyErrorMessage;
238 return false;
241 ContentSettingsStore* store =
242 ContentSettingsService::Get(GetProfile())->content_settings_store();
243 store->SetExtensionContentSetting(extension_id(), primary_pattern,
244 secondary_pattern, content_type,
245 resource_identifier, setting, scope);
246 return true;
249 bool ContentSettingsContentSettingGetResourceIdentifiersFunction::RunAsync() {
250 ContentSettingsType content_type;
251 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
253 if (content_type != CONTENT_SETTINGS_TYPE_PLUGINS) {
254 SendResponse(true);
255 return true;
258 PluginService::GetInstance()->GetPlugins(
259 base::Bind(&ContentSettingsContentSettingGetResourceIdentifiersFunction::
260 OnGotPlugins,
261 this));
262 return true;
265 void ContentSettingsContentSettingGetResourceIdentifiersFunction::OnGotPlugins(
266 const std::vector<content::WebPluginInfo>& plugins) {
267 PluginFinder* finder = PluginFinder::GetInstance();
268 std::set<std::string> group_identifiers;
269 base::ListValue* list = new base::ListValue();
270 for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin();
271 it != plugins.end(); ++it) {
272 scoped_ptr<PluginMetadata> plugin_metadata(finder->GetPluginMetadata(*it));
273 const std::string& group_identifier = plugin_metadata->identifier();
274 if (group_identifiers.find(group_identifier) != group_identifiers.end())
275 continue;
277 group_identifiers.insert(group_identifier);
278 base::DictionaryValue* dict = new base::DictionaryValue();
279 dict->SetString(keys::kIdKey, group_identifier);
280 dict->SetString(keys::kDescriptionKey, plugin_metadata->name());
281 list->Append(dict);
283 SetResult(list);
284 BrowserThread::PostTask(
285 BrowserThread::UI, FROM_HERE, base::Bind(
286 &ContentSettingsContentSettingGetResourceIdentifiersFunction::
287 SendResponse,
288 this,
289 true));
292 } // namespace extensions