Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: chrome/browser/ui/webui/options2/content_settings_handler.cc

Issue 10837331: Options: s/options2/options/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: wut Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/ui/webui/options2/content_settings_handler.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/content_settings/content_settings_details.h"
16 #include "chrome/browser/content_settings/content_settings_utils.h"
17 #include "chrome/browser/content_settings/host_content_settings_map.h"
18 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
19 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/extensions/extension_special_storage_policy.h"
21 #include "chrome/browser/intents/web_intents_util.h"
22 #include "chrome/browser/notifications/desktop_notification_service.h"
23 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
24 #include "chrome/browser/prefs/pref_service.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/common/chrome_notification_types.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/content_settings.h"
30 #include "chrome/common/content_settings_pattern.h"
31 #include "chrome/common/extensions/permissions/api_permission.h"
32 #include "chrome/common/extensions/extension_set.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/common/url_constants.h"
35 #include "content/public/browser/notification_service.h"
36 #include "content/public/browser/notification_source.h"
37 #include "content/public/browser/notification_types.h"
38 #include "content/public/browser/user_metrics.h"
39 #include "content/public/browser/web_ui.h"
40 #include "content/public/common/content_switches.h"
41 #include "grit/generated_resources.h"
42 #include "grit/locale_settings.h"
43 #include "net/base/net_util.h"
44 #include "ui/base/l10n/l10n_util.h"
45
46 #if defined(OS_CHROMEOS)
47 #include "chrome/browser/chromeos/login/user_manager.h"
48 #endif
49
50 using content::UserMetricsAction;
51 using extensions::APIPermission;
52
53 namespace {
54
55 enum ExContentSettingsTypeEnum {
56 EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC =
57 CONTENT_SETTINGS_NUM_TYPES,
58 EX_CONTENT_SETTINGS_NUM_TYPES
59 };
60
61 typedef std::map<ContentSettingsPattern, ContentSetting> OnePatternSettings;
62 typedef std::map<ContentSettingsPattern, OnePatternSettings>
63 AllPatternsSettings;
64
65 // The AppFilter is used in AddExceptionsGrantedByHostedApps() to choose
66 // extensions which should have their extent displayed.
67 typedef bool (*AppFilter)(const extensions::Extension& app, Profile* profile);
68
69 const char* kDisplayPattern = "displayPattern";
70 const char* kSetting = "setting";
71 const char* kOrigin = "origin";
72 const char* kSource = "source";
73 const char* kAppName = "appName";
74 const char* kAppId = "appId";
75 const char* kEmbeddingOrigin = "embeddingOrigin";
76 const char* kDefaultProviderID = "default";
77 const char* kPreferencesSource = "preferences";
78
79 std::string ContentSettingToString(ContentSetting setting) {
80 switch (setting) {
81 case CONTENT_SETTING_ALLOW:
82 return "allow";
83 case CONTENT_SETTING_ASK:
84 return "ask";
85 case CONTENT_SETTING_BLOCK:
86 return "block";
87 case CONTENT_SETTING_SESSION_ONLY:
88 return "session";
89 case CONTENT_SETTING_DEFAULT:
90 return "default";
91 case CONTENT_SETTING_NUM_SETTINGS:
92 NOTREACHED();
93 }
94
95 return "";
96 }
97
98 ContentSetting ContentSettingFromString(const std::string& name) {
99 if (name == "allow")
100 return CONTENT_SETTING_ALLOW;
101 if (name == "ask")
102 return CONTENT_SETTING_ASK;
103 if (name == "block")
104 return CONTENT_SETTING_BLOCK;
105 if (name == "session")
106 return CONTENT_SETTING_SESSION_ONLY;
107
108 NOTREACHED() << name << " is not a recognized content setting.";
109 return CONTENT_SETTING_DEFAULT;
110 }
111
112 std::string GeolocationExceptionToString(
113 const ContentSettingsPattern& origin,
114 const ContentSettingsPattern& embedding_origin) {
115 if (origin == embedding_origin)
116 return origin.ToString();
117
118 // TODO(estade): the page needs to use CSS to indent the string.
119 std::string indent(" ");
120
121 if (embedding_origin == ContentSettingsPattern::Wildcard()) {
122 // NOTE: As long as the user cannot add/edit entries from the exceptions
123 // dialog, it's impossible to actually have a non-default setting for some
124 // origin "embedded on any other site", so this row will never appear. If
125 // we add the ability to add/edit exceptions, we'll need to decide when to
126 // display this and how "removing" it will function.
127 return indent +
128 l10n_util::GetStringUTF8(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER);
129 }
130
131 return indent + l10n_util::GetStringFUTF8(
132 IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST,
133 UTF8ToUTF16(embedding_origin.ToString()));
134 }
135
136 // Create a DictionaryValue* that will act as a data source for a single row
137 // in a HostContentSettingsMap-controlled exceptions table (e.g., cookies).
138 // Ownership of the pointer is passed to the caller.
139 DictionaryValue* GetExceptionForPage(
140 const ContentSettingsPattern& pattern,
141 const ContentSetting& setting,
142 const std::string& provider_name) {
143 DictionaryValue* exception = new DictionaryValue();
144 exception->SetString(kDisplayPattern, pattern.ToString());
145 exception->SetString(kSetting, ContentSettingToString(setting));
146 exception->SetString(kSource, provider_name);
147 return exception;
148 }
149
150 // Create a DictionaryValue* that will act as a data source for a single row
151 // in the Geolocation exceptions table. Ownership of the pointer is passed to
152 // the caller.
153 DictionaryValue* GetGeolocationExceptionForPage(
154 const ContentSettingsPattern& origin,
155 const ContentSettingsPattern& embedding_origin,
156 ContentSetting setting) {
157 DictionaryValue* exception = new DictionaryValue();
158 exception->SetString(kDisplayPattern,
159 GeolocationExceptionToString(origin, embedding_origin));
160 exception->SetString(kSetting, ContentSettingToString(setting));
161 exception->SetString(kOrigin, origin.ToString());
162 exception->SetString(kEmbeddingOrigin, embedding_origin.ToString());
163 return exception;
164 }
165
166 // Create a DictionaryValue* that will act as a data source for a single row
167 // in the desktop notifications exceptions table. Ownership of the pointer is
168 // passed to the caller.
169 DictionaryValue* GetNotificationExceptionForPage(
170 const ContentSettingsPattern& pattern,
171 ContentSetting setting,
172 const std::string& provider_name) {
173 DictionaryValue* exception = new DictionaryValue();
174 exception->SetString(kDisplayPattern, pattern.ToString());
175 exception->SetString(kSetting, ContentSettingToString(setting));
176 exception->SetString(kOrigin, pattern.ToString());
177 exception->SetString(kSource, provider_name);
178 return exception;
179 }
180
181 // Returns true whenever the hosted |app|'s extent enjoys protected storage
182 // under the current |profile|.
183 // Must have the AppFilter signature.
184 bool HasProtectedStorage(const extensions::Extension& app, Profile* profile) {
185 ExtensionSpecialStoragePolicy* policy =
186 profile->GetExtensionSpecialStoragePolicy();
187 return policy->NeedsProtection(&app);
188 }
189
190 // Returns true whenever the |extension| is hosted and has |permission|.
191 // Must have the AppFilter signature.
192 template <APIPermission::ID permission>
193 bool HostedAppHasPermission(
194 const extensions::Extension& extension, Profile* /*profile*/) {
195 return extension.is_hosted_app() && extension.HasAPIPermission(permission);
196 }
197
198 // Add an "Allow"-entry to the list of |exceptions| for a |url_pattern| from
199 // the web extent of a hosted |app|.
200 void AddExceptionForHostedApp(const std::string& url_pattern,
201 const extensions::Extension& app, ListValue* exceptions) {
202 DictionaryValue* exception = new DictionaryValue();
203 exception->SetString(kDisplayPattern, url_pattern);
204 exception->SetString(kSetting, ContentSettingToString(CONTENT_SETTING_ALLOW));
205 exception->SetString(kOrigin, url_pattern);
206 exception->SetString(kEmbeddingOrigin, url_pattern);
207 exception->SetString(kSource, "HostedApp");
208 exception->SetString(kAppName, app.name());
209 exception->SetString(kAppId, app.id());
210 exceptions->Append(exception);
211 }
212
213 // Asks the |profile| for hosted apps which have the |permission| set, and
214 // adds their web extent and launch URL to the |exceptions| list.
215 void AddExceptionsGrantedByHostedApps(
216 Profile* profile, AppFilter app_filter, ListValue* exceptions) {
217 const ExtensionService* extension_service = profile->GetExtensionService();
218 // After ExtensionSystem::Init has been called at the browser's start,
219 // GetExtensionService() should not return NULL, so this is safe:
220 const ExtensionSet* extensions = extension_service->extensions();
221
222 for (ExtensionSet::const_iterator extension = extensions->begin();
223 extension != extensions->end(); ++extension) {
224 if (!app_filter(**extension, profile)) continue;
225
226 URLPatternSet web_extent = (*extension)->web_extent();
227 // Add patterns from web extent.
228 for (URLPatternSet::const_iterator pattern = web_extent.begin();
229 pattern != web_extent.end(); ++pattern) {
230 std::string url_pattern = pattern->GetAsString();
231 AddExceptionForHostedApp(url_pattern, **extension, exceptions);
232 }
233 // Retrieve the launch URL.
234 std::string launch_url_string = (*extension)->launch_web_url();
235 GURL launch_url(launch_url_string);
236 // Skip adding the launch URL if it is part of the web extent.
237 if (web_extent.MatchesURL(launch_url)) continue;
238 AddExceptionForHostedApp(launch_url_string, **extension, exceptions);
239 }
240 }
241
242 ContentSetting FlashPermissionToContentSetting(
243 PP_Flash_BrowserOperations_Permission permission) {
244 switch (permission) {
245 case PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT:
246 return CONTENT_SETTING_DEFAULT;
247 case PP_FLASH_BROWSEROPERATIONS_PERMISSION_ALLOW:
248 return CONTENT_SETTING_ALLOW;
249 case PP_FLASH_BROWSEROPERATIONS_PERMISSION_BLOCK:
250 return CONTENT_SETTING_BLOCK;
251 case PP_FLASH_BROWSEROPERATIONS_PERMISSION_ASK:
252 return CONTENT_SETTING_ASK;
253 default:
254 NOTREACHED();
255 return CONTENT_SETTING_DEFAULT;
256 }
257 }
258
259 PP_Flash_BrowserOperations_Permission FlashPermissionFromContentSetting(
260 ContentSetting setting) {
261 switch (setting) {
262 case CONTENT_SETTING_DEFAULT:
263 return PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT;
264 case CONTENT_SETTING_ALLOW:
265 return PP_FLASH_BROWSEROPERATIONS_PERMISSION_ALLOW;
266 case CONTENT_SETTING_BLOCK:
267 return PP_FLASH_BROWSEROPERATIONS_PERMISSION_BLOCK;
268 case CONTENT_SETTING_ASK:
269 return PP_FLASH_BROWSEROPERATIONS_PERMISSION_ASK;
270 default:
271 NOTREACHED();
272 return PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT;
273 }
274 }
275
276 std::string CanonicalizeHost(const std::string& host) {
277 url_canon::CanonHostInfo info;
278 return net::CanonicalizeHost(host, &info);
279 }
280
281 bool IsValidHost(const std::string& host) {
282 std::string canonicalized_host = CanonicalizeHost(host);
283 return !canonicalized_host.empty();
284 }
285
286 } // namespace
287
288 namespace options {
289
290 class ContentSettingsHandler::ExContentSettingsType {
291 public:
292 explicit ExContentSettingsType(int value) : value_(value) {
293 DCHECK(value_ < EX_CONTENT_SETTINGS_NUM_TYPES);
294 }
295 explicit ExContentSettingsType(ContentSettingsType type) : value_(type) {}
296 explicit ExContentSettingsType(ExContentSettingsTypeEnum type)
297 : value_(type) {}
298
299 bool IsExtraContentSettingsType() const {
300 return value_ >= CONTENT_SETTINGS_NUM_TYPES;
301 }
302
303 operator int() const { return value_; }
304
305 ContentSettingsType ToContentSettingsType() const {
306 DCHECK(value_ < CONTENT_SETTINGS_NUM_TYPES);
307 return static_cast<ContentSettingsType>(value_);
308 }
309
310 private:
311 int value_;
312 };
313
314 ContentSettingsHandler::CachedPepperFlashSettings::CachedPepperFlashSettings()
315 : default_permission(PP_FLASH_BROWSEROPERATIONS_PERMISSION_BLOCK),
316 initialized(false),
317 last_refresh_request_id(0) {
318 }
319
320 ContentSettingsHandler::CachedPepperFlashSettings::~CachedPepperFlashSettings()
321 {
322 }
323
324 struct ContentSettingsHandler::ExContentSettingsTypeNameEntry {
325 int type;
326 const char* name;
327 };
328
329 const ContentSettingsHandler::ExContentSettingsTypeNameEntry
330 ContentSettingsHandler::kExContentSettingsTypeGroupNames[] = {
331 {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"},
332 {CONTENT_SETTINGS_TYPE_IMAGES, "images"},
333 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"},
334 {CONTENT_SETTINGS_TYPE_PLUGINS, "plugins"},
335 {CONTENT_SETTINGS_TYPE_POPUPS, "popups"},
336 {CONTENT_SETTINGS_TYPE_GEOLOCATION, "location"},
337 {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications"},
338 {CONTENT_SETTINGS_TYPE_INTENTS, "intents"},
339 {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, "auto-select-certificate"},
340 {CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen"},
341 {CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock"},
342 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, "mixed-script"},
343 {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, "register-protocol-handler"},
344 {EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC, "pepper-flash-cameramic"},
345 {CONTENT_SETTINGS_TYPE_MEDIASTREAM, "media-stream"},
346 };
347
348 ContentSettingsHandler::ContentSettingsHandler() {
349 }
350
351 ContentSettingsHandler::~ContentSettingsHandler() {
352 }
353
354 void ContentSettingsHandler::GetLocalizedValues(
355 DictionaryValue* localized_strings) {
356 DCHECK(localized_strings);
357
358 static OptionsStringResource resources[] = {
359 { "allowException", IDS_EXCEPTIONS_ALLOW_BUTTON },
360 { "blockException", IDS_EXCEPTIONS_BLOCK_BUTTON },
361 { "sessionException", IDS_EXCEPTIONS_SESSION_ONLY_BUTTON },
362 { "askException", IDS_EXCEPTIONS_ASK_BUTTON },
363 { "otr_exceptions_explanation", IDS_EXCEPTIONS_OTR_LABEL },
364 { "addNewExceptionInstructions", IDS_EXCEPTIONS_ADD_NEW_INSTRUCTIONS },
365 { "manage_exceptions", IDS_EXCEPTIONS_MANAGE },
366 { "manage_handlers", IDS_HANDLERS_MANAGE },
367 { "exceptionPatternHeader", IDS_EXCEPTIONS_PATTERN_HEADER },
368 { "exceptionBehaviorHeader", IDS_EXCEPTIONS_ACTION_HEADER },
369 // Cookies filter.
370 { "cookies_tab_label", IDS_COOKIES_TAB_LABEL },
371 { "cookies_header", IDS_COOKIES_HEADER },
372 { "cookies_allow", IDS_COOKIES_ALLOW_RADIO },
373 { "cookies_block", IDS_COOKIES_BLOCK_RADIO },
374 { "cookies_session_only", IDS_COOKIES_SESSION_ONLY_RADIO },
375 { "cookies_block_3rd_party", IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX },
376 { "cookies_clear_when_close", IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX },
377 { "cookies_lso_clear_when_close", IDS_COOKIES_LSO_CLEAR_WHEN_CLOSE_CHKBOX },
378 { "cookies_show_cookies", IDS_COOKIES_SHOW_COOKIES_BUTTON },
379 { "cookies_show_app_cookies", IDS_COOKIES_SHOW_APP_COOKIES_BUTTON },
380 { "flash_storage_settings", IDS_FLASH_STORAGE_SETTINGS },
381 { "flash_storage_url", IDS_FLASH_STORAGE_URL },
382 // Image filter.
383 { "images_tab_label", IDS_IMAGES_TAB_LABEL },
384 { "images_header", IDS_IMAGES_HEADER },
385 { "images_allow", IDS_IMAGES_LOAD_RADIO },
386 { "images_block", IDS_IMAGES_NOLOAD_RADIO },
387 // JavaScript filter.
388 { "javascript_tab_label", IDS_JAVASCRIPT_TAB_LABEL },
389 { "javascript_header", IDS_JAVASCRIPT_HEADER },
390 { "javascript_allow", IDS_JS_ALLOW_RADIO },
391 { "javascript_block", IDS_JS_DONOTALLOW_RADIO },
392 // Plug-ins filter.
393 { "plugins_tab_label", IDS_PLUGIN_TAB_LABEL },
394 { "plugins_header", IDS_PLUGIN_HEADER },
395 { "plugins_ask", IDS_PLUGIN_ASK_RADIO },
396 { "plugins_allow", IDS_PLUGIN_LOAD_RADIO },
397 { "plugins_block", IDS_PLUGIN_NOLOAD_RADIO },
398 { "disableIndividualPlugins", IDS_PLUGIN_SELECTIVE_DISABLE },
399 // Pop-ups filter.
400 { "popups_tab_label", IDS_POPUP_TAB_LABEL },
401 { "popups_header", IDS_POPUP_HEADER },
402 { "popups_allow", IDS_POPUP_ALLOW_RADIO },
403 { "popups_block", IDS_POPUP_BLOCK_RADIO },
404 // Location filter.
405 { "location_tab_label", IDS_GEOLOCATION_TAB_LABEL },
406 { "location_header", IDS_GEOLOCATION_HEADER },
407 { "location_allow", IDS_GEOLOCATION_ALLOW_RADIO },
408 { "location_ask", IDS_GEOLOCATION_ASK_RADIO },
409 { "location_block", IDS_GEOLOCATION_BLOCK_RADIO },
410 { "set_by", IDS_GEOLOCATION_SET_BY_HOVER },
411 // Notifications filter.
412 { "notifications_tab_label", IDS_NOTIFICATIONS_TAB_LABEL },
413 { "notifications_header", IDS_NOTIFICATIONS_HEADER },
414 { "notifications_allow", IDS_NOTIFICATIONS_ALLOW_RADIO },
415 { "notifications_ask", IDS_NOTIFICATIONS_ASK_RADIO },
416 { "notifications_block", IDS_NOTIFICATIONS_BLOCK_RADIO },
417 // Intents filter.
418 { "webIntentsTabLabel", IDS_WEB_INTENTS_TAB_LABEL },
419 { "allowWebIntents", IDS_ALLOW_WEB_INTENTS },
420 // Fullscreen filter.
421 { "fullscreen_tab_label", IDS_FULLSCREEN_TAB_LABEL },
422 { "fullscreen_header", IDS_FULLSCREEN_HEADER },
423 // Mouse Lock filter.
424 { "mouselock_tab_label", IDS_MOUSE_LOCK_TAB_LABEL },
425 { "mouselock_header", IDS_MOUSE_LOCK_HEADER },
426 { "mouselock_allow", IDS_MOUSE_LOCK_ALLOW_RADIO },
427 { "mouselock_ask", IDS_MOUSE_LOCK_ASK_RADIO },
428 { "mouselock_block", IDS_MOUSE_LOCK_BLOCK_RADIO },
429 // Pepper Flash camera and microphone filter.
430 { "pepperFlashCameramicTabLabel", IDS_PEPPER_FLASH_CAMERAMIC_TAB_LABEL },
431 // The header has to be named as <content_type_name>_header.
432 { "pepper-flash-cameramic_header", IDS_PEPPER_FLASH_CAMERAMIC_HEADER },
433 { "pepperFlashCameramicAsk", IDS_PEPPER_FLASH_CAMERAMIC_ASK_RADIO },
434 { "pepperFlashCameramicBlock", IDS_PEPPER_FLASH_CAMERAMIC_BLOCK_RADIO },
435 #if defined(OS_CHROMEOS)
436 // Protected Content filter
437 { "protectedContentTabLabel", IDS_PROTECTED_CONTENT_TAB_LABEL },
438 { "protectedContentInfo", IDS_PROTECTED_CONTENT_INFO },
439 { "protectedContentEnable", IDS_PROTECTED_CONTENT_ENABLE},
440 #endif // defined(OS_CHROMEOS)
441 // Media stream capture device filter.
442 { "mediaStreamTabLabel", IDS_MEDIA_STREAM_TAB_LABEL },
443 { "media-stream_header", IDS_MEDIA_STREAM_HEADER },
444 { "mediaStreamAsk", IDS_MEDIA_STREAM_ASK_RADIO },
445 { "mediaStreamBlock", IDS_MEDIA_STREAM_BLOCK_RADIO },
446 };
447
448 RegisterStrings(localized_strings, resources, arraysize(resources));
449 RegisterTitle(localized_strings, "contentSettingsPage",
450 IDS_CONTENT_SETTINGS_TITLE);
451
452 // Register titles for each of the individual settings whose exception
453 // dialogs will be processed by |ContentSettingsHandler|.
454 RegisterTitle(localized_strings, "cookies",
455 IDS_COOKIES_TAB_LABEL);
456 RegisterTitle(localized_strings, "images",
457 IDS_IMAGES_TAB_LABEL);
458 RegisterTitle(localized_strings, "javascript",
459 IDS_JAVASCRIPT_TAB_LABEL);
460 RegisterTitle(localized_strings, "plugins",
461 IDS_PLUGIN_TAB_LABEL);
462 RegisterTitle(localized_strings, "popups",
463 IDS_POPUP_TAB_LABEL);
464 RegisterTitle(localized_strings, "location",
465 IDS_GEOLOCATION_TAB_LABEL);
466 RegisterTitle(localized_strings, "notifications",
467 IDS_NOTIFICATIONS_TAB_LABEL);
468 RegisterTitle(localized_strings, "fullscreen",
469 IDS_FULLSCREEN_TAB_LABEL);
470 RegisterTitle(localized_strings, "mouselock",
471 IDS_MOUSE_LOCK_TAB_LABEL);
472 RegisterTitle(localized_strings, "pepper-flash-cameramic",
473 IDS_PEPPER_FLASH_CAMERAMIC_TAB_LABEL);
474 RegisterTitle(localized_strings, "media-stream",
475 IDS_MEDIA_STREAM_TAB_LABEL);
476
477 Profile* profile = Profile::FromWebUI(web_ui());
478 localized_strings->SetBoolean(
479 "enable_web_intents",
480 web_intents::IsWebIntentsEnabledForProfile(profile));
481 }
482
483 void ContentSettingsHandler::InitializeHandler() {
484 notification_registrar_.Add(
485 this, chrome::NOTIFICATION_PROFILE_CREATED,
486 content::NotificationService::AllSources());
487 notification_registrar_.Add(
488 this, chrome::NOTIFICATION_PROFILE_DESTROYED,
489 content::NotificationService::AllSources());
490
491 notification_registrar_.Add(
492 this, chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED,
493 content::NotificationService::AllSources());
494 notification_registrar_.Add(
495 this, chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
496 content::NotificationService::AllSources());
497 Profile* profile = Profile::FromWebUI(web_ui());
498 notification_registrar_.Add(
499 this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
500 content::Source<Profile>(profile));
501
502 PrefService* prefs = profile->GetPrefs();
503 pref_change_registrar_.Init(prefs);
504 pref_change_registrar_.Add(prefs::kGeolocationContentSettings, this);
505 pref_change_registrar_.Add(prefs::kPepperFlashSettingsEnabled, this);
506
507 flash_settings_manager_.reset(new PepperFlashSettingsManager(this, profile));
508 }
509
510 void ContentSettingsHandler::InitializePage() {
511 UpdateHandlersEnabledRadios();
512 UpdateAllExceptionsViewsFromModel();
513
514 flash_cameramic_settings_ = CachedPepperFlashSettings();
515 RefreshFlashSettingsCache(true);
516 }
517
518 void ContentSettingsHandler::Observe(
519 int type,
520 const content::NotificationSource& source,
521 const content::NotificationDetails& details) {
522 switch (type) {
523 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
524 if (content::Source<Profile>(source).ptr()->IsOffTheRecord()) {
525 web_ui()->CallJavascriptFunction(
526 "ContentSettingsExceptionsArea.OTRProfileDestroyed");
527 }
528 break;
529 }
530
531 case chrome::NOTIFICATION_PROFILE_CREATED: {
532 if (content::Source<Profile>(source).ptr()->IsOffTheRecord())
533 UpdateAllOTRExceptionsViewsFromModel();
534 break;
535 }
536
537 case chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED: {
538 // Filter out notifications from other profiles.
539 HostContentSettingsMap* map =
540 content::Source<HostContentSettingsMap>(source).ptr();
541 if (map != GetContentSettingsMap() &&
542 map != GetOTRContentSettingsMap())
543 break;
544
545 const ContentSettingsDetails* settings_details =
546 content::Details<const ContentSettingsDetails>(details).ptr();
547
548 // TODO(estade): we pretend update_all() is always true.
549 if (settings_details->update_all_types()) {
550 UpdateAllExceptionsViewsFromModel();
551 } else {
552 UpdateExceptionsViewFromModel(
553 ExContentSettingsType(settings_details->type()));
554 }
555 break;
556 }
557
558 case chrome::NOTIFICATION_PREF_CHANGED: {
559 const std::string& pref_name =
560 *content::Details<std::string>(details).ptr();
561 if (pref_name == prefs::kGeolocationContentSettings)
562 UpdateGeolocationExceptionsView();
563 else if (pref_name == prefs::kPepperFlashSettingsEnabled)
564 RefreshFlashSettingsCache(false);
565
566 break;
567 }
568
569 case chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED: {
570 UpdateNotificationExceptionsView();
571 break;
572 }
573
574 case chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED: {
575 UpdateHandlersEnabledRadios();
576 break;
577 }
578
579 default:
580 OptionsPageUIHandler::Observe(type, source, details);
581 }
582 }
583
584 void ContentSettingsHandler::OnGetPermissionSettingsCompleted(
585 uint32 request_id,
586 bool success,
587 PP_Flash_BrowserOperations_Permission default_permission,
588 const ppapi::FlashSiteSettings& sites) {
589 if (success &&
590 request_id == flash_cameramic_settings_.last_refresh_request_id) {
591 flash_cameramic_settings_.default_permission = default_permission;
592 flash_cameramic_settings_.sites.clear();
593 for (ppapi::FlashSiteSettings::const_iterator iter = sites.begin();
594 iter != sites.end(); ++iter) {
595 if (IsValidHost(iter->site))
596 flash_cameramic_settings_.sites[iter->site] = iter->permission;
597 }
598 UpdateExceptionsViewFromModel(
599 ExContentSettingsType(EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC));
600
601 if (!flash_cameramic_settings_.initialized) {
602 web_ui()->CallJavascriptFunction(
603 "ContentSettings.enablePepperFlashCameraMicSettings");
604 flash_cameramic_settings_.initialized = true;
605 }
606 }
607 }
608
609 void ContentSettingsHandler::UpdateSettingDefaultFromModel(
610 const ExContentSettingsType& type) {
611 DictionaryValue filter_settings;
612 std::string provider_id;
613 filter_settings.SetString(
614 ExContentSettingsTypeToGroupName(type) + ".value",
615 GetSettingDefaultFromModel(type, &provider_id));
616 filter_settings.SetString(
617 ExContentSettingsTypeToGroupName(type) + ".managedBy", provider_id);
618
619 web_ui()->CallJavascriptFunction(
620 "ContentSettings.setContentFilterSettingsValue", filter_settings);
621 }
622
623 std::string ContentSettingsHandler::GetSettingDefaultFromModel(
624 const ExContentSettingsType& type, std::string* provider_id) {
625 Profile* profile = Profile::FromWebUI(web_ui());
626 ContentSetting default_setting;
627 if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
628 default_setting =
629 DesktopNotificationServiceFactory::GetForProfile(profile)->
630 GetDefaultContentSetting(provider_id);
631 } else if (type == EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC) {
632 default_setting = FlashPermissionToContentSetting(
633 flash_cameramic_settings_.default_permission);
634 *provider_id = kDefaultProviderID;
635 } else {
636 default_setting =
637 profile->GetHostContentSettingsMap()->
638 GetDefaultContentSetting(type.ToContentSettingsType(), provider_id);
639 }
640
641 return ContentSettingToString(default_setting);
642 }
643
644 void ContentSettingsHandler::UpdateHandlersEnabledRadios() {
645 base::FundamentalValue handlers_enabled(
646 GetProtocolHandlerRegistry()->enabled());
647
648 web_ui()->CallJavascriptFunction(
649 "ContentSettings.updateHandlersEnabledRadios",
650 handlers_enabled);
651 }
652
653 void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() {
654 for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
655 type < EX_CONTENT_SETTINGS_NUM_TYPES; ++type) {
656 // The content settings type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
657 // is supposed to be set by policy only. Hence there is no user facing UI
658 // for this content type and we skip it here.
659 if (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE)
660 continue;
661 // The RPH settings are retrieved separately.
662 if (type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS)
663 continue;
664 UpdateExceptionsViewFromModel(ExContentSettingsType(type));
665 }
666 }
667
668 void ContentSettingsHandler::UpdateAllOTRExceptionsViewsFromModel() {
669 for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
670 type < EX_CONTENT_SETTINGS_NUM_TYPES; ++type) {
671 UpdateOTRExceptionsViewFromModel(ExContentSettingsType(type));
672 }
673 }
674
675 void ContentSettingsHandler::UpdateExceptionsViewFromModel(
676 const ExContentSettingsType& type) {
677 switch (type) {
678 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
679 UpdateGeolocationExceptionsView();
680 break;
681 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
682 UpdateNotificationExceptionsView();
683 break;
684 case EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC:
685 UpdateFlashCameraMicExceptionsView();
686 break;
687 case CONTENT_SETTINGS_TYPE_INTENTS:
688 // Don't update intents settings at this point.
689 // Turn on when enable_web_intents_tag is enabled.
690 break;
691 case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT:
692 // We don't yet support exceptions for mixed scripting.
693 break;
694 case CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE:
695 break;
696 case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
697 break;
698 default:
699 UpdateExceptionsViewFromHostContentSettingsMap(
700 type.ToContentSettingsType());
701 break;
702 }
703 }
704
705 void ContentSettingsHandler::UpdateOTRExceptionsViewFromModel(
706 const ExContentSettingsType& type) {
707 switch (type) {
708 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
709 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
710 case CONTENT_SETTINGS_TYPE_INTENTS:
711 case CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE:
712 case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT:
713 case EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC:
714 break;
715 default:
716 UpdateExceptionsViewFromOTRHostContentSettingsMap(
717 type.ToContentSettingsType());
718 break;
719 }
720 }
721
722 void ContentSettingsHandler::UpdateGeolocationExceptionsView() {
723 Profile* profile = Profile::FromWebUI(web_ui());
724 HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
725
726 ContentSettingsForOneType all_settings;
727 map->GetSettingsForOneType(
728 CONTENT_SETTINGS_TYPE_GEOLOCATION,
729 std::string(),
730 &all_settings);
731
732 // Group geolocation settings by primary_pattern.
733 AllPatternsSettings all_patterns_settings;
734 for (ContentSettingsForOneType::iterator i =
735 all_settings.begin();
736 i != all_settings.end();
737 ++i) {
738 // Don't add default settings.
739 if (i->primary_pattern == ContentSettingsPattern::Wildcard() &&
740 i->secondary_pattern == ContentSettingsPattern::Wildcard() &&
741 i->source != kPreferencesSource) {
742 continue;
743 }
744 all_patterns_settings[i->primary_pattern][i->secondary_pattern] =
745 i->setting;
746 }
747
748 ListValue exceptions;
749 AddExceptionsGrantedByHostedApps(
750 profile,
751 HostedAppHasPermission<APIPermission::kGeolocation>,
752 &exceptions);
753
754 for (AllPatternsSettings::iterator i = all_patterns_settings.begin();
755 i != all_patterns_settings.end();
756 ++i) {
757 const ContentSettingsPattern& primary_pattern = i->first;
758 const OnePatternSettings& one_settings = i->second;
759
760 OnePatternSettings::const_iterator parent =
761 one_settings.find(primary_pattern);
762
763 // Add the "parent" entry for the non-embedded setting.
764 ContentSetting parent_setting =
765 parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second;
766 exceptions.Append(GetGeolocationExceptionForPage(primary_pattern,
767 primary_pattern,
768 parent_setting));
769
770 // Add the "children" for any embedded settings.
771 for (OnePatternSettings::const_iterator j = one_settings.begin();
772 j != one_settings.end();
773 ++j) {
774 // Skip the non-embedded setting which we already added above.
775 if (j == parent)
776 continue;
777
778 exceptions.Append(
779 GetGeolocationExceptionForPage(primary_pattern, j->first, j->second));
780 }
781 }
782
783 StringValue type_string(
784 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION));
785 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
786 type_string, exceptions);
787
788 // This is mainly here to keep this function ideologically parallel to
789 // UpdateExceptionsViewFromHostContentSettingsMap().
790 UpdateSettingDefaultFromModel(
791 ExContentSettingsType(CONTENT_SETTINGS_TYPE_GEOLOCATION));
792 }
793
794 void ContentSettingsHandler::UpdateNotificationExceptionsView() {
795 Profile* profile = Profile::FromWebUI(web_ui());
796 DesktopNotificationService* service =
797 DesktopNotificationServiceFactory::GetForProfile(profile);
798
799 ContentSettingsForOneType settings;
800 service->GetNotificationsSettings(&settings);
801
802 ListValue exceptions;
803 AddExceptionsGrantedByHostedApps(profile,
804 HostedAppHasPermission<APIPermission::kNotification>,
805 &exceptions);
806
807 for (ContentSettingsForOneType::const_iterator i =
808 settings.begin();
809 i != settings.end();
810 ++i) {
811 // Don't add default settings.
812 if (i->primary_pattern == ContentSettingsPattern::Wildcard() &&
813 i->secondary_pattern == ContentSettingsPattern::Wildcard() &&
814 i->source != kPreferencesSource) {
815 continue;
816 }
817
818 exceptions.Append(
819 GetNotificationExceptionForPage(i->primary_pattern, i->setting,
820 i->source));
821 }
822
823 StringValue type_string(
824 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
825 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
826 type_string, exceptions);
827
828 // This is mainly here to keep this function ideologically parallel to
829 // UpdateExceptionsViewFromHostContentSettingsMap().
830 UpdateSettingDefaultFromModel(
831 ExContentSettingsType(CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
832 }
833
834 void ContentSettingsHandler::UpdateFlashCameraMicExceptionsView() {
835 ListValue exceptions;
836 for (CachedPepperFlashSettings::SiteMap::iterator iter =
837 flash_cameramic_settings_.sites.begin();
838 iter != flash_cameramic_settings_.sites.end(); ++iter) {
839 DictionaryValue* exception = new DictionaryValue();
840 exception->SetString(kDisplayPattern, iter->first);
841 exception->SetString(
842 kSetting,
843 ContentSettingToString(FlashPermissionToContentSetting(iter->second)));
844 exception->SetString(kSource, "preference");
845 exceptions.Append(exception);
846 }
847
848 StringValue type_string(ExContentSettingsTypeToGroupName(
849 ExContentSettingsType(EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC)));
850 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
851 type_string, exceptions);
852
853 UpdateSettingDefaultFromModel(
854 ExContentSettingsType(EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC));
855 }
856
857 void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap(
858 ContentSettingsType type) {
859 ContentSettingsForOneType entries;
860 GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries);
861
862 ListValue exceptions;
863 for (size_t i = 0; i < entries.size(); ++i) {
864 // Skip default settings from extensions and policy, and the default content
865 // settings; all of them will affect the default setting UI.
866 if (entries[i].primary_pattern == ContentSettingsPattern::Wildcard() &&
867 entries[i].secondary_pattern == ContentSettingsPattern::Wildcard() &&
868 entries[i].source != "preference") {
869 continue;
870 }
871 // The content settings UI does not support secondary content settings
872 // pattern yet. For content settings set through the content settings UI the
873 // secondary pattern is by default a wildcard pattern. Hence users are not
874 // able to modify content settings with a secondary pattern other than the
875 // wildcard pattern. So only show settings that the user is able to modify.
876 // TODO(bauerb): Support a read-only view for those patterns.
877 if (entries[i].secondary_pattern == ContentSettingsPattern::Wildcard()) {
878 // Media Stream is using compound values for exceptions, which are
879 // granted as |CONTENT_SETTING_ALLOW|.
880 ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
881 if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM)
882 content_setting = CONTENT_SETTING_ALLOW;
883 else
884 content_setting = entries[i].setting;
885
886 exceptions.Append(GetExceptionForPage(entries[i].primary_pattern,
887 content_setting,
888 entries[i].source));
889 } else {
890 LOG(ERROR) << "Secondary content settings patterns are not "
891 << "supported by the content settings UI";
892 }
893 }
894
895 StringValue type_string(ContentSettingsTypeToGroupName(type));
896 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions", type_string,
897 exceptions);
898
899 UpdateExceptionsViewFromOTRHostContentSettingsMap(type);
900
901 // TODO(koz): The default for fullscreen is always 'ask'.
902 // http://crbug.com/104683
903 if (type == CONTENT_SETTINGS_TYPE_FULLSCREEN)
904 return;
905
906 // The default may also have changed (we won't get a separate notification).
907 // If it hasn't changed, this call will be harmless.
908 UpdateSettingDefaultFromModel(ExContentSettingsType(type));
909 }
910
911 void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
912 ContentSettingsType type) {
913 const HostContentSettingsMap* otr_settings_map = GetOTRContentSettingsMap();
914 if (!otr_settings_map)
915 return;
916
917 ContentSettingsForOneType otr_entries;
918 otr_settings_map->GetSettingsForOneType(type, "", &otr_entries);
919
920 ListValue otr_exceptions;
921 for (size_t i = 0; i < otr_entries.size(); ++i) {
922 // Off-the-record HostContentSettingsMap contains incognito content settings
923 // as well as normal content settings. Here, we use the incongnito settings
924 // only.
925 if (!otr_entries[i].incognito)
926 continue;
927 // The content settings UI does not support secondary content settings
928 // pattern yet. For content settings set through the content settings UI the
929 // secondary pattern is by default a wildcard pattern. Hence users are not
930 // able to modify content settings with a secondary pattern other than the
931 // wildcard pattern. So only show settings that the user is able to modify.
932 // TODO(bauerb): Support a read-only view for those patterns.
933 if (otr_entries[i].secondary_pattern ==
934 ContentSettingsPattern::Wildcard()) {
935 ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
936 // Media Stream is using compound values for its exceptions and arbitrary
937 // values for its default setting. And all the exceptions are granted as
938 // |CONTENT_SETTING_ALLOW|.
939 if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
940 otr_entries[i].primary_pattern != ContentSettingsPattern::Wildcard())
941 content_setting = CONTENT_SETTING_ALLOW;
942 else
943 content_setting = otr_entries[i].setting;
944
945 otr_exceptions.Append(GetExceptionForPage(otr_entries[i].primary_pattern,
946 content_setting,
947 otr_entries[i].source));
948 } else {
949 LOG(ERROR) << "Secondary content settings patterns are not "
950 << "supported by the content settings UI";
951 }
952 }
953
954 StringValue type_string(ContentSettingsTypeToGroupName(type));
955 web_ui()->CallJavascriptFunction("ContentSettings.setOTRExceptions",
956 type_string, otr_exceptions);
957 }
958
959 void ContentSettingsHandler::RemoveGeolocationException(
960 const ListValue* args, size_t arg_index) {
961 Profile* profile = Profile::FromWebUI(web_ui());
962 std::string origin;
963 std::string embedding_origin;
964 bool rv = args->GetString(arg_index++, &origin);
965 DCHECK(rv);
966 rv = args->GetString(arg_index++, &embedding_origin);
967 DCHECK(rv);
968
969 profile->GetHostContentSettingsMap()->
970 SetContentSetting(ContentSettingsPattern::FromString(origin),
971 ContentSettingsPattern::FromString(embedding_origin),
972 CONTENT_SETTINGS_TYPE_GEOLOCATION,
973 std::string(),
974 CONTENT_SETTING_DEFAULT);
975 }
976
977 void ContentSettingsHandler::RemoveNotificationException(
978 const ListValue* args, size_t arg_index) {
979 Profile* profile = Profile::FromWebUI(web_ui());
980 std::string origin;
981 std::string setting;
982 bool rv = args->GetString(arg_index++, &origin);
983 DCHECK(rv);
984 rv = args->GetString(arg_index++, &setting);
985 DCHECK(rv);
986 ContentSetting content_setting = ContentSettingFromString(setting);
987
988 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
989 content_setting == CONTENT_SETTING_BLOCK);
990 DesktopNotificationServiceFactory::GetForProfile(profile)->
991 ClearSetting(ContentSettingsPattern::FromString(origin));
992 }
993
994 void ContentSettingsHandler::RemoveFlashCameraMicException(
995 const ListValue* args, size_t arg_index) {
996 std::string mode;
997 bool rv = args->GetString(arg_index++, &mode);
998 DCHECK(rv);
999 DCHECK_EQ(mode, "normal");
1000
1001 std::string pattern;
1002 rv = args->GetString(arg_index++, &pattern);
1003 DCHECK(rv);
1004
1005 CachedPepperFlashSettings::SiteMap::iterator iter =
1006 flash_cameramic_settings_.sites.find(pattern);
1007 if (iter != flash_cameramic_settings_.sites.end()) {
1008 flash_cameramic_settings_.sites.erase(iter);
1009 ppapi::FlashSiteSettings site_settings(
1010 1,
1011 ppapi::FlashSiteSetting(pattern,
1012 PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT));
1013 flash_settings_manager_->SetSitePermission(
1014 PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC,
1015 site_settings);
1016 } else {
1017 NOTREACHED();
1018 }
1019
1020 UpdateFlashCameraMicExceptionsView();
1021 }
1022
1023 void ContentSettingsHandler::RemoveExceptionFromHostContentSettingsMap(
1024 const ListValue* args, size_t arg_index,
1025 const ExContentSettingsType& type) {
1026 std::string mode;
1027 bool rv = args->GetString(arg_index++, &mode);
1028 DCHECK(rv);
1029
1030 std::string pattern;
1031 rv = args->GetString(arg_index++, &pattern);
1032 DCHECK(rv);
1033
1034 HostContentSettingsMap* settings_map =
1035 mode == "normal" ? GetContentSettingsMap() :
1036 GetOTRContentSettingsMap();
1037 if (settings_map) {
1038 settings_map->SetWebsiteSetting(
1039 ContentSettingsPattern::FromString(pattern),
1040 ContentSettingsPattern::Wildcard(),
1041 type.ToContentSettingsType(),
1042 "",
1043 NULL);
1044 }
1045 }
1046
1047 void ContentSettingsHandler::RegisterMessages() {
1048 web_ui()->RegisterMessageCallback("setContentFilter",
1049 base::Bind(&ContentSettingsHandler::SetContentFilter,
1050 base::Unretained(this)));
1051 web_ui()->RegisterMessageCallback("removeException",
1052 base::Bind(&ContentSettingsHandler::RemoveException,
1053 base::Unretained(this)));
1054 web_ui()->RegisterMessageCallback("setException",
1055 base::Bind(&ContentSettingsHandler::SetException,
1056 base::Unretained(this)));
1057 web_ui()->RegisterMessageCallback("checkExceptionPatternValidity",
1058 base::Bind(&ContentSettingsHandler::CheckExceptionPatternValidity,
1059 base::Unretained(this)));
1060 }
1061
1062 void ContentSettingsHandler::ApplyWhitelist(ContentSettingsType content_type,
1063 ContentSetting default_setting) {
1064 Profile* profile = Profile::FromWebUI(web_ui());
1065 HostContentSettingsMap* map = GetContentSettingsMap();
1066 if (content_type != CONTENT_SETTINGS_TYPE_PLUGINS)
1067 return;
1068 const int kDefaultWhitelistVersion = 1;
1069 PrefService* prefs = profile->GetPrefs();
1070 int version = prefs->GetInteger(
1071 prefs::kContentSettingsDefaultWhitelistVersion);
1072 if (version >= kDefaultWhitelistVersion)
1073 return;
1074 ContentSetting old_setting =
1075 map->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS, NULL);
1076 // TODO(bauerb): Remove this once the Google Talk plug-in works nicely with
1077 // click-to-play (b/6090625).
1078 if (old_setting == CONTENT_SETTING_ALLOW &&
1079 default_setting == CONTENT_SETTING_ASK) {
1080 map->SetWebsiteSetting(
1081 ContentSettingsPattern::Wildcard(),
1082 ContentSettingsPattern::Wildcard(),
1083 CONTENT_SETTINGS_TYPE_PLUGINS,
1084 "google-talk",
1085 Value::CreateIntegerValue(CONTENT_SETTING_ALLOW));
1086 }
1087 prefs->SetInteger(prefs::kContentSettingsDefaultWhitelistVersion,
1088 kDefaultWhitelistVersion);
1089 }
1090
1091 void ContentSettingsHandler::SetContentFilter(const ListValue* args) {
1092 DCHECK_EQ(2U, args->GetSize());
1093 std::string group, setting;
1094 if (!(args->GetString(0, &group) &&
1095 args->GetString(1, &setting))) {
1096 NOTREACHED();
1097 return;
1098 }
1099
1100 ContentSetting default_setting = ContentSettingFromString(setting);
1101 ExContentSettingsType content_type =
1102 ExContentSettingsTypeFromGroupName(group);
1103 Profile* profile = Profile::FromWebUI(web_ui());
1104
1105 #if defined(OS_CHROMEOS)
1106 // ChromeOS special case : in Guest mode settings are opened in Incognito
1107 // mode, so we need original profile to actually modify settings.
1108 if (chromeos::UserManager::Get()->IsLoggedInAsGuest())
1109 profile = profile->GetOriginalProfile();
1110 #endif
1111
1112 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
1113 DesktopNotificationServiceFactory::GetForProfile(profile)->
1114 SetDefaultContentSetting(default_setting);
1115 } else if (content_type == EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC) {
1116 flash_cameramic_settings_.default_permission =
1117 FlashPermissionFromContentSetting(default_setting);
1118 flash_settings_manager_->SetDefaultPermission(
1119 PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC,
1120 flash_cameramic_settings_.default_permission, false);
1121 RefreshFlashSettingsCache(true);
1122 } else {
1123 HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
1124 ContentSettingsType converted_type = content_type.ToContentSettingsType();
1125 ApplyWhitelist(converted_type, default_setting);
1126 map->SetDefaultContentSetting(converted_type, default_setting);
1127 }
1128 switch (content_type) {
1129 case CONTENT_SETTINGS_TYPE_COOKIES:
1130 content::RecordAction(
1131 UserMetricsAction("Options_DefaultCookieSettingChanged"));
1132 break;
1133 case CONTENT_SETTINGS_TYPE_IMAGES:
1134 content::RecordAction(
1135 UserMetricsAction("Options_DefaultImagesSettingChanged"));
1136 break;
1137 case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
1138 content::RecordAction(
1139 UserMetricsAction("Options_DefaultJavaScriptSettingChanged"));
1140 break;
1141 case CONTENT_SETTINGS_TYPE_PLUGINS:
1142 content::RecordAction(
1143 UserMetricsAction("Options_DefaultPluginsSettingChanged"));
1144 break;
1145 case CONTENT_SETTINGS_TYPE_POPUPS:
1146 content::RecordAction(
1147 UserMetricsAction("Options_DefaultPopupsSettingChanged"));
1148 break;
1149 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
1150 content::RecordAction(
1151 UserMetricsAction("Options_DefaultNotificationsSettingChanged"));
1152 break;
1153 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
1154 content::RecordAction(
1155 UserMetricsAction("Options_DefaultGeolocationSettingChanged"));
1156 break;
1157 case CONTENT_SETTINGS_TYPE_INTENTS:
1158 content::RecordAction(
1159 UserMetricsAction("Options_DefaultHandlersSettingChanged"));
1160 break;
1161 case CONTENT_SETTINGS_TYPE_MOUSELOCK:
1162 content::RecordAction(
1163 UserMetricsAction("Options_DefaultMouseLockSettingChanged"));
1164 break;
1165 case EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC:
1166 content::RecordAction(
1167 UserMetricsAction("Options_DefaultFlashCameraMicSettingChanged"));
1168 break;
1169 case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
1170 content::RecordAction(
1171 UserMetricsAction("Options_DefaultMediaStreamSettingChanged"));
1172 break;
1173 default:
1174 break;
1175 }
1176 }
1177
1178 void ContentSettingsHandler::RemoveException(const ListValue* args) {
1179 size_t arg_i = 0;
1180 std::string type_string;
1181 CHECK(args->GetString(arg_i++, &type_string));
1182
1183 ExContentSettingsType type = ExContentSettingsTypeFromGroupName(type_string);
1184 switch (type) {
1185 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
1186 RemoveGeolocationException(args, arg_i);
1187 break;
1188 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
1189 RemoveNotificationException(args, arg_i);
1190 break;
1191 case EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC:
1192 RemoveFlashCameraMicException(args, arg_i);
1193 break;
1194 default:
1195 RemoveExceptionFromHostContentSettingsMap(args, arg_i, type);
1196 break;
1197 }
1198 }
1199
1200 void ContentSettingsHandler::SetException(const ListValue* args) {
1201 size_t arg_i = 0;
1202 std::string type_string;
1203 CHECK(args->GetString(arg_i++, &type_string));
1204 std::string mode;
1205 CHECK(args->GetString(arg_i++, &mode));
1206 std::string pattern;
1207 CHECK(args->GetString(arg_i++, &pattern));
1208 std::string setting;
1209 CHECK(args->GetString(arg_i++, &setting));
1210
1211 ExContentSettingsType type = ExContentSettingsTypeFromGroupName(type_string);
1212 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
1213 type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
1214 type == CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
1215 NOTREACHED();
1216 } else if (type == EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC) {
1217 DCHECK(IsValidHost(pattern));
1218
1219 if (flash_cameramic_settings_.sites.find(pattern) ==
1220 flash_cameramic_settings_.sites.end()) {
1221 pattern = CanonicalizeHost(pattern);
1222 }
1223 PP_Flash_BrowserOperations_Permission permission =
1224 FlashPermissionFromContentSetting(ContentSettingFromString(setting));
1225 flash_cameramic_settings_.sites[pattern] = permission;
1226 ppapi::FlashSiteSettings
1227 site_settings(1, ppapi::FlashSiteSetting(pattern, permission));
1228 flash_settings_manager_->SetSitePermission(
1229 PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC,
1230 site_settings);
1231 UpdateFlashCameraMicExceptionsView();
1232 } else {
1233 HostContentSettingsMap* settings_map =
1234 mode == "normal" ? GetContentSettingsMap() :
1235 GetOTRContentSettingsMap();
1236
1237 // The settings map could be null if the mode was OTR but the OTR profile
1238 // got destroyed before we received this message.
1239 if (!settings_map)
1240 return;
1241 settings_map->SetContentSetting(ContentSettingsPattern::FromString(pattern),
1242 ContentSettingsPattern::Wildcard(),
1243 type.ToContentSettingsType(),
1244 "",
1245 ContentSettingFromString(setting));
1246 }
1247 }
1248
1249 void ContentSettingsHandler::CheckExceptionPatternValidity(
1250 const ListValue* args) {
1251 size_t arg_i = 0;
1252 std::string type_string;
1253 CHECK(args->GetString(arg_i++, &type_string));
1254 std::string mode_string;
1255 CHECK(args->GetString(arg_i++, &mode_string));
1256 std::string pattern_string;
1257 CHECK(args->GetString(arg_i++, &pattern_string));
1258
1259 ExContentSettingsType type = ExContentSettingsTypeFromGroupName(type_string);
1260 bool is_valid = false;
1261 if (type == EX_CONTENT_SETTINGS_TYPE_PEPPER_FLASH_CAMERAMIC) {
1262 is_valid = IsValidHost(pattern_string);
1263 } else {
1264 ContentSettingsPattern pattern =
1265 ContentSettingsPattern::FromString(pattern_string);
1266 is_valid = pattern.IsValid();
1267 }
1268
1269 scoped_ptr<Value> type_value(Value::CreateStringValue(type_string));
1270 scoped_ptr<Value> mode_value(Value::CreateStringValue(mode_string));
1271 scoped_ptr<Value> pattern_value(Value::CreateStringValue(pattern_string));
1272 scoped_ptr<Value> valid_value(Value::CreateBooleanValue(is_valid));
1273
1274 web_ui()->CallJavascriptFunction(
1275 "ContentSettings.patternValidityCheckComplete",
1276 *type_value.get(),
1277 *mode_value.get(),
1278 *pattern_value.get(),
1279 *valid_value.get());
1280 }
1281
1282 // static
1283 std::string ContentSettingsHandler::ContentSettingsTypeToGroupName(
1284 ContentSettingsType type) {
1285 return ExContentSettingsTypeToGroupName(ExContentSettingsType(type));
1286 }
1287
1288 HostContentSettingsMap* ContentSettingsHandler::GetContentSettingsMap() {
1289 return Profile::FromWebUI(web_ui())->GetHostContentSettingsMap();
1290 }
1291
1292 ProtocolHandlerRegistry* ContentSettingsHandler::GetProtocolHandlerRegistry() {
1293 return Profile::FromWebUI(web_ui())->GetProtocolHandlerRegistry();
1294 }
1295
1296 HostContentSettingsMap*
1297 ContentSettingsHandler::GetOTRContentSettingsMap() {
1298 Profile* profile = Profile::FromWebUI(web_ui());
1299 if (profile->HasOffTheRecordProfile())
1300 return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap();
1301 return NULL;
1302 }
1303
1304 void ContentSettingsHandler::RefreshFlashSettingsCache(bool force) {
1305 if (force || !flash_cameramic_settings_.initialized) {
1306 flash_cameramic_settings_.last_refresh_request_id =
1307 flash_settings_manager_->GetPermissionSettings(
1308 PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC);
1309 }
1310 }
1311
1312 // static
1313 ContentSettingsHandler::ExContentSettingsType
1314 ContentSettingsHandler::ExContentSettingsTypeFromGroupName(
1315 const std::string& name) {
1316 COMPILE_ASSERT(arraysize(kExContentSettingsTypeGroupNames) ==
1317 EX_CONTENT_SETTINGS_NUM_TYPES,
1318 MISSING_CONTENT_SETTINGS_TYPE);
1319
1320 for (size_t i = 0; i < arraysize(kExContentSettingsTypeGroupNames); ++i) {
1321 if (name == kExContentSettingsTypeGroupNames[i].name)
1322 return ExContentSettingsType(kExContentSettingsTypeGroupNames[i].type);
1323 }
1324
1325 NOTREACHED() << name << " is not a recognized content settings type.";
1326 return ExContentSettingsType(CONTENT_SETTINGS_TYPE_DEFAULT);
1327 }
1328
1329 // static
1330 std::string ContentSettingsHandler::ExContentSettingsTypeToGroupName(
1331 const ExContentSettingsType& type) {
1332 for (size_t i = 0; i < arraysize(kExContentSettingsTypeGroupNames); ++i) {
1333 if (type == kExContentSettingsTypeGroupNames[i].type)
1334 return kExContentSettingsTypeGroupNames[i].name;
1335 }
1336
1337 NOTREACHED();
1338 return std::string();
1339 }
1340
1341 } // namespace options
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698