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.
5 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
9 #include "base/command_line.h"
10 #include "base/lazy_instance.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
19 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
20 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
21 #include "chrome/browser/browsing_data/cookies_tree_model.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
24 #include "chrome/browser/media/media_stream_capture_indicator.h"
25 #include "chrome/browser/prerender/prerender_manager.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/common/render_messages.h"
30 #include "components/content_settings/core/browser/content_settings_details.h"
31 #include "components/content_settings/core/browser/content_settings_utils.h"
32 #include "components/content_settings/core/browser/host_content_settings_map.h"
33 #include "components/rappor/rappor_service.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/navigation_details.h"
37 #include "content/public/browser/navigation_entry.h"
38 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/render_frame_host.h"
41 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/browser/web_contents_delegate.h"
44 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
45 #include "net/cookies/canonical_cookie.h"
46 #include "storage/common/fileapi/file_system_types.h"
48 using content::BrowserThread
;
49 using content::NavigationController
;
50 using content::NavigationEntry
;
51 using content::RenderViewHost
;
52 using content::WebContents
;
54 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings
);
58 // Returns the object given a render frame's id.
59 TabSpecificContentSettings
* GetForFrame(int render_process_id
,
60 int render_frame_id
) {
61 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
63 content::RenderFrameHost
* frame
= content::RenderFrameHost::FromID(
64 render_process_id
, render_frame_id
);
65 WebContents
* web_contents
= WebContents::FromRenderFrameHost(frame
);
69 return TabSpecificContentSettings::FromWebContents(web_contents
);
74 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
75 TabSpecificContentSettings
* tab_specific_content_settings
)
76 : tab_specific_content_settings_(tab_specific_content_settings
) {
77 tab_specific_content_settings_
->AddSiteDataObserver(this);
80 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
81 if (tab_specific_content_settings_
)
82 tab_specific_content_settings_
->RemoveSiteDataObserver(this);
85 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
86 tab_specific_content_settings_
= NULL
;
89 TabSpecificContentSettings::TabSpecificContentSettings(WebContents
* tab
)
90 : content::WebContentsObserver(tab
),
91 allowed_local_shared_objects_(
92 Profile::FromBrowserContext(tab
->GetBrowserContext())),
93 blocked_local_shared_objects_(
94 Profile::FromBrowserContext(tab
->GetBrowserContext())),
95 geolocation_usages_state_(
96 Profile::FromBrowserContext(tab
->GetBrowserContext())
97 ->GetHostContentSettingsMap(),
98 Profile::FromBrowserContext(tab
->GetBrowserContext())->GetPrefs(),
99 CONTENT_SETTINGS_TYPE_GEOLOCATION
),
101 Profile::FromBrowserContext(tab
->GetBrowserContext())
102 ->GetHostContentSettingsMap(),
103 Profile::FromBrowserContext(tab
->GetBrowserContext())->GetPrefs(),
104 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
),
105 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
106 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
107 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT
),
108 load_plugins_link_enabled_(true),
109 microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED
),
111 ClearBlockedContentSettingsExceptForCookies();
112 ClearCookieSpecificContentSettings();
114 observer_
.Add(Profile::FromBrowserContext(tab
->GetBrowserContext())
115 ->GetHostContentSettingsMap());
118 TabSpecificContentSettings::~TabSpecificContentSettings() {
120 SiteDataObserver
, observer_list_
, ContentSettingsDestroyed());
124 TabSpecificContentSettings
* TabSpecificContentSettings::Get(
125 int render_process_id
, int render_view_id
) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
128 RenderViewHost
* view
= RenderViewHost::FromID(render_process_id
,
133 WebContents
* web_contents
= WebContents::FromRenderViewHost(view
);
137 return TabSpecificContentSettings::FromWebContents(web_contents
);
141 void TabSpecificContentSettings::CookiesRead(int render_process_id
,
144 const GURL
& frame_url
,
145 const net::CookieList
& cookie_list
,
146 bool blocked_by_policy
,
147 bool is_for_blocking_resource
) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
149 TabSpecificContentSettings
* settings
=
150 GetForFrame(render_process_id
, render_frame_id
);
152 settings
->OnCookiesRead(url
, frame_url
, cookie_list
,
155 prerender::PrerenderManager::RecordCookieEvent(
160 is_for_blocking_resource
,
161 prerender::PrerenderContents::COOKIE_EVENT_SEND
,
166 void TabSpecificContentSettings::CookieChanged(
167 int render_process_id
,
170 const GURL
& frame_url
,
171 const std::string
& cookie_line
,
172 const net::CookieOptions
& options
,
173 bool blocked_by_policy
) {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
175 TabSpecificContentSettings
* settings
=
176 GetForFrame(render_process_id
, render_frame_id
);
178 settings
->OnCookieChanged(url
, frame_url
, cookie_line
, options
,
180 prerender::PrerenderManager::RecordCookieEvent(
185 false /*is_critical_request*/,
186 prerender::PrerenderContents::COOKIE_EVENT_CHANGE
,
191 void TabSpecificContentSettings::WebDatabaseAccessed(
192 int render_process_id
,
195 const base::string16
& name
,
196 const base::string16
& display_name
,
197 bool blocked_by_policy
) {
198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
199 TabSpecificContentSettings
* settings
= GetForFrame(
200 render_process_id
, render_frame_id
);
202 settings
->OnWebDatabaseAccessed(url
, name
, display_name
, blocked_by_policy
);
206 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id
,
210 bool blocked_by_policy
) {
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
212 TabSpecificContentSettings
* settings
= GetForFrame(
213 render_process_id
, render_frame_id
);
215 settings
->OnLocalStorageAccessed(url
, local
, blocked_by_policy
);
219 void TabSpecificContentSettings::IndexedDBAccessed(
220 int render_process_id
,
223 const base::string16
& description
,
224 bool blocked_by_policy
) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
226 TabSpecificContentSettings
* settings
= GetForFrame(
227 render_process_id
, render_frame_id
);
229 settings
->OnIndexedDBAccessed(url
, description
, blocked_by_policy
);
233 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id
,
236 bool blocked_by_policy
) {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
238 TabSpecificContentSettings
* settings
= GetForFrame(
239 render_process_id
, render_frame_id
);
241 settings
->OnFileSystemAccessed(url
, blocked_by_policy
);
244 const base::string16
TabSpecificContentSettings::GetBlockedPluginNames() const {
245 return JoinString(blocked_plugin_names_
, base::ASCIIToUTF16(", "));
248 bool TabSpecificContentSettings::IsContentBlocked(
249 ContentSettingsType content_type
) const {
250 DCHECK(content_type
!= CONTENT_SETTINGS_TYPE_GEOLOCATION
)
251 << "Geolocation settings handled by ContentSettingGeolocationImageModel";
252 DCHECK(content_type
!= CONTENT_SETTINGS_TYPE_NOTIFICATIONS
)
253 << "Notifications settings handled by "
254 << "ContentSettingsNotificationsImageModel";
256 if (content_type
== CONTENT_SETTINGS_TYPE_IMAGES
||
257 content_type
== CONTENT_SETTINGS_TYPE_JAVASCRIPT
||
258 content_type
== CONTENT_SETTINGS_TYPE_PLUGINS
||
259 content_type
== CONTENT_SETTINGS_TYPE_COOKIES
||
260 content_type
== CONTENT_SETTINGS_TYPE_POPUPS
||
261 content_type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
||
262 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
||
263 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
264 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
||
265 content_type
== CONTENT_SETTINGS_TYPE_PPAPI_BROKER
||
266 content_type
== CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
||
267 content_type
== CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
268 return content_blocked_
[content_type
];
274 bool TabSpecificContentSettings::IsBlockageIndicated(
275 ContentSettingsType content_type
) const {
276 return content_blockage_indicated_to_user_
[content_type
];
279 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
280 ContentSettingsType content_type
) {
281 content_blockage_indicated_to_user_
[content_type
] = true;
284 bool TabSpecificContentSettings::IsContentAllowed(
285 ContentSettingsType content_type
) const {
286 // This method currently only returns meaningful values for the content type
287 // cookies, mediastream, PPAPI broker, and downloads.
288 if (content_type
!= CONTENT_SETTINGS_TYPE_COOKIES
&&
289 content_type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM
&&
290 content_type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
&&
291 content_type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
&&
292 content_type
!= CONTENT_SETTINGS_TYPE_PPAPI_BROKER
&&
293 content_type
!= CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
&&
294 content_type
!= CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
298 return content_allowed_
[content_type
];
301 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type
) {
302 OnContentBlockedWithDetail(type
, base::string16());
305 void TabSpecificContentSettings::OnContentBlockedWithDetail(
306 ContentSettingsType type
,
307 const base::string16
& details
) {
308 DCHECK(type
!= CONTENT_SETTINGS_TYPE_GEOLOCATION
)
309 << "Geolocation settings handled by OnGeolocationPermissionSet";
310 DCHECK(type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
&&
311 type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)
312 << "Media stream settings handled by OnMediaStreamPermissionSet";
313 if (type
< 0 || type
>= CONTENT_SETTINGS_NUM_TYPES
)
316 // TODO(robwu): Should this be restricted to cookies only?
317 // In the past, content_allowed_ was set to false, but this logic was inverted
318 // in https://codereview.chromium.org/13375004 to fix an issue with the cookie
319 // permission UI. This unconditional assignment seems incorrect, because the
320 // flag will now always be true after calling either OnContentBlocked or
321 // OnContentAllowed. Consequently IsContentAllowed will always return true
322 // for every supported setting that is not handled elsewhere.
323 content_allowed_
[type
] = true;
325 #if defined(OS_ANDROID)
326 if (type
== CONTENT_SETTINGS_TYPE_POPUPS
) {
327 // For Android we do not have a persistent button that will always be
328 // visible for blocked popups. Instead we have info bars which could be
329 // dismissed. Have to clear the blocked state so we properly notify the
330 // relevant pieces again.
331 content_blocked_
[type
] = false;
332 content_blockage_indicated_to_user_
[type
] = false;
336 if (type
== CONTENT_SETTINGS_TYPE_PLUGINS
&& !details
.empty() &&
337 std::find(blocked_plugin_names_
.begin(), blocked_plugin_names_
.end(),
338 details
) == blocked_plugin_names_
.end()) {
339 blocked_plugin_names_
.push_back(details
);
342 if (!content_blocked_
[type
]) {
343 content_blocked_
[type
] = true;
344 // TODO: it would be nice to have a way of mocking this in tests.
345 content::NotificationService::current()->Notify(
346 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
347 content::Source
<WebContents
>(web_contents()),
348 content::NotificationService::NoDetails());
350 if (type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
) {
351 content_settings::RecordMixedScriptAction(
352 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD
);
354 rappor::RapporService
* rappor_service
=
355 g_browser_process
->rappor_service();
356 if (rappor_service
) {
357 rappor_service
->RecordSample(
358 "ContentSettings.MixedScript.DisplayedShield",
359 rappor::ETLD_PLUS_ONE_RAPPOR_TYPE
,
360 net::registry_controlled_domains::GetDomainAndRegistry(
361 base::UTF16ToUTF8(details
),
362 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES
));
368 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type
) {
369 DCHECK(type
!= CONTENT_SETTINGS_TYPE_GEOLOCATION
)
370 << "Geolocation settings handled by OnGeolocationPermissionSet";
371 DCHECK(type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
&&
372 type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)
373 << "Media stream settings handled by OnMediaStreamPermissionSet";
374 bool access_changed
= false;
375 #if defined(OS_ANDROID)
376 if (type
== CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
&&
377 content_blocked_
[type
]) {
378 // content_allowed_[type] is always set to true in OnContentBlocked, so we
379 // have to use content_blocked_ to detect whether the protected media
380 // setting has changed.
381 content_blocked_
[type
] = false;
382 access_changed
= true;
386 if (!content_allowed_
[type
]) {
387 content_allowed_
[type
] = true;
388 access_changed
= true;
391 if (access_changed
) {
392 content::NotificationService::current()->Notify(
393 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
394 content::Source
<WebContents
>(web_contents()),
395 content::NotificationService::NoDetails());
399 void TabSpecificContentSettings::OnCookiesRead(
401 const GURL
& frame_url
,
402 const net::CookieList
& cookie_list
,
403 bool blocked_by_policy
) {
404 if (cookie_list
.empty())
406 if (blocked_by_policy
) {
407 blocked_local_shared_objects_
.cookies()->AddReadCookies(
408 frame_url
, url
, cookie_list
);
409 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
411 allowed_local_shared_objects_
.cookies()->AddReadCookies(
412 frame_url
, url
, cookie_list
);
413 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
416 NotifySiteDataObservers();
419 void TabSpecificContentSettings::OnCookieChanged(
421 const GURL
& frame_url
,
422 const std::string
& cookie_line
,
423 const net::CookieOptions
& options
,
424 bool blocked_by_policy
) {
425 if (blocked_by_policy
) {
426 blocked_local_shared_objects_
.cookies()->AddChangedCookie(
427 frame_url
, url
, cookie_line
, options
);
428 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
430 allowed_local_shared_objects_
.cookies()->AddChangedCookie(
431 frame_url
, url
, cookie_line
, options
);
432 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
435 NotifySiteDataObservers();
438 void TabSpecificContentSettings::OnIndexedDBAccessed(
440 const base::string16
& description
,
441 bool blocked_by_policy
) {
442 if (blocked_by_policy
) {
443 blocked_local_shared_objects_
.indexed_dbs()->AddIndexedDB(
445 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
447 allowed_local_shared_objects_
.indexed_dbs()->AddIndexedDB(
449 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
452 NotifySiteDataObservers();
455 void TabSpecificContentSettings::OnLocalStorageAccessed(
458 bool blocked_by_policy
) {
459 LocalSharedObjectsContainer
& container
= blocked_by_policy
?
460 blocked_local_shared_objects_
: allowed_local_shared_objects_
;
461 CannedBrowsingDataLocalStorageHelper
* helper
=
462 local
? container
.local_storages() : container
.session_storages();
463 helper
->AddLocalStorage(url
);
465 if (blocked_by_policy
)
466 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
468 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
470 NotifySiteDataObservers();
473 void TabSpecificContentSettings::OnWebDatabaseAccessed(
475 const base::string16
& name
,
476 const base::string16
& display_name
,
477 bool blocked_by_policy
) {
478 if (blocked_by_policy
) {
479 blocked_local_shared_objects_
.databases()->AddDatabase(
480 url
, base::UTF16ToUTF8(name
), base::UTF16ToUTF8(display_name
));
481 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
483 allowed_local_shared_objects_
.databases()->AddDatabase(
484 url
, base::UTF16ToUTF8(name
), base::UTF16ToUTF8(display_name
));
485 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
488 NotifySiteDataObservers();
491 void TabSpecificContentSettings::OnFileSystemAccessed(
493 bool blocked_by_policy
) {
494 if (blocked_by_policy
) {
495 blocked_local_shared_objects_
.file_systems()->AddFileSystem(
496 url
, storage::kFileSystemTypeTemporary
, 0);
497 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
499 allowed_local_shared_objects_
.file_systems()->AddFileSystem(
500 url
, storage::kFileSystemTypeTemporary
, 0);
501 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
504 NotifySiteDataObservers();
507 void TabSpecificContentSettings::OnGeolocationPermissionSet(
508 const GURL
& requesting_origin
,
510 geolocation_usages_state_
.OnPermissionSet(requesting_origin
, allowed
);
511 content::NotificationService::current()->Notify(
512 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
513 content::Source
<WebContents
>(web_contents()),
514 content::NotificationService::NoDetails());
517 #if defined(OS_ANDROID)
518 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
519 const GURL
& requesting_origin
,
522 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
524 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
529 TabSpecificContentSettings::MicrophoneCameraState
530 TabSpecificContentSettings::GetMicrophoneCameraState() const {
531 MicrophoneCameraState state
= microphone_camera_state_
;
533 // Include capture devices in the state if there are still consumers of the
534 // approved media stream.
535 scoped_refptr
<MediaStreamCaptureIndicator
> media_indicator
=
536 MediaCaptureDevicesDispatcher::GetInstance()->
537 GetMediaStreamCaptureIndicator();
538 if (media_indicator
->IsCapturingAudio(web_contents()))
539 state
|= MICROPHONE_ACCESSED
;
540 if (media_indicator
->IsCapturingVideo(web_contents()))
541 state
|= CAMERA_ACCESSED
;
546 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
547 if ((microphone_camera_state_
& MICROPHONE_ACCESSED
) &&
548 ((microphone_camera_state_
& MICROPHONE_BLOCKED
) ?
549 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
) :
550 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)))
553 if ((microphone_camera_state_
& CAMERA_ACCESSED
) &&
554 ((microphone_camera_state_
& CAMERA_BLOCKED
) ?
555 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) :
556 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)))
560 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
562 scoped_refptr
<MediaStreamCaptureIndicator
> media_indicator
=
563 MediaCaptureDevicesDispatcher::GetInstance()->
564 GetMediaStreamCaptureIndicator();
566 if ((microphone_camera_state_
& MICROPHONE_ACCESSED
) &&
567 prefs
->GetString(prefs::kDefaultAudioCaptureDevice
) !=
568 media_stream_selected_audio_device() &&
569 media_indicator
->IsCapturingAudio(web_contents()))
572 if ((microphone_camera_state_
& CAMERA_ACCESSED
) &&
573 prefs
->GetString(prefs::kDefaultVideoCaptureDevice
) !=
574 media_stream_selected_video_device() &&
575 media_indicator
->IsCapturingVideo(web_contents()))
581 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
582 const GURL
& request_origin
,
583 MicrophoneCameraState new_microphone_camera_state
,
584 const std::string
& media_stream_selected_audio_device
,
585 const std::string
& media_stream_selected_video_device
,
586 const std::string
& media_stream_requested_audio_device
,
587 const std::string
& media_stream_requested_video_device
) {
588 media_stream_access_origin_
= request_origin
;
590 if (new_microphone_camera_state
& MICROPHONE_ACCESSED
) {
591 media_stream_requested_audio_device_
= media_stream_requested_audio_device
;
592 media_stream_selected_audio_device_
= media_stream_selected_audio_device
;
593 bool mic_blocked
= (new_microphone_camera_state
& MICROPHONE_BLOCKED
) != 0;
594 content_allowed_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
] = !mic_blocked
;
595 content_blocked_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
] = mic_blocked
;
598 if (new_microphone_camera_state
& CAMERA_ACCESSED
) {
599 media_stream_requested_video_device_
= media_stream_requested_video_device
;
600 media_stream_selected_video_device_
= media_stream_selected_video_device
;
601 bool cam_blocked
= (new_microphone_camera_state
& CAMERA_BLOCKED
) != 0;
602 content_allowed_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
] = !cam_blocked
;
603 content_blocked_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
] = cam_blocked
;
606 if (microphone_camera_state_
!= new_microphone_camera_state
) {
607 microphone_camera_state_
= new_microphone_camera_state
;
608 content::NotificationService::current()->Notify(
609 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
610 content::Source
<WebContents
>(web_contents()),
611 content::NotificationService::NoDetails());
615 void TabSpecificContentSettings::OnMidiSysExAccessed(
616 const GURL
& requesting_origin
) {
617 midi_usages_state_
.OnPermissionSet(requesting_origin
, true);
618 OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
621 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
622 const GURL
& requesting_origin
) {
623 midi_usages_state_
.OnPermissionSet(requesting_origin
, false);
624 OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
627 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
628 for (size_t i
= 0; i
< arraysize(content_blocked_
); ++i
) {
629 if (i
== CONTENT_SETTINGS_TYPE_COOKIES
)
631 content_blocked_
[i
] = false;
632 content_allowed_
[i
] = false;
633 content_blockage_indicated_to_user_
[i
] = false;
635 microphone_camera_state_
= MICROPHONE_CAMERA_NOT_ACCESSED
;
636 load_plugins_link_enabled_
= true;
637 content::NotificationService::current()->Notify(
638 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
639 content::Source
<WebContents
>(web_contents()),
640 content::NotificationService::NoDetails());
643 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
644 blocked_local_shared_objects_
.Reset();
645 allowed_local_shared_objects_
.Reset();
646 content_blocked_
[CONTENT_SETTINGS_TYPE_COOKIES
] = false;
647 content_allowed_
[CONTENT_SETTINGS_TYPE_COOKIES
] = false;
648 content_blockage_indicated_to_user_
[CONTENT_SETTINGS_TYPE_COOKIES
] = false;
649 content::NotificationService::current()->Notify(
650 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
651 content::Source
<WebContents
>(web_contents()),
652 content::NotificationService::NoDetails());
655 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked
) {
656 content_blocked_
[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
] = blocked
;
657 content_allowed_
[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
] = !blocked
;
658 content_blockage_indicated_to_user_
[
659 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
] = false;
660 content::NotificationService::current()->Notify(
661 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
662 content::Source
<WebContents
>(web_contents()),
663 content::NotificationService::NoDetails());
666 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked
) {
667 content_blocked_
[CONTENT_SETTINGS_TYPE_POPUPS
] = blocked
;
668 content_blockage_indicated_to_user_
[CONTENT_SETTINGS_TYPE_POPUPS
] = false;
669 content::NotificationService::current()->Notify(
670 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
671 content::Source
<WebContents
>(web_contents()),
672 content::NotificationService::NoDetails());
675 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed
) {
677 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER
);
679 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER
);
683 void TabSpecificContentSettings::OnContentSettingChanged(
684 const ContentSettingsPattern
& primary_pattern
,
685 const ContentSettingsPattern
& secondary_pattern
,
686 ContentSettingsType content_type
,
687 std::string resource_identifier
) {
688 const ContentSettingsDetails
details(
689 primary_pattern
, secondary_pattern
, content_type
, resource_identifier
);
690 const NavigationController
& controller
= web_contents()->GetController();
691 NavigationEntry
* entry
= controller
.GetVisibleEntry();
694 entry_url
= entry
->GetURL();
695 if (details
.update_all() ||
696 // The visible NavigationEntry is the URL in the URL field of a tab.
697 // Currently this should be matched by the |primary_pattern|.
698 details
.primary_pattern().Matches(entry_url
)) {
700 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
701 const HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
703 if (content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
704 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) {
705 const GURL media_origin
= media_stream_access_origin();
706 ContentSetting setting
= map
->GetContentSetting(media_origin
,
710 content_allowed_
[content_type
] = setting
== CONTENT_SETTING_ALLOW
;
711 content_blocked_
[content_type
] = setting
== CONTENT_SETTING_BLOCK
;
713 RendererContentSettingRules rules
;
714 GetRendererContentSettingRules(map
, &rules
);
715 Send(new ChromeViewMsg_SetContentSettingRules(rules
));
719 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
720 content::RenderFrameHost
* render_frame_host
) {
721 // We want to tell the renderer-side code to ignore content settings for this
723 render_frame_host
->Send(new ChromeViewMsg_SetAsInterstitial(
724 render_frame_host
->GetRoutingID()));
727 bool TabSpecificContentSettings::OnMessageReceived(
728 const IPC::Message
& message
,
729 content::RenderFrameHost
* render_frame_host
) {
731 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings
, message
)
732 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked
,
733 OnContentBlockedWithDetail
)
734 IPC_MESSAGE_UNHANDLED(handled
= false)
735 IPC_END_MESSAGE_MAP()
739 void TabSpecificContentSettings::DidNavigateMainFrame(
740 const content::LoadCommittedDetails
& details
,
741 const content::FrameNavigateParams
& params
) {
742 if (!details
.is_in_page
) {
743 // Clear "blocked" flags.
744 ClearBlockedContentSettingsExceptForCookies();
745 blocked_plugin_names_
.clear();
746 GeolocationDidNavigate(details
);
747 MidiDidNavigate(details
);
751 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
752 content::RenderFrameHost
* render_frame_host
,
753 const GURL
& validated_url
,
755 bool is_iframe_srcdoc
) {
756 if (render_frame_host
->GetParent())
759 // If we're displaying a network error page do not reset the content
760 // settings delegate's cookies so the user has a chance to modify cookie
763 ClearCookieSpecificContentSettings();
764 ClearGeolocationContentSettings();
765 ClearMidiContentSettings();
766 ClearPendingProtocolHandler();
769 void TabSpecificContentSettings::AppCacheAccessed(const GURL
& manifest_url
,
770 bool blocked_by_policy
) {
771 if (blocked_by_policy
) {
772 blocked_local_shared_objects_
.appcaches()->AddAppCache(manifest_url
);
773 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
775 allowed_local_shared_objects_
.appcaches()->AddAppCache(manifest_url
);
776 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
780 void TabSpecificContentSettings::AddSiteDataObserver(
781 SiteDataObserver
* observer
) {
782 observer_list_
.AddObserver(observer
);
785 void TabSpecificContentSettings::RemoveSiteDataObserver(
786 SiteDataObserver
* observer
) {
787 observer_list_
.RemoveObserver(observer
);
790 void TabSpecificContentSettings::NotifySiteDataObservers() {
791 FOR_EACH_OBSERVER(SiteDataObserver
, observer_list_
, OnSiteDataAccessed());
794 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
795 geolocation_usages_state_
.ClearStateMap();
798 void TabSpecificContentSettings::ClearMidiContentSettings() {
799 midi_usages_state_
.ClearStateMap();
802 void TabSpecificContentSettings::GeolocationDidNavigate(
803 const content::LoadCommittedDetails
& details
) {
804 geolocation_usages_state_
.DidNavigate(details
);
807 void TabSpecificContentSettings::MidiDidNavigate(
808 const content::LoadCommittedDetails
& details
) {
809 midi_usages_state_
.DidNavigate(details
);