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