Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / chrome / browser / ui / content_settings / content_setting_bubble_model.cc
blob6e3ef6d10139fc66a28efbf0232630229b2a9928
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;
41 namespace {
42 struct ContentSettingsTypeIdEntry {
43 ContentSettingsType type;
44 int id;
47 int GetIdForContentType(const ContentSettingsTypeIdEntry* entries,
48 size_t num_entries,
49 ContentSettingsType type) {
50 for (size_t i = 0; i < num_entries; ++i) {
51 if (entries[i].type == type)
52 return entries[i].id;
54 return 0;
57 } // namespace
59 ContentSettingTitleAndLinkModel::ContentSettingTitleAndLinkModel(
60 Delegate* delegate,
61 WebContents* web_contents,
62 Profile* profile,
63 ContentSettingsType content_type)
64 : ContentSettingBubbleModel(web_contents, profile, content_type),
65 delegate_(delegate) {
66 // Notifications do not have a bubble.
67 DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
68 SetBlockedResources();
69 SetTitle();
70 SetManageLink();
73 void ContentSettingTitleAndLinkModel::SetBlockedResources() {
74 TabSpecificContentSettings* settings =
75 TabSpecificContentSettings::FromWebContents(web_contents());
76 const std::set<std::string>& resources = settings->BlockedResourcesForType(
77 content_type());
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);
115 int title_id =
116 GetIdForContentType(title_ids, num_title_ids, content_type());
117 if (title_id)
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() {
137 if (delegate_)
138 delegate_->ShowContentSettingsPage(content_type());
141 class ContentSettingTitleLinkAndCustomModel
142 : public ContentSettingTitleAndLinkModel {
143 public:
144 ContentSettingTitleLinkAndCustomModel(Delegate* delegate,
145 WebContents* web_contents,
146 Profile* profile,
147 ContentSettingsType content_type);
148 virtual ~ContentSettingTitleLinkAndCustomModel() {}
150 private:
151 void SetCustomLink();
152 virtual void OnCustomLinkClicked() {}
155 ContentSettingTitleLinkAndCustomModel::ContentSettingTitleLinkAndCustomModel(
156 Delegate* delegate,
157 WebContents* web_contents,
158 Profile* profile,
159 ContentSettingsType content_type)
160 : ContentSettingTitleAndLinkModel(
161 delegate, web_contents, profile, content_type) {
162 SetCustomLink();
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},
171 int custom_link_id =
172 GetIdForContentType(kCustomIDs, arraysize(kCustomIDs), content_type());
173 if (custom_link_id)
174 set_custom_link(l10n_util::GetStringUTF8(custom_link_id));
177 class ContentSettingSingleRadioGroup
178 : public ContentSettingTitleLinkAndCustomModel {
179 public:
180 ContentSettingSingleRadioGroup(Delegate* delegate,
181 WebContents* web_contents,
182 Profile* profile,
183 ContentSettingsType content_type);
184 virtual ~ContentSettingSingleRadioGroup();
186 protected:
187 bool settings_changed() const;
189 private:
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_;
196 int selected_item_;
199 ContentSettingSingleRadioGroup::ContentSettingSingleRadioGroup(
200 Delegate* delegate,
201 WebContents* web_contents,
202 Profile* profile,
203 ContentSettingsType content_type)
204 : ContentSettingTitleLinkAndCustomModel(delegate, web_contents, profile,
205 content_type),
206 block_setting_(CONTENT_SETTING_BLOCK),
207 selected_item_(0) {
208 SetRadioGroup();
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());
219 } else {
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(
238 url,
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);
295 } else {
296 SettingInfo info;
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;
303 } else {
304 most_restrictive_setting = CONTENT_SETTING_ALLOW;
305 for (std::set<std::string>::const_iterator it = resources.begin();
306 it != resources.end(); ++it) {
307 SettingInfo info;
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;
315 break;
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|.
326 } else {
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);
332 } else {
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) {
342 if (profile()) {
343 profile()->GetHostContentSettingsMap()->AddExceptionForURL(
344 bubble_content().radio_group.url,
345 bubble_content().radio_group.url,
346 content_type(),
347 resource_identifier,
348 setting);
352 void ContentSettingSingleRadioGroup::OnRadioClicked(int radio_index) {
353 selected_item_ = radio_index;
356 class ContentSettingCookiesBubbleModel : public ContentSettingSingleRadioGroup {
357 public:
358 ContentSettingCookiesBubbleModel(Delegate* delegate,
359 WebContents* web_contents,
360 Profile* profile,
361 ContentSettingsType content_type);
363 virtual ~ContentSettingCookiesBubbleModel();
365 private:
366 virtual void OnCustomLinkClicked() OVERRIDE;
369 ContentSettingCookiesBubbleModel::ContentSettingCookiesBubbleModel(
370 Delegate* delegate,
371 WebContents* web_contents,
372 Profile* profile,
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() {
390 if (!web_contents())
391 return;
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 {
401 public:
402 ContentSettingPluginBubbleModel(Delegate* delegate,
403 WebContents* web_contents,
404 Profile* profile,
405 ContentSettingsType content_type);
407 virtual ~ContentSettingPluginBubbleModel() {}
409 private:
410 virtual void OnCustomLinkClicked() OVERRIDE;
413 ContentSettingPluginBubbleModel::ContentSettingPluginBubbleModel(
414 Delegate* delegate,
415 WebContents* web_contents,
416 Profile* profile,
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(),
432 std::string()));
433 set_custom_link_enabled(false);
434 TabSpecificContentSettings::FromWebContents(web_contents())->
435 set_load_plugins_link_enabled(false);
438 class ContentSettingPopupBubbleModel : public ContentSettingSingleRadioGroup {
439 public:
440 ContentSettingPopupBubbleModel(Delegate* delegate,
441 WebContents* web_contents,
442 Profile* profile,
443 ContentSettingsType content_type);
444 virtual ~ContentSettingPopupBubbleModel() {}
446 private:
447 void SetPopups();
448 virtual void OnPopupClicked(int index);
451 ContentSettingPopupBubbleModel::ContentSettingPopupBubbleModel(
452 Delegate* delegate,
453 WebContents* web_contents,
454 Profile* profile,
455 ContentSettingsType content_type)
456 : ContentSettingSingleRadioGroup(
457 delegate, web_contents, profile, content_type) {
458 SetPopups();
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.
471 if (title.empty())
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 {
490 public:
491 ContentSettingDomainListBubbleModel(Delegate* delegate,
492 WebContents* web_contents,
493 Profile* profile,
494 ContentSettingsType content_type);
495 virtual ~ContentSettingDomainListBubbleModel() {}
497 private:
498 void MaybeAddDomainList(const std::set<std::string>& hosts, int title_id);
499 void SetDomainsAndCustomLink();
500 virtual void OnCustomLinkClicked() OVERRIDE;
503 ContentSettingDomainListBubbleModel::ContentSettingDomainListBubbleModel(
504 Delegate* delegate,
505 WebContents* web_contents,
506 Profile* profile,
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
534 // permission state.
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() {
553 if (!web_contents())
554 return;
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,
571 std::string(),
572 CONTENT_SETTING_DEFAULT);
576 class ContentSettingMixedScriptBubbleModel
577 : public ContentSettingTitleLinkAndCustomModel {
578 public:
579 ContentSettingMixedScriptBubbleModel(Delegate* delegate,
580 WebContents* web_contents,
581 Profile* profile,
582 ContentSettingsType content_type);
584 virtual ~ContentSettingMixedScriptBubbleModel() {}
586 private:
587 virtual void OnCustomLinkClicked() OVERRIDE;
590 ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel(
591 Delegate* delegate,
592 WebContents* web_contents,
593 Profile* profile,
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(
610 Delegate* delegate,
611 WebContents* web_contents,
612 Profile* profile,
613 ProtocolHandlerRegistry* registry,
614 ContentSettingsType content_type)
615 : ContentSettingTitleAndLinkModel(
616 delegate, web_contents, profile, content_type),
617 selected_item_(0),
618 registry_(registry),
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();
629 string16 protocol;
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);
636 } else {
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()),
644 protocol));
645 } else {
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;
673 else
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)
683 return;
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();
693 else
694 NOTREACHED();
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());
735 } else {
736 registry_->OnAcceptRegisterProtocolHandler(previous_handler_);
740 // static
741 ContentSettingBubbleModel*
742 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
743 Delegate* delegate,
744 WebContents* web_contents,
745 Profile* profile,
746 ContentSettingsType content_type) {
747 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES) {
748 return new ContentSettingCookiesBubbleModel(delegate, web_contents, profile,
749 content_type);
751 if (content_type == CONTENT_SETTINGS_TYPE_POPUPS) {
752 return new ContentSettingPopupBubbleModel(delegate, web_contents, profile,
753 content_type);
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,
761 content_type);
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,
774 content_type);
777 ContentSettingBubbleModel::ContentSettingBubbleModel(
778 WebContents* web_contents,
779 Profile* profile,
780 ContentSettingsType content_type)
781 : web_contents_(web_contents),
782 profile_(profile),
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(
815 int type,
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;
822 } else {
823 DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type);
824 DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
825 profile_ = NULL;