• 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_utils.h"
21 #include "chrome/browser/content_settings/host_content_settings_map.h"
22 #include "chrome/browser/prerender/prerender_manager.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/render_messages.h"
26 #include "components/content_settings/core/browser/content_settings_details.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_registrar.h"
32 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/render_frame_host.h"
34 #include "content/public/browser/render_view_host.h"
35 #include "content/public/browser/web_contents.h"
36 #include "content/public/browser/web_contents_delegate.h"
37 #include "net/cookies/canonical_cookie.h"
38 #include "storage/common/fileapi/file_system_types.h"
39 
40 using content::BrowserThread;
41 using content::NavigationController;
42 using content::NavigationEntry;
43 using content::RenderViewHost;
44 using content::WebContents;
45 
46 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
47 
SiteDataObserver(TabSpecificContentSettings * tab_specific_content_settings)48 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
49     TabSpecificContentSettings* tab_specific_content_settings)
50     : tab_specific_content_settings_(tab_specific_content_settings) {
51   tab_specific_content_settings_->AddSiteDataObserver(this);
52 }
53 
~SiteDataObserver()54 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
55   if (tab_specific_content_settings_)
56     tab_specific_content_settings_->RemoveSiteDataObserver(this);
57 }
58 
ContentSettingsDestroyed()59 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
60   tab_specific_content_settings_ = NULL;
61 }
62 
TabSpecificContentSettings(WebContents * tab)63 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
64     : content::WebContentsObserver(tab),
65       profile_(Profile::FromBrowserContext(tab->GetBrowserContext())),
66       allowed_local_shared_objects_(profile_),
67       blocked_local_shared_objects_(profile_),
68       geolocation_usages_state_(profile_, CONTENT_SETTINGS_TYPE_GEOLOCATION),
69       midi_usages_state_(profile_, CONTENT_SETTINGS_TYPE_MIDI_SYSEX),
70       pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
71       previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
72       pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
73       load_plugins_link_enabled_(true),
74       observer_(this) {
75   ClearBlockedContentSettingsExceptForCookies();
76   ClearCookieSpecificContentSettings();
77 
78   observer_.Add(profile_->GetHostContentSettingsMap());
79 }
80 
~TabSpecificContentSettings()81 TabSpecificContentSettings::~TabSpecificContentSettings() {
82   FOR_EACH_OBSERVER(
83       SiteDataObserver, observer_list_, ContentSettingsDestroyed());
84 }
85 
Get(int render_process_id,int render_view_id)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 
GetForFrame(int render_process_id,int render_frame_id)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
CookiesRead(int render_process_id,int render_frame_id,const GURL & url,const GURL & frame_url,const net::CookieList & cookie_list,bool blocked_by_policy,bool is_for_blocking_resource)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
CookieChanged(int render_process_id,int render_frame_id,const GURL & url,const GURL & frame_url,const std::string & cookie_line,const net::CookieOptions & options,bool blocked_by_policy)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
WebDatabaseAccessed(int render_process_id,int render_frame_id,const GURL & url,const base::string16 & name,const base::string16 & display_name,bool blocked_by_policy)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
DOMStorageAccessed(int render_process_id,int render_frame_id,const GURL & url,bool local,bool blocked_by_policy)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
IndexedDBAccessed(int render_process_id,int render_frame_id,const GURL & url,const base::string16 & description,bool blocked_by_policy)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
FileSystemAccessed(int render_process_id,int render_frame_id,const GURL & url,bool blocked_by_policy)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 
IsContentBlocked(ContentSettingsType content_type) const219 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 
IsBlockageIndicated(ContentSettingsType content_type) const245 bool TabSpecificContentSettings::IsBlockageIndicated(
246     ContentSettingsType content_type) const {
247   return content_blockage_indicated_to_user_[content_type];
248 }
249 
SetBlockageHasBeenIndicated(ContentSettingsType content_type)250 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
251     ContentSettingsType content_type) {
252   content_blockage_indicated_to_user_[content_type] = true;
253 }
254 
IsContentAllowed(ContentSettingsType content_type) const255 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 
OnContentBlocked(ContentSettingsType type)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 
OnContentAllowed(ContentSettingsType type)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 
OnCookiesRead(const GURL & url,const GURL & frame_url,const net::CookieList & cookie_list,bool blocked_by_policy)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 
OnCookieChanged(const GURL & url,const GURL & frame_url,const std::string & cookie_line,const net::CookieOptions & options,bool blocked_by_policy)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 
OnIndexedDBAccessed(const GURL & url,const base::string16 & description,bool blocked_by_policy)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 
OnLocalStorageAccessed(const GURL & url,bool local,bool blocked_by_policy)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 
OnWebDatabaseAccessed(const GURL & url,const base::string16 & name,const base::string16 & display_name,bool blocked_by_policy)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 
OnFileSystemAccessed(const GURL & url,bool blocked_by_policy)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(
446         url, storage::kFileSystemTypeTemporary, 0);
447     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
448   } else {
449     allowed_local_shared_objects_.file_systems()->AddFileSystem(
450         url, storage::kFileSystemTypeTemporary, 0);
451     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
452   }
453 
454   NotifySiteDataObservers();
455 }
456 
OnGeolocationPermissionSet(const GURL & requesting_origin,bool allowed)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)
OnProtectedMediaIdentifierPermissionSet(const GURL & requesting_origin,bool allowed)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
GetMicrophoneCameraState() const480 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 
OnMediaStreamPermissionSet(const GURL & request_origin,const MediaStreamDevicesController::MediaStreamTypeSettingsMap & request_permissions)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 
OnMidiSysExAccessed(const GURL & requesting_origin)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 
OnMidiSysExAccessBlocked(const GURL & requesting_origin)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 
ClearBlockedContentSettingsExceptForCookies()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 
ClearCookieSpecificContentSettings()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 
SetDownloadsBlocked(bool blocked)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 
SetPopupsBlocked(bool blocked)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 
GeolocationDidNavigate(const content::LoadCommittedDetails & details)607 void TabSpecificContentSettings::GeolocationDidNavigate(
608       const content::LoadCommittedDetails& details) {
609   geolocation_usages_state_.DidNavigate(details);
610 }
611 
MidiDidNavigate(const content::LoadCommittedDetails & details)612 void TabSpecificContentSettings::MidiDidNavigate(
613     const content::LoadCommittedDetails& details) {
614   midi_usages_state_.DidNavigate(details);
615 }
616 
ClearGeolocationContentSettings()617 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
618   geolocation_usages_state_.ClearStateMap();
619 }
620 
ClearMidiContentSettings()621 void TabSpecificContentSettings::ClearMidiContentSettings() {
622   midi_usages_state_.ClearStateMap();
623 }
624 
SetPepperBrokerAllowed(bool allowed)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 
RenderFrameForInterstitialPageCreated(content::RenderFrameHost * render_frame_host)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 
OnMessageReceived(const IPC::Message & message,content::RenderFrameHost * render_frame_host)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 
DidNavigateMainFrame(const content::LoadCommittedDetails & details,const content::FrameNavigateParams & params)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 
DidStartProvisionalLoadForFrame(content::RenderFrameHost * render_frame_host,const GURL & validated_url,bool is_error_page,bool is_iframe_srcdoc)663 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
664     content::RenderFrameHost* render_frame_host,
665     const GURL& validated_url,
666     bool is_error_page,
667     bool is_iframe_srcdoc) {
668   if (render_frame_host->GetParent())
669     return;
670 
671   // If we're displaying a network error page do not reset the content
672   // settings delegate's cookies so the user has a chance to modify cookie
673   // settings.
674   if (!is_error_page)
675     ClearCookieSpecificContentSettings();
676   ClearGeolocationContentSettings();
677   ClearMidiContentSettings();
678   ClearPendingProtocolHandler();
679 }
680 
AppCacheAccessed(const GURL & manifest_url,bool blocked_by_policy)681 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
682                                                   bool blocked_by_policy) {
683   if (blocked_by_policy) {
684     blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
685     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
686   } else {
687     allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
688     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
689   }
690 }
691 
OnContentSettingChanged(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,std::string resource_identifier)692 void TabSpecificContentSettings::OnContentSettingChanged(
693     const ContentSettingsPattern& primary_pattern,
694     const ContentSettingsPattern& secondary_pattern,
695     ContentSettingsType content_type,
696     std::string resource_identifier) {
697   const ContentSettingsDetails details(
698       primary_pattern, secondary_pattern, content_type, resource_identifier);
699   const NavigationController& controller = web_contents()->GetController();
700   NavigationEntry* entry = controller.GetVisibleEntry();
701   GURL entry_url;
702   if (entry)
703     entry_url = entry->GetURL();
704   if (details.update_all() ||
705       // The visible NavigationEntry is the URL in the URL field of a tab.
706       // Currently this should be matched by the |primary_pattern|.
707       details.primary_pattern().Matches(entry_url)) {
708     Profile* profile =
709         Profile::FromBrowserContext(web_contents()->GetBrowserContext());
710     RendererContentSettingRules rules;
711     GetRendererContentSettingRules(profile->GetHostContentSettingsMap(),
712                                    &rules);
713     Send(new ChromeViewMsg_SetContentSettingRules(rules));
714   }
715 }
716 
AddSiteDataObserver(SiteDataObserver * observer)717 void TabSpecificContentSettings::AddSiteDataObserver(
718     SiteDataObserver* observer) {
719   observer_list_.AddObserver(observer);
720 }
721 
RemoveSiteDataObserver(SiteDataObserver * observer)722 void TabSpecificContentSettings::RemoveSiteDataObserver(
723     SiteDataObserver* observer) {
724   observer_list_.RemoveObserver(observer);
725 }
726 
NotifySiteDataObservers()727 void TabSpecificContentSettings::NotifySiteDataObservers() {
728   FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
729 }
730