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/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