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/ui/webui/options/content_settings_handler.h"
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/logging.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/values.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/content_settings/web_site_settings_uma_util.h"
22 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
23 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
24 #include "chrome/browser/extensions/extension_special_storage_policy.h"
25 #include "chrome/browser/notifications/desktop_notification_profile_util.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/ui/browser_list.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/grit/generated_resources.h"
33 #include "chrome/grit/locale_settings.h"
34 #include "components/content_settings/core/browser/content_settings_details.h"
35 #include "components/content_settings/core/browser/content_settings_utils.h"
36 #include "components/content_settings/core/browser/host_content_settings_map.h"
37 #include "components/content_settings/core/browser/plugins_field_trial.h"
38 #include "components/content_settings/core/browser/website_settings_info.h"
39 #include "components/content_settings/core/browser/website_settings_registry.h"
40 #include "components/content_settings/core/common/content_settings.h"
41 #include "components/content_settings/core/common/content_settings_pattern.h"
42 #include "components/google/core/browser/google_util.h"
43 #include "components/signin/core/common/profile_management_switches.h"
44 #include "components/user_prefs/user_prefs.h"
45 #include "content/public/browser/notification_service.h"
46 #include "content/public/browser/notification_source.h"
47 #include "content/public/browser/notification_types.h"
48 #include "content/public/browser/storage_partition.h"
49 #include "content/public/browser/user_metrics.h"
50 #include "content/public/browser/web_contents.h"
51 #include "content/public/browser/web_ui.h"
52 #include "content/public/common/content_switches.h"
53 #include "content/public/common/page_zoom.h"
54 #include "content/public/common/url_constants.h"
55 #include "extensions/browser/extension_registry.h"
56 #include "extensions/common/extension_set.h"
57 #include "extensions/common/permissions/api_permission.h"
58 #include "extensions/common/permissions/permissions_data.h"
59 #include "ui/base/l10n/l10n_util.h"
61 #if defined(OS_CHROMEOS)
62 #include "components/user_manager/user_manager.h"
65 using base::UserMetricsAction
;
66 using content_settings::ContentSettingToString
;
67 using content_settings::ContentSettingFromString
;
68 using extensions::APIPermission
;
72 struct ContentSettingsTypeNameEntry
{
73 ContentSettingsType type
;
77 // Maps from a secondary pattern to a setting.
78 typedef std::map
<ContentSettingsPattern
, ContentSetting
>
80 // Maps from a primary pattern/source pair to a OnePatternSettings. All the
81 // mappings in OnePatternSettings share the given primary pattern and source.
82 typedef std::map
<std::pair
<ContentSettingsPattern
, std::string
>,
86 // The AppFilter is used in AddExceptionsGrantedByHostedApps() to choose
87 // extensions which should have their extent displayed.
88 typedef bool (*AppFilter
)(const extensions::Extension
& app
,
89 content::BrowserContext
* profile
);
91 const char kExceptionsLearnMoreUrl
[] =
92 "https://support.google.com/chrome/?p=settings_manage_exceptions";
94 const char kSetting
[] = "setting";
95 const char kOrigin
[] = "origin";
96 const char kPolicyProviderId
[] = "policy";
97 const char kSource
[] = "source";
98 const char kAppName
[] = "appName";
99 const char kAppId
[] = "appId";
100 const char kEmbeddingOrigin
[] = "embeddingOrigin";
101 const char kPreferencesSource
[] = "preference";
102 const char kZoom
[] = "zoom";
104 const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames
[] = {
105 {CONTENT_SETTINGS_TYPE_COOKIES
, "cookies"},
106 {CONTENT_SETTINGS_TYPE_IMAGES
, "images"},
107 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, "javascript"},
108 {CONTENT_SETTINGS_TYPE_PLUGINS
, "plugins"},
109 {CONTENT_SETTINGS_TYPE_POPUPS
, "popups"},
110 {CONTENT_SETTINGS_TYPE_GEOLOCATION
, "location"},
111 {CONTENT_SETTINGS_TYPE_NOTIFICATIONS
, "notifications"},
112 {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
, "auto-select-certificate"},
113 {CONTENT_SETTINGS_TYPE_FULLSCREEN
, "fullscreen"},
114 {CONTENT_SETTINGS_TYPE_MOUSELOCK
, "mouselock"},
115 {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
, "register-protocol-handler"},
116 {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
, "media-stream-mic"},
117 {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
, "media-stream-camera"},
118 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, "ppapi-broker"},
119 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, "multiple-automatic-downloads"},
120 {CONTENT_SETTINGS_TYPE_MIDI_SYSEX
, "midi-sysex"},
121 {CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
, "push-messaging"},
122 {CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS
, "ssl-cert-decisions"},
123 #if defined(OS_CHROMEOS)
124 {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
, "protectedContent"},
128 // A pseudo content type. We use it to display data like a content setting even
129 // though it is not a real content setting.
130 const char kZoomContentType
[] = "zoomlevels";
132 content::BrowserContext
* GetBrowserContext(content::WebUI
* web_ui
) {
133 return web_ui
->GetWebContents()->GetBrowserContext();
136 ContentSettingsType
ContentSettingsTypeFromGroupName(const std::string
& name
) {
137 for (size_t i
= 0; i
< arraysize(kContentSettingsTypeGroupNames
); ++i
) {
138 if (name
== kContentSettingsTypeGroupNames
[i
].name
)
139 return kContentSettingsTypeGroupNames
[i
].type
;
142 NOTREACHED() << name
<< " is not a recognized content settings type.";
143 return CONTENT_SETTINGS_TYPE_DEFAULT
;
146 // Create a DictionaryValue* that will act as a data source for a single row
147 // in a HostContentSettingsMap-controlled exceptions table (e.g., cookies).
148 scoped_ptr
<base::DictionaryValue
> GetExceptionForPage(
149 const ContentSettingsPattern
& pattern
,
150 const ContentSettingsPattern
& secondary_pattern
,
151 const ContentSetting
& setting
,
152 const std::string
& provider_name
) {
153 base::DictionaryValue
* exception
= new base::DictionaryValue();
154 exception
->SetString(kOrigin
, pattern
.ToString());
155 exception
->SetString(kEmbeddingOrigin
,
156 secondary_pattern
== ContentSettingsPattern::Wildcard() ?
158 secondary_pattern
.ToString());
159 exception
->SetString(kSetting
, ContentSettingToString(setting
));
160 exception
->SetString(kSource
, provider_name
);
161 return make_scoped_ptr(exception
);
164 // Create a DictionaryValue* that will act as a data source for a single row
165 // in the Geolocation exceptions table.
166 scoped_ptr
<base::DictionaryValue
> GetGeolocationExceptionForPage(
167 const ContentSettingsPattern
& origin
,
168 const ContentSettingsPattern
& embedding_origin
,
169 ContentSetting setting
) {
170 base::DictionaryValue
* exception
= new base::DictionaryValue();
171 exception
->SetString(kSetting
, ContentSettingToString(setting
));
172 exception
->SetString(kOrigin
, origin
.ToString());
173 exception
->SetString(kEmbeddingOrigin
, embedding_origin
.ToString());
174 return make_scoped_ptr(exception
);
177 // Create a DictionaryValue* that will act as a data source for a single row
178 // in the desktop notifications exceptions table.
179 scoped_ptr
<base::DictionaryValue
> GetNotificationExceptionForPage(
180 const ContentSettingsPattern
& primary_pattern
,
181 const ContentSettingsPattern
& secondary_pattern
,
182 ContentSetting setting
,
183 const std::string
& provider_name
) {
184 std::string embedding_origin
;
185 if (secondary_pattern
!= ContentSettingsPattern::Wildcard())
186 embedding_origin
= secondary_pattern
.ToString();
188 base::DictionaryValue
* exception
= new base::DictionaryValue();
189 exception
->SetString(kSetting
, ContentSettingToString(setting
));
190 exception
->SetString(kOrigin
, primary_pattern
.ToString());
191 exception
->SetString(kEmbeddingOrigin
, embedding_origin
);
192 exception
->SetString(kSource
, provider_name
);
193 return make_scoped_ptr(exception
);
196 // Returns true whenever the |extension| is hosted and has |permission|.
197 // Must have the AppFilter signature.
198 template <APIPermission::ID permission
>
199 bool HostedAppHasPermission(const extensions::Extension
& extension
,
200 content::BrowserContext
* /* context */) {
201 return extension
.is_hosted_app() &&
202 extension
.permissions_data()->HasAPIPermission(permission
);
205 // Add an "Allow"-entry to the list of |exceptions| for a |url_pattern| from
206 // the web extent of a hosted |app|.
207 void AddExceptionForHostedApp(const std::string
& url_pattern
,
208 const extensions::Extension
& app
, base::ListValue
* exceptions
) {
209 base::DictionaryValue
* exception
= new base::DictionaryValue();
210 exception
->SetString(kSetting
, ContentSettingToString(CONTENT_SETTING_ALLOW
));
211 exception
->SetString(kOrigin
, url_pattern
);
212 exception
->SetString(kEmbeddingOrigin
, url_pattern
);
213 exception
->SetString(kSource
, "HostedApp");
214 exception
->SetString(kAppName
, app
.name());
215 exception
->SetString(kAppId
, app
.id());
216 exceptions
->Append(exception
);
219 // Asks the |profile| for hosted apps which have the |permission| set, and
220 // adds their web extent and launch URL to the |exceptions| list.
221 void AddExceptionsGrantedByHostedApps(content::BrowserContext
* context
,
222 AppFilter app_filter
,
223 base::ListValue
* exceptions
) {
224 const extensions::ExtensionSet
& extensions
=
225 extensions::ExtensionRegistry::Get(context
)->enabled_extensions();
226 for (extensions::ExtensionSet::const_iterator extension
= extensions
.begin();
227 extension
!= extensions
.end(); ++extension
) {
228 if (!app_filter(*extension
->get(), context
))
231 extensions::URLPatternSet web_extent
= (*extension
)->web_extent();
232 // Add patterns from web extent.
233 for (extensions::URLPatternSet::const_iterator pattern
= web_extent
.begin();
234 pattern
!= web_extent
.end(); ++pattern
) {
235 std::string url_pattern
= pattern
->GetAsString();
236 AddExceptionForHostedApp(url_pattern
, *extension
->get(), exceptions
);
238 // Retrieve the launch URL.
240 extensions::AppLaunchInfo::GetLaunchWebURL(extension
->get());
241 // Skip adding the launch URL if it is part of the web extent.
242 if (web_extent
.MatchesURL(launch_url
))
244 AddExceptionForHostedApp(launch_url
.spec(), *extension
->get(), exceptions
);
252 ContentSettingsHandler::MediaSettingsInfo::MediaSettingsInfo() {
255 ContentSettingsHandler::MediaSettingsInfo::~MediaSettingsInfo() {
258 ContentSettingsHandler::MediaSettingsInfo::ForFlash::ForFlash()
259 : default_setting(CONTENT_SETTING_DEFAULT
),
261 last_refresh_request_id(0) {
264 ContentSettingsHandler::MediaSettingsInfo::ForFlash::~ForFlash() {
267 ContentSettingsHandler::MediaSettingsInfo::ForFlash
&
268 ContentSettingsHandler::MediaSettingsInfo::forFlash() {
269 return flash_settings_
;
272 ContentSettingsHandler::MediaSettingsInfo::ForOneType
&
273 ContentSettingsHandler::MediaSettingsInfo::forType(
274 ContentSettingsType type
) {
275 if (type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)
276 return mic_settings_
;
277 else if (type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)
278 return camera_settings_
;
281 return mic_settings_
;
284 ContentSettingsHandler::MediaSettingsInfo::ForOneType::ForOneType()
285 : show_flash_default_link(false),
286 show_flash_exceptions_link(false),
287 default_setting(CONTENT_SETTING_DEFAULT
),
288 policy_disable(false),
289 default_setting_initialized(false),
290 exceptions_initialized(false) {
293 ContentSettingsHandler::MediaSettingsInfo::ForOneType::~ForOneType() {
296 ContentSettingsHandler::ContentSettingsHandler() : observer_(this) {
299 ContentSettingsHandler::~ContentSettingsHandler() {
302 void ContentSettingsHandler::GetLocalizedValues(
303 base::DictionaryValue
* localized_strings
) {
304 DCHECK(localized_strings
);
306 static OptionsStringResource resources
[] = {
307 {"allowException", IDS_EXCEPTIONS_ALLOW_BUTTON
},
308 {"blockException", IDS_EXCEPTIONS_BLOCK_BUTTON
},
309 {"sessionException", IDS_EXCEPTIONS_SESSION_ONLY_BUTTON
},
310 {"detectException", IDS_EXCEPTIONS_DETECT_IMPORTANT_CONTENT_BUTTON
},
311 {"askException", IDS_EXCEPTIONS_ASK_BUTTON
},
312 {"otrExceptionsExplanation", IDS_EXCEPTIONS_OTR_LABEL
},
313 {"addNewExceptionInstructions", IDS_EXCEPTIONS_ADD_NEW_INSTRUCTIONS
},
314 {"manageExceptions", IDS_EXCEPTIONS_MANAGE
},
315 {"manageHandlers", IDS_HANDLERS_MANAGE
},
316 {"exceptionPatternHeader", IDS_EXCEPTIONS_PATTERN_HEADER
},
317 {"exceptionBehaviorHeader", IDS_EXCEPTIONS_ACTION_HEADER
},
318 {"exceptionZoomHeader", IDS_EXCEPTIONS_ZOOM_HEADER
},
319 {"embeddedOnHost", IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST
},
321 {"cookiesTabLabel", IDS_COOKIES_TAB_LABEL
},
322 {"cookiesHeader", IDS_COOKIES_HEADER
},
323 {"cookiesAllow", IDS_COOKIES_ALLOW_RADIO
},
324 {"cookiesBlock", IDS_COOKIES_BLOCK_RADIO
},
325 {"cookiesSession", IDS_COOKIES_SESSION_ONLY_RADIO
},
326 {"cookiesBlock3rdParty", IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX
},
327 {"cookiesShowCookies", IDS_COOKIES_SHOW_COOKIES_BUTTON
},
328 {"flashStorageSettings", IDS_FLASH_STORAGE_SETTINGS
},
329 {"flashStorageUrl", IDS_FLASH_STORAGE_URL
},
330 #if defined(ENABLE_GOOGLE_NOW)
331 {"googleGeolocationAccessEnable",
332 IDS_GEOLOCATION_GOOGLE_ACCESS_ENABLE_CHKBOX
},
335 {"imagesTabLabel", IDS_IMAGES_TAB_LABEL
},
336 {"imagesHeader", IDS_IMAGES_HEADER
},
337 {"imagesAllow", IDS_IMAGES_LOAD_RADIO
},
338 {"imagesBlock", IDS_IMAGES_NOLOAD_RADIO
},
339 // JavaScript filter.
340 {"javascriptTabLabel", IDS_JAVASCRIPT_TAB_LABEL
},
341 {"javascriptHeader", IDS_JAVASCRIPT_HEADER
},
342 {"javascriptAllow", IDS_JS_ALLOW_RADIO
},
343 {"javascriptBlock", IDS_JS_DONOTALLOW_RADIO
},
345 {"pluginsTabLabel", IDS_PLUGIN_TAB_LABEL
},
346 {"pluginsHeader", IDS_PLUGIN_HEADER
},
347 {"pluginsAllow", IDS_PLUGIN_ALLOW_RADIO
},
348 {"pluginsBlock", IDS_PLUGIN_BLOCK_RADIO
},
349 {"manageIndividualPlugins", IDS_PLUGIN_MANAGE_INDIVIDUAL
},
351 {"popupsTabLabel", IDS_POPUP_TAB_LABEL
},
352 {"popupsHeader", IDS_POPUP_HEADER
},
353 {"popupsAllow", IDS_POPUP_ALLOW_RADIO
},
354 {"popupsBlock", IDS_POPUP_BLOCK_RADIO
},
356 {"locationTabLabel", IDS_GEOLOCATION_TAB_LABEL
},
357 {"locationHeader", IDS_GEOLOCATION_HEADER
},
358 {"locationAllow", IDS_GEOLOCATION_ALLOW_RADIO
},
359 {"locationAsk", IDS_GEOLOCATION_ASK_RADIO
},
360 {"locationBlock", IDS_GEOLOCATION_BLOCK_RADIO
},
361 {"setBy", IDS_GEOLOCATION_SET_BY_HOVER
},
362 // Notifications filter.
363 {"notificationsTabLabel", IDS_NOTIFICATIONS_TAB_LABEL
},
364 {"notificationsHeader", IDS_NOTIFICATIONS_HEADER
},
365 {"notificationsAllow", IDS_NOTIFICATIONS_ALLOW_RADIO
},
366 {"notificationsAsk", IDS_NOTIFICATIONS_ASK_RADIO
},
367 {"notificationsBlock", IDS_NOTIFICATIONS_BLOCK_RADIO
},
368 // Fullscreen filter.
369 {"fullscreenTabLabel", IDS_FULLSCREEN_TAB_LABEL
},
370 {"fullscreenHeader", IDS_FULLSCREEN_HEADER
},
371 // Mouse Lock filter.
372 {"mouselockTabLabel", IDS_MOUSE_LOCK_TAB_LABEL
},
373 {"mouselockHeader", IDS_MOUSE_LOCK_HEADER
},
374 {"mouselockAllow", IDS_MOUSE_LOCK_ALLOW_RADIO
},
375 {"mouselockAsk", IDS_MOUSE_LOCK_ASK_RADIO
},
376 {"mouselockBlock", IDS_MOUSE_LOCK_BLOCK_RADIO
},
377 #if defined(OS_CHROMEOS) || defined(OS_WIN)
378 // Protected Content filter
379 {"protectedContentTabLabel", IDS_PROTECTED_CONTENT_TAB_LABEL
},
380 {"protectedContentInfo", IDS_PROTECTED_CONTENT_INFO
},
381 {"protectedContentEnable", IDS_PROTECTED_CONTENT_ENABLE
},
382 {"protectedContentHeader", IDS_PROTECTED_CONTENT_HEADER
},
383 #endif // defined(OS_CHROMEOS) || defined(OS_WIN)
384 // Microphone filter.
385 {"mediaStreamMicTabLabel", IDS_MEDIA_STREAM_MIC_TAB_LABEL
},
386 {"mediaStreamMicHeader", IDS_MEDIA_STREAM_MIC_HEADER
},
387 {"mediaStreamMicAsk", IDS_MEDIA_STREAM_ASK_AUDIO_ONLY_RADIO
},
388 {"mediaStreamMicBlock", IDS_MEDIA_STREAM_BLOCK_AUDIO_ONLY_RADIO
},
390 {"mediaStreamCameraTabLabel", IDS_MEDIA_STREAM_CAMERA_TAB_LABEL
},
391 {"mediaStreamCameraHeader", IDS_MEDIA_STREAM_CAMERA_HEADER
},
392 {"mediaStreamCameraAsk", IDS_MEDIA_STREAM_ASK_VIDEO_ONLY_RADIO
},
393 {"mediaStreamCameraBlock", IDS_MEDIA_STREAM_BLOCK_VIDEO_ONLY_RADIO
},
394 // Flash media settings.
395 {"mediaPepperFlashMicDefaultDivergedLabel",
396 IDS_MEDIA_PEPPER_FLASH_MIC_DEFAULT_DIVERGED_LABEL
},
397 {"mediaPepperFlashCameraDefaultDivergedLabel",
398 IDS_MEDIA_PEPPER_FLASH_CAMERA_DEFAULT_DIVERGED_LABEL
},
399 {"mediaPepperFlashMicExceptionsDivergedLabel",
400 IDS_MEDIA_PEPPER_FLASH_MIC_EXCEPTIONS_DIVERGED_LABEL
},
401 {"mediaPepperFlashCameraExceptionsDivergedLabel",
402 IDS_MEDIA_PEPPER_FLASH_CAMERA_EXCEPTIONS_DIVERGED_LABEL
},
403 {"mediaPepperFlashChangeLink", IDS_MEDIA_PEPPER_FLASH_CHANGE_LINK
},
404 {"mediaPepperFlashGlobalPrivacyURL", IDS_FLASH_GLOBAL_PRIVACY_URL
},
405 {"mediaPepperFlashWebsitePrivacyURL", IDS_FLASH_WEBSITE_PRIVACY_URL
},
406 // PPAPI broker filter.
407 {"ppapiBrokerHeader", IDS_PPAPI_BROKER_HEADER
},
408 {"ppapiBrokerTabLabel", IDS_PPAPI_BROKER_TAB_LABEL
},
409 {"ppapiBrokerAllow", IDS_PPAPI_BROKER_ALLOW_RADIO
},
410 {"ppapiBrokerAsk", IDS_PPAPI_BROKER_ASK_RADIO
},
411 {"ppapiBrokerBlock", IDS_PPAPI_BROKER_BLOCK_RADIO
},
412 // Multiple automatic downloads
413 {"multipleAutomaticDownloadsTabLabel", IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL
},
414 {"multipleAutomaticDownloadsHeader", IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL
},
415 {"multipleAutomaticDownloadsAllow", IDS_AUTOMATIC_DOWNLOADS_ALLOW_RADIO
},
416 {"multipleAutomaticDownloadsAsk", IDS_AUTOMATIC_DOWNLOADS_ASK_RADIO
},
417 {"multipleAutomaticDownloadsBlock", IDS_AUTOMATIC_DOWNLOADS_BLOCK_RADIO
},
418 // MIDI system exclusive messages
419 {"midiSysexHeader", IDS_MIDI_SYSEX_TAB_LABEL
},
420 {"midiSysExAllow", IDS_MIDI_SYSEX_ALLOW_RADIO
},
421 {"midiSysExAsk", IDS_MIDI_SYSEX_ASK_RADIO
},
422 {"midiSysExBlock", IDS_MIDI_SYSEX_BLOCK_RADIO
},
423 // Push messaging strings
424 {"pushMessagingHeader", IDS_PUSH_MESSAGES_TAB_LABEL
},
425 {"pushMessagingAllow", IDS_PUSH_MESSSAGING_ALLOW_RADIO
},
426 {"pushMessagingAsk", IDS_PUSH_MESSSAGING_ASK_RADIO
},
427 {"pushMessagingBlock", IDS_PUSH_MESSSAGING_BLOCK_RADIO
},
428 {"zoomlevelsHeader", IDS_ZOOMLEVELS_HEADER_AND_TAB_LABEL
},
429 {"zoomLevelsManage", IDS_ZOOMLEVELS_MANAGE_BUTTON
},
432 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
434 PrefService
* prefs
= Profile::FromWebUI(web_ui())->GetPrefs();
435 const base::Value
* default_pref
= prefs
->GetDefaultPrefValue(
436 content_settings::WebsiteSettingsRegistry::GetInstance()
437 ->Get(CONTENT_SETTINGS_TYPE_PLUGINS
)
438 ->default_value_pref_name());
440 int default_value
= CONTENT_SETTING_DEFAULT
;
441 bool success
= default_pref
->GetAsInteger(&default_value
);
443 DCHECK_NE(default_value
, CONTENT_SETTING_DEFAULT
);
445 int plugin_ids
= default_value
== CONTENT_SETTING_DETECT_IMPORTANT_CONTENT
?
446 IDS_PLUGIN_DETECT_RECOMMENDED_RADIO
: IDS_PLUGIN_DETECT_RADIO
;
447 localized_strings
->SetString("pluginsDetect",
448 l10n_util::GetStringUTF16(plugin_ids
));
450 RegisterTitle(localized_strings
, "contentSettingsPage",
451 IDS_CONTENT_SETTINGS_TITLE
);
453 // Register titles for each of the individual settings whose exception
454 // dialogs will be processed by |ContentSettingsHandler|.
455 RegisterTitle(localized_strings
, "cookies",
456 IDS_COOKIES_TAB_LABEL
);
457 RegisterTitle(localized_strings
, "images",
458 IDS_IMAGES_TAB_LABEL
);
459 RegisterTitle(localized_strings
, "javascript",
460 IDS_JAVASCRIPT_TAB_LABEL
);
461 RegisterTitle(localized_strings
, "plugins",
462 IDS_PLUGIN_TAB_LABEL
);
463 RegisterTitle(localized_strings
, "popups",
464 IDS_POPUP_TAB_LABEL
);
465 RegisterTitle(localized_strings
, "location",
466 IDS_GEOLOCATION_TAB_LABEL
);
467 RegisterTitle(localized_strings
, "notifications",
468 IDS_NOTIFICATIONS_TAB_LABEL
);
469 RegisterTitle(localized_strings
, "fullscreen",
470 IDS_FULLSCREEN_TAB_LABEL
);
471 RegisterTitle(localized_strings
, "mouselock",
472 IDS_MOUSE_LOCK_TAB_LABEL
);
473 #if defined(OS_CHROMEOS)
474 RegisterTitle(localized_strings
, "protectedContent",
475 IDS_PROTECTED_CONTENT_TAB_LABEL
);
477 RegisterTitle(localized_strings
, "media-stream-mic",
478 IDS_MEDIA_STREAM_MIC_TAB_LABEL
);
479 RegisterTitle(localized_strings
, "media-stream-camera",
480 IDS_MEDIA_STREAM_CAMERA_TAB_LABEL
);
481 RegisterTitle(localized_strings
, "ppapi-broker",
482 IDS_PPAPI_BROKER_TAB_LABEL
);
483 RegisterTitle(localized_strings
, "multiple-automatic-downloads",
484 IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL
);
485 RegisterTitle(localized_strings
, "midi-sysex",
486 IDS_MIDI_SYSEX_TAB_LABEL
);
487 RegisterTitle(localized_strings
, "zoomlevels",
488 IDS_ZOOMLEVELS_HEADER_AND_TAB_LABEL
);
490 localized_strings
->SetString("exceptionsLearnMoreUrl",
491 kExceptionsLearnMoreUrl
);
494 void ContentSettingsHandler::InitializeHandler() {
495 notification_registrar_
.Add(
496 this, chrome::NOTIFICATION_PROFILE_CREATED
,
497 content::NotificationService::AllSources());
498 notification_registrar_
.Add(
499 this, chrome::NOTIFICATION_PROFILE_DESTROYED
,
500 content::NotificationService::AllSources());
502 content::BrowserContext
* context
= GetBrowserContext(web_ui());
503 notification_registrar_
.Add(
504 this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED
,
505 content::Source
<content::BrowserContext
>(context
));
507 PrefService
* prefs
= user_prefs::UserPrefs::Get(context
);
508 pref_change_registrar_
.Init(prefs
);
509 pref_change_registrar_
.Add(
510 prefs::kPepperFlashSettingsEnabled
,
511 base::Bind(&ContentSettingsHandler::OnPepperFlashPrefChanged
,
512 base::Unretained(this)));
513 pref_change_registrar_
.Add(
514 prefs::kAudioCaptureAllowed
,
515 base::Bind(&ContentSettingsHandler::UpdateSettingDefaultFromModel
,
516 base::Unretained(this),
517 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
));
518 pref_change_registrar_
.Add(
519 prefs::kAudioCaptureAllowedUrls
,
520 base::Bind(&ContentSettingsHandler::UpdateExceptionsViewFromModel
,
521 base::Unretained(this),
522 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
));
523 pref_change_registrar_
.Add(
524 prefs::kVideoCaptureAllowed
,
525 base::Bind(&ContentSettingsHandler::UpdateSettingDefaultFromModel
,
526 base::Unretained(this),
527 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
));
528 pref_change_registrar_
.Add(
529 prefs::kVideoCaptureAllowedUrls
,
530 base::Bind(&ContentSettingsHandler::UpdateExceptionsViewFromModel
,
531 base::Unretained(this),
532 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
));
533 pref_change_registrar_
.Add(
536 &ContentSettingsHandler::UpdateProtectedContentExceptionsButton
,
537 base::Unretained(this)));
539 // Here we only subscribe to the HostZoomMap for the default storage partition
540 // since we don't allow the user to manage the zoom levels for apps.
541 // We're only interested in zoom-levels that are persisted, since the user
542 // is given the opportunity to view/delete these in the content-settings page.
543 host_zoom_map_subscription_
=
544 content::HostZoomMap::GetDefaultForBrowserContext(context
)
545 ->AddZoomLevelChangedCallback(
546 base::Bind(&ContentSettingsHandler::OnZoomLevelChanged
,
547 base::Unretained(this)));
549 if (!switches::IsEnableWebviewBasedSignin()) {
550 // The legacy signin page uses a different storage partition, so we need to
551 // add a subscription for its HostZoomMap separately.
552 GURL
signin_url(chrome::kChromeUIChromeSigninURL
);
553 content::StoragePartition
* signin_partition
=
554 content::BrowserContext::GetStoragePartitionForSite(
555 GetBrowserContext(web_ui()), signin_url
);
556 content::HostZoomMap
* signin_host_zoom_map
=
557 signin_partition
->GetHostZoomMap();
558 signin_host_zoom_map_subscription_
=
559 signin_host_zoom_map
->AddZoomLevelChangedCallback(
560 base::Bind(&ContentSettingsHandler::OnZoomLevelChanged
,
561 base::Unretained(this)));
564 flash_settings_manager_
.reset(new PepperFlashSettingsManager(this, context
));
566 Profile
* profile
= Profile::FromWebUI(web_ui());
567 observer_
.Add(profile
->GetHostContentSettingsMap());
568 if (profile
->HasOffTheRecordProfile()) {
569 auto map
= profile
->GetOffTheRecordProfile()->GetHostContentSettingsMap();
570 if (!observer_
.IsObserving(map
))
575 void ContentSettingsHandler::InitializePage() {
576 media_settings_
.reset(new MediaSettingsInfo());
577 RefreshFlashMediaSettings();
579 UpdateHandlersEnabledRadios();
580 UpdateAllExceptionsViewsFromModel();
581 UpdateProtectedContentExceptionsButton();
584 void ContentSettingsHandler::OnContentSettingChanged(
585 const ContentSettingsPattern
& primary_pattern
,
586 const ContentSettingsPattern
& secondary_pattern
,
587 ContentSettingsType content_type
,
588 std::string resource_identifier
) {
589 const ContentSettingsDetails
details(
590 primary_pattern
, secondary_pattern
, content_type
, resource_identifier
);
591 // TODO(estade): we pretend update_all() is always true.
592 if (details
.update_all_types())
593 UpdateAllExceptionsViewsFromModel();
595 UpdateExceptionsViewFromModel(details
.type());
598 void ContentSettingsHandler::Observe(
600 const content::NotificationSource
& source
,
601 const content::NotificationDetails
& details
) {
603 case chrome::NOTIFICATION_PROFILE_DESTROYED
: {
604 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
605 if (profile
->IsOffTheRecord() &&
606 observer_
.IsObserving(profile
->GetHostContentSettingsMap())) {
607 web_ui()->CallJavascriptFunction(
608 "ContentSettingsExceptionsArea.OTRProfileDestroyed");
609 observer_
.Remove(profile
->GetHostContentSettingsMap());
614 case chrome::NOTIFICATION_PROFILE_CREATED
: {
615 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
616 if (profile
->IsOffTheRecord()) {
617 UpdateAllOTRExceptionsViewsFromModel();
618 observer_
.Add(profile
->GetHostContentSettingsMap());
623 case chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED
: {
624 UpdateHandlersEnabledRadios();
630 void ContentSettingsHandler::OnGetPermissionSettingsCompleted(
633 PP_Flash_BrowserOperations_Permission default_permission
,
634 const ppapi::FlashSiteSettings
& sites
) {
635 MediaSettingsInfo::ForFlash
& settings
= media_settings_
->forFlash();
636 if (success
&& request_id
== settings
.last_refresh_request_id
) {
637 settings
.initialized
= true;
638 settings
.default_setting
=
639 PepperFlashContentSettingsUtils::FlashPermissionToContentSetting(
641 PepperFlashContentSettingsUtils::FlashSiteSettingsToMediaExceptions(
642 sites
, &settings
.exceptions
);
643 PepperFlashContentSettingsUtils::SortMediaExceptions(
644 &settings
.exceptions
);
646 UpdateFlashMediaLinksVisibility(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
);
647 UpdateFlashMediaLinksVisibility(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
);
651 void ContentSettingsHandler::UpdateSettingDefaultFromModel(
652 ContentSettingsType type
) {
653 std::string provider_id
;
654 ContentSetting default_setting
=
655 GetContentSettingsMap()->GetDefaultContentSetting(type
, &provider_id
);
657 #if defined(ENABLE_PLUGINS)
659 content_settings::PluginsFieldTrial::EffectiveContentSetting(
660 type
, default_setting
);
663 // Camera and microphone default content settings cannot be set by the policy.
664 // However, the policy can disable them. Treat this case visually in the same
665 // way as if the policy set the default setting to BLOCK. Furthermore, compare
666 // the settings with Flash settings and show links to the Flash settings site
668 if (type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
669 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) {
670 UpdateMediaSettingsFromPrefs(type
);
671 if (media_settings_
->forType(type
).policy_disable
) {
672 default_setting
= CONTENT_SETTING_BLOCK
;
673 provider_id
= kPolicyProviderId
;
677 base::DictionaryValue filter_settings
;
678 filter_settings
.SetString(ContentSettingsTypeToGroupName(type
) + ".value",
679 ContentSettingToString(default_setting
));
680 filter_settings
.SetString(
681 ContentSettingsTypeToGroupName(type
) + ".managedBy", provider_id
);
683 web_ui()->CallJavascriptFunction(
684 "ContentSettings.setContentFilterSettingsValue", filter_settings
);
687 void ContentSettingsHandler::UpdateMediaSettingsFromPrefs(
688 ContentSettingsType type
) {
689 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetBrowserContext(web_ui()));
690 MediaSettingsInfo::ForOneType
& settings
= media_settings_
->forType(type
);
691 std::string policy_pref
= (type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)
692 ? prefs::kAudioCaptureAllowed
693 : prefs::kVideoCaptureAllowed
;
695 settings
.policy_disable
= !prefs
->GetBoolean(policy_pref
) &&
696 prefs
->IsManagedPreference(policy_pref
);
697 settings
.default_setting
=
698 GetContentSettingsMap()->GetDefaultContentSetting(type
, NULL
);
699 settings
.default_setting_initialized
= true;
701 UpdateFlashMediaLinksVisibility(type
);
702 UpdateMediaDeviceDropdownVisibility(type
);
705 void ContentSettingsHandler::UpdateHandlersEnabledRadios() {
706 base::FundamentalValue
handlers_enabled(
707 GetProtocolHandlerRegistry()->enabled());
709 web_ui()->CallJavascriptFunction(
710 "ContentSettings.updateHandlersEnabledRadios",
714 void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() {
715 for (int type
= CONTENT_SETTINGS_TYPE_DEFAULT
+ 1;
716 type
< CONTENT_SETTINGS_NUM_TYPES
; ++type
) {
717 UpdateExceptionsViewFromModel(static_cast<ContentSettingsType
>(type
));
719 // Zoom levels are not actually a content type so we need to handle them
721 UpdateZoomLevelsExceptionsView();
724 void ContentSettingsHandler::UpdateAllOTRExceptionsViewsFromModel() {
725 for (int type
= CONTENT_SETTINGS_TYPE_DEFAULT
+ 1;
726 type
< CONTENT_SETTINGS_NUM_TYPES
; ++type
) {
727 UpdateOTRExceptionsViewFromModel(static_cast<ContentSettingsType
>(type
));
731 void ContentSettingsHandler::UpdateExceptionsViewFromModel(
732 ContentSettingsType type
) {
734 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
735 UpdateGeolocationExceptionsView();
737 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
738 UpdateNotificationExceptionsView();
740 case CONTENT_SETTINGS_TYPE_MEDIASTREAM
:
741 // The content settings type CONTENT_SETTINGS_TYPE_MEDIASSTREAM
744 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
:
745 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
:
746 CompareMediaExceptionsWithFlash(type
);
747 UpdateExceptionsViewFromHostContentSettingsMap(type
);
749 case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
:
750 // We don't yet support exceptions for mixed scripting.
752 case CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
:
753 // The content settings type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
754 // is supposed to be set by policy only. Hence there is no user facing UI
755 // for this content type and we skip it here.
757 case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
:
758 // The RPH settings are retrieved separately.
760 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX
:
761 UpdateMIDISysExExceptionsView();
763 case CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS
:
764 // The content settings type CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS is
765 // supposed to be set by flags and field trials only, thus there is no
766 // user facing UI for this content type and we skip it here.
768 case CONTENT_SETTINGS_TYPE_APP_BANNER
:
769 // The content settings type CONTENT_SETTINGS_TYPE_APP_BANNER is used to
770 // track whether app banners should be shown or not, and is not a user
771 // visible content setting.
773 case CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT
:
774 // The content settings type CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT is used
775 // to track engagement with various origins, and is not a user visible
778 case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE
:
779 // Durable storage is not yet user visible. TODO(dgrogan): Make it so.
780 // https://crbug.com/482814
783 UpdateExceptionsViewFromHostContentSettingsMap(type
);
788 void ContentSettingsHandler::UpdateOTRExceptionsViewFromModel(
789 ContentSettingsType type
) {
791 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
792 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
793 case CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
:
794 case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
:
795 case CONTENT_SETTINGS_TYPE_MEDIASTREAM
:
796 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
:
797 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
:
798 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
:
799 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX
:
800 case CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS
:
801 case CONTENT_SETTINGS_TYPE_APP_BANNER
:
802 case CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT
:
803 case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE
:
806 UpdateExceptionsViewFromOTRHostContentSettingsMap(type
);
811 // TODO(estade): merge with GetExceptionsFromHostContentSettingsMap.
812 void ContentSettingsHandler::UpdateGeolocationExceptionsView() {
813 Profile
* profile
= Profile::FromWebUI(web_ui());
814 HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
816 ContentSettingsForOneType all_settings
;
817 map
->GetSettingsForOneType(
818 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
822 // Group geolocation settings by primary_pattern.
823 AllPatternsSettings all_patterns_settings
;
824 for (ContentSettingsForOneType::iterator i
= all_settings
.begin();
825 i
!= all_settings
.end(); ++i
) {
826 // Don't add default settings.
827 if (i
->primary_pattern
== ContentSettingsPattern::Wildcard() &&
828 i
->secondary_pattern
== ContentSettingsPattern::Wildcard() &&
829 i
->source
!= kPreferencesSource
) {
832 all_patterns_settings
[std::make_pair(i
->primary_pattern
, i
->source
)]
833 [i
->secondary_pattern
] = i
->setting
;
836 base::ListValue exceptions
;
837 AddExceptionsGrantedByHostedApps(
839 HostedAppHasPermission
<APIPermission::kGeolocation
>,
842 for (AllPatternsSettings::iterator i
= all_patterns_settings
.begin();
843 i
!= all_patterns_settings
.end(); ++i
) {
844 const ContentSettingsPattern
& primary_pattern
= i
->first
.first
;
845 const OnePatternSettings
& one_settings
= i
->second
;
847 OnePatternSettings::const_iterator parent
=
848 one_settings
.find(primary_pattern
);
850 // Add the "parent" entry for the non-embedded setting.
851 ContentSetting parent_setting
=
852 parent
== one_settings
.end() ? CONTENT_SETTING_DEFAULT
: parent
->second
;
853 exceptions
.Append(GetGeolocationExceptionForPage(primary_pattern
,
857 // Add the "children" for any embedded settings.
858 for (OnePatternSettings::const_iterator j
= one_settings
.begin();
859 j
!= one_settings
.end();
861 // Skip the non-embedded setting which we already added above.
865 exceptions
.Append(GetGeolocationExceptionForPage(
866 primary_pattern
, j
->first
, j
->second
));
870 base::StringValue
type_string(
871 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION
));
872 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
873 type_string
, exceptions
);
875 // This is mainly here to keep this function ideologically parallel to
876 // UpdateExceptionsViewFromHostContentSettingsMap().
877 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
880 void ContentSettingsHandler::UpdateNotificationExceptionsView() {
881 Profile
* profile
= Profile::FromWebUI(web_ui());
882 ContentSettingsForOneType settings
;
883 DesktopNotificationProfileUtil::GetNotificationsSettings(profile
, &settings
);
885 base::ListValue exceptions
;
886 AddExceptionsGrantedByHostedApps(
888 HostedAppHasPermission
<APIPermission::kNotifications
>,
891 for (ContentSettingsForOneType::const_iterator i
=
895 // Don't add default settings.
896 if (i
->primary_pattern
== ContentSettingsPattern::Wildcard() &&
897 i
->secondary_pattern
== ContentSettingsPattern::Wildcard() &&
898 i
->source
!= kPreferencesSource
) {
903 GetNotificationExceptionForPage(i
->primary_pattern
,
904 i
->secondary_pattern
,
909 base::StringValue
type_string(
910 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
));
911 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
912 type_string
, exceptions
);
914 // This is mainly here to keep this function ideologically parallel to
915 // UpdateExceptionsViewFromHostContentSettingsMap().
916 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
919 void ContentSettingsHandler::CompareMediaExceptionsWithFlash(
920 ContentSettingsType type
) {
921 MediaSettingsInfo::ForOneType
& settings
= media_settings_
->forType(type
);
923 base::ListValue exceptions
;
924 GetExceptionsFromHostContentSettingsMap(
925 GetContentSettingsMap(),
929 settings
.exceptions
.clear();
930 for (base::ListValue::const_iterator entry
= exceptions
.begin();
931 entry
!= exceptions
.end(); ++entry
) {
932 base::DictionaryValue
* dict
= nullptr;
933 bool valid_dict
= (*entry
)->GetAsDictionary(&dict
);
938 dict
->GetString(kOrigin
, &origin
);
939 dict
->GetString(kSetting
, &setting
);
941 settings
.exceptions
.push_back(MediaException(
942 ContentSettingsPattern::FromString(origin
),
943 ContentSettingFromString(setting
)));
946 PepperFlashContentSettingsUtils::SortMediaExceptions(
947 &settings
.exceptions
);
949 settings
.exceptions_initialized
= true;
950 UpdateFlashMediaLinksVisibility(type
);
953 void ContentSettingsHandler::UpdateMIDISysExExceptionsView() {
954 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
955 UpdateExceptionsViewFromHostContentSettingsMap(
956 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
959 void ContentSettingsHandler::AdjustZoomLevelsListForSigninPageIfNecessary(
960 content::HostZoomMap::ZoomLevelVector
* zoom_levels
) {
961 if (switches::IsEnableWebviewBasedSignin())
964 GURL
signin_url(chrome::kChromeUIChromeSigninURL
);
965 content::HostZoomMap
* signin_host_zoom_map
=
966 content::BrowserContext::GetStoragePartitionForSite(
967 GetBrowserContext(web_ui()), signin_url
)->GetHostZoomMap();
969 // Since zoom levels set for scheme + host are not persisted, and since the
970 // signin page zoom levels need to be persisted, they are stored without
971 // a scheme. We use an empty scheme string to indicate this.
973 std::string host
= signin_url
.host();
975 // If there's a WebView signin zoom level, remove it.
976 content::HostZoomMap::ZoomLevelVector::iterator it
=
977 std::find_if(zoom_levels
->begin(), zoom_levels
->end(),
978 [&host
](content::HostZoomMap::ZoomLevelChange change
) {
979 return change
.host
== host
;
981 if (it
!= zoom_levels
->end())
982 zoom_levels
->erase(it
);
984 // If there's a non-WebView signin zoom level, add it.
985 if (signin_host_zoom_map
->HasZoomLevel(scheme
, host
)) {
986 content::HostZoomMap::ZoomLevelChange change
= {
987 content::HostZoomMap::ZOOM_CHANGED_FOR_HOST
,
990 signin_host_zoom_map
->GetZoomLevelForHostAndScheme(scheme
, host
)};
991 zoom_levels
->push_back(change
);
995 void ContentSettingsHandler::UpdateZoomLevelsExceptionsView() {
996 base::ListValue zoom_levels_exceptions
;
998 content::HostZoomMap
* host_zoom_map
=
999 content::HostZoomMap::GetDefaultForBrowserContext(
1000 GetBrowserContext(web_ui()));
1001 content::HostZoomMap::ZoomLevelVector
zoom_levels(
1002 host_zoom_map
->GetAllZoomLevels());
1004 AdjustZoomLevelsListForSigninPageIfNecessary(&zoom_levels
);
1006 // Sort ZoomLevelChanges by host and scheme
1007 // (a.com < http://a.com < https://a.com < b.com).
1008 std::sort(zoom_levels
.begin(), zoom_levels
.end(),
1009 [](const content::HostZoomMap::ZoomLevelChange
& a
,
1010 const content::HostZoomMap::ZoomLevelChange
& b
) {
1011 return a
.host
== b
.host
? a
.scheme
< b
.scheme
: a
.host
< b
.host
;
1014 for (content::HostZoomMap::ZoomLevelVector::const_iterator i
=
1015 zoom_levels
.begin();
1016 i
!= zoom_levels
.end();
1018 scoped_ptr
<base::DictionaryValue
> exception(new base::DictionaryValue
);
1020 case content::HostZoomMap::ZOOM_CHANGED_FOR_HOST
: {
1021 exception
->SetString(kOrigin
, i
->host
);
1022 std::string host
= i
->host
;
1023 if (host
== content::kUnreachableWebDataURL
) {
1025 l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL
);
1027 exception
->SetString(kOrigin
, host
);
1030 case content::HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST
:
1031 // These are not stored in preferences and get cleared on next browser
1032 // start. Therefore, we don't care for them.
1034 case content::HostZoomMap::PAGE_SCALE_IS_ONE_CHANGED
:
1036 case content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM
:
1039 exception
->SetString(kSetting
,
1040 ContentSettingToString(CONTENT_SETTING_DEFAULT
));
1042 // Calculate the zoom percent from the factor. Round up to the nearest whole
1044 int zoom_percent
= static_cast<int>(
1045 content::ZoomLevelToZoomFactor(i
->zoom_level
) * 100 + 0.5);
1046 exception
->SetString(
1048 l10n_util::GetStringFUTF16(IDS_ZOOM_PERCENT
,
1049 base::IntToString16(zoom_percent
)));
1050 exception
->SetString(kSource
, kPreferencesSource
);
1051 // Append the new entry to the list and map.
1052 zoom_levels_exceptions
.Append(exception
.release());
1055 base::StringValue
type_string(kZoomContentType
);
1056 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
1057 type_string
, zoom_levels_exceptions
);
1060 void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap(
1061 ContentSettingsType type
) {
1062 base::ListValue exceptions
;
1063 GetExceptionsFromHostContentSettingsMap(
1064 GetContentSettingsMap(), type
, &exceptions
);
1065 base::StringValue
type_string(ContentSettingsTypeToGroupName(type
));
1066 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions", type_string
,
1069 UpdateExceptionsViewFromOTRHostContentSettingsMap(type
);
1071 // TODO(koz): The default for fullscreen is always 'ask'.
1072 // http://crbug.com/104683
1073 if (type
== CONTENT_SETTINGS_TYPE_FULLSCREEN
)
1076 #if defined(OS_CHROMEOS)
1077 // Also the default for protected contents is managed in another place.
1078 if (type
== CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
)
1082 // The default may also have changed (we won't get a separate notification).
1083 // If it hasn't changed, this call will be harmless.
1084 UpdateSettingDefaultFromModel(type
);
1087 void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
1088 ContentSettingsType type
) {
1089 const HostContentSettingsMap
* otr_settings_map
= GetOTRContentSettingsMap();
1090 if (!otr_settings_map
)
1092 base::ListValue exceptions
;
1093 GetExceptionsFromHostContentSettingsMap(otr_settings_map
, type
, &exceptions
);
1094 base::StringValue
type_string(ContentSettingsTypeToGroupName(type
));
1095 web_ui()->CallJavascriptFunction("ContentSettings.setOTRExceptions",
1096 type_string
, exceptions
);
1099 scoped_ptr
<base::ListValue
> ContentSettingsHandler::GetPolicyAllowedUrls(
1100 ContentSettingsType type
) {
1101 DCHECK(type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
1102 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
);
1104 PrefService
* prefs
= Profile::FromWebUI(web_ui())->GetPrefs();
1105 const base::ListValue
* policy_urls
= prefs
->GetList(
1106 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
1107 ? prefs::kAudioCaptureAllowedUrls
1108 : prefs::kVideoCaptureAllowedUrls
);
1110 // Convert the URLs to |ContentSettingsPattern|s. Ignore any invalid ones.
1111 std::vector
<ContentSettingsPattern
> patterns
;
1112 for (const base::Value
* entry
: *policy_urls
) {
1114 bool valid_string
= entry
->GetAsString(&url
);
1118 ContentSettingsPattern pattern
= ContentSettingsPattern::FromString(url
);
1119 if (!pattern
.IsValid())
1122 patterns
.push_back(pattern
);
1125 std::sort(patterns
.begin(), patterns
.end());
1127 scoped_ptr
<base::ListValue
> exceptions(new base::ListValue());
1128 for (const ContentSettingsPattern
& pattern
: patterns
) {
1129 exceptions
->Append(GetExceptionForPage(
1131 ContentSettingsPattern(),
1132 CONTENT_SETTING_ALLOW
,
1133 kPolicyProviderId
));
1136 return exceptions
.Pass();
1139 void ContentSettingsHandler::GetExceptionsFromHostContentSettingsMap(
1140 const HostContentSettingsMap
* map
,
1141 ContentSettingsType type
,
1142 base::ListValue
* exceptions
) {
1143 ContentSettingsForOneType entries
;
1144 map
->GetSettingsForOneType(type
, std::string(), &entries
);
1145 // Group settings by primary_pattern.
1146 AllPatternsSettings all_patterns_settings
;
1147 for (ContentSettingsForOneType::iterator i
= entries
.begin();
1148 i
!= entries
.end(); ++i
) {
1149 // Don't add default settings.
1150 if (i
->primary_pattern
== ContentSettingsPattern::Wildcard() &&
1151 i
->secondary_pattern
== ContentSettingsPattern::Wildcard() &&
1152 i
->source
!= kPreferencesSource
) {
1156 // Off-the-record HostContentSettingsMap contains incognito content settings
1157 // as well as normal content settings. Here, we use the incongnito settings
1159 if (map
->is_off_the_record() && !i
->incognito
)
1162 all_patterns_settings
[std::make_pair(i
->primary_pattern
, i
->source
)]
1163 [i
->secondary_pattern
] = i
->setting
;
1166 // Keep the exceptions sorted by provider so they will be displayed in
1167 // precedence order.
1168 ScopedVector
<base::ListValue
> all_provider_exceptions
;
1169 all_provider_exceptions
.resize(HostContentSettingsMap::NUM_PROVIDER_TYPES
);
1170 for (auto& one_provider_exceptions
: all_provider_exceptions
)
1171 one_provider_exceptions
= new base::ListValue();
1173 for (AllPatternsSettings::iterator i
= all_patterns_settings
.begin();
1174 i
!= all_patterns_settings
.end();
1176 const ContentSettingsPattern
& primary_pattern
= i
->first
.first
;
1177 const OnePatternSettings
& one_settings
= i
->second
;
1179 // The "parent" entry either has an identical primary and secondary pattern,
1180 // or has a wildcard secondary. The two cases are indistinguishable in the
1182 OnePatternSettings::const_iterator parent
=
1183 one_settings
.find(primary_pattern
);
1184 if (parent
== one_settings
.end())
1185 parent
= one_settings
.find(ContentSettingsPattern::Wildcard());
1187 const std::string
& source
= i
->first
.second
;
1188 base::ListValue
* this_provider_exceptions
=
1189 all_provider_exceptions
[
1190 HostContentSettingsMap::GetProviderTypeFromSource(source
)];
1192 // Add the "parent" entry for the non-embedded setting.
1193 ContentSetting parent_setting
=
1194 parent
== one_settings
.end() ? CONTENT_SETTING_DEFAULT
: parent
->second
;
1195 const ContentSettingsPattern
& secondary_pattern
=
1196 parent
== one_settings
.end() ? primary_pattern
: parent
->first
;
1197 this_provider_exceptions
->Append(GetExceptionForPage(primary_pattern
,
1202 // Add the "children" for any embedded settings.
1203 for (OnePatternSettings::const_iterator j
= one_settings
.begin();
1204 j
!= one_settings
.end(); ++j
) {
1205 // Skip the non-embedded setting which we already added above.
1209 ContentSetting content_setting
= j
->second
;
1210 this_provider_exceptions
->Append(GetExceptionForPage(
1218 // For camera and microphone, we do not have policy exceptions, but we do have
1219 // the policy-set allowed URLs, which should be displayed in the same manner.
1220 if (type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
1221 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) {
1222 base::ListValue
* policy_exceptions
= all_provider_exceptions
[
1223 HostContentSettingsMap::GetProviderTypeFromSource(kPolicyProviderId
)];
1224 DCHECK(policy_exceptions
->empty());
1225 policy_exceptions
->Swap(GetPolicyAllowedUrls(type
).get());
1228 for (const auto& one_provider_exceptions
: all_provider_exceptions
) {
1229 // Append the patterns in reverse order, so the ones with the highest
1230 // precedence (the more specific ones) are on the top.
1231 while (!one_provider_exceptions
->empty()) {
1232 scoped_ptr
<base::Value
> exception
;
1233 one_provider_exceptions
->Remove(
1234 one_provider_exceptions
->GetSize() - 1, &exception
);
1235 exceptions
->Append(exception
.release());
1240 void ContentSettingsHandler::RemoveExceptionFromHostContentSettingsMap(
1241 const base::ListValue
* args
,
1242 ContentSettingsType type
) {
1244 bool rv
= args
->GetString(1, &mode
);
1247 std::string pattern
;
1248 rv
= args
->GetString(2, &pattern
);
1251 // The fourth argument to this handler is optional.
1252 std::string secondary_pattern
;
1253 if (args
->GetSize() >= 4U) {
1254 rv
= args
->GetString(3, &secondary_pattern
);
1258 HostContentSettingsMap
* settings_map
=
1259 mode
== "normal" ? GetContentSettingsMap() :
1260 GetOTRContentSettingsMap();
1262 settings_map
->SetWebsiteSetting(
1263 ContentSettingsPattern::FromString(pattern
),
1264 secondary_pattern
.empty() ?
1265 ContentSettingsPattern::Wildcard() :
1266 ContentSettingsPattern::FromString(secondary_pattern
),
1273 void ContentSettingsHandler::RemoveZoomLevelException(
1274 const base::ListValue
* args
) {
1276 bool rv
= args
->GetString(1, &mode
);
1279 std::string pattern
;
1280 rv
= args
->GetString(2, &pattern
);
1284 l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL
)) {
1285 pattern
= content::kUnreachableWebDataURL
;
1288 content::HostZoomMap
* host_zoom_map
;
1289 if (switches::IsEnableWebviewBasedSignin() ||
1290 pattern
!= chrome::kChromeUIChromeSigninHost
) {
1292 content::HostZoomMap::GetDefaultForBrowserContext(
1293 GetBrowserContext(web_ui()));
1296 content::BrowserContext::GetStoragePartitionForSite(
1297 GetBrowserContext(web_ui()), GURL(chrome::kChromeUIChromeSigninURL
))
1300 double default_level
= host_zoom_map
->GetDefaultZoomLevel();
1301 host_zoom_map
->SetZoomLevelForHost(pattern
, default_level
);
1304 void ContentSettingsHandler::RegisterMessages() {
1305 web_ui()->RegisterMessageCallback("setContentFilter",
1306 base::Bind(&ContentSettingsHandler::SetContentFilter
,
1307 base::Unretained(this)));
1308 web_ui()->RegisterMessageCallback("removeException",
1309 base::Bind(&ContentSettingsHandler::RemoveException
,
1310 base::Unretained(this)));
1311 web_ui()->RegisterMessageCallback("setException",
1312 base::Bind(&ContentSettingsHandler::SetException
,
1313 base::Unretained(this)));
1314 web_ui()->RegisterMessageCallback("checkExceptionPatternValidity",
1315 base::Bind(&ContentSettingsHandler::CheckExceptionPatternValidity
,
1316 base::Unretained(this)));
1319 void ContentSettingsHandler::SetContentFilter(const base::ListValue
* args
) {
1320 DCHECK_EQ(2U, args
->GetSize());
1321 std::string group
, setting
;
1322 if (!(args
->GetString(0, &group
) &&
1323 args
->GetString(1, &setting
))) {
1328 ContentSetting default_setting
= ContentSettingFromString(setting
);
1329 ContentSettingsType content_type
= ContentSettingsTypeFromGroupName(group
);
1330 Profile
* profile
= Profile::FromWebUI(web_ui());
1332 #if defined(OS_CHROMEOS)
1333 // ChromeOS special case : in Guest mode settings are opened in Incognito
1334 // mode, so we need original profile to actually modify settings.
1335 if (user_manager::UserManager::Get()->IsLoggedInAsGuest())
1336 profile
= profile
->GetOriginalProfile();
1339 HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
1341 // MEDIASTREAM is deprecated and the two separate settings MEDIASTREAM_CAMERA
1342 // and MEDIASTREAM_MIC should be used instead. However, we still only have
1343 // one pair of radio buttons that sets both settings.
1344 // TODO(msramek): Clean this up once we have the new UI for media.
1345 if (content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
) {
1346 map
->SetDefaultContentSetting(
1347 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
, default_setting
);
1348 map
->SetDefaultContentSetting(
1349 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
, default_setting
);
1351 map
->SetDefaultContentSetting(content_type
, default_setting
);
1354 switch (content_type
) {
1355 case CONTENT_SETTINGS_TYPE_COOKIES
:
1356 content::RecordAction(
1357 UserMetricsAction("Options_DefaultCookieSettingChanged"));
1359 case CONTENT_SETTINGS_TYPE_IMAGES
:
1360 content::RecordAction(
1361 UserMetricsAction("Options_DefaultImagesSettingChanged"));
1363 case CONTENT_SETTINGS_TYPE_JAVASCRIPT
:
1364 content::RecordAction(
1365 UserMetricsAction("Options_DefaultJavaScriptSettingChanged"));
1367 case CONTENT_SETTINGS_TYPE_PLUGINS
:
1368 content::RecordAction(
1369 UserMetricsAction("Options_DefaultPluginsSettingChanged"));
1371 case CONTENT_SETTINGS_TYPE_POPUPS
:
1372 content::RecordAction(
1373 UserMetricsAction("Options_DefaultPopupsSettingChanged"));
1375 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
1376 content::RecordAction(
1377 UserMetricsAction("Options_DefaultNotificationsSettingChanged"));
1379 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
1380 content::RecordAction(
1381 UserMetricsAction("Options_DefaultGeolocationSettingChanged"));
1383 case CONTENT_SETTINGS_TYPE_MOUSELOCK
:
1384 content::RecordAction(
1385 UserMetricsAction("Options_DefaultMouseLockSettingChanged"));
1387 case CONTENT_SETTINGS_TYPE_MEDIASTREAM
:
1388 content::RecordAction(
1389 UserMetricsAction("Options_DefaultMediaStreamMicSettingChanged"));
1391 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
:
1392 content::RecordAction(
1393 UserMetricsAction("Options_DefaultMultipleAutomaticDLSettingChange"));
1395 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX
:
1396 content::RecordAction(
1397 UserMetricsAction("Options_DefaultMIDISysExSettingChanged"));
1399 case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
:
1400 content::RecordAction(
1401 UserMetricsAction("Options_DefaultPushMessagingSettingChanged"));
1408 void ContentSettingsHandler::RemoveException(const base::ListValue
* args
) {
1409 std::string type_string
;
1410 CHECK(args
->GetString(0, &type_string
));
1412 // Zoom levels are no actual content type so we need to handle them
1413 // separately. They would not be recognized by
1414 // ContentSettingsTypeFromGroupName.
1415 if (type_string
== kZoomContentType
) {
1416 RemoveZoomLevelException(args
);
1420 ContentSettingsType type
= ContentSettingsTypeFromGroupName(type_string
);
1421 RemoveExceptionFromHostContentSettingsMap(args
, type
);
1423 WebSiteSettingsUmaUtil::LogPermissionChange(
1424 type
, ContentSetting::CONTENT_SETTING_DEFAULT
);
1427 void ContentSettingsHandler::SetException(const base::ListValue
* args
) {
1428 std::string type_string
;
1429 CHECK(args
->GetString(0, &type_string
));
1431 CHECK(args
->GetString(1, &mode
));
1432 std::string pattern
;
1433 CHECK(args
->GetString(2, &pattern
));
1434 std::string setting
;
1435 CHECK(args
->GetString(3, &setting
));
1437 ContentSettingsType type
= ContentSettingsTypeFromGroupName(type_string
);
1438 if (type
== CONTENT_SETTINGS_TYPE_GEOLOCATION
||
1439 type
== CONTENT_SETTINGS_TYPE_NOTIFICATIONS
||
1440 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
||
1441 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
1442 type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) {
1445 HostContentSettingsMap
* settings_map
=
1446 mode
== "normal" ? GetContentSettingsMap() :
1447 GetOTRContentSettingsMap();
1449 // The settings map could be null if the mode was OTR but the OTR profile
1450 // got destroyed before we received this message.
1453 settings_map
->SetContentSetting(ContentSettingsPattern::FromString(pattern
),
1454 ContentSettingsPattern::Wildcard(),
1457 ContentSettingFromString(setting
));
1461 void ContentSettingsHandler::CheckExceptionPatternValidity(
1462 const base::ListValue
* args
) {
1463 std::string type_string
;
1464 CHECK(args
->GetString(0, &type_string
));
1465 std::string mode_string
;
1466 CHECK(args
->GetString(1, &mode_string
));
1467 std::string pattern_string
;
1468 CHECK(args
->GetString(2, &pattern_string
));
1470 ContentSettingsPattern pattern
=
1471 ContentSettingsPattern::FromString(pattern_string
);
1473 web_ui()->CallJavascriptFunction(
1474 "ContentSettings.patternValidityCheckComplete",
1475 base::StringValue(type_string
),
1476 base::StringValue(mode_string
),
1477 base::StringValue(pattern_string
),
1478 base::FundamentalValue(pattern
.IsValid()));
1482 std::string
ContentSettingsHandler::ContentSettingsTypeToGroupName(
1483 ContentSettingsType type
) {
1484 for (size_t i
= 0; i
< arraysize(kContentSettingsTypeGroupNames
); ++i
) {
1485 if (type
== kContentSettingsTypeGroupNames
[i
].type
)
1486 return kContentSettingsTypeGroupNames
[i
].name
;
1490 return std::string();
1493 HostContentSettingsMap
* ContentSettingsHandler::GetContentSettingsMap() {
1494 return Profile::FromWebUI(web_ui())->GetHostContentSettingsMap();
1497 ProtocolHandlerRegistry
* ContentSettingsHandler::GetProtocolHandlerRegistry() {
1498 return ProtocolHandlerRegistryFactory::GetForBrowserContext(
1499 GetBrowserContext(web_ui()));
1502 HostContentSettingsMap
*
1503 ContentSettingsHandler::GetOTRContentSettingsMap() {
1504 Profile
* profile
= Profile::FromWebUI(web_ui());
1505 if (profile
->HasOffTheRecordProfile())
1506 return profile
->GetOffTheRecordProfile()->GetHostContentSettingsMap();
1510 void ContentSettingsHandler::RefreshFlashMediaSettings() {
1511 MediaSettingsInfo::ForFlash
& settings
= media_settings_
->forFlash();
1512 settings
.initialized
= false;
1514 settings
.last_refresh_request_id
=
1515 flash_settings_manager_
->GetPermissionSettings(
1516 PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC
);
1519 void ContentSettingsHandler::OnPepperFlashPrefChanged() {
1521 DEFAULT_SETTING
, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
, false);
1523 DEFAULT_SETTING
, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
, false);
1525 EXCEPTIONS
, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
, false);
1527 EXCEPTIONS
, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
, false);
1529 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetBrowserContext(web_ui()));
1530 if (prefs
->GetBoolean(prefs::kPepperFlashSettingsEnabled
))
1531 RefreshFlashMediaSettings();
1533 media_settings_
->forFlash().initialized
= false;
1536 void ContentSettingsHandler::OnZoomLevelChanged(
1537 const content::HostZoomMap::ZoomLevelChange
& change
) {
1538 UpdateZoomLevelsExceptionsView();
1541 void ContentSettingsHandler::ShowFlashMediaLink(
1542 LinkType link_type
, ContentSettingsType content_type
, bool show
) {
1543 MediaSettingsInfo::ForOneType
& settings
=
1544 media_settings_
->forType(content_type
);
1546 bool& show_link
= link_type
== DEFAULT_SETTING
?
1547 settings
.show_flash_default_link
:
1548 settings
.show_flash_exceptions_link
;
1550 if (show_link
!= show
) {
1551 web_ui()->CallJavascriptFunction(
1552 "ContentSettings.showMediaPepperFlashLink",
1554 link_type
== DEFAULT_SETTING
? "default" : "exceptions"),
1556 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
1559 base::FundamentalValue(show
));
1564 void ContentSettingsHandler::UpdateFlashMediaLinksVisibility(
1565 ContentSettingsType type
) {
1566 MediaSettingsInfo::ForOneType
& settings
= media_settings_
->forType(type
);
1567 MediaSettingsInfo::ForFlash
& flash_settings
= media_settings_
->forFlash();
1569 if (!flash_settings
.initialized
)
1572 // We handle four cases - default settings and exceptions for microphone
1573 // and camera. We use the following criteria to determine whether to show
1576 // 1. Flash won't send us notifications when its settings get changed, which
1577 // means the Flash settings in |media_settings_| may be out-dated, especially
1578 // after we show links to change Flash settings.
1579 // In order to avoid confusion, we won't hide the links once they are showed.
1580 // One exception is that we will hide them when Pepper Flash is disabled
1581 // (handled in OnPepperFlashPrefChanged()).
1583 // 2. If audio or video capture are disabled by policy, the respective link
1584 // shouldn't be showed. Flash conforms to the policy in this case because
1585 // it cannot open those devices.
1587 // 3. Otherwise, we show the link if the corresponding setting is different
1588 // in HostContentSettingsMap than it is in Flash.
1589 if (settings
.policy_disable
)
1592 if (settings
.default_setting_initialized
&&
1593 !settings
.show_flash_default_link
&&
1594 (flash_settings
.default_setting
!=
1595 settings
.default_setting
)) {
1596 ShowFlashMediaLink(DEFAULT_SETTING
, type
, true);
1599 if (settings
.exceptions_initialized
&&
1600 !settings
.show_flash_exceptions_link
&&
1601 !PepperFlashContentSettingsUtils::AreMediaExceptionsEqual(
1602 settings
.default_setting
,
1603 settings
.exceptions
,
1604 flash_settings
.default_setting
,
1605 flash_settings
.exceptions
)) {
1606 ShowFlashMediaLink(EXCEPTIONS
, type
, true);
1610 void ContentSettingsHandler::UpdateMediaDeviceDropdownVisibility(
1611 ContentSettingsType type
) {
1612 MediaSettingsInfo::ForOneType
& settings
= media_settings_
->forType(type
);
1614 web_ui()->CallJavascriptFunction(
1615 "ContentSettings.setDevicesMenuVisibility",
1616 base::StringValue(ContentSettingsTypeToGroupName(type
)),
1617 base::FundamentalValue(!settings
.policy_disable
));
1620 void ContentSettingsHandler::UpdateProtectedContentExceptionsButton() {
1621 #if defined(OS_CHROMEOS)
1622 // Guests cannot modify exceptions. UIAccountTweaks will disabled the button.
1623 if (user_manager::UserManager::Get()->IsLoggedInAsGuest())
1627 // Exceptions apply only when the feature is enabled.
1628 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetBrowserContext(web_ui()));
1629 bool enable_exceptions
= prefs
->GetBoolean(prefs::kEnableDRM
);
1630 web_ui()->CallJavascriptFunction(
1631 "ContentSettings.enableProtectedContentExceptions",
1632 base::FundamentalValue(enable_exceptions
));
1635 } // namespace options