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. 4 5 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 6 7 #include <list> 8 9 #include "base/command_line.h" 10 #include "base/lazy_instance.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" 13 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" 14 #include "chrome/browser/browsing_data/browsing_data_database_helper.h" 15 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" 16 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" 17 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" 18 #include "chrome/browser/browsing_data/cookies_tree_model.h" 19 #include "chrome/browser/chrome_notification_types.h" 20 #include "chrome/browser/content_settings/content_settings_details.h" 21 #include "chrome/browser/content_settings/content_settings_utils.h" 22 #include "chrome/browser/content_settings/host_content_settings_map.h" 23 #include "chrome/browser/prerender/prerender_manager.h" 24 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/render_messages.h" 27 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/navigation_controller.h" 29 #include "content/public/browser/navigation_details.h" 30 #include "content/public/browser/navigation_entry.h" 31 #include "content/public/browser/notification_service.h" 32 #include "content/public/browser/render_frame_host.h" 33 #include "content/public/browser/render_view_host.h" 34 #include "content/public/browser/web_contents.h" 35 #include "content/public/browser/web_contents_delegate.h" 36 #include "net/cookies/canonical_cookie.h" 37 #include "webkit/common/fileapi/file_system_types.h" 38 39 using content::BrowserThread; 40 using content::NavigationController; 41 using content::NavigationEntry; 42 using content::RenderViewHost; 43 using content::WebContents; 44 45 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings); 46 47 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver( 48 TabSpecificContentSettings* tab_specific_content_settings) 49 : tab_specific_content_settings_(tab_specific_content_settings) { 50 tab_specific_content_settings_->AddSiteDataObserver(this); 51 } 52 53 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() { 54 if (tab_specific_content_settings_) 55 tab_specific_content_settings_->RemoveSiteDataObserver(this); 56 } 57 58 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() { 59 tab_specific_content_settings_ = NULL; 60 } 61 62 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab) 63 : content::WebContentsObserver(tab), 64 profile_(Profile::FromBrowserContext(tab->GetBrowserContext())), 65 allowed_local_shared_objects_(profile_), 66 blocked_local_shared_objects_(profile_), 67 geolocation_usages_state_(profile_, CONTENT_SETTINGS_TYPE_GEOLOCATION), 68 midi_usages_state_(profile_, CONTENT_SETTINGS_TYPE_MIDI_SYSEX), 69 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()), 70 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()), 71 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT), 72 load_plugins_link_enabled_(true) { 73 ClearBlockedContentSettingsExceptForCookies(); 74 ClearCookieSpecificContentSettings(); 75 76 registrar_.Add(this, chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED, 77 content::Source<HostContentSettingsMap>( 78 profile_->GetHostContentSettingsMap())); 79 } 80 81 TabSpecificContentSettings::~TabSpecificContentSettings() { 82 FOR_EACH_OBSERVER( 83 SiteDataObserver, observer_list_, ContentSettingsDestroyed()); 84 } 85 86 TabSpecificContentSettings* TabSpecificContentSettings::Get( 87 int render_process_id, int render_view_id) { 88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 89 90 RenderViewHost* view = RenderViewHost::FromID(render_process_id, 91 render_view_id); 92 if (!view) 93 return NULL; 94 95 WebContents* web_contents = WebContents::FromRenderViewHost(view); 96 if (!web_contents) 97 return NULL; 98 99 return TabSpecificContentSettings::FromWebContents(web_contents); 100 } 101 102 TabSpecificContentSettings* TabSpecificContentSettings::GetForFrame( 103 int render_process_id, int render_frame_id) { 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 105 106 content::RenderFrameHost* frame = content::RenderFrameHost::FromID( 107 render_process_id, render_frame_id); 108 WebContents* web_contents = WebContents::FromRenderFrameHost(frame); 109 if (!web_contents) 110 return NULL; 111 112 return TabSpecificContentSettings::FromWebContents(web_contents); 113 } 114 115 // static 116 void TabSpecificContentSettings::CookiesRead(int render_process_id, 117 int render_frame_id, 118 const GURL& url, 119 const GURL& frame_url, 120 const net::CookieList& cookie_list, 121 bool blocked_by_policy, 122 bool is_for_blocking_resource) { 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 124 TabSpecificContentSettings* settings = 125 GetForFrame(render_process_id, render_frame_id); 126 if (settings) { 127 settings->OnCookiesRead(url, frame_url, cookie_list, 128 blocked_by_policy); 129 } 130 prerender::PrerenderManager::RecordCookieEvent( 131 render_process_id, 132 render_frame_id, 133 url, 134 frame_url, 135 is_for_blocking_resource, 136 prerender::PrerenderContents::COOKIE_EVENT_SEND, 137 &cookie_list); 138 } 139 140 // static 141 void TabSpecificContentSettings::CookieChanged( 142 int render_process_id, 143 int render_frame_id, 144 const GURL& url, 145 const GURL& frame_url, 146 const std::string& cookie_line, 147 const net::CookieOptions& options, 148 bool blocked_by_policy) { 149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 150 TabSpecificContentSettings* settings = 151 GetForFrame(render_process_id, render_frame_id); 152 if (settings) 153 settings->OnCookieChanged(url, frame_url, cookie_line, options, 154 blocked_by_policy); 155 prerender::PrerenderManager::RecordCookieEvent( 156 render_process_id, 157 render_frame_id, 158 url, 159 frame_url, 160 false /*is_critical_request*/, 161 prerender::PrerenderContents::COOKIE_EVENT_CHANGE, 162 NULL); 163 } 164 165 // static 166 void TabSpecificContentSettings::WebDatabaseAccessed( 167 int render_process_id, 168 int render_frame_id, 169 const GURL& url, 170 const base::string16& name, 171 const base::string16& display_name, 172 bool blocked_by_policy) { 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 174 TabSpecificContentSettings* settings = GetForFrame( 175 render_process_id, render_frame_id); 176 if (settings) 177 settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy); 178 } 179 180 // static 181 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id, 182 int render_frame_id, 183 const GURL& url, 184 bool local, 185 bool blocked_by_policy) { 186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 187 TabSpecificContentSettings* settings = GetForFrame( 188 render_process_id, render_frame_id); 189 if (settings) 190 settings->OnLocalStorageAccessed(url, local, blocked_by_policy); 191 } 192 193 // static 194 void TabSpecificContentSettings::IndexedDBAccessed( 195 int render_process_id, 196 int render_frame_id, 197 const GURL& url, 198 const base::string16& description, 199 bool blocked_by_policy) { 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 201 TabSpecificContentSettings* settings = GetForFrame( 202 render_process_id, render_frame_id); 203 if (settings) 204 settings->OnIndexedDBAccessed(url, description, blocked_by_policy); 205 } 206 207 // static 208 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id, 209 int render_frame_id, 210 const GURL& url, 211 bool blocked_by_policy) { 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 213 TabSpecificContentSettings* settings = GetForFrame( 214 render_process_id, render_frame_id); 215 if (settings) 216 settings->OnFileSystemAccessed(url, blocked_by_policy); 217 } 218 219 bool TabSpecificContentSettings::IsContentBlocked( 220 ContentSettingsType content_type) const { 221 DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION) 222 << "Geolocation settings handled by ContentSettingGeolocationImageModel"; 223 DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS) 224 << "Notifications settings handled by " 225 << "ContentSettingsNotificationsImageModel"; 226 227 if (content_type == CONTENT_SETTINGS_TYPE_IMAGES || 228 content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT || 229 content_type == CONTENT_SETTINGS_TYPE_PLUGINS || 230 content_type == CONTENT_SETTINGS_TYPE_COOKIES || 231 content_type == CONTENT_SETTINGS_TYPE_POPUPS || 232 content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT || 233 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM || 234 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || 235 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA || 236 content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER || 237 content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS || 238 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { 239 return content_blocked_[content_type]; 240 } 241 242 return false; 243 } 244 245 bool TabSpecificContentSettings::IsBlockageIndicated( 246 ContentSettingsType content_type) const { 247 return content_blockage_indicated_to_user_[content_type]; 248 } 249 250 void TabSpecificContentSettings::SetBlockageHasBeenIndicated( 251 ContentSettingsType content_type) { 252 content_blockage_indicated_to_user_[content_type] = true; 253 } 254 255 bool TabSpecificContentSettings::IsContentAllowed( 256 ContentSettingsType content_type) const { 257 // This method currently only returns meaningful values for the content type 258 // cookies, mediastream, PPAPI broker, and downloads. 259 if (content_type != CONTENT_SETTINGS_TYPE_COOKIES && 260 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM && 261 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC && 262 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA && 263 content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER && 264 content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS && 265 content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { 266 return false; 267 } 268 269 return content_allowed_[content_type]; 270 } 271 272 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) { 273 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION) 274 << "Geolocation settings handled by OnGeolocationPermissionSet"; 275 if (type < 0 || type >= CONTENT_SETTINGS_NUM_TYPES) 276 return; 277 278 // Media is different from other content setting types since it allows new 279 // setting to kick in without reloading the page, and the UI for media is 280 // always reflecting the newest permission setting. 281 switch (type) { 282 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: 283 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: 284 #if defined(OS_ANDROID) 285 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: 286 #endif 287 content_allowed_[type] = false; 288 break; 289 default: 290 content_allowed_[type] = true; 291 break; 292 } 293 294 #if defined(OS_ANDROID) 295 if (type == CONTENT_SETTINGS_TYPE_POPUPS) { 296 // For Android we do not have a persistent button that will always be 297 // visible for blocked popups. Instead we have info bars which could be 298 // dismissed. Have to clear the blocked state so we properly notify the 299 // relevant pieces again. 300 content_blocked_[type] = false; 301 content_blockage_indicated_to_user_[type] = false; 302 } 303 #endif 304 305 if (!content_blocked_[type]) { 306 content_blocked_[type] = true; 307 // TODO: it would be nice to have a way of mocking this in tests. 308 content::NotificationService::current()->Notify( 309 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 310 content::Source<WebContents>(web_contents()), 311 content::NotificationService::NoDetails()); 312 } 313 } 314 315 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) { 316 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION) 317 << "Geolocation settings handled by OnGeolocationPermissionSet"; 318 bool access_changed = false; 319 switch (type) { 320 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: 321 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: 322 #if defined(OS_ANDROID) 323 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: 324 #endif 325 // The setting for media is overwritten here because media does not need 326 // to reload the page to have the new setting kick in. See issue/175993. 327 if (content_blocked_[type]) { 328 content_blocked_[type] = false; 329 access_changed = true; 330 } 331 break; 332 default: 333 break; 334 } 335 336 if (!content_allowed_[type]) { 337 content_allowed_[type] = true; 338 access_changed = true; 339 } 340 341 if (access_changed) { 342 content::NotificationService::current()->Notify( 343 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 344 content::Source<WebContents>(web_contents()), 345 content::NotificationService::NoDetails()); 346 } 347 } 348 349 void TabSpecificContentSettings::OnCookiesRead( 350 const GURL& url, 351 const GURL& frame_url, 352 const net::CookieList& cookie_list, 353 bool blocked_by_policy) { 354 if (cookie_list.empty()) 355 return; 356 if (blocked_by_policy) { 357 blocked_local_shared_objects_.cookies()->AddReadCookies( 358 frame_url, url, cookie_list); 359 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 360 } else { 361 allowed_local_shared_objects_.cookies()->AddReadCookies( 362 frame_url, url, cookie_list); 363 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 364 } 365 366 NotifySiteDataObservers(); 367 } 368 369 void TabSpecificContentSettings::OnCookieChanged( 370 const GURL& url, 371 const GURL& frame_url, 372 const std::string& cookie_line, 373 const net::CookieOptions& options, 374 bool blocked_by_policy) { 375 if (blocked_by_policy) { 376 blocked_local_shared_objects_.cookies()->AddChangedCookie( 377 frame_url, url, cookie_line, options); 378 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 379 } else { 380 allowed_local_shared_objects_.cookies()->AddChangedCookie( 381 frame_url, url, cookie_line, options); 382 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 383 } 384 385 NotifySiteDataObservers(); 386 } 387 388 void TabSpecificContentSettings::OnIndexedDBAccessed( 389 const GURL& url, 390 const base::string16& description, 391 bool blocked_by_policy) { 392 if (blocked_by_policy) { 393 blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB( 394 url, description); 395 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 396 } else { 397 allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB( 398 url, description); 399 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 400 } 401 402 NotifySiteDataObservers(); 403 } 404 405 void TabSpecificContentSettings::OnLocalStorageAccessed( 406 const GURL& url, 407 bool local, 408 bool blocked_by_policy) { 409 LocalSharedObjectsContainer& container = blocked_by_policy ? 410 blocked_local_shared_objects_ : allowed_local_shared_objects_; 411 CannedBrowsingDataLocalStorageHelper* helper = 412 local ? container.local_storages() : container.session_storages(); 413 helper->AddLocalStorage(url); 414 415 if (blocked_by_policy) 416 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 417 else 418 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 419 420 NotifySiteDataObservers(); 421 } 422 423 void TabSpecificContentSettings::OnWebDatabaseAccessed( 424 const GURL& url, 425 const base::string16& name, 426 const base::string16& display_name, 427 bool blocked_by_policy) { 428 if (blocked_by_policy) { 429 blocked_local_shared_objects_.databases()->AddDatabase( 430 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name)); 431 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 432 } else { 433 allowed_local_shared_objects_.databases()->AddDatabase( 434 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name)); 435 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 436 } 437 438 NotifySiteDataObservers(); 439 } 440 441 void TabSpecificContentSettings::OnFileSystemAccessed( 442 const GURL& url, 443 bool blocked_by_policy) { 444 if (blocked_by_policy) { 445 blocked_local_shared_objects_.file_systems()->AddFileSystem(url, 446 fileapi::kFileSystemTypeTemporary, 0); 447 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 448 } else { 449 allowed_local_shared_objects_.file_systems()->AddFileSystem(url, 450 fileapi::kFileSystemTypeTemporary, 0); 451 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 452 } 453 454 NotifySiteDataObservers(); 455 } 456 457 void TabSpecificContentSettings::OnGeolocationPermissionSet( 458 const GURL& requesting_origin, 459 bool allowed) { 460 geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed); 461 content::NotificationService::current()->Notify( 462 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 463 content::Source<WebContents>(web_contents()), 464 content::NotificationService::NoDetails()); 465 } 466 467 #if defined(OS_ANDROID) 468 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet( 469 const GURL& requesting_origin, 470 bool allowed) { 471 if (allowed) { 472 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER); 473 } else { 474 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER); 475 } 476 } 477 #endif 478 479 TabSpecificContentSettings::MicrophoneCameraState 480 TabSpecificContentSettings::GetMicrophoneCameraState() const { 481 if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) && 482 IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { 483 return MICROPHONE_CAMERA_ACCESSED; 484 } else if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) { 485 return MICROPHONE_ACCESSED; 486 } else if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { 487 return CAMERA_ACCESSED; 488 } 489 490 if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) && 491 IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { 492 return MICROPHONE_CAMERA_BLOCKED; 493 } else if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) { 494 return MICROPHONE_BLOCKED; 495 } else if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { 496 return CAMERA_BLOCKED; 497 } 498 499 return MICROPHONE_CAMERA_NOT_ACCESSED; 500 } 501 502 void TabSpecificContentSettings::OnMediaStreamPermissionSet( 503 const GURL& request_origin, 504 const MediaStreamDevicesController::MediaStreamTypeSettingsMap& 505 request_permissions) { 506 media_stream_access_origin_ = request_origin; 507 508 MediaStreamDevicesController::MediaStreamTypeSettingsMap::const_iterator it = 509 request_permissions.find(content::MEDIA_DEVICE_AUDIO_CAPTURE); 510 if (it != request_permissions.end()) { 511 media_stream_requested_audio_device_ = it->second.requested_device_id; 512 switch (it->second.permission) { 513 case MediaStreamDevicesController::MEDIA_NONE: 514 NOTREACHED(); 515 break; 516 case MediaStreamDevicesController::MEDIA_ALLOWED: 517 OnContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); 518 break; 519 // TODO(grunell): UI should show for what reason access has been blocked. 520 case MediaStreamDevicesController::MEDIA_BLOCKED_BY_POLICY: 521 case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER_SETTING: 522 case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER: 523 OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); 524 break; 525 } 526 } 527 528 it = request_permissions.find(content::MEDIA_DEVICE_VIDEO_CAPTURE); 529 if (it != request_permissions.end()) { 530 media_stream_requested_video_device_ = it->second.requested_device_id; 531 switch (it->second.permission) { 532 case MediaStreamDevicesController::MEDIA_NONE: 533 NOTREACHED(); 534 break; 535 case MediaStreamDevicesController::MEDIA_ALLOWED: 536 OnContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); 537 break; 538 // TODO(grunell): UI should show for what reason access has been blocked. 539 case MediaStreamDevicesController::MEDIA_BLOCKED_BY_POLICY: 540 case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER_SETTING: 541 case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER: 542 OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); 543 break; 544 } 545 } 546 } 547 548 void TabSpecificContentSettings::OnMidiSysExAccessed( 549 const GURL& requesting_origin) { 550 midi_usages_state_.OnPermissionSet(requesting_origin, true); 551 OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX); 552 } 553 554 void TabSpecificContentSettings::OnMidiSysExAccessBlocked( 555 const GURL& requesting_origin) { 556 midi_usages_state_.OnPermissionSet(requesting_origin, false); 557 OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX); 558 } 559 560 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() { 561 for (size_t i = 0; i < arraysize(content_blocked_); ++i) { 562 if (i == CONTENT_SETTINGS_TYPE_COOKIES) 563 continue; 564 content_blocked_[i] = false; 565 content_allowed_[i] = false; 566 content_blockage_indicated_to_user_[i] = false; 567 } 568 load_plugins_link_enabled_ = true; 569 content::NotificationService::current()->Notify( 570 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 571 content::Source<WebContents>(web_contents()), 572 content::NotificationService::NoDetails()); 573 } 574 575 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() { 576 blocked_local_shared_objects_.Reset(); 577 allowed_local_shared_objects_.Reset(); 578 content_blocked_[CONTENT_SETTINGS_TYPE_COOKIES] = false; 579 content_allowed_[CONTENT_SETTINGS_TYPE_COOKIES] = false; 580 content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_COOKIES] = false; 581 content::NotificationService::current()->Notify( 582 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 583 content::Source<WebContents>(web_contents()), 584 content::NotificationService::NoDetails()); 585 } 586 587 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked) { 588 content_blocked_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = blocked; 589 content_allowed_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = !blocked; 590 content_blockage_indicated_to_user_[ 591 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = false; 592 content::NotificationService::current()->Notify( 593 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 594 content::Source<WebContents>(web_contents()), 595 content::NotificationService::NoDetails()); 596 } 597 598 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked) { 599 content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked; 600 content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false; 601 content::NotificationService::current()->Notify( 602 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 603 content::Source<WebContents>(web_contents()), 604 content::NotificationService::NoDetails()); 605 } 606 607 void TabSpecificContentSettings::GeolocationDidNavigate( 608 const content::LoadCommittedDetails& details) { 609 geolocation_usages_state_.DidNavigate(details); 610 } 611 612 void TabSpecificContentSettings::MidiDidNavigate( 613 const content::LoadCommittedDetails& details) { 614 midi_usages_state_.DidNavigate(details); 615 } 616 617 void TabSpecificContentSettings::ClearGeolocationContentSettings() { 618 geolocation_usages_state_.ClearStateMap(); 619 } 620 621 void TabSpecificContentSettings::ClearMidiContentSettings() { 622 midi_usages_state_.ClearStateMap(); 623 } 624 625 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) { 626 if (allowed) { 627 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER); 628 } else { 629 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER); 630 } 631 } 632 633 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated( 634 content::RenderFrameHost* render_frame_host) { 635 // We want to tell the renderer-side code to ignore content settings for this 636 // page. 637 render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial( 638 render_frame_host->GetRoutingID())); 639 } 640 641 bool TabSpecificContentSettings::OnMessageReceived( 642 const IPC::Message& message, 643 content::RenderFrameHost* render_frame_host) { 644 bool handled = true; 645 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message) 646 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked) 647 IPC_MESSAGE_UNHANDLED(handled = false) 648 IPC_END_MESSAGE_MAP() 649 return handled; 650 } 651 652 void TabSpecificContentSettings::DidNavigateMainFrame( 653 const content::LoadCommittedDetails& details, 654 const content::FrameNavigateParams& params) { 655 if (!details.is_in_page) { 656 // Clear "blocked" flags. 657 ClearBlockedContentSettingsExceptForCookies(); 658 GeolocationDidNavigate(details); 659 MidiDidNavigate(details); 660 } 661 } 662 663 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame( 664 int64 frame_id, 665 int64 parent_frame_id, 666 bool is_main_frame, 667 const GURL& validated_url, 668 bool is_error_page, 669 bool is_iframe_srcdoc, 670 RenderViewHost* render_view_host) { 671 if (!is_main_frame) 672 return; 673 674 // If we're displaying a network error page do not reset the content 675 // settings delegate's cookies so the user has a chance to modify cookie 676 // settings. 677 if (!is_error_page) 678 ClearCookieSpecificContentSettings(); 679 ClearGeolocationContentSettings(); 680 ClearMidiContentSettings(); 681 ClearPendingProtocolHandler(); 682 } 683 684 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url, 685 bool blocked_by_policy) { 686 if (blocked_by_policy) { 687 blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url); 688 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); 689 } else { 690 allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url); 691 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 692 } 693 } 694 695 void TabSpecificContentSettings::Observe( 696 int type, 697 const content::NotificationSource& source, 698 const content::NotificationDetails& details) { 699 DCHECK(type == chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED); 700 701 content::Details<const ContentSettingsDetails> settings_details(details); 702 const NavigationController& controller = web_contents()->GetController(); 703 NavigationEntry* entry = controller.GetVisibleEntry(); 704 GURL entry_url; 705 if (entry) 706 entry_url = entry->GetURL(); 707 if (settings_details.ptr()->update_all() || 708 // The visible NavigationEntry is the URL in the URL field of a tab. 709 // Currently this should be matched by the |primary_pattern|. 710 settings_details.ptr()->primary_pattern().Matches(entry_url)) { 711 Profile* profile = 712 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 713 RendererContentSettingRules rules; 714 GetRendererContentSettingRules(profile->GetHostContentSettingsMap(), 715 &rules); 716 Send(new ChromeViewMsg_SetContentSettingRules(rules)); 717 } 718 } 719 720 void TabSpecificContentSettings::AddSiteDataObserver( 721 SiteDataObserver* observer) { 722 observer_list_.AddObserver(observer); 723 } 724 725 void TabSpecificContentSettings::RemoveSiteDataObserver( 726 SiteDataObserver* observer) { 727 observer_list_.RemoveObserver(observer); 728 } 729 730 void TabSpecificContentSettings::NotifySiteDataObservers() { 731 FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed()); 732 } 733