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