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