1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/options/website_settings_handler.h"
7 #include "base/metrics/histogram.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_iterator.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "components/content_settings/core/browser/content_settings_utils.h"
14 #include "components/content_settings/core/browser/host_content_settings_map.h"
15 #include "components/power/origin_power_map.h"
16 #include "components/power/origin_power_map_factory.h"
17 #include "content/public/browser/dom_storage_context.h"
18 #include "content/public/browser/storage_partition.h"
19 #include "content/public/browser/user_metrics.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/browser/web_ui.h"
22 #include "extensions/browser/app_window/app_window_registry.h"
23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/common/constants.h"
25 #include "extensions/common/extension.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/l10n/time_format.h"
28 #include "ui/base/text/bytes_formatting.h"
30 #if defined(OS_CHROMEOS)
31 #include "components/user_manager/user_manager.h"
34 using base::UserMetricsAction
;
35 using power::OriginPowerMap
;
36 using power::OriginPowerMapFactory
;
40 const char kBattery
[] = "battery";
41 const int kHttpPort
= 80;
42 const int kHttpsPort
= 443;
43 const char kPreferencesSource
[] = "preference";
44 const char kStorage
[] = "storage";
45 const ContentSettingsType kValidTypes
[] = {
46 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
,
47 CONTENT_SETTINGS_TYPE_COOKIES
,
48 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
49 CONTENT_SETTINGS_TYPE_IMAGES
,
50 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
51 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
52 CONTENT_SETTINGS_TYPE_MEDIASTREAM
,
53 CONTENT_SETTINGS_TYPE_PLUGINS
,
54 CONTENT_SETTINGS_TYPE_POPUPS
};
55 const size_t kValidTypesLength
= arraysize(kValidTypes
);
57 // Enumeration used for UMA Histograms of parsing last_setting_.
58 // Do not insert, remove, or reorder. Add only to end.
59 // TODO: Remove histogram by 2015. crbug.com/433475
60 enum LastSettingParsed
{
65 UPDATE_ORIGINS_PARSED
,
66 UPDATE_ORIGINS_INVALID
,
67 HANDLE_UPDATE_ORIGINS_EMPTY
,
68 HANDLE_UPDATE_ORIGINS_PARSED
,
69 HANDLE_UPDATE_ORIGINS_INVALID
,
70 LAST_SETTING_MAX_ENUMERATION_VALUE
73 void RecordUmaHistogramOfLastSetting(LastSettingParsed parsed
) {
74 UMA_HISTOGRAM_ENUMERATION("ContentSettings.LastSettingParsed", parsed
,
75 LAST_SETTING_MAX_ENUMERATION_VALUE
);
82 WebsiteSettingsHandler::WebsiteSettingsHandler()
84 weak_ptr_factory_(this) {
87 WebsiteSettingsHandler::~WebsiteSettingsHandler() {
90 void WebsiteSettingsHandler::GetLocalizedValues(
91 base::DictionaryValue
* localized_strings
) {
92 DCHECK(localized_strings
);
94 static OptionsStringResource resources
[] = {
95 {"websitesOptionsPageTabTitle", IDS_WEBSITE_SETTINGS_TITLE
},
96 {"websitesSettingsEditPage", IDS_WEBSITE_SETTINGS_EDIT_TITLE
},
97 {"websitesManage", IDS_WEBSITE_SETTINGS_MANAGE
},
98 {"websitesSearch", IDS_WEBSITE_SETTINGS_SEARCH_ORIGINS
},
99 {"websitesLabelLocation", IDS_WEBSITE_SETTINGS_TYPE_LOCATION
},
100 {"websitesLabelMediaStream", IDS_WEBSITE_SETTINGS_TYPE_MEDIASTREAM
},
101 {"websitesLabelNotifications", IDS_WEBSITE_SETTINGS_TYPE_NOTIFICATIONS
},
102 {"websitesLabelOn", IDS_WEBSITE_SETTINGS_CONTENT_SETTING_ENABLED
},
103 {"websitesLabelStorage", IDS_WEBSITE_SETTINGS_TYPE_STORAGE
},
104 {"websitesLabelBattery", IDS_WEBSITE_SETTINGS_TYPE_BATTERY
},
105 {"websitesCookiesDescription", IDS_WEBSITE_SETTINGS_COOKIES_DESCRIPTION
},
106 {"websitesLocationDescription",
107 IDS_WEBSITE_SETTINGS_LOCATION_DESCRIPTION
},
108 {"websitesMediaStreamDescription",
109 IDS_WEBSITE_SETTINGS_MEDIASTREAM_DESCRIPTION
},
110 {"websitesNotificationsDescription",
111 IDS_WEBSITE_SETTINGS_NOTIFICATIONS_DESCRIPTION
},
112 {"websitesDownloadsDescription",
113 IDS_WEBSITE_SETTINGS_DOWNLOAD_DESCRIPTION
},
114 {"websitesPluginsDescription", IDS_WEBSITE_SETTINGS_PLUGINS_DESCRIPTION
},
115 {"websitesPopupsDescription", IDS_WEBSITE_SETTINGS_POPUPS_DESCRIPTION
},
116 {"websitesJavascriptDescription",
117 IDS_WEBSITE_SETTINGS_JAVASCRIPT_DESCRIPTION
},
118 {"websitesImagesDescription", IDS_WEBSITE_SETTINGS_IMAGES_DESCRIPTION
},
119 {"websitesButtonClear", IDS_WEBSITE_SETTINGS_STORAGE_CLEAR_BUTTON
},
120 {"websitesButtonStop", IDS_WEBSITE_SETTINGS_BATTERY_STOP_BUTTON
},
121 {"websitesAllowedListTitle", IDS_WEBSITE_SETTINGS_ALLOWED_LIST_TITLE
},
122 {"websitesBlockedListTitle", IDS_WEBSITE_SETTINGS_BLOCKED_LIST_TITLE
},
123 {"storageTabLabel", IDS_WEBSITE_SETTINGS_TYPE_STORAGE
},
124 {"batteryTabLabel", IDS_WEBSITE_SETTINGS_TYPE_BATTERY
},
127 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
129 localized_strings
, "websiteSettingsPage", IDS_WEBSITE_SETTINGS_TITLE
);
132 void WebsiteSettingsHandler::InitializeHandler() {
133 Profile
* profile
= GetProfile();
134 HostContentSettingsMap
* settings
= profile
->GetHostContentSettingsMap();
135 observer_
.Add(settings
);
137 power::OriginPowerMap
* origin_power_map
=
138 power::OriginPowerMapFactory::GetForBrowserContext(profile
);
139 // OriginPowerMap may not be available in tests.
140 if (origin_power_map
) {
141 subscription_
= origin_power_map
->AddPowerConsumptionUpdatedCallback(
142 base::Bind(&WebsiteSettingsHandler::Update
, base::Unretained(this)));
146 void WebsiteSettingsHandler::RegisterMessages() {
147 web_ui()->RegisterMessageCallback(
149 base::Bind(&WebsiteSettingsHandler::HandleUpdateOrigins
,
150 base::Unretained(this)));
152 web_ui()->RegisterMessageCallback(
153 "updateOriginsSearchResults",
154 base::Bind(&WebsiteSettingsHandler::HandleUpdateSearchResults
,
155 base::Unretained(this)));
157 web_ui()->RegisterMessageCallback(
158 "updateLocalStorage",
159 base::Bind(&WebsiteSettingsHandler::HandleUpdateLocalStorage
,
160 base::Unretained(this)));
162 web_ui()->RegisterMessageCallback(
163 "updateBatteryUsage",
164 base::Bind(&WebsiteSettingsHandler::HandleUpdateBatteryUsage
,
165 base::Unretained(this)));
167 web_ui()->RegisterMessageCallback(
169 base::Bind(&WebsiteSettingsHandler::HandleGetOriginInfo
,
170 base::Unretained(this)));
172 web_ui()->RegisterMessageCallback(
173 "setOriginPermission",
174 base::Bind(&WebsiteSettingsHandler::HandleSetOriginPermission
,
175 base::Unretained(this)));
177 web_ui()->RegisterMessageCallback(
179 base::Bind(&WebsiteSettingsHandler::HandleMaybeShowEditPage
,
180 base::Unretained(this)));
182 web_ui()->RegisterMessageCallback(
183 "deleteLocalStorage",
184 base::Bind(&WebsiteSettingsHandler::HandleDeleteLocalStorage
,
185 base::Unretained(this)));
187 web_ui()->RegisterMessageCallback(
189 base::Bind(&WebsiteSettingsHandler::HandleStopOrigin
,
190 base::Unretained(this)));
192 web_ui()->RegisterMessageCallback(
193 "updateDefaultSetting",
194 base::Bind(&WebsiteSettingsHandler::HandleUpdateDefaultSetting
,
195 base::Unretained(this)));
197 web_ui()->RegisterMessageCallback(
198 "setDefaultContentSetting",
199 base::Bind(&WebsiteSettingsHandler::HandleSetDefaultSetting
,
200 base::Unretained(this)));
202 web_ui()->RegisterMessageCallback(
204 base::Bind(&WebsiteSettingsHandler::HandleSetGlobalToggle
,
205 base::Unretained(this)));
208 // content_settings::Observer implementation.
209 void WebsiteSettingsHandler::OnContentSettingChanged(
210 const ContentSettingsPattern
& primary_pattern
,
211 const ContentSettingsPattern
& secondary_pattern
,
212 ContentSettingsType content_type
,
213 std::string resource_identifier
) {
217 void WebsiteSettingsHandler::OnContentSettingUsed(
218 const ContentSettingsPattern
& primary_pattern
,
219 const ContentSettingsPattern
& secondary_pattern
,
220 ContentSettingsType content_type
) {
224 void WebsiteSettingsHandler::HandleUpdateOrigins(const base::ListValue
* args
) {
225 std::string content_setting_name
;
226 bool rv
= args
->GetString(0, &content_setting_name
);
229 ContentSettingsType content_type
;
230 if (!content_settings::GetTypeFromName(content_setting_name
, &content_type
))
233 kValidTypes
+ kValidTypesLength
,
234 std::find(kValidTypes
, kValidTypes
+ kValidTypesLength
, content_type
));
236 last_setting_
= content_setting_name
;
238 // Histogram to understand the source of parsing errors. crbug.com/432600.
239 // TODO: Remove histogram by 2015. crbug.com/433475
240 ContentSettingsType last_setting
;
241 if (!content_settings::GetTypeFromName(last_setting_
, &last_setting
)) {
242 if (last_setting_
.empty())
243 RecordUmaHistogramOfLastSetting(HANDLE_UPDATE_ORIGINS_EMPTY
);
245 RecordUmaHistogramOfLastSetting(HANDLE_UPDATE_ORIGINS_INVALID
);
247 RecordUmaHistogramOfLastSetting(HANDLE_UPDATE_ORIGINS_PARSED
);
253 void WebsiteSettingsHandler::HandleUpdateSearchResults(
254 const base::ListValue
* args
) {
255 bool rv
= args
->GetString(0, &last_filter_
);
261 void WebsiteSettingsHandler::HandleUpdateLocalStorage(
262 const base::ListValue
* args
) {
263 if (!local_storage_
.get()) {
264 Profile
* profile
= GetProfile();
265 local_storage_
= new BrowsingDataLocalStorageHelper(profile
);
268 last_setting_
= kStorage
;
270 local_storage_
->StartFetching(
271 base::Bind(&WebsiteSettingsHandler::OnLocalStorageFetched
,
272 weak_ptr_factory_
.GetWeakPtr()));
275 void WebsiteSettingsHandler::HandleMaybeShowEditPage(
276 const base::ListValue
* args
) {
278 bool rv
= args
->GetString(0, &site
);
281 GURL
last_site(site
);
282 if (!last_site
.is_valid())
285 last_site_
= last_site
;
286 base::StringValue
site_value(site
);
287 web_ui()->CallJavascriptFunction("WebsiteSettingsEditor.showEditPage",
291 void WebsiteSettingsHandler::OnLocalStorageFetched(const std::list
<
292 BrowsingDataLocalStorageHelper::LocalStorageInfo
>& storage
) {
293 local_storage_list_
= storage
;
295 GetInfoForOrigin(last_site_
, false);
298 void WebsiteSettingsHandler::Update() {
299 DCHECK(!last_setting_
.empty());
301 // Histogram to understand the source of parsing errors. crbug.com/432600.
302 // TODO: Remove histogram by 2015. crbug.com/433475
303 ContentSettingsType last_setting
;
304 if (!content_settings::GetTypeFromName(last_setting_
, &last_setting
)) {
305 if (last_setting_
.empty())
306 RecordUmaHistogramOfLastSetting(UPDATE_EMPTY
);
308 RecordUmaHistogramOfLastSetting(UPDATE_INVALID
);
310 RecordUmaHistogramOfLastSetting(UPDATE_PARSED
);
313 if (last_setting_
== kStorage
)
314 UpdateLocalStorage();
315 else if (last_setting_
== kBattery
)
316 UpdateBatteryUsage();
321 void WebsiteSettingsHandler::UpdateOrigins() {
322 Profile
* profile
= GetProfile();
323 HostContentSettingsMap
* settings
= profile
->GetHostContentSettingsMap();
325 ContentSettingsForOneType all_settings
;
326 ContentSettingsType last_setting
;
327 if (!content_settings::GetTypeFromName(last_setting_
, &last_setting
)) {
328 // TODO: Remove histogram by 2015. crbug.com/433475
329 if (last_setting_
.empty())
330 RecordUmaHistogramOfLastSetting(UPDATE_ORIGINS_EMPTY
);
332 RecordUmaHistogramOfLastSetting(UPDATE_ORIGINS_INVALID
);
336 RecordUmaHistogramOfLastSetting(UPDATE_ORIGINS_PARSED
);
338 if (last_setting
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
)
339 last_setting
= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
;
341 settings
->GetSettingsForOneType(last_setting
, std::string(), &all_settings
);
343 base::DictionaryValue allowed_origins
;
344 base::DictionaryValue blocked_origins
;
345 for (ContentSettingsForOneType::const_iterator it
= all_settings
.begin();
346 it
!= all_settings
.end();
348 // Don't add default settings.
349 if (it
->primary_pattern
== ContentSettingsPattern::Wildcard() &&
350 it
->secondary_pattern
== ContentSettingsPattern::Wildcard() &&
351 it
->source
!= kPreferencesSource
) {
355 GURL
origin_url(it
->primary_pattern
.ToString());
356 std::string origin
= origin_url
.spec();
358 // Hide the port if it is using a standard URL scheme.
359 if ((origin_url
.SchemeIs(url::kHttpScheme
) &&
360 origin_url
.IntPort() == kHttpPort
) ||
361 (origin_url
.SchemeIs(url::kHttpsScheme
) &&
362 origin_url
.IntPort() == kHttpsPort
)) {
363 url::Replacements
<char> replacements
;
364 replacements
.ClearPort();
365 origin
= origin_url
.ReplaceComponents(replacements
).spec();
368 // Mediastream isn't set unless both mic and camera are set to the same.
369 if (last_setting
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
) {
370 ContentSetting cam_setting
= settings
->GetContentSettingWithoutOverride(
373 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
,
375 if (it
->setting
!= cam_setting
)
379 if (origin
.find(last_filter_
) == base::string16::npos
)
382 base::Time last_usage
= settings
->GetLastUsageByPattern(
383 it
->primary_pattern
, it
->secondary_pattern
, last_setting
);
385 scoped_ptr
<base::DictionaryValue
> origin_entry(new base::DictionaryValue());
386 origin_entry
->SetDoubleWithoutPathExpansion("usage",
387 last_usage
.ToDoubleT());
388 base::string16 usage_string
;
389 if (last_usage
.ToDoubleT()) {
390 usage_string
= ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED
,
391 ui::TimeFormat::LENGTH_SHORT
,
392 base::Time::Now() - last_usage
);
394 origin_entry
->SetStringWithoutPathExpansion("usageString", usage_string
);
395 origin_entry
->SetStringWithoutPathExpansion("readableName",
396 GetReadableName(origin_url
));
398 if (it
->setting
== CONTENT_SETTING_BLOCK
)
399 blocked_origins
.SetWithoutPathExpansion(origin
, origin_entry
.Pass());
401 allowed_origins
.SetWithoutPathExpansion(origin
, origin_entry
.Pass());
404 bool is_globally_allowed
= settings
->GetContentSettingOverride(last_setting
);
405 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins",
408 base::FundamentalValue(is_globally_allowed
));
411 void WebsiteSettingsHandler::HandleGetOriginInfo(const base::ListValue
* args
) {
413 bool rv
= args
->GetString(0, &url
);
417 if (!origin
.is_valid())
420 GetInfoForOrigin(origin
, true);
423 void WebsiteSettingsHandler::HandleSetOriginPermission(
424 const base::ListValue
* args
) {
425 std::string setting_name
;
426 bool rv
= args
->GetString(0, &setting_name
);
428 ContentSettingsType settings_type
;
429 if (!content_settings::GetTypeFromName(setting_name
, &settings_type
))
433 rv
= args
->GetString(1, &value
);
436 ContentSetting setting
= content_settings::ContentSettingFromString(value
);
437 Profile
* profile
= GetProfile();
438 HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
439 ContentSetting default_value
=
440 map
->GetDefaultContentSetting(settings_type
, NULL
);
442 // Users are not allowed to be the source of the "ask" setting. It is an
443 // ephemeral setting which is removed once the question is asked.
444 if (setting
== CONTENT_SETTING_ASK
&& setting
== default_value
)
445 setting
= CONTENT_SETTING_DEFAULT
;
447 ContentSettingsPattern primary_pattern
;
448 ContentSettingsPattern secondary_pattern
;
449 switch (settings_type
) {
450 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
451 primary_pattern
= ContentSettingsPattern::FromURLNoWildcard(last_site_
);
452 secondary_pattern
= ContentSettingsPattern::Wildcard();
454 case CONTENT_SETTINGS_TYPE_MEDIASTREAM
:
455 primary_pattern
= ContentSettingsPattern::FromURLNoWildcard(last_site_
);
456 secondary_pattern
= ContentSettingsPattern::Wildcard();
457 map
->SetContentSetting(primary_pattern
,
459 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
462 map
->SetContentSetting(primary_pattern
,
464 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
,
468 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
:
469 case CONTENT_SETTINGS_TYPE_COOKIES
:
470 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
471 case CONTENT_SETTINGS_TYPE_IMAGES
:
472 case CONTENT_SETTINGS_TYPE_JAVASCRIPT
:
473 case CONTENT_SETTINGS_TYPE_PLUGINS
:
474 case CONTENT_SETTINGS_TYPE_POPUPS
:
475 primary_pattern
= ContentSettingsPattern::FromURLNoWildcard(last_site_
);
476 secondary_pattern
= ContentSettingsPattern::FromURLNoWildcard(last_site_
);
479 NOTREACHED() << "Content settings type not yet supported.";
483 content_settings::SettingInfo info
;
484 scoped_ptr
<base::Value
> v(map
->GetWebsiteSettingWithoutOverride(
485 last_site_
, last_site_
, settings_type
, std::string(), &info
));
486 map
->SetNarrowestWebsiteSetting(primary_pattern
,
494 void WebsiteSettingsHandler::HandleUpdateBatteryUsage(
495 const base::ListValue
* args
) {
496 last_setting_
= kBattery
;
497 UpdateBatteryUsage();
500 void WebsiteSettingsHandler::HandleDeleteLocalStorage(
501 const base::ListValue
* args
) {
502 DCHECK(!last_site_
.is_empty());
503 DeleteLocalStorage(last_site_
);
506 void WebsiteSettingsHandler::HandleStopOrigin(const base::ListValue
* args
) {
507 DCHECK(!last_site_
.is_empty());
508 StopOrigin(last_site_
);
511 void WebsiteSettingsHandler::HandleUpdateDefaultSetting(
512 const base::ListValue
* args
) {
513 ContentSettingsType type
;
514 if (!content_settings::GetTypeFromName(last_setting_
, &type
))
517 Profile
* profile
= GetProfile();
518 std::string provider_id
;
519 ContentSetting default_setting
=
520 profile
->GetHostContentSettingsMap()->GetDefaultContentSetting(
523 base::DictionaryValue filter_settings
;
524 filter_settings
.SetString(
525 "value", content_settings::ContentSettingToString(default_setting
));
526 filter_settings
.SetString("managedBy", provider_id
);
528 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.updateDefault",
532 void WebsiteSettingsHandler::HandleSetDefaultSetting(
533 const base::ListValue
* args
) {
534 DCHECK_EQ(1U, args
->GetSize());
536 if (!args
->GetString(0, &setting
)) {
540 ContentSetting new_default
=
541 content_settings::ContentSettingFromString(setting
);
543 ContentSettingsType last_setting
;
544 if (!content_settings::GetTypeFromName(last_setting_
, &last_setting
))
546 Profile
* profile
= GetProfile();
548 HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
549 map
->SetDefaultContentSetting(last_setting
, new_default
);
551 switch (last_setting
) {
552 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
:
553 content::RecordAction(
554 UserMetricsAction("Options_DefaultMultipleAutomaticDLSettingChange"));
556 case CONTENT_SETTINGS_TYPE_COOKIES
:
557 content::RecordAction(
558 UserMetricsAction("Options_DefaultCookieSettingChanged"));
560 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
561 content::RecordAction(
562 UserMetricsAction("Options_DefaultGeolocationSettingChanged"));
564 case CONTENT_SETTINGS_TYPE_IMAGES
:
565 content::RecordAction(
566 UserMetricsAction("Options_DefaultImagesSettingChanged"));
568 case CONTENT_SETTINGS_TYPE_JAVASCRIPT
:
569 content::RecordAction(
570 UserMetricsAction("Options_DefaultJavaScriptSettingChanged"));
572 case CONTENT_SETTINGS_TYPE_MEDIASTREAM
:
573 content::RecordAction(
574 UserMetricsAction("Options_DefaultMediaStreamMicSettingChanged"));
576 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
577 content::RecordAction(
578 UserMetricsAction("Options_DefaultNotificationsSettingChanged"));
580 case CONTENT_SETTINGS_TYPE_PLUGINS
:
581 content::RecordAction(
582 UserMetricsAction("Options_DefaultPluginsSettingChanged"));
584 case CONTENT_SETTINGS_TYPE_POPUPS
:
585 content::RecordAction(
586 UserMetricsAction("Options_DefaultPopupsSettingChanged"));
594 void WebsiteSettingsHandler::HandleSetGlobalToggle(
595 const base::ListValue
* args
) {
596 DCHECK_EQ(1U, args
->GetSize());
598 bool rv
= args
->GetBoolean(0, &is_enabled
);
601 ContentSettingsType last_setting
;
602 if (!content_settings::GetTypeFromName(last_setting_
, &last_setting
))
605 Profile
* profile
= GetProfile();
606 HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
607 map
->SetContentSettingOverride(last_setting
, is_enabled
);
610 void WebsiteSettingsHandler::GetInfoForOrigin(const GURL
& site_url
,
612 Profile
* profile
= GetProfile();
613 HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
615 double storage
= 0.0;
616 for (LocalStorageList::const_iterator it
= local_storage_list_
.begin();
617 it
!= local_storage_list_
.end();
619 if (it
->origin_url
== site_url
) {
620 storage
= static_cast<double>(it
->size
);
626 battery
= OriginPowerMapFactory::GetForBrowserContext(
627 GetProfile())->GetPowerForOrigin(site_url
);
629 base::DictionaryValue
* permissions
= new base::DictionaryValue
;
630 for (size_t i
= 0; i
< arraysize(kValidTypes
); ++i
) {
631 ContentSettingsType permission_type
= kValidTypes
[i
];
633 // Append the possible settings.
634 scoped_ptr
<base::ListValue
> options(new base::ListValue());
635 ContentSetting default_value
=
636 map
->GetDefaultContentSetting(permission_type
, NULL
);
637 if (default_value
!= CONTENT_SETTING_ALLOW
&&
638 default_value
!= CONTENT_SETTING_BLOCK
) {
639 options
->AppendString(
640 content_settings::ContentSettingToString(default_value
));
642 options
->AppendString(
643 content_settings::ContentSettingToString(CONTENT_SETTING_ALLOW
));
644 options
->AppendString(
645 content_settings::ContentSettingToString(CONTENT_SETTING_BLOCK
));
646 if (permission_type
== CONTENT_SETTINGS_TYPE_COOKIES
) {
647 options
->AppendString(content_settings::ContentSettingToString(
648 CONTENT_SETTING_SESSION_ONLY
));
651 ContentSetting permission
;
652 content_settings::SettingInfo info
;
653 if (permission_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
) {
654 scoped_ptr
<base::Value
> mic_value(map
->GetWebsiteSettingWithoutOverride(
657 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
660 ContentSetting mic_setting
=
661 content_settings::ValueToContentSetting(mic_value
.get());
662 ContentSetting cam_setting
= map
->GetContentSettingWithoutOverride(
665 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
,
668 if (mic_setting
!= cam_setting
)
669 permission
= CONTENT_SETTING_ASK
;
671 permission
= mic_setting
;
673 scoped_ptr
<base::Value
> v(map
->GetWebsiteSettingWithoutOverride(
674 site_url
, site_url
, permission_type
, std::string(), &info
));
675 permission
= content_settings::ValueToContentSetting(v
.get());
678 scoped_ptr
<base::DictionaryValue
>
679 permission_info(new base::DictionaryValue());
680 permission_info
->SetStringWithoutPathExpansion(
681 "setting", content_settings::ContentSettingToString(permission
));
682 permission_info
->SetWithoutPathExpansion("options", options
.Pass());
683 permission_info
->SetBooleanWithoutPathExpansion(
684 "editable", info
.source
== content_settings::SETTING_SOURCE_USER
);
685 permissions
->SetWithoutPathExpansion(
686 content_settings::GetTypeName(permission_type
), permission_info
.Pass());
689 base::Value
* storage_used
= new base::StringValue(l10n_util::GetStringFUTF16(
690 IDS_WEBSITE_SETTINGS_STORAGE_USED
, ui::FormatBytes(storage
)));
691 base::Value
* battery_used
=
692 new base::StringValue(l10n_util::GetStringFUTF16Int(
693 IDS_WEBSITE_SETTINGS_BATTERY_USED
, battery
));
695 web_ui()->CallJavascriptFunction("WebsiteSettingsEditor.populateOrigin",
699 base::FundamentalValue(show_page
));
702 void WebsiteSettingsHandler::UpdateLocalStorage() {
703 base::DictionaryValue local_storage_map
;
704 for (LocalStorageList::const_iterator it
= local_storage_list_
.begin();
705 it
!= local_storage_list_
.end();
707 std::string origin
= it
->origin_url
.spec();
709 if (origin
.find(last_filter_
) == base::string16::npos
)
712 scoped_ptr
<base::DictionaryValue
> origin_entry(new base::DictionaryValue());
713 origin_entry
->SetDoubleWithoutPathExpansion(
714 "usage", static_cast<double>(it
->size
));
715 origin_entry
->SetStringWithoutPathExpansion(
716 "usageString", ui::FormatBytes(it
->size
));
717 origin_entry
->SetStringWithoutPathExpansion(
718 "readableName", GetReadableName(it
->origin_url
));
719 local_storage_map
.SetWithoutPathExpansion(origin
, origin_entry
.Pass());
721 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins",
725 void WebsiteSettingsHandler::UpdateBatteryUsage() {
726 base::DictionaryValue power_map
;
727 OriginPowerMap
* origins
=
728 OriginPowerMapFactory::GetForBrowserContext(GetProfile());
729 OriginPowerMap::PercentOriginMap percent_map
= origins
->GetPercentOriginMap();
730 for (std::map
<GURL
, int>::iterator it
= percent_map
.begin();
731 it
!= percent_map
.end();
733 std::string origin
= it
->first
.spec();
735 if (origin
.find(last_filter_
) == base::string16::npos
)
738 scoped_ptr
<base::DictionaryValue
> origin_entry(new base::DictionaryValue());
739 origin_entry
->SetInteger("usage", it
->second
);
740 if (it
->second
== 0) {
741 origin_entry
->SetString(
743 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_BATTERY_ZERO_PERCENT
));
745 origin_entry
->SetString(
747 l10n_util::GetStringFUTF16Int(IDS_WEBSITE_SETTINGS_BATTERY_PERCENT
,
750 origin_entry
->SetStringWithoutPathExpansion("readableName",
751 GetReadableName(it
->first
));
752 power_map
.SetWithoutPathExpansion(origin
, origin_entry
.Pass());
754 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins",
758 void WebsiteSettingsHandler::StopOrigin(const GURL
& site_url
) {
759 Profile
* profile
= GetProfile();
760 if (site_url
.SchemeIs(extensions::kExtensionScheme
)) {
761 const extensions::Extension
* extension
=
762 extensions::ExtensionRegistry::Get(profile
)
763 ->enabled_extensions()
764 .GetHostedAppByURL(site_url
);
766 extensions::AppWindowRegistry::Get(profile
)
767 ->CloseAllAppWindowsForApp(extension
->id());
771 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
772 Browser
* browser
= *it
;
773 TabStripModel
* model
= browser
->tab_strip_model();
774 for (int idx
= 0; idx
< model
->count(); idx
++) {
775 content::WebContents
* web_contents
= model
->GetWebContentsAt(idx
);
776 // Can't discard tabs that are already discarded or active.
777 if (model
->IsTabDiscarded(idx
) || (model
->active_index() == idx
))
780 // Don't discard tabs that belong to other profiles or other origins.
781 if (web_contents
->GetLastCommittedURL().GetOrigin() != site_url
||
783 Profile::FromBrowserContext(web_contents
->GetBrowserContext())) {
786 model
->DiscardWebContentsAt(idx
);
791 void WebsiteSettingsHandler::DeleteLocalStorage(const GURL
& site_url
) {
792 Profile
* profile
= GetProfile();
793 content::DOMStorageContext
* dom_storage_context_
=
794 content::BrowserContext::GetDefaultStoragePartition(profile
)
795 ->GetDOMStorageContext();
796 dom_storage_context_
->DeleteLocalStorage(site_url
);
798 // Load a new BrowsingDataLocalStorageHelper to update.
799 local_storage_
= new BrowsingDataLocalStorageHelper(profile
);
801 local_storage_
->StartFetching(
802 base::Bind(&WebsiteSettingsHandler::OnLocalStorageFetched
,
803 weak_ptr_factory_
.GetWeakPtr()));
806 const std::string
& WebsiteSettingsHandler::GetReadableName(
807 const GURL
& site_url
) {
808 if (site_url
.SchemeIs(extensions::kExtensionScheme
)) {
809 const extensions::ExtensionRegistry
* registry
=
810 extensions::ExtensionRegistry::Get(GetProfile());
811 const extensions::Extension
* extension
=
812 registry
->enabled_extensions().GetByID(site_url
.host());
813 // If extension is NULL, it was removed and we cannot look up its name.
815 return site_url
.spec();
817 return extension
->name();
819 return site_url
.spec();
822 Profile
* WebsiteSettingsHandler::GetProfile() {
823 Profile
* profile
= Profile::FromWebUI(web_ui());
824 #if defined(OS_CHROMEOS)
825 // Chrome OS special case: in Guest mode settings are opened in Incognito
826 // mode, so we need original profile to actually modify settings.
827 if (user_manager::UserManager::Get()->IsLoggedInAsGuest())
828 profile
= profile
->GetOriginalProfile();
833 } // namespace options