• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SiteDataObserver(TabSpecificContentSettings * tab_specific_content_settings)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 
~SiteDataObserver()52 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
53   if (tab_specific_content_settings_)
54     tab_specific_content_settings_->RemoveSiteDataObserver(this);
55 }
56 
ContentSettingsDestroyed()57 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
58   tab_specific_content_settings_ = NULL;
59 }
60 
TabSpecificContentSettings(WebContents * tab)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 
~TabSpecificContentSettings()80 TabSpecificContentSettings::~TabSpecificContentSettings() {
81   FOR_EACH_OBSERVER(
82       SiteDataObserver, observer_list_, ContentSettingsDestroyed());
83 }
84 
Get(int render_process_id,int render_view_id)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
CookiesRead(int render_process_id,int render_view_id,const GURL & url,const GURL & frame_url,const net::CookieList & cookie_list,bool blocked_by_policy)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
CookieChanged(int render_process_id,int render_view_id,const GURL & url,const GURL & frame_url,const std::string & cookie_line,const net::CookieOptions & options,bool blocked_by_policy)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
WebDatabaseAccessed(int render_process_id,int render_view_id,const GURL & url,const base::string16 & name,const base::string16 & display_name,bool blocked_by_policy)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
DOMStorageAccessed(int render_process_id,int render_view_id,const GURL & url,bool local,bool blocked_by_policy)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
IndexedDBAccessed(int render_process_id,int render_view_id,const GURL & url,const base::string16 & description,bool blocked_by_policy)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
FileSystemAccessed(int render_process_id,int render_view_id,const GURL & url,bool blocked_by_policy)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 
IsContentBlocked(ContentSettingsType content_type) const195 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 
IsBlockageIndicated(ContentSettingsType content_type) const221 bool TabSpecificContentSettings::IsBlockageIndicated(
222     ContentSettingsType content_type) const {
223   return content_blockage_indicated_to_user_[content_type];
224 }
225 
SetBlockageHasBeenIndicated(ContentSettingsType content_type)226 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
227     ContentSettingsType content_type) {
228   content_blockage_indicated_to_user_[content_type] = true;
229 }
230 
IsContentAllowed(ContentSettingsType content_type) const231 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 
OnContentBlocked(ContentSettingsType type)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 
OnContentAllowed(ContentSettingsType type)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 
OnCookiesRead(const GURL & url,const GURL & frame_url,const net::CookieList & cookie_list,bool blocked_by_policy)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 
OnCookieChanged(const GURL & url,const GURL & frame_url,const std::string & cookie_line,const net::CookieOptions & options,bool blocked_by_policy)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 
OnIndexedDBAccessed(const GURL & url,const base::string16 & description,bool blocked_by_policy)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 
OnLocalStorageAccessed(const GURL & url,bool local,bool blocked_by_policy)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 
OnWebDatabaseAccessed(const GURL & url,const base::string16 & name,const base::string16 & display_name,bool blocked_by_policy)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 
OnFileSystemAccessed(const GURL & url,bool blocked_by_policy)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 
OnGeolocationPermissionSet(const GURL & requesting_origin,bool allowed)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)
OnProtectedMediaIdentifierPermissionSet(const GURL & requesting_origin,bool allowed)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
GetMicrophoneCameraState() const456 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 
OnMediaStreamPermissionSet(const GURL & request_origin,const MediaStreamDevicesController::MediaStreamTypeSettingsMap & request_permissions)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 
OnMIDISysExAccessed(const GURL & requesting_origin)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 
OnMIDISysExAccessBlocked(const GURL & requesting_origin)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 
ClearBlockedContentSettingsExceptForCookies()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 
ClearCookieSpecificContentSettings()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 
SetDownloadsBlocked(bool blocked)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 
SetPopupsBlocked(bool blocked)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 
GeolocationDidNavigate(const content::LoadCommittedDetails & details)583 void TabSpecificContentSettings::GeolocationDidNavigate(
584       const content::LoadCommittedDetails& details) {
585   geolocation_usages_state_.DidNavigate(details);
586 }
587 
MIDIDidNavigate(const content::LoadCommittedDetails & details)588 void TabSpecificContentSettings::MIDIDidNavigate(
589     const content::LoadCommittedDetails& details) {
590   midi_usages_state_.DidNavigate(details);
591 }
592 
ClearGeolocationContentSettings()593 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
594   geolocation_usages_state_.ClearStateMap();
595 }
596 
ClearMIDIContentSettings()597 void TabSpecificContentSettings::ClearMIDIContentSettings() {
598   midi_usages_state_.ClearStateMap();
599 }
600 
SetPepperBrokerAllowed(bool allowed)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 
RenderViewForInterstitialPageCreated(RenderViewHost * render_view_host)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 
OnMessageReceived(const IPC::Message & message)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 
DidNavigateMainFrame(const content::LoadCommittedDetails & details,const content::FrameNavigateParams & params)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 
DidStartProvisionalLoadForFrame(int64 frame_id,int64 parent_frame_id,bool is_main_frame,const GURL & validated_url,bool is_error_page,bool is_iframe_srcdoc,RenderViewHost * render_view_host)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 
AppCacheAccessed(const GURL & manifest_url,bool blocked_by_policy)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 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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 
AddSiteDataObserver(SiteDataObserver * observer)695 void TabSpecificContentSettings::AddSiteDataObserver(
696     SiteDataObserver* observer) {
697   observer_list_.AddObserver(observer);
698 }
699 
RemoveSiteDataObserver(SiteDataObserver * observer)700 void TabSpecificContentSettings::RemoveSiteDataObserver(
701     SiteDataObserver* observer) {
702   observer_list_.RemoveObserver(observer);
703 }
704 
NotifySiteDataObservers()705 void TabSpecificContentSettings::NotifySiteDataObservers() {
706   FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
707 }
708