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/utf_string_conversions.h"
8 #include "chrome/browser/content_settings/content_settings_utils.h"
9 #include "chrome/browser/content_settings/cookie_settings.h"
10 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
11 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
12 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
13 #include "chrome/browser/favicon/favicon_tab_helper.h"
14 #include "chrome/browser/infobars/infobar_tab_helper.h"
15 #include "chrome/browser/prefs/pref_service.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
18 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.h"
19 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
20 #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
21 #include "chrome/common/chrome_notification_types.h"
22 #include "chrome/common/content_settings.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/common/render_messages.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/user_metrics.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/browser/web_contents_delegate.h"
30 #include "grit/generated_resources.h"
31 #include "net/base/net_util.h"
32 #include "ui/base/l10n/l10n_util.h"
34 using content::UserMetricsAction
;
35 using content::WebContents
;
36 using content_settings::SettingInfo
;
37 using content_settings::SettingSource
;
38 using content_settings::SETTING_SOURCE_USER
;
39 using content_settings::SETTING_SOURCE_NONE
;
42 struct ContentSettingsTypeIdEntry
{
43 ContentSettingsType type
;
47 int GetIdForContentType(const ContentSettingsTypeIdEntry
* entries
,
49 ContentSettingsType type
) {
50 for (size_t i
= 0; i
< num_entries
; ++i
) {
51 if (entries
[i
].type
== type
)
59 ContentSettingTitleAndLinkModel::ContentSettingTitleAndLinkModel(
61 WebContents
* web_contents
,
63 ContentSettingsType content_type
)
64 : ContentSettingBubbleModel(web_contents
, profile
, content_type
),
66 // Notifications do not have a bubble.
67 DCHECK_NE(content_type
, CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
68 SetBlockedResources();
73 void ContentSettingTitleAndLinkModel::SetBlockedResources() {
74 TabSpecificContentSettings
* settings
=
75 TabSpecificContentSettings::FromWebContents(web_contents());
76 const std::set
<std::string
>& resources
= settings
->BlockedResourcesForType(
78 for (std::set
<std::string
>::const_iterator it
= resources
.begin();
79 it
!= resources
.end(); ++it
) {
80 AddBlockedResource(*it
);
84 void ContentSettingTitleAndLinkModel::SetTitle() {
85 static const ContentSettingsTypeIdEntry kBlockedTitleIDs
[] = {
86 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_TITLE
},
87 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_TITLE
},
88 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_TITLE
},
89 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_MESSAGE
},
90 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_TITLE
},
91 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
,
92 IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT
},
94 // Fields as for kBlockedTitleIDs, above.
95 static const ContentSettingsTypeIdEntry
96 kResourceSpecificBlockedTitleIDs
[] = {
97 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_TITLE
},
99 static const ContentSettingsTypeIdEntry kAccessedTitleIDs
[] = {
100 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_ACCESSED_COOKIES_TITLE
},
102 const ContentSettingsTypeIdEntry
*title_ids
= kBlockedTitleIDs
;
103 size_t num_title_ids
= arraysize(kBlockedTitleIDs
);
104 if (web_contents() &&
105 TabSpecificContentSettings::FromWebContents(
106 web_contents())->IsContentAccessed(content_type()) &&
107 !TabSpecificContentSettings::FromWebContents(
108 web_contents())->IsContentBlocked(content_type())) {
109 title_ids
= kAccessedTitleIDs
;
110 num_title_ids
= arraysize(kAccessedTitleIDs
);
111 } else if (!bubble_content().resource_identifiers
.empty()) {
112 title_ids
= kResourceSpecificBlockedTitleIDs
;
113 num_title_ids
= arraysize(kResourceSpecificBlockedTitleIDs
);
116 GetIdForContentType(title_ids
, num_title_ids
, content_type());
118 set_title(l10n_util::GetStringUTF8(title_id
));
121 void ContentSettingTitleAndLinkModel::SetManageLink() {
122 static const ContentSettingsTypeIdEntry kLinkIDs
[] = {
123 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_LINK
},
124 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_LINK
},
125 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_LINK
},
126 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_LINK
},
127 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_LINK
},
128 {CONTENT_SETTINGS_TYPE_GEOLOCATION
, IDS_GEOLOCATION_BUBBLE_MANAGE_LINK
},
129 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
, IDS_LEARN_MORE
},
130 {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
, IDS_HANDLERS_BUBBLE_MANAGE_LINK
}
132 set_manage_link(l10n_util::GetStringUTF8(
133 GetIdForContentType(kLinkIDs
, arraysize(kLinkIDs
), content_type())));
136 void ContentSettingTitleAndLinkModel::OnManageLinkClicked() {
138 delegate_
->ShowContentSettingsPage(content_type());
141 class ContentSettingTitleLinkAndCustomModel
142 : public ContentSettingTitleAndLinkModel
{
144 ContentSettingTitleLinkAndCustomModel(Delegate
* delegate
,
145 WebContents
* web_contents
,
147 ContentSettingsType content_type
);
148 virtual ~ContentSettingTitleLinkAndCustomModel() {}
151 void SetCustomLink();
152 virtual void OnCustomLinkClicked() {}
155 ContentSettingTitleLinkAndCustomModel::ContentSettingTitleLinkAndCustomModel(
157 WebContents
* web_contents
,
159 ContentSettingsType content_type
)
160 : ContentSettingTitleAndLinkModel(
161 delegate
, web_contents
, profile
, content_type
) {
165 void ContentSettingTitleLinkAndCustomModel::SetCustomLink() {
166 static const ContentSettingsTypeIdEntry kCustomIDs
[] = {
167 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_INFO
},
168 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_LOAD_ALL
},
169 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
, IDS_ALLOW_INSECURE_CONTENT_BUTTON
},
172 GetIdForContentType(kCustomIDs
, arraysize(kCustomIDs
), content_type());
174 set_custom_link(l10n_util::GetStringUTF8(custom_link_id
));
177 class ContentSettingSingleRadioGroup
178 : public ContentSettingTitleLinkAndCustomModel
{
180 ContentSettingSingleRadioGroup(Delegate
* delegate
,
181 WebContents
* web_contents
,
183 ContentSettingsType content_type
);
184 virtual ~ContentSettingSingleRadioGroup();
187 bool settings_changed() const;
190 void SetRadioGroup();
191 void AddException(ContentSetting setting
,
192 const std::string
& resource_identifier
);
193 virtual void OnRadioClicked(int radio_index
);
195 ContentSetting block_setting_
;
199 ContentSettingSingleRadioGroup::ContentSettingSingleRadioGroup(
201 WebContents
* web_contents
,
203 ContentSettingsType content_type
)
204 : ContentSettingTitleLinkAndCustomModel(delegate
, web_contents
, profile
,
206 block_setting_(CONTENT_SETTING_BLOCK
),
211 ContentSettingSingleRadioGroup::~ContentSettingSingleRadioGroup() {
212 if (settings_changed()) {
213 ContentSetting setting
=
214 selected_item_
== 0 ? CONTENT_SETTING_ALLOW
: block_setting_
;
215 const std::set
<std::string
>& resources
=
216 bubble_content().resource_identifiers
;
217 if (resources
.empty()) {
218 AddException(setting
, std::string());
220 for (std::set
<std::string
>::const_iterator it
= resources
.begin();
221 it
!= resources
.end(); ++it
) {
222 AddException(setting
, *it
);
228 bool ContentSettingSingleRadioGroup::settings_changed() const {
229 return selected_item_
!= bubble_content().radio_group
.default_item
;
232 // Initialize the radio group by setting the appropriate labels for the
233 // content type and setting the default value based on the content setting.
234 void ContentSettingSingleRadioGroup::SetRadioGroup() {
235 GURL url
= web_contents()->GetURL();
236 string16 display_host_utf16
;
237 net::AppendFormattedHost(
239 profile()->GetPrefs()->GetString(prefs::kAcceptLanguages
),
240 &display_host_utf16
);
241 std::string
display_host(UTF16ToUTF8(display_host_utf16
));
243 if (display_host
.empty())
244 display_host
= url
.spec();
246 const std::set
<std::string
>& resources
=
247 bubble_content().resource_identifiers
;
249 RadioGroup radio_group
;
250 radio_group
.url
= url
;
252 static const ContentSettingsTypeIdEntry kAllowIDs
[] = {
253 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_UNBLOCK
},
254 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_UNBLOCK
},
255 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_UNBLOCK
},
256 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_UNBLOCK_ALL
},
257 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_UNBLOCK
},
259 // Fields as for kAllowIDs, above.
260 static const ContentSettingsTypeIdEntry kResourceSpecificAllowIDs
[] = {
261 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_UNBLOCK
},
263 std::string radio_allow_label
;
264 const ContentSettingsTypeIdEntry
* allow_ids
= resources
.empty() ?
265 kAllowIDs
: kResourceSpecificAllowIDs
;
266 size_t num_allow_ids
= resources
.empty() ?
267 arraysize(kAllowIDs
) : arraysize(kResourceSpecificAllowIDs
);
268 radio_allow_label
= l10n_util::GetStringFUTF8(
269 GetIdForContentType(allow_ids
, num_allow_ids
, content_type()),
270 UTF8ToUTF16(display_host
));
272 static const ContentSettingsTypeIdEntry kBlockIDs
[] = {
273 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_NO_ACTION
},
274 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_NO_ACTION
},
275 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_NO_ACTION
},
276 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_NO_ACTION
},
277 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_NO_ACTION
},
279 std::string radio_block_label
;
280 radio_block_label
= l10n_util::GetStringUTF8(
281 GetIdForContentType(kBlockIDs
, arraysize(kBlockIDs
), content_type()));
283 radio_group
.radio_items
.push_back(radio_allow_label
);
284 radio_group
.radio_items
.push_back(radio_block_label
);
285 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
286 CookieSettings
* cookie_settings
=
287 CookieSettings::Factory::GetForProfile(profile());
288 ContentSetting most_restrictive_setting
;
289 SettingSource most_restrictive_setting_source
= SETTING_SOURCE_NONE
;
291 if (resources
.empty()) {
292 if (content_type() == CONTENT_SETTINGS_TYPE_COOKIES
) {
293 most_restrictive_setting
= cookie_settings
->GetCookieSetting(
294 url
, url
, true, &most_restrictive_setting_source
);
297 scoped_ptr
<Value
> value(map
->GetWebsiteSetting(
298 url
, url
, content_type(), std::string(), &info
));
299 most_restrictive_setting
=
300 content_settings::ValueToContentSetting(value
.get());
301 most_restrictive_setting_source
= info
.source
;
304 most_restrictive_setting
= CONTENT_SETTING_ALLOW
;
305 for (std::set
<std::string
>::const_iterator it
= resources
.begin();
306 it
!= resources
.end(); ++it
) {
308 scoped_ptr
<Value
> value(map
->GetWebsiteSetting(
309 url
, url
, content_type(), *it
, &info
));
310 ContentSetting setting
=
311 content_settings::ValueToContentSetting(value
.get());
312 if (setting
== CONTENT_SETTING_BLOCK
) {
313 most_restrictive_setting
= CONTENT_SETTING_BLOCK
;
314 most_restrictive_setting_source
= info
.source
;
317 if (setting
== CONTENT_SETTING_ASK
) {
318 most_restrictive_setting
= CONTENT_SETTING_ASK
;
319 most_restrictive_setting_source
= info
.source
;
323 if (most_restrictive_setting
== CONTENT_SETTING_ALLOW
) {
324 radio_group
.default_item
= 0;
325 // |block_setting_| is already set to |CONTENT_SETTING_BLOCK|.
327 radio_group
.default_item
= 1;
328 block_setting_
= most_restrictive_setting
;
330 if (most_restrictive_setting_source
!= SETTING_SOURCE_USER
) {
331 set_radio_group_enabled(false);
333 set_radio_group_enabled(true);
335 selected_item_
= radio_group
.default_item
;
336 set_radio_group(radio_group
);
339 void ContentSettingSingleRadioGroup::AddException(
340 ContentSetting setting
,
341 const std::string
& resource_identifier
) {
343 profile()->GetHostContentSettingsMap()->AddExceptionForURL(
344 bubble_content().radio_group
.url
,
345 bubble_content().radio_group
.url
,
352 void ContentSettingSingleRadioGroup::OnRadioClicked(int radio_index
) {
353 selected_item_
= radio_index
;
356 class ContentSettingCookiesBubbleModel
: public ContentSettingSingleRadioGroup
{
358 ContentSettingCookiesBubbleModel(Delegate
* delegate
,
359 WebContents
* web_contents
,
361 ContentSettingsType content_type
);
363 virtual ~ContentSettingCookiesBubbleModel();
366 virtual void OnCustomLinkClicked() OVERRIDE
;
369 ContentSettingCookiesBubbleModel::ContentSettingCookiesBubbleModel(
371 WebContents
* web_contents
,
373 ContentSettingsType content_type
)
374 : ContentSettingSingleRadioGroup(
375 delegate
, web_contents
, profile
, content_type
) {
376 DCHECK_EQ(CONTENT_SETTINGS_TYPE_COOKIES
, content_type
);
377 set_custom_link_enabled(true);
380 ContentSettingCookiesBubbleModel::~ContentSettingCookiesBubbleModel() {
381 if (settings_changed()) {
382 InfoBarTabHelper
* infobar_helper
=
383 InfoBarTabHelper::FromWebContents(web_contents());
384 infobar_helper
->AddInfoBar(
385 new CollectedCookiesInfoBarDelegate(infobar_helper
));
389 void ContentSettingCookiesBubbleModel::OnCustomLinkClicked() {
392 content::NotificationService::current()->Notify(
393 chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN
,
394 content::Source
<TabSpecificContentSettings
>(
395 TabSpecificContentSettings::FromWebContents(web_contents())),
396 content::NotificationService::NoDetails());
397 delegate()->ShowCollectedCookiesDialog(web_contents());
400 class ContentSettingPluginBubbleModel
: public ContentSettingSingleRadioGroup
{
402 ContentSettingPluginBubbleModel(Delegate
* delegate
,
403 WebContents
* web_contents
,
405 ContentSettingsType content_type
);
407 virtual ~ContentSettingPluginBubbleModel() {}
410 virtual void OnCustomLinkClicked() OVERRIDE
;
413 ContentSettingPluginBubbleModel::ContentSettingPluginBubbleModel(
415 WebContents
* web_contents
,
417 ContentSettingsType content_type
)
418 : ContentSettingSingleRadioGroup(
419 delegate
, web_contents
, profile
, content_type
) {
420 DCHECK_EQ(content_type
, CONTENT_SETTINGS_TYPE_PLUGINS
);
421 set_custom_link_enabled(web_contents
&&
422 TabSpecificContentSettings::FromWebContents(
423 web_contents
)->load_plugins_link_enabled());
426 void ContentSettingPluginBubbleModel::OnCustomLinkClicked() {
427 content::RecordAction(UserMetricsAction("ClickToPlay_LoadAll_Bubble"));
428 DCHECK(web_contents());
429 content::RenderViewHost
* host
= web_contents()->GetRenderViewHost();
430 // TODO(bauerb): We should send the identifiers of blocked plug-ins here.
431 host
->Send(new ChromeViewMsg_LoadBlockedPlugins(host
->GetRoutingID(),
433 set_custom_link_enabled(false);
434 TabSpecificContentSettings::FromWebContents(web_contents())->
435 set_load_plugins_link_enabled(false);
438 class ContentSettingPopupBubbleModel
: public ContentSettingSingleRadioGroup
{
440 ContentSettingPopupBubbleModel(Delegate
* delegate
,
441 WebContents
* web_contents
,
443 ContentSettingsType content_type
);
444 virtual ~ContentSettingPopupBubbleModel() {}
448 virtual void OnPopupClicked(int index
);
451 ContentSettingPopupBubbleModel::ContentSettingPopupBubbleModel(
453 WebContents
* web_contents
,
455 ContentSettingsType content_type
)
456 : ContentSettingSingleRadioGroup(
457 delegate
, web_contents
, profile
, content_type
) {
462 void ContentSettingPopupBubbleModel::SetPopups() {
463 std::vector
<WebContents
*> blocked_contents
;
464 BlockedContentTabHelper::FromWebContents(web_contents())->
465 GetBlockedContents(&blocked_contents
);
466 for (std::vector
<WebContents
*>::const_iterator
467 i
= blocked_contents
.begin(); i
!= blocked_contents
.end(); ++i
) {
468 std::string
title(UTF16ToUTF8((*i
)->GetTitle()));
469 // The popup may not have committed a load yet, in which case it won't
470 // have a URL or title.
472 title
= l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE
);
473 PopupItem popup_item
;
474 popup_item
.title
= title
;
475 popup_item
.image
= FaviconTabHelper::FromWebContents(*i
)->GetFavicon();
476 popup_item
.web_contents
= *i
;
477 add_popup(popup_item
);
481 void ContentSettingPopupBubbleModel::OnPopupClicked(int index
) {
482 if (web_contents()) {
483 BlockedContentTabHelper::FromWebContents(web_contents())->
484 LaunchForContents(bubble_content().popup_items
[index
].web_contents
);
488 class ContentSettingDomainListBubbleModel
489 : public ContentSettingTitleAndLinkModel
{
491 ContentSettingDomainListBubbleModel(Delegate
* delegate
,
492 WebContents
* web_contents
,
494 ContentSettingsType content_type
);
495 virtual ~ContentSettingDomainListBubbleModel() {}
498 void MaybeAddDomainList(const std::set
<std::string
>& hosts
, int title_id
);
499 void SetDomainsAndCustomLink();
500 virtual void OnCustomLinkClicked() OVERRIDE
;
503 ContentSettingDomainListBubbleModel::ContentSettingDomainListBubbleModel(
505 WebContents
* web_contents
,
507 ContentSettingsType content_type
)
508 : ContentSettingTitleAndLinkModel(
509 delegate
, web_contents
, profile
, content_type
) {
510 DCHECK_EQ(CONTENT_SETTINGS_TYPE_GEOLOCATION
, content_type
) <<
511 "SetDomains currently only supports geolocation content type";
512 SetDomainsAndCustomLink();
515 void ContentSettingDomainListBubbleModel::MaybeAddDomainList(
516 const std::set
<std::string
>& hosts
, int title_id
) {
517 if (!hosts
.empty()) {
518 DomainList domain_list
;
519 domain_list
.title
= l10n_util::GetStringUTF8(title_id
);
520 domain_list
.hosts
= hosts
;
521 add_domain_list(domain_list
);
525 void ContentSettingDomainListBubbleModel::SetDomainsAndCustomLink() {
526 TabSpecificContentSettings
* content_settings
=
527 TabSpecificContentSettings::FromWebContents(web_contents());
528 const GeolocationSettingsState
& settings
=
529 content_settings
->geolocation_settings_state();
530 GeolocationSettingsState::FormattedHostsPerState formatted_hosts_per_state
;
531 unsigned int tab_state_flags
= 0;
532 settings
.GetDetailedInfo(&formatted_hosts_per_state
, &tab_state_flags
);
533 // Divide the tab's current geolocation users into sets according to their
535 MaybeAddDomainList(formatted_hosts_per_state
[CONTENT_SETTING_ALLOW
],
536 IDS_GEOLOCATION_BUBBLE_SECTION_ALLOWED
);
538 MaybeAddDomainList(formatted_hosts_per_state
[CONTENT_SETTING_BLOCK
],
539 IDS_GEOLOCATION_BUBBLE_SECTION_DENIED
);
541 if (tab_state_flags
& GeolocationSettingsState::TABSTATE_HAS_EXCEPTION
) {
542 set_custom_link(l10n_util::GetStringUTF8(
543 IDS_GEOLOCATION_BUBBLE_CLEAR_LINK
));
544 set_custom_link_enabled(true);
545 } else if (tab_state_flags
&
546 GeolocationSettingsState::TABSTATE_HAS_CHANGED
) {
547 set_custom_link(l10n_util::GetStringUTF8(
548 IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR
));
552 void ContentSettingDomainListBubbleModel::OnCustomLinkClicked() {
555 // Reset this embedder's entry to default for each of the requesting
556 // origins currently on the page.
557 const GURL
& embedder_url
= web_contents()->GetURL();
558 TabSpecificContentSettings
* content_settings
=
559 TabSpecificContentSettings::FromWebContents(web_contents());
560 const GeolocationSettingsState::StateMap
& state_map
=
561 content_settings
->geolocation_settings_state().state_map();
562 HostContentSettingsMap
* settings_map
=
563 profile()->GetHostContentSettingsMap();
565 for (GeolocationSettingsState::StateMap::const_iterator it
=
566 state_map
.begin(); it
!= state_map
.end(); ++it
) {
567 settings_map
->SetContentSetting(
568 ContentSettingsPattern::FromURLNoWildcard(it
->first
),
569 ContentSettingsPattern::FromURLNoWildcard(embedder_url
),
570 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
572 CONTENT_SETTING_DEFAULT
);
576 class ContentSettingMixedScriptBubbleModel
577 : public ContentSettingTitleLinkAndCustomModel
{
579 ContentSettingMixedScriptBubbleModel(Delegate
* delegate
,
580 WebContents
* web_contents
,
582 ContentSettingsType content_type
);
584 virtual ~ContentSettingMixedScriptBubbleModel() {}
587 virtual void OnCustomLinkClicked() OVERRIDE
;
590 ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel(
592 WebContents
* web_contents
,
594 ContentSettingsType content_type
)
595 : ContentSettingTitleLinkAndCustomModel(
596 delegate
, web_contents
, profile
, content_type
) {
597 DCHECK_EQ(content_type
, CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
);
598 set_custom_link_enabled(true);
601 void ContentSettingMixedScriptBubbleModel::OnCustomLinkClicked() {
602 content::RecordAction(UserMetricsAction("MixedScript_LoadAnyway_Bubble"));
603 DCHECK(web_contents());
604 content::RenderViewHost
* host
= web_contents()->GetRenderViewHost();
605 host
->Send(new ChromeViewMsg_SetAllowRunningInsecureContent(
606 host
->GetRoutingID(), true));
609 ContentSettingRPHBubbleModel::ContentSettingRPHBubbleModel(
611 WebContents
* web_contents
,
613 ProtocolHandlerRegistry
* registry
,
614 ContentSettingsType content_type
)
615 : ContentSettingTitleAndLinkModel(
616 delegate
, web_contents
, profile
, content_type
),
619 pending_handler_(ProtocolHandler::EmptyProtocolHandler()),
620 previous_handler_(ProtocolHandler::EmptyProtocolHandler()) {
622 DCHECK_EQ(CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
, content_type
);
624 TabSpecificContentSettings
* content_settings
=
625 TabSpecificContentSettings::FromWebContents(web_contents
);
626 pending_handler_
= content_settings
->pending_protocol_handler();
627 previous_handler_
= content_settings
->previous_protocol_handler();
630 if (pending_handler_
.protocol() == "mailto") {
631 protocol
= l10n_util::GetStringUTF16(
632 IDS_REGISTER_PROTOCOL_HANDLER_MAILTO_NAME
);
633 } else if (pending_handler_
.protocol() == "webcal") {
634 protocol
= l10n_util::GetStringUTF16(
635 IDS_REGISTER_PROTOCOL_HANDLER_WEBCAL_NAME
);
637 protocol
= UTF8ToUTF16(pending_handler_
.protocol());
640 if (previous_handler_
.IsEmpty()) {
641 set_title(l10n_util::GetStringFUTF8(
642 IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM
,
643 pending_handler_
.title(), UTF8ToUTF16(pending_handler_
.url().host()),
646 set_title(l10n_util::GetStringFUTF8(
647 IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE
,
648 pending_handler_
.title(), UTF8ToUTF16(pending_handler_
.url().host()),
649 protocol
, previous_handler_
.title()));
652 std::string radio_allow_label
=
653 l10n_util::GetStringFUTF8(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT
,
654 pending_handler_
.title());
655 std::string radio_deny_label
=
656 l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_DENY
);
657 std::string radio_ignore_label
=
658 l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_IGNORE
);
660 GURL url
= web_contents
->GetURL();
661 RadioGroup radio_group
;
662 radio_group
.url
= url
;
664 radio_group
.radio_items
.push_back(radio_allow_label
);
665 radio_group
.radio_items
.push_back(radio_deny_label
);
666 radio_group
.radio_items
.push_back(radio_ignore_label
);
667 ContentSetting setting
=
668 content_settings
->pending_protocol_handler_setting();
669 if (setting
== CONTENT_SETTING_ALLOW
)
670 radio_group
.default_item
= RPH_ALLOW
;
671 else if (setting
== CONTENT_SETTING_BLOCK
)
672 radio_group
.default_item
= RPH_BLOCK
;
674 radio_group
.default_item
= RPH_IGNORE
;
676 selected_item_
= radio_group
.default_item
;
677 set_radio_group_enabled(true);
678 set_radio_group(radio_group
);
681 void ContentSettingRPHBubbleModel::OnRadioClicked(int radio_index
) {
682 if (selected_item_
== radio_index
)
685 selected_item_
= radio_index
;
687 if (radio_index
== RPH_ALLOW
)
688 RegisterProtocolHandler();
689 else if (radio_index
== RPH_BLOCK
)
690 UnregisterProtocolHandler();
691 else if (radio_index
== RPH_IGNORE
)
692 IgnoreProtocolHandler();
697 void ContentSettingRPHBubbleModel::OnDoneClicked() {
698 // The user has one chance to deal with the RPH content setting UI,
699 // then we remove it.
700 TabSpecificContentSettings::FromWebContents(web_contents())->
701 ClearPendingProtocolHandler();
702 content::NotificationService::current()->Notify(
703 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
704 content::Source
<WebContents
>(web_contents()),
705 content::NotificationService::NoDetails());
708 void ContentSettingRPHBubbleModel::RegisterProtocolHandler() {
709 // A no-op if the handler hasn't been ignored, but needed in case the user
710 // selects sequences like register/ignore/register.
711 registry_
->RemoveIgnoredHandler(pending_handler_
);
713 registry_
->OnAcceptRegisterProtocolHandler(pending_handler_
);
714 TabSpecificContentSettings::FromWebContents(web_contents())->
715 set_pending_protocol_handler_setting(CONTENT_SETTING_ALLOW
);
718 void ContentSettingRPHBubbleModel::UnregisterProtocolHandler() {
719 registry_
->OnDenyRegisterProtocolHandler(pending_handler_
);
720 TabSpecificContentSettings::FromWebContents(web_contents())->
721 set_pending_protocol_handler_setting(CONTENT_SETTING_BLOCK
);
722 ClearOrSetPreviousHandler();
725 void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() {
726 registry_
->OnIgnoreRegisterProtocolHandler(pending_handler_
);
727 TabSpecificContentSettings::FromWebContents(web_contents())->
728 set_pending_protocol_handler_setting(CONTENT_SETTING_DEFAULT
);
729 ClearOrSetPreviousHandler();
732 void ContentSettingRPHBubbleModel::ClearOrSetPreviousHandler() {
733 if (previous_handler_
.IsEmpty()) {
734 registry_
->ClearDefault(pending_handler_
.protocol());
736 registry_
->OnAcceptRegisterProtocolHandler(previous_handler_
);
741 ContentSettingBubbleModel
*
742 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
744 WebContents
* web_contents
,
746 ContentSettingsType content_type
) {
747 if (content_type
== CONTENT_SETTINGS_TYPE_COOKIES
) {
748 return new ContentSettingCookiesBubbleModel(delegate
, web_contents
, profile
,
751 if (content_type
== CONTENT_SETTINGS_TYPE_POPUPS
) {
752 return new ContentSettingPopupBubbleModel(delegate
, web_contents
, profile
,
755 if (content_type
== CONTENT_SETTINGS_TYPE_GEOLOCATION
) {
756 return new ContentSettingDomainListBubbleModel(delegate
, web_contents
,
757 profile
, content_type
);
759 if (content_type
== CONTENT_SETTINGS_TYPE_PLUGINS
) {
760 return new ContentSettingPluginBubbleModel(delegate
, web_contents
, profile
,
763 if (content_type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
) {
764 return new ContentSettingMixedScriptBubbleModel(delegate
, web_contents
,
765 profile
, content_type
);
767 if (content_type
== CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
) {
768 ProtocolHandlerRegistry
* registry
=
769 ProtocolHandlerRegistryFactory::GetForProfile(profile
);
770 return new ContentSettingRPHBubbleModel(delegate
, web_contents
, profile
,
771 registry
, content_type
);
773 return new ContentSettingSingleRadioGroup(delegate
, web_contents
, profile
,
777 ContentSettingBubbleModel::ContentSettingBubbleModel(
778 WebContents
* web_contents
,
780 ContentSettingsType content_type
)
781 : web_contents_(web_contents
),
783 content_type_(content_type
) {
784 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
785 content::Source
<WebContents
>(web_contents
));
786 registrar_
.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED
,
787 content::Source
<Profile
>(profile_
));
790 ContentSettingBubbleModel::~ContentSettingBubbleModel() {
793 ContentSettingBubbleModel::RadioGroup::RadioGroup() : default_item(0) {}
795 ContentSettingBubbleModel::RadioGroup::~RadioGroup() {}
797 ContentSettingBubbleModel::DomainList::DomainList() {}
799 ContentSettingBubbleModel::DomainList::~DomainList() {}
801 ContentSettingBubbleModel::BubbleContent::BubbleContent()
802 : radio_group_enabled(false),
803 custom_link_enabled(false) {
806 ContentSettingBubbleModel::BubbleContent::~BubbleContent() {}
809 void ContentSettingBubbleModel::AddBlockedResource(
810 const std::string
& resource_identifier
) {
811 bubble_content_
.resource_identifiers
.insert(resource_identifier
);
814 void ContentSettingBubbleModel::Observe(
816 const content::NotificationSource
& source
,
817 const content::NotificationDetails
& details
) {
818 if (type
== content::NOTIFICATION_WEB_CONTENTS_DESTROYED
) {
819 DCHECK_EQ(web_contents_
,
820 content::Source
<WebContents
>(source
).ptr());
821 web_contents_
= NULL
;
823 DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED
, type
);
824 DCHECK_EQ(profile_
, content::Source
<Profile
>(source
).ptr());