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