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