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. 4 5#include "chrome/browser/ui/webui/options/website_settings_handler.h" 6 7#include "chrome/browser/content_settings/content_settings_utils.h" 8#include "chrome/browser/content_settings/host_content_settings_map.h" 9#include "chrome/browser/extensions/extension_service.h" 10#include "chrome/browser/profiles/profile.h" 11#include "chrome/browser/ui/browser.h" 12#include "chrome/browser/ui/browser_iterator.h" 13#include "chrome/browser/ui/tabs/tab_strip_model.h" 14#include "chrome/grit/generated_resources.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/browser/extension_system.h" 25#include "extensions/common/constants.h" 26#include "extensions/common/extension.h" 27#include "ui/base/l10n/l10n_util.h" 28#include "ui/base/l10n/time_format.h" 29#include "ui/base/text/bytes_formatting.h" 30 31#if defined(OS_CHROMEOS) 32#include "components/user_manager/user_manager.h" 33#endif 34 35using base::UserMetricsAction; 36using power::OriginPowerMap; 37using power::OriginPowerMapFactory; 38 39namespace { 40 41const char kBattery[] = "battery"; 42const int kHttpPort = 80; 43const int kHttpsPort = 443; 44const char kPreferencesSource[] = "preference"; 45const char kStorage[] = "storage"; 46const ContentSettingsType kValidTypes[] = { 47 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, 48 CONTENT_SETTINGS_TYPE_COOKIES, 49 CONTENT_SETTINGS_TYPE_GEOLOCATION, 50 CONTENT_SETTINGS_TYPE_IMAGES, 51 CONTENT_SETTINGS_TYPE_JAVASCRIPT, 52 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 53 CONTENT_SETTINGS_TYPE_MEDIASTREAM, 54 CONTENT_SETTINGS_TYPE_PLUGINS, 55 CONTENT_SETTINGS_TYPE_POPUPS}; 56const size_t kValidTypesLength = arraysize(kValidTypes); 57 58} // namespace 59 60namespace options { 61 62WebsiteSettingsHandler::WebsiteSettingsHandler() 63 : observer_(this), 64 weak_ptr_factory_(this) { 65} 66 67WebsiteSettingsHandler::~WebsiteSettingsHandler() { 68} 69 70void WebsiteSettingsHandler::GetLocalizedValues( 71 base::DictionaryValue* localized_strings) { 72 DCHECK(localized_strings); 73 74 static OptionsStringResource resources[] = { 75 {"websitesOptionsPageTabTitle", IDS_WEBSITE_SETTINGS_TITLE}, 76 {"websitesSettingsEditPage", IDS_WEBSITE_SETTINGS_EDIT_TITLE}, 77 {"websitesManage", IDS_WEBSITE_SETTINGS_MANAGE}, 78 {"websitesSearch", IDS_WEBSITE_SETTINGS_SEARCH_ORIGINS}, 79 {"websitesLabelLocation", IDS_WEBSITE_SETTINGS_TYPE_LOCATION}, 80 {"websitesLabelMediaStream", IDS_WEBSITE_SETTINGS_TYPE_MEDIASTREAM}, 81 {"websitesLabelNotifications", IDS_WEBSITE_SETTINGS_TYPE_NOTIFICATIONS}, 82 {"websitesLabelOn", IDS_WEBSITE_SETTINGS_CONTENT_SETTING_ENABLED}, 83 {"websitesLabelStorage", IDS_WEBSITE_SETTINGS_TYPE_STORAGE}, 84 {"websitesLabelBattery", IDS_WEBSITE_SETTINGS_TYPE_BATTERY}, 85 {"websitesCookiesDescription", IDS_WEBSITE_SETTINGS_COOKIES_DESCRIPTION}, 86 {"websitesLocationDescription", 87 IDS_WEBSITE_SETTINGS_LOCATION_DESCRIPTION}, 88 {"websitesMediaStreamDescription", 89 IDS_WEBSITE_SETTINGS_MEDIASTREAM_DESCRIPTION}, 90 {"websitesNotificationsDescription", 91 IDS_WEBSITE_SETTINGS_NOTIFICATIONS_DESCRIPTION}, 92 {"websitesDownloadsDescription", 93 IDS_WEBSITE_SETTINGS_DOWNLOAD_DESCRIPTION}, 94 {"websitesPluginsDescription", IDS_WEBSITE_SETTINGS_PLUGINS_DESCRIPTION}, 95 {"websitesPopupsDescription", IDS_WEBSITE_SETTINGS_POPUPS_DESCRIPTION}, 96 {"websitesJavascriptDescription", 97 IDS_WEBSITE_SETTINGS_JAVASCRIPT_DESCRIPTION}, 98 {"websitesImagesDescription", IDS_WEBSITE_SETTINGS_IMAGES_DESCRIPTION}, 99 {"websitesButtonClear", IDS_WEBSITE_SETTINGS_STORAGE_CLEAR_BUTTON}, 100 {"websitesButtonStop", IDS_WEBSITE_SETTINGS_BATTERY_STOP_BUTTON}, 101 {"websitesAllowedListTitle", IDS_WEBSITE_SETTINGS_ALLOWED_LIST_TITLE}, 102 {"websitesBlockedListTitle", IDS_WEBSITE_SETTINGS_BLOCKED_LIST_TITLE}, 103 {"storageTabLabel", IDS_WEBSITE_SETTINGS_TYPE_STORAGE}, 104 {"batteryTabLabel", IDS_WEBSITE_SETTINGS_TYPE_BATTERY}, 105 }; 106 107 RegisterStrings(localized_strings, resources, arraysize(resources)); 108 RegisterTitle( 109 localized_strings, "websiteSettingsPage", IDS_WEBSITE_SETTINGS_TITLE); 110} 111 112void WebsiteSettingsHandler::InitializeHandler() { 113 Profile* profile = GetProfile(); 114 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap(); 115 observer_.Add(settings); 116 117 power::OriginPowerMap* origin_power_map = 118 power::OriginPowerMapFactory::GetForBrowserContext(profile); 119 // OriginPowerMap may not be available in tests. 120 if (origin_power_map) { 121 subscription_ = origin_power_map->AddPowerConsumptionUpdatedCallback( 122 base::Bind(&WebsiteSettingsHandler::Update, base::Unretained(this))); 123 } 124} 125 126void WebsiteSettingsHandler::RegisterMessages() { 127 web_ui()->RegisterMessageCallback( 128 "updateOrigins", 129 base::Bind(&WebsiteSettingsHandler::HandleUpdateOrigins, 130 base::Unretained(this))); 131 132 web_ui()->RegisterMessageCallback( 133 "updateOriginsSearchResults", 134 base::Bind(&WebsiteSettingsHandler::HandleUpdateSearchResults, 135 base::Unretained(this))); 136 137 web_ui()->RegisterMessageCallback( 138 "updateLocalStorage", 139 base::Bind(&WebsiteSettingsHandler::HandleUpdateLocalStorage, 140 base::Unretained(this))); 141 142 web_ui()->RegisterMessageCallback( 143 "updateBatteryUsage", 144 base::Bind(&WebsiteSettingsHandler::HandleUpdateBatteryUsage, 145 base::Unretained(this))); 146 147 web_ui()->RegisterMessageCallback( 148 "getOriginInfo", 149 base::Bind(&WebsiteSettingsHandler::HandleGetOriginInfo, 150 base::Unretained(this))); 151 152 web_ui()->RegisterMessageCallback( 153 "setOriginPermission", 154 base::Bind(&WebsiteSettingsHandler::HandleSetOriginPermission, 155 base::Unretained(this))); 156 157 web_ui()->RegisterMessageCallback( 158 "maybeShowEditPage", 159 base::Bind(&WebsiteSettingsHandler::HandleMaybeShowEditPage, 160 base::Unretained(this))); 161 162 web_ui()->RegisterMessageCallback( 163 "deleteLocalStorage", 164 base::Bind(&WebsiteSettingsHandler::HandleDeleteLocalStorage, 165 base::Unretained(this))); 166 167 web_ui()->RegisterMessageCallback( 168 "stopOrigin", 169 base::Bind(&WebsiteSettingsHandler::HandleStopOrigin, 170 base::Unretained(this))); 171 172 web_ui()->RegisterMessageCallback( 173 "updateDefaultSetting", 174 base::Bind(&WebsiteSettingsHandler::HandleUpdateDefaultSetting, 175 base::Unretained(this))); 176 177 web_ui()->RegisterMessageCallback( 178 "setDefaultContentSetting", 179 base::Bind(&WebsiteSettingsHandler::HandleSetDefaultSetting, 180 base::Unretained(this))); 181 182 web_ui()->RegisterMessageCallback( 183 "setGlobalEnabled", 184 base::Bind(&WebsiteSettingsHandler::HandleSetGlobalToggle, 185 base::Unretained(this))); 186} 187 188// content_settings::Observer implementation. 189void WebsiteSettingsHandler::OnContentSettingChanged( 190 const ContentSettingsPattern& primary_pattern, 191 const ContentSettingsPattern& secondary_pattern, 192 ContentSettingsType content_type, 193 std::string resource_identifier) { 194 Update(); 195} 196 197void WebsiteSettingsHandler::OnContentSettingUsed( 198 const ContentSettingsPattern& primary_pattern, 199 const ContentSettingsPattern& secondary_pattern, 200 ContentSettingsType content_type) { 201 Update(); 202} 203 204void WebsiteSettingsHandler::HandleUpdateOrigins(const base::ListValue* args) { 205 std::string content_setting_name; 206 bool rv = args->GetString(0, &content_setting_name); 207 DCHECK(rv); 208 209 ContentSettingsType content_type; 210 if (!content_settings::GetTypeFromName(content_setting_name, &content_type)) 211 return; 212 DCHECK_NE( 213 kValidTypes + kValidTypesLength, 214 std::find(kValidTypes, kValidTypes + kValidTypesLength, content_type)); 215 216 last_setting_ = content_setting_name; 217 UpdateOrigins(); 218} 219 220void WebsiteSettingsHandler::HandleUpdateSearchResults( 221 const base::ListValue* args) { 222 bool rv = args->GetString(0, &last_filter_); 223 DCHECK(rv); 224 225 Update(); 226} 227 228void WebsiteSettingsHandler::HandleUpdateLocalStorage( 229 const base::ListValue* args) { 230 if (!local_storage_.get()) { 231 Profile* profile = GetProfile(); 232 local_storage_ = new BrowsingDataLocalStorageHelper(profile); 233 } 234 235 last_setting_ = kStorage; 236 237 local_storage_->StartFetching( 238 base::Bind(&WebsiteSettingsHandler::OnLocalStorageFetched, 239 weak_ptr_factory_.GetWeakPtr())); 240} 241 242void WebsiteSettingsHandler::HandleMaybeShowEditPage( 243 const base::ListValue* args) { 244 std::string site; 245 bool rv = args->GetString(0, &site); 246 DCHECK(rv); 247 248 GURL last_site(site); 249 if (!last_site.is_valid()) 250 return; 251 252 last_site_ = last_site; 253 base::StringValue site_value(site); 254 web_ui()->CallJavascriptFunction("WebsiteSettingsEditor.showEditPage", 255 site_value); 256} 257 258void WebsiteSettingsHandler::OnLocalStorageFetched(const std::list< 259 BrowsingDataLocalStorageHelper::LocalStorageInfo>& storage) { 260 local_storage_list_ = storage; 261 Update(); 262 GetInfoForOrigin(last_site_, false); 263} 264 265void WebsiteSettingsHandler::Update() { 266 DCHECK(!last_setting_.empty()); 267 if (last_setting_ == kStorage) 268 UpdateLocalStorage(); 269 else if (last_setting_ == kBattery) 270 UpdateBatteryUsage(); 271 else 272 UpdateOrigins(); 273} 274 275void WebsiteSettingsHandler::UpdateOrigins() { 276 Profile* profile = GetProfile(); 277 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap(); 278 279 ContentSettingsForOneType all_settings; 280 ContentSettingsType last_setting; 281 if (!content_settings::GetTypeFromName(last_setting_, &last_setting)) 282 return; 283 284 if (last_setting == CONTENT_SETTINGS_TYPE_MEDIASTREAM) 285 last_setting = CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC; 286 287 settings->GetSettingsForOneType(last_setting, std::string(), &all_settings); 288 289 base::DictionaryValue allowed_origins; 290 base::DictionaryValue blocked_origins; 291 for (ContentSettingsForOneType::const_iterator it = all_settings.begin(); 292 it != all_settings.end(); 293 ++it) { 294 // Don't add default settings. 295 if (it->primary_pattern == ContentSettingsPattern::Wildcard() && 296 it->secondary_pattern == ContentSettingsPattern::Wildcard() && 297 it->source != kPreferencesSource) { 298 continue; 299 } 300 301 GURL origin_url(it->primary_pattern.ToString()); 302 std::string origin = origin_url.spec(); 303 304 // Hide the port if it is using a standard URL scheme. 305 if ((origin_url.SchemeIs(url::kHttpScheme) && 306 origin_url.IntPort() == kHttpPort) || 307 (origin_url.SchemeIs(url::kHttpsScheme) && 308 origin_url.IntPort() == kHttpsPort)) { 309 url::Replacements<char> replacements; 310 replacements.ClearPort(); 311 origin = origin_url.ReplaceComponents(replacements).spec(); 312 } 313 314 // Mediastream isn't set unless both mic and camera are set to the same. 315 if (last_setting == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { 316 ContentSetting cam_setting = settings->GetContentSettingWithoutOverride( 317 origin_url, 318 origin_url, 319 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 320 std::string()); 321 if (it->setting != cam_setting) 322 continue; 323 } 324 325 if (origin.find(last_filter_) == base::string16::npos) 326 continue; 327 328 base::Time last_usage = settings->GetLastUsageByPattern( 329 it->primary_pattern, it->secondary_pattern, last_setting); 330 331 base::DictionaryValue* origin_entry = new base::DictionaryValue(); 332 origin_entry->SetDoubleWithoutPathExpansion("usage", 333 last_usage.ToDoubleT()); 334 base::string16 usage_string; 335 if (last_usage.ToDoubleT()) { 336 usage_string = ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, 337 ui::TimeFormat::LENGTH_SHORT, 338 base::Time::Now() - last_usage); 339 } 340 origin_entry->SetStringWithoutPathExpansion("usageString", usage_string); 341 origin_entry->SetStringWithoutPathExpansion("readableName", 342 GetReadableName(origin_url)); 343 344 if (it->setting == CONTENT_SETTING_BLOCK) 345 blocked_origins.SetWithoutPathExpansion(origin, origin_entry); 346 else 347 allowed_origins.SetWithoutPathExpansion(origin, origin_entry); 348 } 349 350 bool is_globally_allowed = settings->GetContentSettingOverride(last_setting); 351 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins", 352 allowed_origins, 353 blocked_origins, 354 base::FundamentalValue(is_globally_allowed)); 355} 356 357void WebsiteSettingsHandler::HandleGetOriginInfo(const base::ListValue* args) { 358 std::string url; 359 bool rv = args->GetString(0, &url); 360 DCHECK(rv); 361 GURL origin(url); 362 363 if (!origin.is_valid()) 364 return; 365 366 GetInfoForOrigin(origin, true); 367} 368 369void WebsiteSettingsHandler::HandleSetOriginPermission( 370 const base::ListValue* args) { 371 std::string setting_name; 372 bool rv = args->GetString(0, &setting_name); 373 DCHECK(rv); 374 ContentSettingsType settings_type; 375 if (!content_settings::GetTypeFromName(setting_name, &settings_type)) 376 return; 377 378 std::string value; 379 rv = args->GetString(1, &value); 380 DCHECK(rv); 381 382 ContentSetting setting = content_settings::ContentSettingFromString(value); 383 Profile* profile = GetProfile(); 384 HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); 385 ContentSetting default_value = 386 map->GetDefaultContentSetting(settings_type, NULL); 387 388 // Users are not allowed to be the source of the "ask" setting. It is an 389 // ephemeral setting which is removed once the question is asked. 390 if (setting == CONTENT_SETTING_ASK && setting == default_value) 391 setting = CONTENT_SETTING_DEFAULT; 392 393 ContentSettingsPattern primary_pattern; 394 ContentSettingsPattern secondary_pattern; 395 switch (settings_type) { 396 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 397 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_); 398 secondary_pattern = ContentSettingsPattern::Wildcard(); 399 break; 400 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: 401 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_); 402 secondary_pattern = ContentSettingsPattern::Wildcard(); 403 map->SetContentSetting(primary_pattern, 404 secondary_pattern, 405 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 406 std::string(), 407 setting); 408 map->SetContentSetting(primary_pattern, 409 secondary_pattern, 410 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 411 std::string(), 412 setting); 413 return; 414 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS: 415 case CONTENT_SETTINGS_TYPE_COOKIES: 416 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 417 case CONTENT_SETTINGS_TYPE_IMAGES: 418 case CONTENT_SETTINGS_TYPE_JAVASCRIPT: 419 case CONTENT_SETTINGS_TYPE_PLUGINS: 420 case CONTENT_SETTINGS_TYPE_POPUPS: 421 primary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_); 422 secondary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_); 423 break; 424 default: 425 NOTREACHED() << "Content settings type not yet supported."; 426 return; 427 } 428 429 content_settings::SettingInfo info; 430 scoped_ptr<base::Value> v(map->GetWebsiteSettingWithoutOverride( 431 last_site_, last_site_, settings_type, std::string(), &info)); 432 map->SetNarrowestWebsiteSetting(primary_pattern, 433 secondary_pattern, 434 settings_type, 435 std::string(), 436 setting, 437 info); 438} 439 440void WebsiteSettingsHandler::HandleUpdateBatteryUsage( 441 const base::ListValue* args) { 442 last_setting_ = kBattery; 443 UpdateBatteryUsage(); 444} 445 446void WebsiteSettingsHandler::HandleDeleteLocalStorage( 447 const base::ListValue* args) { 448 DCHECK(!last_site_.is_empty()); 449 DeleteLocalStorage(last_site_); 450} 451 452void WebsiteSettingsHandler::HandleStopOrigin(const base::ListValue* args) { 453 DCHECK(!last_site_.is_empty()); 454 StopOrigin(last_site_); 455} 456 457// TODO(dhnishi): Remove default settings duplication from the 458// WebsiteSettingsHandler and the ContentSettingsHandler. 459void WebsiteSettingsHandler::HandleUpdateDefaultSetting( 460 const base::ListValue* args) { 461 ContentSettingsType last_setting; 462 if (!content_settings::GetTypeFromName(last_setting_, &last_setting)) 463 return; 464 465 base::DictionaryValue filter_settings; 466 std::string provider_id; 467 filter_settings.SetString( 468 "value", GetSettingDefaultFromModel(last_setting, &provider_id)); 469 filter_settings.SetString("managedBy", provider_id); 470 471 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.updateDefault", 472 filter_settings); 473} 474 475void WebsiteSettingsHandler::HandleSetDefaultSetting( 476 const base::ListValue* args) { 477 DCHECK_EQ(1U, args->GetSize()); 478 std::string setting; 479 if (!args->GetString(0, &setting)) { 480 NOTREACHED(); 481 return; 482 } 483 ContentSetting new_default = 484 content_settings::ContentSettingFromString(setting); 485 486 ContentSettingsType last_setting; 487 if (!content_settings::GetTypeFromName(last_setting_, &last_setting)) 488 return; 489 Profile* profile = GetProfile(); 490 491 HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); 492 map->SetDefaultContentSetting(last_setting, new_default); 493 494 switch (last_setting) { 495 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS: 496 content::RecordAction( 497 UserMetricsAction("Options_DefaultMultipleAutomaticDLSettingChange")); 498 break; 499 case CONTENT_SETTINGS_TYPE_COOKIES: 500 content::RecordAction( 501 UserMetricsAction("Options_DefaultCookieSettingChanged")); 502 break; 503 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 504 content::RecordAction( 505 UserMetricsAction("Options_DefaultGeolocationSettingChanged")); 506 break; 507 case CONTENT_SETTINGS_TYPE_IMAGES: 508 content::RecordAction( 509 UserMetricsAction("Options_DefaultImagesSettingChanged")); 510 break; 511 case CONTENT_SETTINGS_TYPE_JAVASCRIPT: 512 content::RecordAction( 513 UserMetricsAction("Options_DefaultJavaScriptSettingChanged")); 514 break; 515 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: 516 content::RecordAction( 517 UserMetricsAction("Options_DefaultMediaStreamMicSettingChanged")); 518 break; 519 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 520 content::RecordAction( 521 UserMetricsAction("Options_DefaultNotificationsSettingChanged")); 522 break; 523 case CONTENT_SETTINGS_TYPE_PLUGINS: 524 content::RecordAction( 525 UserMetricsAction("Options_DefaultPluginsSettingChanged")); 526 break; 527 case CONTENT_SETTINGS_TYPE_POPUPS: 528 content::RecordAction( 529 UserMetricsAction("Options_DefaultPopupsSettingChanged")); 530 break; 531 default: 532 NOTREACHED(); 533 return; 534 } 535} 536 537void WebsiteSettingsHandler::HandleSetGlobalToggle( 538 const base::ListValue* args) { 539 DCHECK_EQ(1U, args->GetSize()); 540 bool is_enabled; 541 bool rv = args->GetBoolean(0, &is_enabled); 542 DCHECK(rv); 543 544 ContentSettingsType last_setting; 545 if (!content_settings::GetTypeFromName(last_setting_, &last_setting)) 546 return; 547 548 Profile* profile = GetProfile(); 549 HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); 550 map->SetContentSettingOverride(last_setting, is_enabled); 551} 552 553void WebsiteSettingsHandler::GetInfoForOrigin(const GURL& site_url, 554 bool show_page) { 555 Profile* profile = GetProfile(); 556 HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); 557 558 double storage = 0.0; 559 for (LocalStorageList::const_iterator it = local_storage_list_.begin(); 560 it != local_storage_list_.end(); 561 it++) { 562 if (it->origin_url == site_url) { 563 storage = static_cast<double>(it->size); 564 break; 565 } 566 } 567 568 int battery = 0; 569 battery = OriginPowerMapFactory::GetForBrowserContext( 570 GetProfile())->GetPowerForOrigin(site_url); 571 572 base::DictionaryValue* permissions = new base::DictionaryValue; 573 for (size_t i = 0; i < arraysize(kValidTypes); ++i) { 574 ContentSettingsType permission_type = kValidTypes[i]; 575 576 // Append the possible settings. 577 base::ListValue* options = new base::ListValue; 578 ContentSetting default_value = 579 map->GetDefaultContentSetting(permission_type, NULL); 580 if (default_value != CONTENT_SETTING_ALLOW && 581 default_value != CONTENT_SETTING_BLOCK) { 582 options->AppendString( 583 content_settings::ContentSettingToString(default_value)); 584 } 585 options->AppendString( 586 content_settings::ContentSettingToString(CONTENT_SETTING_ALLOW)); 587 options->AppendString( 588 content_settings::ContentSettingToString(CONTENT_SETTING_BLOCK)); 589 if (permission_type == CONTENT_SETTINGS_TYPE_COOKIES) { 590 options->AppendString(content_settings::ContentSettingToString( 591 CONTENT_SETTING_SESSION_ONLY)); 592 } 593 594 ContentSetting permission; 595 content_settings::SettingInfo info; 596 if (permission_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM) { 597 scoped_ptr<base::Value> mic_value(map->GetWebsiteSettingWithoutOverride( 598 site_url, 599 site_url, 600 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 601 std::string(), 602 &info)); 603 ContentSetting mic_setting = 604 content_settings::ValueToContentSetting(mic_value.get()); 605 ContentSetting cam_setting = map->GetContentSettingWithoutOverride( 606 site_url, 607 site_url, 608 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 609 std::string()); 610 611 if (mic_setting != cam_setting) 612 permission = CONTENT_SETTING_ASK; 613 else 614 permission = mic_setting; 615 } else { 616 scoped_ptr<base::Value> v(map->GetWebsiteSettingWithoutOverride( 617 site_url, site_url, permission_type, std::string(), &info)); 618 permission = content_settings::ValueToContentSetting(v.get()); 619 } 620 621 base::DictionaryValue* permission_info = new base::DictionaryValue; 622 permission_info->SetStringWithoutPathExpansion( 623 "setting", content_settings::ContentSettingToString(permission)); 624 permission_info->SetWithoutPathExpansion("options", options); 625 permission_info->SetBooleanWithoutPathExpansion( 626 "editable", info.source == content_settings::SETTING_SOURCE_USER); 627 permissions->SetWithoutPathExpansion( 628 content_settings::GetTypeName(permission_type), permission_info); 629 } 630 631 base::Value* storage_used = new base::StringValue(l10n_util::GetStringFUTF16( 632 IDS_WEBSITE_SETTINGS_STORAGE_USED, ui::FormatBytes(storage))); 633 base::Value* battery_used = 634 new base::StringValue(l10n_util::GetStringFUTF16Int( 635 IDS_WEBSITE_SETTINGS_BATTERY_USED, battery)); 636 637 web_ui()->CallJavascriptFunction("WebsiteSettingsEditor.populateOrigin", 638 *storage_used, 639 *battery_used, 640 *permissions, 641 base::FundamentalValue(show_page)); 642} 643 644void WebsiteSettingsHandler::UpdateLocalStorage() { 645 base::DictionaryValue local_storage_map; 646 for (LocalStorageList::const_iterator it = local_storage_list_.begin(); 647 it != local_storage_list_.end(); 648 it++) { 649 std::string origin = it->origin_url.spec(); 650 651 if (origin.find(last_filter_) == base::string16::npos) 652 continue; 653 654 base::DictionaryValue* origin_entry = new base::DictionaryValue(); 655 origin_entry->SetWithoutPathExpansion( 656 "usage", new base::FundamentalValue(static_cast<double>(it->size))); 657 origin_entry->SetWithoutPathExpansion( 658 "usageString", new base::StringValue(ui::FormatBytes(it->size))); 659 origin_entry->SetStringWithoutPathExpansion( 660 "readableName", GetReadableName(it->origin_url)); 661 local_storage_map.SetWithoutPathExpansion(origin, origin_entry); 662 } 663 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins", 664 local_storage_map); 665} 666 667void WebsiteSettingsHandler::UpdateBatteryUsage() { 668 base::DictionaryValue power_map; 669 OriginPowerMap* origins = 670 OriginPowerMapFactory::GetForBrowserContext(GetProfile()); 671 OriginPowerMap::PercentOriginMap percent_map = origins->GetPercentOriginMap(); 672 for (std::map<GURL, int>::iterator it = percent_map.begin(); 673 it != percent_map.end(); 674 ++it) { 675 std::string origin = it->first.spec(); 676 677 if (origin.find(last_filter_) == base::string16::npos) 678 continue; 679 680 base::DictionaryValue* origin_entry = new base::DictionaryValue(); 681 origin_entry->SetInteger("usage", it->second); 682 if (it->second == 0) { 683 origin_entry->SetString( 684 "usageString", 685 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_BATTERY_ZERO_PERCENT)); 686 } else { 687 origin_entry->SetString( 688 "usageString", 689 l10n_util::GetStringFUTF16Int(IDS_WEBSITE_SETTINGS_BATTERY_PERCENT, 690 it->second)); 691 } 692 origin_entry->SetStringWithoutPathExpansion("readableName", 693 GetReadableName(it->first)); 694 power_map.SetWithoutPathExpansion(origin, origin_entry); 695 } 696 web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins", 697 power_map); 698} 699 700std::string WebsiteSettingsHandler::GetSettingDefaultFromModel( 701 ContentSettingsType type, 702 std::string* provider_id) { 703 Profile* profile = GetProfile(); 704 ContentSetting default_setting = 705 profile->GetHostContentSettingsMap()->GetDefaultContentSetting( 706 type, provider_id); 707 708 return content_settings::ContentSettingToString(default_setting); 709} 710 711void WebsiteSettingsHandler::StopOrigin(const GURL& site_url) { 712 Profile* profile = GetProfile(); 713 if (site_url.SchemeIs(extensions::kExtensionScheme)) { 714 const extensions::Extension* extension = 715 extensions::ExtensionRegistry::Get(profile) 716 ->enabled_extensions() 717 .GetHostedAppByURL(site_url); 718 if (extension) { 719 extensions::AppWindowRegistry::Get(profile) 720 ->CloseAllAppWindowsForApp(extension->id()); 721 } 722 } 723 724 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 725 Browser* browser = *it; 726 TabStripModel* model = browser->tab_strip_model(); 727 for (int idx = 0; idx < model->count(); idx++) { 728 content::WebContents* web_contents = model->GetWebContentsAt(idx); 729 // Can't discard tabs that are already discarded or active. 730 if (model->IsTabDiscarded(idx) || (model->active_index() == idx)) 731 continue; 732 733 // Don't discard tabs that belong to other profiles or other origins. 734 if (web_contents->GetLastCommittedURL().GetOrigin() != site_url || 735 profile != 736 Profile::FromBrowserContext(web_contents->GetBrowserContext())) { 737 continue; 738 } 739 model->DiscardWebContentsAt(idx); 740 } 741 } 742} 743 744void WebsiteSettingsHandler::DeleteLocalStorage(const GURL& site_url) { 745 Profile* profile = GetProfile(); 746 content::DOMStorageContext* dom_storage_context_ = 747 content::BrowserContext::GetDefaultStoragePartition(profile) 748 ->GetDOMStorageContext(); 749 dom_storage_context_->DeleteLocalStorage(site_url); 750 751 // Load a new BrowsingDataLocalStorageHelper to update. 752 local_storage_ = new BrowsingDataLocalStorageHelper(profile); 753 754 local_storage_->StartFetching( 755 base::Bind(&WebsiteSettingsHandler::OnLocalStorageFetched, 756 weak_ptr_factory_.GetWeakPtr())); 757} 758 759const std::string& WebsiteSettingsHandler::GetReadableName( 760 const GURL& site_url) { 761 if (site_url.SchemeIs(extensions::kExtensionScheme)) { 762 Profile* profile = GetProfile(); 763 ExtensionService* extension_service = 764 extensions::ExtensionSystem::Get(profile)->extension_service(); 765 766 const extensions::Extension* extension = 767 extension_service->extensions()->GetExtensionOrAppByURL(site_url); 768 // If extension is NULL, it was removed and we cannot look up its name. 769 if (!extension) 770 return site_url.spec(); 771 772 return extension->name(); 773 } 774 return site_url.spec(); 775} 776 777Profile* WebsiteSettingsHandler::GetProfile() { 778 Profile* profile = Profile::FromWebUI(web_ui()); 779#if defined(OS_CHROMEOS) 780 // Chrome OS special case: in Guest mode settings are opened in Incognito 781 // mode, so we need original profile to actually modify settings. 782 if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) 783 profile = profile->GetOriginalProfile(); 784#endif 785 return profile; 786} 787 788} // namespace options 789