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/content_settings/content_setting_bubble_model.h"
7 #include "base/command_line.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
12 #include "chrome/browser/content_settings/cookie_settings.h"
13 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
14 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
15 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
16 #include "chrome/browser/infobars/infobar_service.h"
17 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
18 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
21 #include "chrome/browser/ui/browser_navigator.h"
22 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
23 #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/render_messages.h"
27 #include "chrome/grit/generated_resources.h"
28 #include "components/content_settings/content/common/content_settings_messages.h"
29 #include "components/content_settings/core/browser/content_settings_utils.h"
30 #include "components/content_settings/core/common/content_settings.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/browser/render_process_host.h"
34 #include "content/public/browser/render_view_host.h"
35 #include "content/public/browser/user_metrics.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/browser/web_contents_delegate.h"
38 #include "content/public/common/origin_util.h"
39 #include "grit/components_strings.h"
40 #include "grit/theme_resources.h"
41 #include "net/base/net_util.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/base/resource/resource_bundle.h"
44 #include "ui/resources/grit/ui_resources.h"
46 using base::UserMetricsAction
;
47 using content::WebContents
;
48 using content_settings::SettingInfo
;
49 using content_settings::SettingSource
;
50 using content_settings::SETTING_SOURCE_USER
;
51 using content_settings::SETTING_SOURCE_NONE
;
55 const int kAllowButtonIndex
= 0;
57 // These states must match the order of appearance of the radio buttons
58 // in the XIB file for the Mac port.
65 struct ContentSettingsTypeIdEntry
{
66 ContentSettingsType type
;
70 int GetIdForContentType(const ContentSettingsTypeIdEntry
* entries
,
72 ContentSettingsType type
) {
73 for (size_t i
= 0; i
< num_entries
; ++i
) {
74 if (entries
[i
].type
== type
)
80 const content::MediaStreamDevice
& GetMediaDeviceById(
81 const std::string
& device_id
,
82 const content::MediaStreamDevices
& devices
) {
83 DCHECK(!devices
.empty());
84 for (const content::MediaStreamDevice
& device
: devices
) {
85 if (device
.id
== device_id
)
89 // A device with the |device_id| was not found. It is likely that the device
90 // has been unplugged from the OS. Return the first device as the default
92 return *devices
.begin();
97 ContentSettingTitleAndLinkModel::ContentSettingTitleAndLinkModel(
99 WebContents
* web_contents
,
101 ContentSettingsType content_type
)
102 : ContentSettingBubbleModel(web_contents
, profile
, content_type
),
103 delegate_(delegate
) {
104 // Notifications do not have a bubble.
105 DCHECK_NE(content_type
, CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
111 void ContentSettingTitleAndLinkModel::SetTitle() {
112 TabSpecificContentSettings
* content_settings
= NULL
;
113 if (web_contents()) {
115 TabSpecificContentSettings::FromWebContents(web_contents());
118 static const ContentSettingsTypeIdEntry kBlockedTitleIDs
[] = {
119 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_TITLE
},
120 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_TITLE
},
121 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_TITLE
},
122 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_TITLE
},
123 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_TITLE
},
124 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
,
125 IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT
},
126 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
,
127 IDS_BLOCKED_PPAPI_BROKER_TITLE
},
128 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_BLOCKED_DOWNLOAD_TITLE
},
130 // Fields as for kBlockedTitleIDs, above.
131 static const ContentSettingsTypeIdEntry kAccessedTitleIDs
[] = {
132 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_ACCESSED_COOKIES_TITLE
},
133 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_ALLOWED_PPAPI_BROKER_TITLE
},
134 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_ALLOWED_DOWNLOAD_TITLE
},
136 const ContentSettingsTypeIdEntry
*title_ids
= kBlockedTitleIDs
;
137 size_t num_title_ids
= arraysize(kBlockedTitleIDs
);
138 if (content_settings
&& content_settings
->IsContentAllowed(content_type()) &&
139 !content_settings
->IsContentBlocked(content_type())) {
140 title_ids
= kAccessedTitleIDs
;
141 num_title_ids
= arraysize(kAccessedTitleIDs
);
144 GetIdForContentType(title_ids
, num_title_ids
, content_type());
146 set_title(l10n_util::GetStringUTF8(title_id
));
149 void ContentSettingTitleAndLinkModel::SetManageLink() {
150 static const ContentSettingsTypeIdEntry kLinkIDs
[] = {
151 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_LINK
},
152 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_LINK
},
153 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_LINK
},
154 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_LINK
},
155 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_LINK
},
156 {CONTENT_SETTINGS_TYPE_GEOLOCATION
, IDS_GEOLOCATION_BUBBLE_MANAGE_LINK
},
157 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
, IDS_LEARN_MORE
},
158 {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
, IDS_HANDLERS_BUBBLE_MANAGE_LINK
},
159 {CONTENT_SETTINGS_TYPE_MEDIASTREAM
, IDS_MEDIASTREAM_BUBBLE_MANAGE_LINK
},
160 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_PPAPI_BROKER_BUBBLE_MANAGE_LINK
},
161 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_BLOCKED_DOWNLOADS_LINK
},
162 {CONTENT_SETTINGS_TYPE_MIDI_SYSEX
, IDS_MIDI_SYSEX_BUBBLE_MANAGE_LINK
},
164 set_manage_link(l10n_util::GetStringUTF8(
165 GetIdForContentType(kLinkIDs
, arraysize(kLinkIDs
), content_type())));
168 void ContentSettingTitleAndLinkModel::OnManageLinkClicked() {
170 delegate_
->ShowContentSettingsPage(content_type());
173 void ContentSettingTitleAndLinkModel::SetLearnMoreLink() {
174 static const ContentSettingsTypeIdEntry kLearnMoreIDs
[] = {
175 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_LEARN_MORE
},
178 GetIdForContentType(kLearnMoreIDs
, arraysize(kLearnMoreIDs
),
181 set_learn_more_link(l10n_util::GetStringUTF8(learn_more_id
));
184 void ContentSettingTitleAndLinkModel::OnLearnMoreLinkClicked() {
186 delegate_
->ShowLearnMorePage(content_type());
189 class ContentSettingTitleLinkAndCustomModel
190 : public ContentSettingTitleAndLinkModel
{
192 ContentSettingTitleLinkAndCustomModel(Delegate
* delegate
,
193 WebContents
* web_contents
,
195 ContentSettingsType content_type
);
196 ~ContentSettingTitleLinkAndCustomModel() override
{}
199 void SetCustomLink();
200 void OnCustomLinkClicked() override
{}
203 ContentSettingTitleLinkAndCustomModel::ContentSettingTitleLinkAndCustomModel(
205 WebContents
* web_contents
,
207 ContentSettingsType content_type
)
208 : ContentSettingTitleAndLinkModel(
209 delegate
, web_contents
, profile
, content_type
) {
213 void ContentSettingTitleLinkAndCustomModel::SetCustomLink() {
214 static const ContentSettingsTypeIdEntry kCustomIDs
[] = {
215 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_INFO
},
216 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_LOAD_ALL
},
217 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
, IDS_ALLOW_INSECURE_CONTENT_BUTTON
},
220 GetIdForContentType(kCustomIDs
, arraysize(kCustomIDs
), content_type());
222 set_custom_link(l10n_util::GetStringUTF8(custom_link_id
));
225 class ContentSettingSingleRadioGroup
226 : public ContentSettingTitleLinkAndCustomModel
{
228 ContentSettingSingleRadioGroup(Delegate
* delegate
,
229 WebContents
* web_contents
,
231 ContentSettingsType content_type
);
232 ~ContentSettingSingleRadioGroup() override
;
235 bool settings_changed() const;
236 int selected_item() const { return selected_item_
; }
239 void SetRadioGroup();
240 void AddException(ContentSetting setting
);
241 void OnRadioClicked(int radio_index
) override
;
243 ContentSetting block_setting_
;
247 ContentSettingSingleRadioGroup::ContentSettingSingleRadioGroup(
249 WebContents
* web_contents
,
251 ContentSettingsType content_type
)
252 : ContentSettingTitleLinkAndCustomModel(delegate
, web_contents
, profile
,
254 block_setting_(CONTENT_SETTING_BLOCK
),
259 ContentSettingSingleRadioGroup::~ContentSettingSingleRadioGroup() {
260 if (settings_changed()) {
261 ContentSetting setting
=
262 selected_item_
== kAllowButtonIndex
?
263 CONTENT_SETTING_ALLOW
:
265 AddException(setting
);
269 bool ContentSettingSingleRadioGroup::settings_changed() const {
270 return selected_item_
!= bubble_content().radio_group
.default_item
;
273 // Initialize the radio group by setting the appropriate labels for the
274 // content type and setting the default value based on the content setting.
275 void ContentSettingSingleRadioGroup::SetRadioGroup() {
276 GURL url
= web_contents()->GetURL();
277 base::string16 display_host
;
278 net::AppendFormattedHost(
280 profile()->GetPrefs()->GetString(prefs::kAcceptLanguages
),
283 if (display_host
.empty())
284 display_host
= base::ASCIIToUTF16(url
.spec());
286 TabSpecificContentSettings
* content_settings
=
287 TabSpecificContentSettings::FromWebContents(web_contents());
289 !content_settings
->IsContentBlocked(content_type());
291 content_settings
->IsContentAllowed(content_type()));
293 RadioGroup radio_group
;
294 radio_group
.url
= url
;
296 static const ContentSettingsTypeIdEntry kBlockedAllowIDs
[] = {
297 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_UNBLOCK
},
298 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_UNBLOCK
},
299 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_UNBLOCK
},
300 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_UNBLOCK_ALL
},
301 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_UNBLOCK
},
302 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_BLOCKED_PPAPI_BROKER_UNBLOCK
},
303 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_BLOCKED_DOWNLOAD_UNBLOCK
},
305 // Fields as for kBlockedAllowIDs, above.
306 static const ContentSettingsTypeIdEntry kAllowedAllowIDs
[] = {
307 // TODO(bauerb): The string shouldn't be "unblock" (they weren't blocked).
308 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_UNBLOCK
},
309 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_ALLOWED_PPAPI_BROKER_NO_ACTION
},
310 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_ALLOWED_DOWNLOAD_NO_ACTION
},
313 std::string radio_allow_label
;
315 int resource_id
= GetIdForContentType(kAllowedAllowIDs
,
316 arraysize(kAllowedAllowIDs
),
318 radio_allow_label
= (content_type() == CONTENT_SETTINGS_TYPE_COOKIES
) ?
319 l10n_util::GetStringFUTF8(resource_id
, display_host
) :
320 l10n_util::GetStringUTF8(resource_id
);
322 radio_allow_label
= l10n_util::GetStringFUTF8(
323 GetIdForContentType(kBlockedAllowIDs
, arraysize(kBlockedAllowIDs
),
328 static const ContentSettingsTypeIdEntry kBlockedBlockIDs
[] = {
329 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_NO_ACTION
},
330 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_NO_ACTION
},
331 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_NO_ACTION
},
332 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_NO_ACTION
},
333 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_NO_ACTION
},
334 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_BLOCKED_PPAPI_BROKER_NO_ACTION
},
335 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_BLOCKED_DOWNLOAD_NO_ACTION
},
337 static const ContentSettingsTypeIdEntry kAllowedBlockIDs
[] = {
338 // TODO(bauerb): The string should say "block".
339 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_NO_ACTION
},
340 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_ALLOWED_PPAPI_BROKER_BLOCK
},
341 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_ALLOWED_DOWNLOAD_BLOCK
},
344 std::string radio_block_label
;
346 int resource_id
= GetIdForContentType(kAllowedBlockIDs
,
347 arraysize(kAllowedBlockIDs
),
349 radio_block_label
= (content_type() == CONTENT_SETTINGS_TYPE_COOKIES
) ?
350 l10n_util::GetStringUTF8(resource_id
) :
351 l10n_util::GetStringFUTF8(resource_id
, display_host
);
353 radio_block_label
= l10n_util::GetStringUTF8(
354 GetIdForContentType(kBlockedBlockIDs
, arraysize(kBlockedBlockIDs
),
358 radio_group
.radio_items
.push_back(radio_allow_label
);
359 radio_group
.radio_items
.push_back(radio_block_label
);
360 ContentSetting setting
;
361 SettingSource setting_source
= SETTING_SOURCE_NONE
;
362 bool setting_is_wildcard
= false;
364 if (content_type() == CONTENT_SETTINGS_TYPE_COOKIES
) {
365 CookieSettings
* cookie_settings
=
366 CookieSettings::Factory::GetForProfile(profile()).get();
367 setting
= cookie_settings
->GetCookieSetting(
368 url
, url
, true, &setting_source
);
371 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
372 scoped_ptr
<base::Value
> value
=
373 map
->GetWebsiteSetting(url
, url
, content_type(), std::string(), &info
);
374 setting
= content_settings::ValueToContentSetting(value
.get());
375 setting_source
= info
.source
;
376 setting_is_wildcard
=
377 info
.primary_pattern
== ContentSettingsPattern::Wildcard() &&
378 info
.secondary_pattern
== ContentSettingsPattern::Wildcard();
381 if (content_type() == CONTENT_SETTINGS_TYPE_PLUGINS
&&
382 setting
== CONTENT_SETTING_ALLOW
&&
383 setting_is_wildcard
) {
384 // In the corner case of unrecognized plugins (which are now blocked by
385 // default) we indicate the blocked state in the UI and allow the user to
387 radio_group
.default_item
= 1;
388 } else if (setting
== CONTENT_SETTING_ALLOW
) {
389 radio_group
.default_item
= kAllowButtonIndex
;
390 // |block_setting_| is already set to |CONTENT_SETTING_BLOCK|.
392 radio_group
.default_item
= 1;
393 block_setting_
= setting
;
396 set_setting_is_managed(setting_source
!= SETTING_SOURCE_USER
);
397 if (setting_source
!= SETTING_SOURCE_USER
) {
398 set_radio_group_enabled(false);
400 set_radio_group_enabled(true);
402 selected_item_
= radio_group
.default_item
;
403 set_radio_group(radio_group
);
406 void ContentSettingSingleRadioGroup::AddException(ContentSetting setting
) {
408 profile()->GetHostContentSettingsMap()->AddExceptionForURL(
409 bubble_content().radio_group
.url
,
410 bubble_content().radio_group
.url
,
416 void ContentSettingSingleRadioGroup::OnRadioClicked(int radio_index
) {
417 selected_item_
= radio_index
;
420 class ContentSettingCookiesBubbleModel
: public ContentSettingSingleRadioGroup
{
422 ContentSettingCookiesBubbleModel(Delegate
* delegate
,
423 WebContents
* web_contents
,
426 ~ContentSettingCookiesBubbleModel() override
;
429 void OnCustomLinkClicked() override
;
432 ContentSettingCookiesBubbleModel::ContentSettingCookiesBubbleModel(
434 WebContents
* web_contents
,
436 : ContentSettingSingleRadioGroup(delegate
,
439 CONTENT_SETTINGS_TYPE_COOKIES
) {
440 set_custom_link_enabled(true);
443 ContentSettingCookiesBubbleModel::~ContentSettingCookiesBubbleModel() {
444 // On some plattforms e.g. MacOS X it is possible to close a tab while the
445 // cookies settings bubble is open. This resets the web contents to NULL.
446 if (settings_changed() && web_contents()) {
447 CollectedCookiesInfoBarDelegate::Create(
448 InfoBarService::FromWebContents(web_contents()));
452 void ContentSettingCookiesBubbleModel::OnCustomLinkClicked() {
455 content::NotificationService::current()->Notify(
456 chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN
,
457 content::Source
<TabSpecificContentSettings
>(
458 TabSpecificContentSettings::FromWebContents(web_contents())),
459 content::NotificationService::NoDetails());
460 delegate()->ShowCollectedCookiesDialog(web_contents());
463 class ContentSettingPluginBubbleModel
: public ContentSettingSingleRadioGroup
{
465 ContentSettingPluginBubbleModel(Delegate
* delegate
,
466 WebContents
* web_contents
,
469 ~ContentSettingPluginBubbleModel() override
;
472 void OnCustomLinkClicked() override
;
475 ContentSettingPluginBubbleModel::ContentSettingPluginBubbleModel(
477 WebContents
* web_contents
,
479 : ContentSettingSingleRadioGroup(delegate
,
482 CONTENT_SETTINGS_TYPE_PLUGINS
) {
483 // Disable the "Run all plugins this time" link if the setting is managed and
484 // can't be controlled by the user or if the user already clicked on the link
485 // and ran all plugins.
486 set_custom_link_enabled(!setting_is_managed() &&
488 TabSpecificContentSettings::FromWebContents(
489 web_contents
)->load_plugins_link_enabled());
490 // Build blocked plugin list.
492 TabSpecificContentSettings
* content_settings
=
493 TabSpecificContentSettings::FromWebContents(web_contents
);
495 const std::vector
<base::string16
>& blocked_plugins
=
496 content_settings
->blocked_plugin_names();
497 for (const base::string16
& blocked_plugin
: blocked_plugins
) {
498 ListItem
plugin_item(
499 ui::ResourceBundle::GetSharedInstance().GetImageNamed(
500 IDR_BLOCKED_PLUGINS
),
501 base::UTF16ToUTF8(blocked_plugin
), false, 0);
502 add_list_item(plugin_item
);
507 ContentSettingPluginBubbleModel::~ContentSettingPluginBubbleModel() {
508 if (settings_changed()) {
509 // If the user elected to allow all plugins then run plugins at this time.
510 if (selected_item() == kAllowButtonIndex
)
511 OnCustomLinkClicked();
515 void ContentSettingPluginBubbleModel::OnCustomLinkClicked() {
516 content::RecordAction(UserMetricsAction("ClickToPlay_LoadAll_Bubble"));
517 // Web contents can be NULL if the tab was closed while the plugins
518 // settings bubble is visible.
521 #if defined(ENABLE_PLUGINS)
522 // TODO(bauerb): We should send the identifiers of blocked plugins here.
523 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
524 web_contents(), true, std::string());
526 set_custom_link_enabled(false);
527 TabSpecificContentSettings::FromWebContents(web_contents())->
528 set_load_plugins_link_enabled(false);
531 class ContentSettingPopupBubbleModel
: public ContentSettingSingleRadioGroup
{
533 ContentSettingPopupBubbleModel(Delegate
* delegate
,
534 WebContents
* web_contents
,
536 ~ContentSettingPopupBubbleModel() override
{}
539 void OnListItemClicked(int index
) override
;
541 int32
item_id_from_item_index(int index
) const {
542 return bubble_content().list_items
[index
].item_id
;
546 ContentSettingPopupBubbleModel::ContentSettingPopupBubbleModel(
548 WebContents
* web_contents
,
550 : ContentSettingSingleRadioGroup(delegate
,
553 CONTENT_SETTINGS_TYPE_POPUPS
) {
555 // Build blocked popup list.
556 std::map
<int32
, GURL
> blocked_popups
=
557 PopupBlockerTabHelper::FromWebContents(web_contents
)
558 ->GetBlockedPopupRequests();
559 for (const std::pair
<int32
, GURL
>& blocked_popup
: blocked_popups
) {
560 std::string
title(blocked_popup
.second
.spec());
561 // The popup may not have a valid URL.
563 title
= l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE
);
564 ListItem
popup_item(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
565 IDR_DEFAULT_FAVICON
),
566 title
, true, blocked_popup
.first
);
567 add_list_item(popup_item
);
572 void ContentSettingPopupBubbleModel::OnListItemClicked(int index
) {
573 if (web_contents()) {
574 PopupBlockerTabHelper::FromWebContents(web_contents())
575 ->ShowBlockedPopup(item_id_from_item_index(index
));
579 // The model of the content settings bubble for media settings.
580 class ContentSettingMediaStreamBubbleModel
581 : public ContentSettingTitleAndLinkModel
{
583 ContentSettingMediaStreamBubbleModel(Delegate
* delegate
,
584 WebContents
* web_contents
,
587 ~ContentSettingMediaStreamBubbleModel() override
;
591 // Sets the data for the radio buttons of the bubble.
592 void SetRadioGroup();
593 // Sets the data for the media menus of the bubble.
594 void SetMediaMenus();
595 void SetCustomLink();
596 // Updates the camera and microphone setting with the passed |setting|.
597 void UpdateSettings(ContentSetting setting
);
598 // Updates the camera and microphone default device with the passed |type|
600 void UpdateDefaultDeviceForType(content::MediaStreamType type
,
601 const std::string
& device
);
603 // ContentSettingBubbleModel implementation.
604 void OnRadioClicked(int radio_index
) override
;
605 void OnMediaMenuClicked(content::MediaStreamType type
,
606 const std::string
& selected_device
) override
;
608 // The index of the selected radio item.
610 // The content settings that are associated with the individual radio
612 ContentSetting radio_item_setting_
[2];
613 // The state of the microphone and camera access.
614 TabSpecificContentSettings::MicrophoneCameraState state_
;
617 ContentSettingMediaStreamBubbleModel::ContentSettingMediaStreamBubbleModel(
619 WebContents
* web_contents
,
621 : ContentSettingTitleAndLinkModel(
622 delegate
, web_contents
, profile
, CONTENT_SETTINGS_TYPE_MEDIASTREAM
),
624 state_(TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED
) {
626 // Initialize the content settings associated with the individual radio
628 radio_item_setting_
[0] = CONTENT_SETTING_ASK
;
629 radio_item_setting_
[1] = CONTENT_SETTING_BLOCK
;
631 TabSpecificContentSettings
* content_settings
=
632 TabSpecificContentSettings::FromWebContents(web_contents
);
633 state_
= content_settings
->GetMicrophoneCameraState();
634 DCHECK(state_
& (TabSpecificContentSettings::MICROPHONE_ACCESSED
|
635 TabSpecificContentSettings::CAMERA_ACCESSED
));
643 ContentSettingMediaStreamBubbleModel::~ContentSettingMediaStreamBubbleModel() {
644 // On some platforms (e.g. MacOS X) it is possible to close a tab while the
645 // media stream bubble is open. This resets the web contents to NULL.
649 for (const std::pair
<content::MediaStreamType
, MediaMenu
>& media_menu
:
650 bubble_content().media_menus
) {
651 if (media_menu
.second
.selected_device
.id
!=
652 media_menu
.second
.default_device
.id
) {
653 UpdateDefaultDeviceForType(media_menu
.first
,
654 media_menu
.second
.selected_device
.id
);
658 // Update the media settings if the radio button selection was changed.
659 if (selected_item_
!= bubble_content().radio_group
.default_item
) {
660 UpdateSettings(radio_item_setting_
[selected_item_
]);
664 void ContentSettingMediaStreamBubbleModel::SetTitle() {
665 DCHECK_NE(TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED
, state_
);
667 if (state_
& TabSpecificContentSettings::MICROPHONE_BLOCKED
) {
668 title_id
= (state_
& TabSpecificContentSettings::CAMERA_BLOCKED
) ?
669 IDS_MICROPHONE_CAMERA_BLOCKED
: IDS_MICROPHONE_BLOCKED
;
670 } else if (state_
& TabSpecificContentSettings::CAMERA_BLOCKED
) {
671 title_id
= IDS_CAMERA_BLOCKED
;
672 } else if (state_
& TabSpecificContentSettings::MICROPHONE_ACCESSED
) {
673 title_id
= (state_
& TabSpecificContentSettings::CAMERA_ACCESSED
) ?
674 IDS_MICROPHONE_CAMERA_ALLOWED
: IDS_MICROPHONE_ACCESSED
;
675 } else if (state_
& TabSpecificContentSettings::CAMERA_ACCESSED
) {
676 title_id
= IDS_CAMERA_ACCESSED
;
678 set_title(l10n_util::GetStringUTF8(title_id
));
681 void ContentSettingMediaStreamBubbleModel::SetRadioGroup() {
682 TabSpecificContentSettings
* content_settings
=
683 TabSpecificContentSettings::FromWebContents(web_contents());
684 GURL url
= content_settings
->media_stream_access_origin();
685 RadioGroup radio_group
;
686 radio_group
.url
= url
;
688 base::string16 display_host_utf16
;
689 net::AppendFormattedHost(
691 profile()->GetPrefs()->GetString(prefs::kAcceptLanguages
),
692 &display_host_utf16
);
693 std::string
display_host(base::UTF16ToUTF8(display_host_utf16
));
694 if (display_host
.empty())
695 display_host
= url
.spec();
697 bool is_mic
= (state_
& TabSpecificContentSettings::MICROPHONE_ACCESSED
) != 0;
698 bool is_cam
= (state_
& TabSpecificContentSettings::CAMERA_ACCESSED
) != 0;
699 DCHECK(is_mic
|| is_cam
);
700 int radio_allow_label_id
= 0;
701 int radio_block_label_id
= 0;
702 if (state_
& (TabSpecificContentSettings::MICROPHONE_BLOCKED
|
703 TabSpecificContentSettings::CAMERA_BLOCKED
)) {
704 if (content::IsOriginSecure(url
)) {
705 radio_item_setting_
[0] = CONTENT_SETTING_ALLOW
;
706 radio_allow_label_id
= IDS_BLOCKED_MEDIASTREAM_CAMERA_ALLOW
;
708 radio_allow_label_id
= is_cam
?
709 IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_ALLOW
:
710 IDS_BLOCKED_MEDIASTREAM_MIC_ALLOW
;
712 radio_allow_label_id
= IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK
;
714 radio_allow_label_id
= is_cam
?
715 IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_ASK
:
716 IDS_BLOCKED_MEDIASTREAM_MIC_ASK
;
718 radio_block_label_id
= IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION
;
720 radio_block_label_id
= is_cam
?
721 IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION
:
722 IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION
;
724 if (is_mic
&& is_cam
) {
725 radio_allow_label_id
= IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION
;
726 radio_block_label_id
= IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK
;
728 radio_allow_label_id
= IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION
;
729 radio_block_label_id
= IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK
;
731 radio_allow_label_id
= IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION
;
732 radio_block_label_id
= IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK
;
736 (is_mic
&& content_settings
->IsContentBlocked(
737 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)) ||
738 (is_cam
&& content_settings
->IsContentBlocked(
739 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)) ? 1 : 0;
741 std::string radio_allow_label
= l10n_util::GetStringFUTF8(
742 radio_allow_label_id
, base::UTF8ToUTF16(display_host
));
743 std::string radio_block_label
=
744 l10n_util::GetStringUTF8(radio_block_label_id
);
746 radio_group
.default_item
= selected_item_
;
747 radio_group
.radio_items
.push_back(radio_allow_label
);
748 radio_group
.radio_items
.push_back(radio_block_label
);
750 set_radio_group(radio_group
);
751 set_radio_group_enabled(true);
754 void ContentSettingMediaStreamBubbleModel::UpdateSettings(
755 ContentSetting setting
) {
757 HostContentSettingsMap
* content_settings
=
758 profile()->GetHostContentSettingsMap();
759 TabSpecificContentSettings
* tab_content_settings
=
760 TabSpecificContentSettings::FromWebContents(web_contents());
761 // The same patterns must be used as in other places (e.g. the infobar) in
762 // order to override the existing rule. Otherwise a new rule is created.
763 // TODO(markusheintz): Extract to a helper so that there is only a single
765 ContentSettingsPattern primary_pattern
=
766 ContentSettingsPattern::FromURLNoWildcard(
767 tab_content_settings
->media_stream_access_origin());
768 ContentSettingsPattern secondary_pattern
=
769 ContentSettingsPattern::Wildcard();
770 if (state_
& TabSpecificContentSettings::MICROPHONE_ACCESSED
) {
771 content_settings
->SetContentSetting(
772 primary_pattern
, secondary_pattern
,
773 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
, std::string(), setting
);
775 if (state_
& TabSpecificContentSettings::CAMERA_ACCESSED
) {
776 content_settings
->SetContentSetting(
777 primary_pattern
, secondary_pattern
,
778 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
, std::string(), setting
);
783 void ContentSettingMediaStreamBubbleModel::UpdateDefaultDeviceForType(
784 content::MediaStreamType type
,
785 const std::string
& device
) {
786 PrefService
* prefs
= profile()->GetPrefs();
787 if (type
== content::MEDIA_DEVICE_AUDIO_CAPTURE
) {
788 prefs
->SetString(prefs::kDefaultAudioCaptureDevice
, device
);
790 DCHECK_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE
, type
);
791 prefs
->SetString(prefs::kDefaultVideoCaptureDevice
, device
);
795 void ContentSettingMediaStreamBubbleModel::SetMediaMenus() {
796 TabSpecificContentSettings
* content_settings
=
797 TabSpecificContentSettings::FromWebContents(web_contents());
798 const std::string
& requested_microphone
=
799 content_settings
->media_stream_requested_audio_device();
800 const std::string
& requested_camera
=
801 content_settings
->media_stream_requested_video_device();
803 // Add microphone menu.
804 PrefService
* prefs
= profile()->GetPrefs();
805 MediaCaptureDevicesDispatcher
* dispatcher
=
806 MediaCaptureDevicesDispatcher::GetInstance();
807 const content::MediaStreamDevices
& microphones
=
808 dispatcher
->GetAudioCaptureDevices();
810 if (state_
& TabSpecificContentSettings::MICROPHONE_ACCESSED
) {
812 mic_menu
.label
= l10n_util::GetStringUTF8(IDS_MEDIA_SELECTED_MIC_LABEL
);
813 if (!microphones
.empty()) {
814 std::string preferred_mic
;
815 if (requested_microphone
.empty()) {
816 preferred_mic
= prefs
->GetString(prefs::kDefaultAudioCaptureDevice
);
817 mic_menu
.disabled
= false;
819 // Set the |disabled| to true in order to disable the device selection
820 // menu on the media settings bubble. This must be done if the website
821 // manages the microphone devices itself.
822 preferred_mic
= requested_microphone
;
823 mic_menu
.disabled
= true;
826 mic_menu
.default_device
= GetMediaDeviceById(preferred_mic
, microphones
);
827 mic_menu
.selected_device
= mic_menu
.default_device
;
829 add_media_menu(content::MEDIA_DEVICE_AUDIO_CAPTURE
, mic_menu
);
832 if (state_
& TabSpecificContentSettings::CAMERA_ACCESSED
) {
833 const content::MediaStreamDevices
& cameras
=
834 dispatcher
->GetVideoCaptureDevices();
835 MediaMenu camera_menu
;
837 l10n_util::GetStringUTF8(IDS_MEDIA_SELECTED_CAMERA_LABEL
);
838 if (!cameras
.empty()) {
839 std::string preferred_camera
;
840 if (requested_camera
.empty()) {
841 preferred_camera
= prefs
->GetString(prefs::kDefaultVideoCaptureDevice
);
842 camera_menu
.disabled
= false;
844 // Disable the menu since the website is managing the camera devices
846 preferred_camera
= requested_camera
;
847 camera_menu
.disabled
= true;
850 camera_menu
.default_device
=
851 GetMediaDeviceById(preferred_camera
, cameras
);
852 camera_menu
.selected_device
= camera_menu
.default_device
;
854 add_media_menu(content::MEDIA_DEVICE_VIDEO_CAPTURE
, camera_menu
);
858 void ContentSettingMediaStreamBubbleModel::SetCustomLink() {
859 TabSpecificContentSettings
* content_settings
=
860 TabSpecificContentSettings::FromWebContents(web_contents());
861 if (content_settings
->IsMicrophoneCameraStateChanged()) {
862 set_custom_link(l10n_util::GetStringUTF8(
863 IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE
));
867 void ContentSettingMediaStreamBubbleModel::OnRadioClicked(int radio_index
) {
868 selected_item_
= radio_index
;
871 void ContentSettingMediaStreamBubbleModel::OnMediaMenuClicked(
872 content::MediaStreamType type
,
873 const std::string
& selected_device_id
) {
874 DCHECK(type
== content::MEDIA_DEVICE_AUDIO_CAPTURE
||
875 type
== content::MEDIA_DEVICE_VIDEO_CAPTURE
);
876 DCHECK_EQ(1U, bubble_content().media_menus
.count(type
));
877 MediaCaptureDevicesDispatcher
* dispatcher
=
878 MediaCaptureDevicesDispatcher::GetInstance();
879 const content::MediaStreamDevices
& devices
=
880 (type
== content::MEDIA_DEVICE_AUDIO_CAPTURE
) ?
881 dispatcher
->GetAudioCaptureDevices() :
882 dispatcher
->GetVideoCaptureDevices();
883 set_selected_device(GetMediaDeviceById(selected_device_id
, devices
));
886 class ContentSettingDomainListBubbleModel
887 : public ContentSettingTitleAndLinkModel
{
889 ContentSettingDomainListBubbleModel(Delegate
* delegate
,
890 WebContents
* web_contents
,
892 ContentSettingsType content_type
);
893 ~ContentSettingDomainListBubbleModel() override
{}
896 void MaybeAddDomainList(const std::set
<std::string
>& hosts
, int title_id
);
897 void SetDomainsAndCustomLink();
898 void OnCustomLinkClicked() override
;
901 ContentSettingDomainListBubbleModel::ContentSettingDomainListBubbleModel(
903 WebContents
* web_contents
,
905 ContentSettingsType content_type
)
906 : ContentSettingTitleAndLinkModel(
907 delegate
, web_contents
, profile
, content_type
) {
908 DCHECK_EQ(CONTENT_SETTINGS_TYPE_GEOLOCATION
, content_type
) <<
909 "SetDomains currently only supports geolocation content type";
910 SetDomainsAndCustomLink();
913 void ContentSettingDomainListBubbleModel::MaybeAddDomainList(
914 const std::set
<std::string
>& hosts
, int title_id
) {
915 if (!hosts
.empty()) {
916 DomainList domain_list
;
917 domain_list
.title
= l10n_util::GetStringUTF8(title_id
);
918 domain_list
.hosts
= hosts
;
919 add_domain_list(domain_list
);
923 void ContentSettingDomainListBubbleModel::SetDomainsAndCustomLink() {
924 TabSpecificContentSettings
* content_settings
=
925 TabSpecificContentSettings::FromWebContents(web_contents());
926 const ContentSettingsUsagesState
& usages
=
927 content_settings
->geolocation_usages_state();
928 ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state
;
929 unsigned int tab_state_flags
= 0;
930 usages
.GetDetailedInfo(&formatted_hosts_per_state
, &tab_state_flags
);
931 // Divide the tab's current geolocation users into sets according to their
933 MaybeAddDomainList(formatted_hosts_per_state
[CONTENT_SETTING_ALLOW
],
934 IDS_GEOLOCATION_BUBBLE_SECTION_ALLOWED
);
936 MaybeAddDomainList(formatted_hosts_per_state
[CONTENT_SETTING_BLOCK
],
937 IDS_GEOLOCATION_BUBBLE_SECTION_DENIED
);
939 if (tab_state_flags
& ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION
) {
940 set_custom_link(l10n_util::GetStringUTF8(
941 IDS_GEOLOCATION_BUBBLE_CLEAR_LINK
));
942 set_custom_link_enabled(true);
943 } else if (tab_state_flags
&
944 ContentSettingsUsagesState::TABSTATE_HAS_CHANGED
) {
945 set_custom_link(l10n_util::GetStringUTF8(
946 IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR
));
950 void ContentSettingDomainListBubbleModel::OnCustomLinkClicked() {
953 // Reset this embedder's entry to default for each of the requesting
954 // origins currently on the page.
955 const GURL
& embedder_url
= web_contents()->GetURL();
956 TabSpecificContentSettings
* content_settings
=
957 TabSpecificContentSettings::FromWebContents(web_contents());
958 const ContentSettingsUsagesState::StateMap
& state_map
=
959 content_settings
->geolocation_usages_state().state_map();
960 HostContentSettingsMap
* settings_map
=
961 profile()->GetHostContentSettingsMap();
963 for (const std::pair
<GURL
, ContentSetting
>& map_entry
: state_map
) {
964 settings_map
->SetContentSetting(
965 ContentSettingsPattern::FromURLNoWildcard(map_entry
.first
),
966 ContentSettingsPattern::FromURLNoWildcard(embedder_url
),
967 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string(),
968 CONTENT_SETTING_DEFAULT
);
972 class ContentSettingMixedScriptBubbleModel
973 : public ContentSettingTitleLinkAndCustomModel
{
975 ContentSettingMixedScriptBubbleModel(Delegate
* delegate
,
976 WebContents
* web_contents
,
979 ~ContentSettingMixedScriptBubbleModel() override
{}
982 void OnCustomLinkClicked() override
;
985 ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel(
987 WebContents
* web_contents
,
989 : ContentSettingTitleLinkAndCustomModel(delegate
,
992 CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
) {
993 content_settings::RecordMixedScriptAction(
994 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_BUBBLE
);
995 set_custom_link_enabled(true);
998 void ContentSettingMixedScriptBubbleModel::OnCustomLinkClicked() {
999 content_settings::RecordMixedScriptAction(
1000 content_settings::MIXED_SCRIPT_ACTION_CLICKED_ALLOW
);
1001 DCHECK(web_contents());
1002 web_contents()->SendToAllFrames(
1003 new ChromeViewMsg_SetAllowRunningInsecureContent(MSG_ROUTING_NONE
, true));
1004 web_contents()->GetMainFrame()->Send(new ChromeViewMsg_ReloadFrame(
1005 web_contents()->GetMainFrame()->GetRoutingID()));
1008 ContentSettingRPHBubbleModel::ContentSettingRPHBubbleModel(
1010 WebContents
* web_contents
,
1012 ProtocolHandlerRegistry
* registry
)
1013 : ContentSettingTitleAndLinkModel(delegate
,
1016 CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
),
1018 registry_(registry
),
1019 pending_handler_(ProtocolHandler::EmptyProtocolHandler()),
1020 previous_handler_(ProtocolHandler::EmptyProtocolHandler()) {
1021 TabSpecificContentSettings
* content_settings
=
1022 TabSpecificContentSettings::FromWebContents(web_contents
);
1023 pending_handler_
= content_settings
->pending_protocol_handler();
1024 previous_handler_
= content_settings
->previous_protocol_handler();
1026 base::string16 protocol
;
1027 if (pending_handler_
.protocol() == "mailto") {
1028 protocol
= l10n_util::GetStringUTF16(
1029 IDS_REGISTER_PROTOCOL_HANDLER_MAILTO_NAME
);
1030 } else if (pending_handler_
.protocol() == "webcal") {
1031 protocol
= l10n_util::GetStringUTF16(
1032 IDS_REGISTER_PROTOCOL_HANDLER_WEBCAL_NAME
);
1034 protocol
= base::UTF8ToUTF16(pending_handler_
.protocol());
1037 // Note that we ignore the |title| parameter.
1038 if (previous_handler_
.IsEmpty()) {
1039 set_title(l10n_util::GetStringFUTF8(
1040 IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM
,
1041 base::UTF8ToUTF16(pending_handler_
.url().host()),
1044 set_title(l10n_util::GetStringFUTF8(
1045 IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE
,
1046 base::UTF8ToUTF16(pending_handler_
.url().host()),
1048 base::UTF8ToUTF16(previous_handler_
.url().host())));
1051 std::string radio_allow_label
=
1052 l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT
);
1053 std::string radio_deny_label
=
1054 l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_DENY
);
1055 std::string radio_ignore_label
=
1056 l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_IGNORE
);
1058 GURL url
= web_contents
->GetURL();
1059 RadioGroup radio_group
;
1060 radio_group
.url
= url
;
1062 radio_group
.radio_items
.push_back(radio_allow_label
);
1063 radio_group
.radio_items
.push_back(radio_deny_label
);
1064 radio_group
.radio_items
.push_back(radio_ignore_label
);
1065 ContentSetting setting
=
1066 content_settings
->pending_protocol_handler_setting();
1067 if (setting
== CONTENT_SETTING_ALLOW
)
1068 radio_group
.default_item
= RPH_ALLOW
;
1069 else if (setting
== CONTENT_SETTING_BLOCK
)
1070 radio_group
.default_item
= RPH_BLOCK
;
1072 radio_group
.default_item
= RPH_IGNORE
;
1074 selected_item_
= radio_group
.default_item
;
1075 set_radio_group_enabled(true);
1076 set_radio_group(radio_group
);
1079 void ContentSettingRPHBubbleModel::OnRadioClicked(int radio_index
) {
1080 if (selected_item_
== radio_index
)
1083 selected_item_
= radio_index
;
1085 if (radio_index
== RPH_ALLOW
)
1086 RegisterProtocolHandler();
1087 else if (radio_index
== RPH_BLOCK
)
1088 UnregisterProtocolHandler();
1089 else if (radio_index
== RPH_IGNORE
)
1090 IgnoreProtocolHandler();
1095 void ContentSettingRPHBubbleModel::OnDoneClicked() {
1096 // The user has one chance to deal with the RPH content setting UI,
1097 // then we remove it.
1098 TabSpecificContentSettings::FromWebContents(web_contents())->
1099 ClearPendingProtocolHandler();
1100 content::NotificationService::current()->Notify(
1101 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
1102 content::Source
<WebContents
>(web_contents()),
1103 content::NotificationService::NoDetails());
1106 void ContentSettingRPHBubbleModel::RegisterProtocolHandler() {
1107 // A no-op if the handler hasn't been ignored, but needed in case the user
1108 // selects sequences like register/ignore/register.
1109 registry_
->RemoveIgnoredHandler(pending_handler_
);
1111 registry_
->OnAcceptRegisterProtocolHandler(pending_handler_
);
1112 TabSpecificContentSettings::FromWebContents(web_contents())->
1113 set_pending_protocol_handler_setting(CONTENT_SETTING_ALLOW
);
1116 void ContentSettingRPHBubbleModel::UnregisterProtocolHandler() {
1117 registry_
->OnDenyRegisterProtocolHandler(pending_handler_
);
1118 TabSpecificContentSettings::FromWebContents(web_contents())->
1119 set_pending_protocol_handler_setting(CONTENT_SETTING_BLOCK
);
1120 ClearOrSetPreviousHandler();
1123 void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() {
1124 registry_
->OnIgnoreRegisterProtocolHandler(pending_handler_
);
1125 TabSpecificContentSettings::FromWebContents(web_contents())->
1126 set_pending_protocol_handler_setting(CONTENT_SETTING_DEFAULT
);
1127 ClearOrSetPreviousHandler();
1130 void ContentSettingRPHBubbleModel::ClearOrSetPreviousHandler() {
1131 if (previous_handler_
.IsEmpty()) {
1132 registry_
->ClearDefault(pending_handler_
.protocol());
1134 registry_
->OnAcceptRegisterProtocolHandler(previous_handler_
);
1138 class ContentSettingMidiSysExBubbleModel
1139 : public ContentSettingTitleAndLinkModel
{
1141 ContentSettingMidiSysExBubbleModel(Delegate
* delegate
,
1142 WebContents
* web_contents
,
1144 ~ContentSettingMidiSysExBubbleModel() override
{}
1147 void MaybeAddDomainList(const std::set
<std::string
>& hosts
, int title_id
);
1148 void SetDomainsAndCustomLink();
1149 void OnCustomLinkClicked() override
;
1152 ContentSettingMidiSysExBubbleModel::ContentSettingMidiSysExBubbleModel(
1154 WebContents
* web_contents
,
1156 : ContentSettingTitleAndLinkModel(delegate
,
1159 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
1160 SetDomainsAndCustomLink();
1163 void ContentSettingMidiSysExBubbleModel::MaybeAddDomainList(
1164 const std::set
<std::string
>& hosts
, int title_id
) {
1165 if (!hosts
.empty()) {
1166 DomainList domain_list
;
1167 domain_list
.title
= l10n_util::GetStringUTF8(title_id
);
1168 domain_list
.hosts
= hosts
;
1169 add_domain_list(domain_list
);
1173 void ContentSettingMidiSysExBubbleModel::SetDomainsAndCustomLink() {
1174 TabSpecificContentSettings
* content_settings
=
1175 TabSpecificContentSettings::FromWebContents(web_contents());
1176 const ContentSettingsUsagesState
& usages_state
=
1177 content_settings
->midi_usages_state();
1178 ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state
;
1179 unsigned int tab_state_flags
= 0;
1180 usages_state
.GetDetailedInfo(&formatted_hosts_per_state
, &tab_state_flags
);
1181 // Divide the tab's current MIDI sysex users into sets according to their
1182 // permission state.
1183 MaybeAddDomainList(formatted_hosts_per_state
[CONTENT_SETTING_ALLOW
],
1184 IDS_MIDI_SYSEX_BUBBLE_ALLOWED
);
1186 MaybeAddDomainList(formatted_hosts_per_state
[CONTENT_SETTING_BLOCK
],
1187 IDS_MIDI_SYSEX_BUBBLE_DENIED
);
1189 if (tab_state_flags
& ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION
) {
1190 set_custom_link(l10n_util::GetStringUTF8(
1191 IDS_MIDI_SYSEX_BUBBLE_CLEAR_LINK
));
1192 set_custom_link_enabled(true);
1193 } else if (tab_state_flags
&
1194 ContentSettingsUsagesState::TABSTATE_HAS_CHANGED
) {
1195 set_custom_link(l10n_util::GetStringUTF8(
1196 IDS_MIDI_SYSEX_BUBBLE_REQUIRE_RELOAD_TO_CLEAR
));
1200 void ContentSettingMidiSysExBubbleModel::OnCustomLinkClicked() {
1201 if (!web_contents())
1203 // Reset this embedder's entry to default for each of the requesting
1204 // origins currently on the page.
1205 const GURL
& embedder_url
= web_contents()->GetURL();
1206 TabSpecificContentSettings
* content_settings
=
1207 TabSpecificContentSettings::FromWebContents(web_contents());
1208 const ContentSettingsUsagesState::StateMap
& state_map
=
1209 content_settings
->midi_usages_state().state_map();
1210 HostContentSettingsMap
* settings_map
=
1211 profile()->GetHostContentSettingsMap();
1213 for (const std::pair
<GURL
, ContentSetting
>& map_entry
: state_map
) {
1214 settings_map
->SetContentSetting(
1215 ContentSettingsPattern::FromURLNoWildcard(map_entry
.first
),
1216 ContentSettingsPattern::FromURLNoWildcard(embedder_url
),
1217 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
, std::string(),
1218 CONTENT_SETTING_DEFAULT
);
1223 ContentSettingBubbleModel
*
1224 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
1226 WebContents
* web_contents
,
1228 ContentSettingsType content_type
) {
1229 if (content_type
== CONTENT_SETTINGS_TYPE_COOKIES
) {
1230 return new ContentSettingCookiesBubbleModel(delegate
, web_contents
,
1233 if (content_type
== CONTENT_SETTINGS_TYPE_POPUPS
) {
1234 return new ContentSettingPopupBubbleModel(delegate
, web_contents
, profile
);
1236 if (content_type
== CONTENT_SETTINGS_TYPE_GEOLOCATION
) {
1237 return new ContentSettingDomainListBubbleModel(delegate
, web_contents
,
1238 profile
, content_type
);
1240 if (content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
) {
1241 return new ContentSettingMediaStreamBubbleModel(delegate
, web_contents
,
1244 if (content_type
== CONTENT_SETTINGS_TYPE_PLUGINS
) {
1245 return new ContentSettingPluginBubbleModel(delegate
, web_contents
, profile
);
1247 if (content_type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
) {
1248 return new ContentSettingMixedScriptBubbleModel(delegate
, web_contents
,
1251 if (content_type
== CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
) {
1252 ProtocolHandlerRegistry
* registry
=
1253 ProtocolHandlerRegistryFactory::GetForBrowserContext(profile
);
1254 return new ContentSettingRPHBubbleModel(delegate
, web_contents
, profile
,
1257 if (content_type
== CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
1258 return new ContentSettingMidiSysExBubbleModel(delegate
, web_contents
,
1261 return new ContentSettingSingleRadioGroup(delegate
, web_contents
, profile
,
1265 ContentSettingBubbleModel::ContentSettingBubbleModel(
1266 WebContents
* web_contents
,
1268 ContentSettingsType content_type
)
1269 : web_contents_(web_contents
),
1271 content_type_(content_type
),
1272 setting_is_managed_(false) {
1273 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
1274 content::Source
<WebContents
>(web_contents
));
1275 registrar_
.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED
,
1276 content::Source
<Profile
>(profile_
));
1279 ContentSettingBubbleModel::~ContentSettingBubbleModel() {
1282 ContentSettingBubbleModel::RadioGroup::RadioGroup() : default_item(0) {}
1284 ContentSettingBubbleModel::RadioGroup::~RadioGroup() {}
1286 ContentSettingBubbleModel::DomainList::DomainList() {}
1288 ContentSettingBubbleModel::DomainList::~DomainList() {}
1290 ContentSettingBubbleModel::MediaMenu::MediaMenu() : disabled(false) {}
1292 ContentSettingBubbleModel::MediaMenu::~MediaMenu() {}
1294 ContentSettingBubbleModel::BubbleContent::BubbleContent()
1295 : radio_group_enabled(false),
1296 custom_link_enabled(false) {
1299 ContentSettingBubbleModel::BubbleContent::~BubbleContent() {}
1301 void ContentSettingBubbleModel::Observe(
1303 const content::NotificationSource
& source
,
1304 const content::NotificationDetails
& details
) {
1305 if (type
== content::NOTIFICATION_WEB_CONTENTS_DESTROYED
) {
1306 DCHECK_EQ(web_contents_
,
1307 content::Source
<WebContents
>(source
).ptr());
1308 web_contents_
= NULL
;
1310 DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED
, type
);
1311 DCHECK_EQ(profile_
, content::Source
<Profile
>(source
).ptr());