content_settings_handler.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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/content_settings_handler.h" 6 7#include "base/callback.h" 8#include "base/command_line.h" 9#include "base/utf_string_conversions.h" 10#include "base/values.h" 11#include "chrome/browser/browser_list.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/content_settings/content_settings_details.h" 14#include "chrome/browser/content_settings/host_content_settings_map.h" 15#include "chrome/browser/geolocation/geolocation_content_settings_map.h" 16#include "chrome/browser/notifications/desktop_notification_service.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/common/chrome_switches.h" 19#include "chrome/common/content_settings_helper.h" 20#include "chrome/common/notification_service.h" 21#include "chrome/common/notification_source.h" 22#include "chrome/common/notification_type.h" 23#include "chrome/common/pref_names.h" 24#include "chrome/common/url_constants.h" 25#include "grit/generated_resources.h" 26#include "grit/locale_settings.h" 27#include "ui/base/l10n/l10n_util.h" 28 29namespace { 30 31const char* kDisplayPattern = "displayPattern"; 32const char* kSetting = "setting"; 33const char* kOrigin = "origin"; 34const char* kEmbeddingOrigin = "embeddingOrigin"; 35 36const char* const kContentSettingsTypeGroupNames[] = { 37 "cookies", 38 "images", 39 "javascript", 40 "plugins", 41 "popups", 42 "location", 43 "notifications", 44 "prerender", 45}; 46COMPILE_ASSERT(arraysize(kContentSettingsTypeGroupNames) == 47 CONTENT_SETTINGS_NUM_TYPES, 48 invalid_content_settings_type_group_names_size); 49 50 51ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) { 52 53 for (int content_settings_type = CONTENT_SETTINGS_TYPE_COOKIES; 54 content_settings_type < CONTENT_SETTINGS_NUM_TYPES; 55 ++content_settings_type) { 56 if (name == kContentSettingsTypeGroupNames[content_settings_type]) 57 return static_cast<ContentSettingsType>(content_settings_type); 58 } 59 60 NOTREACHED() << name << " is not a recognized content settings type."; 61 return CONTENT_SETTINGS_TYPE_DEFAULT; 62} 63 64std::string ContentSettingToString(ContentSetting setting) { 65 switch (setting) { 66 case CONTENT_SETTING_ALLOW: 67 return "allow"; 68 case CONTENT_SETTING_ASK: 69 return "ask"; 70 case CONTENT_SETTING_BLOCK: 71 return "block"; 72 case CONTENT_SETTING_SESSION_ONLY: 73 return "session"; 74 case CONTENT_SETTING_DEFAULT: 75 return "default"; 76 case CONTENT_SETTING_NUM_SETTINGS: 77 NOTREACHED(); 78 } 79 80 return ""; 81} 82 83ContentSetting ContentSettingFromString(const std::string& name) { 84 if (name == "allow") 85 return CONTENT_SETTING_ALLOW; 86 if (name == "ask") 87 return CONTENT_SETTING_ASK; 88 if (name == "block") 89 return CONTENT_SETTING_BLOCK; 90 if (name == "session") 91 return CONTENT_SETTING_SESSION_ONLY; 92 93 NOTREACHED() << name << " is not a recognized content setting."; 94 return CONTENT_SETTING_DEFAULT; 95} 96 97std::string GeolocationExceptionToString(const GURL& origin, 98 const GURL& embedding_origin) { 99 if (origin == embedding_origin) 100 return content_settings_helper::OriginToString(origin); 101 102 // TODO(estade): the page needs to use CSS to indent the string. 103 std::string indent(" "); 104 if (embedding_origin.is_empty()) { 105 // NOTE: As long as the user cannot add/edit entries from the exceptions 106 // dialog, it's impossible to actually have a non-default setting for some 107 // origin "embedded on any other site", so this row will never appear. If 108 // we add the ability to add/edit exceptions, we'll need to decide when to 109 // display this and how "removing" it will function. 110 return indent + 111 l10n_util::GetStringUTF8(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER); 112 } 113 114 return indent + l10n_util::GetStringFUTF8( 115 IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST, 116 UTF8ToUTF16(content_settings_helper::OriginToString(embedding_origin))); 117} 118 119// Create a DictionaryValue* that will act as a data source for a single row 120// in a HostContentSettingsMap-controlled exceptions table (e.g., cookies). 121// Ownership of the pointer is passed to the caller. 122DictionaryValue* GetExceptionForPage( 123 const ContentSettingsPattern pattern, 124 ContentSetting setting) { 125 DictionaryValue* exception = new DictionaryValue(); 126 exception->Set( 127 kDisplayPattern, 128 new StringValue(pattern.AsString())); 129 exception->Set( 130 kSetting, 131 new StringValue(ContentSettingToString(setting))); 132 return exception; 133} 134 135// Create a DictionaryValue* that will act as a data source for a single row 136// in the Geolocation exceptions table. Ownership of the pointer is passed to 137// the caller. 138DictionaryValue* GetGeolocationExceptionForPage(const GURL& origin, 139 const GURL& embedding_origin, 140 ContentSetting setting) { 141 DictionaryValue* exception = new DictionaryValue(); 142 exception->Set( 143 kDisplayPattern, 144 new StringValue(GeolocationExceptionToString(origin, embedding_origin))); 145 exception->Set( 146 kSetting, 147 new StringValue(ContentSettingToString(setting))); 148 exception->Set( 149 kOrigin, 150 new StringValue(origin.spec())); 151 exception->Set( 152 kEmbeddingOrigin, 153 new StringValue(embedding_origin.spec())); 154 return exception; 155} 156 157// Create a DictionaryValue* that will act as a data source for a single row 158// in the desktop notifications exceptions table. Ownership of the pointer is 159// passed to the caller. 160DictionaryValue* GetNotificationExceptionForPage( 161 const GURL& url, 162 ContentSetting setting) { 163 DictionaryValue* exception = new DictionaryValue(); 164 exception->Set( 165 kDisplayPattern, 166 new StringValue(content_settings_helper::OriginToString(url))); 167 exception->Set( 168 kSetting, 169 new StringValue(ContentSettingToString(setting))); 170 exception->Set( 171 kOrigin, 172 new StringValue(url.spec())); 173 return exception; 174} 175 176} // namespace 177 178ContentSettingsHandler::ContentSettingsHandler() { 179} 180 181ContentSettingsHandler::~ContentSettingsHandler() { 182} 183 184void ContentSettingsHandler::GetLocalizedValues( 185 DictionaryValue* localized_strings) { 186 DCHECK(localized_strings); 187 188 static OptionsStringResource resources[] = { 189 { "content_exceptions", IDS_COOKIES_EXCEPTIONS_BUTTON }, 190 { "allowException", IDS_EXCEPTIONS_ALLOW_BUTTON }, 191 { "blockException", IDS_EXCEPTIONS_BLOCK_BUTTON }, 192 { "sessionException", IDS_EXCEPTIONS_SESSION_ONLY_BUTTON }, 193 { "askException", IDS_EXCEPTIONS_ASK_BUTTON }, 194 { "addExceptionRow", IDS_EXCEPTIONS_ADD_BUTTON }, 195 { "removeExceptionRow", IDS_EXCEPTIONS_REMOVE_BUTTON }, 196 { "editExceptionRow", IDS_EXCEPTIONS_EDIT_BUTTON }, 197 { "otr_exceptions_explanation", IDS_EXCEPTIONS_OTR_LABEL }, 198 { "examplePattern", IDS_EXCEPTIONS_PATTERN_EXAMPLE }, 199 { "addNewExceptionInstructions", IDS_EXCEPTIONS_ADD_NEW_INSTRUCTIONS }, 200 { "manage_exceptions", IDS_EXCEPTIONS_MANAGE }, 201 // Cookies filter. 202 { "cookies_tab_label", IDS_COOKIES_TAB_LABEL }, 203 { "cookies_header", IDS_COOKIES_HEADER }, 204 { "cookies_allow", IDS_COOKIES_ALLOW_RADIO }, 205 { "cookies_ask", IDS_COOKIES_ASK_EVERY_TIME_RADIO }, 206 { "cookies_block", IDS_COOKIES_BLOCK_RADIO }, 207 { "cookies_block_3rd_party", IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX }, 208 { "cookies_show_cookies", IDS_COOKIES_SHOW_COOKIES_BUTTON }, 209 { "flash_storage_settings", IDS_FLASH_STORAGE_SETTINGS }, 210 { "flash_storage_url", IDS_FLASH_STORAGE_URL }, 211 // Image filter. 212 { "images_tab_label", IDS_IMAGES_TAB_LABEL }, 213 { "images_header", IDS_IMAGES_HEADER }, 214 { "images_allow", IDS_IMAGES_LOAD_RADIO }, 215 { "images_block", IDS_IMAGES_NOLOAD_RADIO }, 216 // JavaScript filter. 217 { "javascript_tab_label", IDS_JAVASCRIPT_TAB_LABEL }, 218 { "javascript_header", IDS_JAVASCRIPT_HEADER }, 219 { "javascript_allow", IDS_JS_ALLOW_RADIO }, 220 { "javascript_block", IDS_JS_DONOTALLOW_RADIO }, 221 // Plug-ins filter. 222 { "plugins_tab_label", IDS_PLUGIN_TAB_LABEL }, 223 { "plugins_header", IDS_PLUGIN_HEADER }, 224 { "plugins_ask", IDS_PLUGIN_ASK_RADIO }, 225 { "plugins_allow", IDS_PLUGIN_LOAD_RADIO }, 226 { "plugins_block", IDS_PLUGIN_NOLOAD_RADIO }, 227 { "disable_individual_plugins", IDS_PLUGIN_SELECTIVE_DISABLE }, 228 // Pop-ups filter. 229 { "popups_tab_label", IDS_POPUP_TAB_LABEL }, 230 { "popups_header", IDS_POPUP_HEADER }, 231 { "popups_allow", IDS_POPUP_ALLOW_RADIO }, 232 { "popups_block", IDS_POPUP_BLOCK_RADIO }, 233 // Location filter. 234 { "location_tab_label", IDS_GEOLOCATION_TAB_LABEL }, 235 { "location_header", IDS_GEOLOCATION_HEADER }, 236 { "location_allow", IDS_GEOLOCATION_ALLOW_RADIO }, 237 { "location_ask", IDS_GEOLOCATION_ASK_RADIO }, 238 { "location_block", IDS_GEOLOCATION_BLOCK_RADIO }, 239 // Notifications filter. 240 { "notifications_tab_label", IDS_NOTIFICATIONS_TAB_LABEL }, 241 { "notifications_header", IDS_NOTIFICATIONS_HEADER }, 242 { "notifications_allow", IDS_NOTIFICATIONS_ALLOW_RADIO }, 243 { "notifications_ask", IDS_NOTIFICATIONS_ASK_RADIO }, 244 { "notifications_block", IDS_NOTIFICATIONS_BLOCK_RADIO }, 245 }; 246 247 RegisterStrings(localized_strings, resources, arraysize(resources)); 248 RegisterTitle(localized_strings, "contentSettingsPage", 249 IDS_CONTENT_SETTINGS_TITLE); 250 localized_strings->SetBoolean("enable_click_to_play", 251 CommandLine::ForCurrentProcess()->HasSwitch( 252 switches::kEnableClickToPlay)); 253} 254 255void ContentSettingsHandler::Initialize() { 256 const HostContentSettingsMap* settings_map = GetContentSettingsMap(); 257 scoped_ptr<Value> block_3rd_party(Value::CreateBooleanValue( 258 settings_map->BlockThirdPartyCookies())); 259 web_ui_->CallJavascriptFunction( 260 L"ContentSettings.setBlockThirdPartyCookies", *block_3rd_party.get()); 261 262 clear_plugin_lso_data_enabled_.Init(prefs::kClearPluginLSODataEnabled, 263 g_browser_process->local_state(), 264 this); 265 UpdateClearPluginLSOData(); 266 267 notification_registrar_.Add( 268 this, NotificationType::OTR_PROFILE_CREATED, 269 NotificationService::AllSources()); 270 notification_registrar_.Add( 271 this, NotificationType::PROFILE_DESTROYED, 272 NotificationService::AllSources()); 273 274 UpdateAllExceptionsViewsFromModel(); 275 notification_registrar_.Add( 276 this, NotificationType::CONTENT_SETTINGS_CHANGED, 277 NotificationService::AllSources()); 278 notification_registrar_.Add( 279 this, NotificationType::DESKTOP_NOTIFICATION_DEFAULT_CHANGED, 280 NotificationService::AllSources()); 281 notification_registrar_.Add( 282 this, NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED, 283 NotificationService::AllSources()); 284 285 PrefService* prefs = web_ui_->GetProfile()->GetPrefs(); 286 pref_change_registrar_.Init(prefs); 287 pref_change_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); 288 pref_change_registrar_.Add(prefs::kGeolocationContentSettings, this); 289} 290 291void ContentSettingsHandler::Observe(NotificationType type, 292 const NotificationSource& source, 293 const NotificationDetails& details) { 294 switch (type.value) { 295 case NotificationType::PROFILE_DESTROYED: { 296 Profile* profile = static_cast<Source<Profile> >(source).ptr(); 297 if (profile->IsOffTheRecord()) { 298 web_ui_->CallJavascriptFunction( 299 L"ContentSettingsExceptionsArea.OTRProfileDestroyed"); 300 } 301 break; 302 } 303 304 case NotificationType::OTR_PROFILE_CREATED: { 305 UpdateAllOTRExceptionsViewsFromModel(); 306 break; 307 } 308 309 case NotificationType::CONTENT_SETTINGS_CHANGED: { 310 const ContentSettingsDetails* settings_details = 311 Details<const ContentSettingsDetails>(details).ptr(); 312 313 // TODO(estade): we pretend update_all() is always true. 314 if (settings_details->update_all_types()) 315 UpdateAllExceptionsViewsFromModel(); 316 else 317 UpdateExceptionsViewFromModel(settings_details->type()); 318 break; 319 } 320 321 case NotificationType::PREF_CHANGED: { 322 const std::string& pref_name = *Details<std::string>(details).ptr(); 323 if (pref_name == prefs::kGeolocationDefaultContentSetting) 324 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION); 325 else if (pref_name == prefs::kGeolocationContentSettings) 326 UpdateGeolocationExceptionsView(); 327 else if (pref_name == prefs::kClearPluginLSODataEnabled) 328 UpdateClearPluginLSOData(); 329 break; 330 } 331 332 case NotificationType::DESKTOP_NOTIFICATION_DEFAULT_CHANGED: { 333 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); 334 break; 335 } 336 337 case NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED: { 338 UpdateNotificationExceptionsView(); 339 break; 340 } 341 342 default: 343 OptionsPageUIHandler::Observe(type, source, details); 344 } 345} 346 347void ContentSettingsHandler::UpdateClearPluginLSOData() { 348 int label_id = clear_plugin_lso_data_enabled_.GetValue() ? 349 IDS_COOKIES_LSO_CLEAR_WHEN_CLOSE_CHKBOX : 350 IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX; 351 scoped_ptr<Value> label( 352 Value::CreateStringValue(l10n_util::GetStringUTF16(label_id))); 353 web_ui_->CallJavascriptFunction( 354 L"ContentSettings.setClearLocalDataOnShutdownLabel", *label); 355} 356 357void ContentSettingsHandler::UpdateSettingDefaultFromModel( 358 ContentSettingsType type) { 359 DictionaryValue filter_settings; 360 filter_settings.SetString(ContentSettingsTypeToGroupName(type) + ".value", 361 GetSettingDefaultFromModel(type)); 362 filter_settings.SetBoolean(ContentSettingsTypeToGroupName(type) + ".managed", 363 GetDefaultSettingManagedFromModel(type)); 364 365 web_ui_->CallJavascriptFunction( 366 L"ContentSettings.setContentFilterSettingsValue", filter_settings); 367} 368 369std::string ContentSettingsHandler::GetSettingDefaultFromModel( 370 ContentSettingsType type) { 371 ContentSetting default_setting; 372 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { 373 default_setting = web_ui_->GetProfile()-> 374 GetGeolocationContentSettingsMap()->GetDefaultContentSetting(); 375 } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 376 default_setting = web_ui_->GetProfile()-> 377 GetDesktopNotificationService()->GetDefaultContentSetting(); 378 } else { 379 default_setting = GetContentSettingsMap()->GetDefaultContentSetting(type); 380 } 381 382 return ContentSettingToString(default_setting); 383} 384 385bool ContentSettingsHandler::GetDefaultSettingManagedFromModel( 386 ContentSettingsType type) { 387 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { 388 return web_ui_->GetProfile()-> 389 GetGeolocationContentSettingsMap()->IsDefaultContentSettingManaged(); 390 } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 391 return web_ui_->GetProfile()-> 392 GetDesktopNotificationService()->IsDefaultContentSettingManaged(); 393 } else { 394 return GetContentSettingsMap()->IsDefaultContentSettingManaged(type); 395 } 396} 397 398void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() { 399 for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1; 400 type < CONTENT_SETTINGS_NUM_TYPES; ++type) { 401 UpdateExceptionsViewFromModel(static_cast<ContentSettingsType>(type)); 402 } 403} 404 405void ContentSettingsHandler::UpdateAllOTRExceptionsViewsFromModel() { 406 for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1; 407 type < CONTENT_SETTINGS_NUM_TYPES; ++type) { 408 UpdateOTRExceptionsViewFromModel(static_cast<ContentSettingsType>(type)); 409 } 410} 411 412void ContentSettingsHandler::UpdateExceptionsViewFromModel( 413 ContentSettingsType type) { 414 switch (type) { 415 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 416 UpdateGeolocationExceptionsView(); 417 break; 418 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 419 UpdateNotificationExceptionsView(); 420 break; 421 case CONTENT_SETTINGS_TYPE_PRERENDER: 422 // Prerender is currently (02/24/2011) an experimental feature which is 423 // only turned on via about:flags. There is intentionally no UI in 424 // chrome://preferences for CONTENT_SETTINGS_TYPE_PRERENDER. 425 // TODO(cbentzel): Change once prerender moves out of about:flags. 426 break; 427 default: 428 UpdateExceptionsViewFromHostContentSettingsMap(type); 429 break; 430 } 431} 432 433void ContentSettingsHandler::UpdateOTRExceptionsViewFromModel( 434 ContentSettingsType type) { 435 switch (type) { 436 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 437 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 438 case CONTENT_SETTINGS_TYPE_PRERENDER: 439 break; 440 default: 441 UpdateExceptionsViewFromOTRHostContentSettingsMap(type); 442 break; 443 } 444} 445 446void ContentSettingsHandler::UpdateGeolocationExceptionsView() { 447 GeolocationContentSettingsMap* map = 448 web_ui_->GetProfile()->GetGeolocationContentSettingsMap(); 449 GeolocationContentSettingsMap::AllOriginsSettings all_settings = 450 map->GetAllOriginsSettings(); 451 GeolocationContentSettingsMap::AllOriginsSettings::const_iterator i; 452 453 ListValue exceptions; 454 for (i = all_settings.begin(); i != all_settings.end(); ++i) { 455 const GURL& origin = i->first; 456 const GeolocationContentSettingsMap::OneOriginSettings& one_settings = 457 i->second; 458 459 GeolocationContentSettingsMap::OneOriginSettings::const_iterator parent = 460 one_settings.find(origin); 461 462 // Add the "parent" entry for the non-embedded setting. 463 ContentSetting parent_setting = 464 parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second; 465 exceptions.Append( 466 GetGeolocationExceptionForPage(origin, origin, parent_setting)); 467 468 // Add the "children" for any embedded settings. 469 GeolocationContentSettingsMap::OneOriginSettings::const_iterator j; 470 for (j = one_settings.begin(); j != one_settings.end(); ++j) { 471 // Skip the non-embedded setting which we already added above. 472 if (j == parent) 473 continue; 474 475 exceptions.Append( 476 GetGeolocationExceptionForPage(origin, j->first, j->second)); 477 } 478 } 479 480 StringValue type_string( 481 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION)); 482 web_ui_->CallJavascriptFunction( 483 L"ContentSettings.setExceptions", type_string, exceptions); 484 485 // This is mainly here to keep this function ideologically parallel to 486 // UpdateExceptionsViewFromHostContentSettingsMap(). 487 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION); 488} 489 490void ContentSettingsHandler::UpdateNotificationExceptionsView() { 491 DesktopNotificationService* service = 492 web_ui_->GetProfile()->GetDesktopNotificationService(); 493 494 std::vector<GURL> allowed(service->GetAllowedOrigins()); 495 std::vector<GURL> blocked(service->GetBlockedOrigins()); 496 497 ListValue exceptions; 498 for (size_t i = 0; i < allowed.size(); ++i) { 499 exceptions.Append( 500 GetNotificationExceptionForPage(allowed[i], CONTENT_SETTING_ALLOW)); 501 } 502 for (size_t i = 0; i < blocked.size(); ++i) { 503 exceptions.Append( 504 GetNotificationExceptionForPage(blocked[i], CONTENT_SETTING_BLOCK)); 505 } 506 507 StringValue type_string( 508 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS)); 509 web_ui_->CallJavascriptFunction( 510 L"ContentSettings.setExceptions", type_string, exceptions); 511 512 // This is mainly here to keep this function ideologically parallel to 513 // UpdateExceptionsViewFromHostContentSettingsMap(). 514 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); 515} 516 517void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap( 518 ContentSettingsType type) { 519 HostContentSettingsMap::SettingsForOneType entries; 520 GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries); 521 522 ListValue exceptions; 523 for (size_t i = 0; i < entries.size(); ++i) { 524 exceptions.Append(GetExceptionForPage(entries[i].first, entries[i].second)); 525 } 526 527 StringValue type_string(ContentSettingsTypeToGroupName(type)); 528 web_ui_->CallJavascriptFunction( 529 L"ContentSettings.setExceptions", type_string, exceptions); 530 531 UpdateExceptionsViewFromOTRHostContentSettingsMap(type); 532 533 // The default may also have changed (we won't get a separate notification). 534 // If it hasn't changed, this call will be harmless. 535 UpdateSettingDefaultFromModel(type); 536} 537 538void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap( 539 ContentSettingsType type) { 540 const HostContentSettingsMap* otr_settings_map = GetOTRContentSettingsMap(); 541 if (!otr_settings_map) 542 return; 543 544 HostContentSettingsMap::SettingsForOneType otr_entries; 545 otr_settings_map->GetSettingsForOneType(type, "", &otr_entries); 546 547 ListValue otr_exceptions; 548 for (size_t i = 0; i < otr_entries.size(); ++i) { 549 otr_exceptions.Append(GetExceptionForPage(otr_entries[i].first, 550 otr_entries[i].second)); 551 } 552 553 StringValue type_string(ContentSettingsTypeToGroupName(type)); 554 web_ui_->CallJavascriptFunction( 555 L"ContentSettings.setOTRExceptions", type_string, otr_exceptions); 556} 557 558void ContentSettingsHandler::RegisterMessages() { 559 web_ui_->RegisterMessageCallback("setContentFilter", 560 NewCallback(this, 561 &ContentSettingsHandler::SetContentFilter)); 562 web_ui_->RegisterMessageCallback("setAllowThirdPartyCookies", 563 NewCallback(this, 564 &ContentSettingsHandler::SetAllowThirdPartyCookies)); 565 web_ui_->RegisterMessageCallback("removeException", 566 NewCallback(this, 567 &ContentSettingsHandler::RemoveException)); 568 web_ui_->RegisterMessageCallback("setException", 569 NewCallback(this, 570 &ContentSettingsHandler::SetException)); 571 web_ui_->RegisterMessageCallback("checkExceptionPatternValidity", 572 NewCallback(this, 573 &ContentSettingsHandler::CheckExceptionPatternValidity)); 574} 575 576void ContentSettingsHandler::SetContentFilter(const ListValue* args) { 577 DCHECK_EQ(2U, args->GetSize()); 578 std::string group, setting; 579 if (!(args->GetString(0, &group) && 580 args->GetString(1, &setting))) { 581 NOTREACHED(); 582 return; 583 } 584 585 ContentSetting default_setting = ContentSettingFromString(setting); 586 ContentSettingsType content_type = ContentSettingsTypeFromGroupName(group); 587 if (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { 588 web_ui_->GetProfile()->GetGeolocationContentSettingsMap()-> 589 SetDefaultContentSetting(default_setting); 590 } else if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 591 web_ui_->GetProfile()->GetDesktopNotificationService()-> 592 SetDefaultContentSetting(default_setting); 593 } else { 594 GetContentSettingsMap()-> 595 SetDefaultContentSetting(content_type, default_setting); 596 } 597} 598 599void ContentSettingsHandler::SetAllowThirdPartyCookies(const ListValue* args) { 600 std::wstring allow = ExtractStringValue(args); 601 602 GetContentSettingsMap()->SetBlockThirdPartyCookies(allow == L"true"); 603} 604 605void ContentSettingsHandler::RemoveException(const ListValue* args) { 606 size_t arg_i = 0; 607 std::string type_string; 608 CHECK(args->GetString(arg_i++, &type_string)); 609 610 ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string); 611 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { 612 std::string origin; 613 std::string embedding_origin; 614 bool rv = args->GetString(arg_i++, &origin); 615 DCHECK(rv); 616 rv = args->GetString(arg_i++, &embedding_origin); 617 DCHECK(rv); 618 619 web_ui_->GetProfile()->GetGeolocationContentSettingsMap()-> 620 SetContentSetting(GURL(origin), 621 GURL(embedding_origin), 622 CONTENT_SETTING_DEFAULT); 623 } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 624 std::string origin; 625 std::string setting; 626 bool rv = args->GetString(arg_i++, &origin); 627 DCHECK(rv); 628 rv = args->GetString(arg_i++, &setting); 629 DCHECK(rv); 630 ContentSetting content_setting = ContentSettingFromString(setting); 631 if (content_setting == CONTENT_SETTING_ALLOW) { 632 web_ui_->GetProfile()->GetDesktopNotificationService()-> 633 ResetAllowedOrigin(GURL(origin)); 634 } else { 635 DCHECK_EQ(content_setting, CONTENT_SETTING_BLOCK); 636 web_ui_->GetProfile()->GetDesktopNotificationService()-> 637 ResetBlockedOrigin(GURL(origin)); 638 } 639 } else { 640 std::string mode; 641 bool rv = args->GetString(arg_i++, &mode); 642 DCHECK(rv); 643 644 std::string pattern; 645 rv = args->GetString(arg_i++, &pattern); 646 DCHECK(rv); 647 648 HostContentSettingsMap* settings_map = 649 mode == "normal" ? GetContentSettingsMap() : 650 GetOTRContentSettingsMap(); 651 // The settings map could be null if the mode was OTR but the OTR profile 652 // got destroyed before we received this message. 653 if (settings_map) { 654 settings_map->SetContentSetting( 655 ContentSettingsPattern(pattern), 656 ContentSettingsTypeFromGroupName(type_string), 657 "", 658 CONTENT_SETTING_DEFAULT); 659 } 660 } 661} 662 663void ContentSettingsHandler::SetException(const ListValue* args) { 664 size_t arg_i = 0; 665 std::string type_string; 666 CHECK(args->GetString(arg_i++, &type_string)); 667 std::string mode; 668 CHECK(args->GetString(arg_i++, &mode)); 669 std::string pattern; 670 CHECK(args->GetString(arg_i++, &pattern)); 671 std::string setting; 672 CHECK(args->GetString(arg_i++, &setting)); 673 674 ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string); 675 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION || 676 type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 677 NOTREACHED(); 678 return; 679 } 680 681 HostContentSettingsMap* settings_map = 682 mode == "normal" ? GetContentSettingsMap() : 683 GetOTRContentSettingsMap(); 684 685 // The settings map could be null if the mode was OTR but the OTR profile 686 // got destroyed before we received this message. 687 if (!settings_map) 688 return; 689 690 settings_map->SetContentSetting(ContentSettingsPattern(pattern), 691 type, 692 "", 693 ContentSettingFromString(setting)); 694} 695 696void ContentSettingsHandler::CheckExceptionPatternValidity( 697 const ListValue* args) { 698 size_t arg_i = 0; 699 Value* type; 700 CHECK(args->Get(arg_i++, &type)); 701 std::string mode_string; 702 CHECK(args->GetString(arg_i++, &mode_string)); 703 std::string pattern_string; 704 CHECK(args->GetString(arg_i++, &pattern_string)); 705 706 ContentSettingsPattern pattern(pattern_string); 707 708 scoped_ptr<Value> mode_value(Value::CreateStringValue(mode_string)); 709 scoped_ptr<Value> pattern_value(Value::CreateStringValue(pattern_string)); 710 scoped_ptr<Value> valid_value(Value::CreateBooleanValue(pattern.IsValid())); 711 712 web_ui_->CallJavascriptFunction( 713 L"ContentSettings.patternValidityCheckComplete", *type, 714 *mode_value.get(), 715 *pattern_value.get(), 716 *valid_value.get()); 717} 718 719// static 720std::string ContentSettingsHandler::ContentSettingsTypeToGroupName( 721 ContentSettingsType type) { 722 if (type < CONTENT_SETTINGS_TYPE_COOKIES || 723 type >= CONTENT_SETTINGS_NUM_TYPES) { 724 NOTREACHED(); 725 return ""; 726 } 727 return kContentSettingsTypeGroupNames[type]; 728} 729 730HostContentSettingsMap* ContentSettingsHandler::GetContentSettingsMap() { 731 return web_ui_->GetProfile()->GetHostContentSettingsMap(); 732} 733 734HostContentSettingsMap* 735 ContentSettingsHandler::GetOTRContentSettingsMap() { 736 Profile* profile = web_ui_->GetProfile(); 737 if (profile->HasOffTheRecordProfile()) 738 return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap(); 739 return NULL; 740} 741