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/browsing_data/browsing_data_appcache_helper.h"
15 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
19 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
20 #include "chrome/browser/browsing_data/cookies_tree_model.h"
21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
23 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
24 #include "chrome/browser/media/media_stream_capture_indicator.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/common/render_messages.h"
29 #include "components/content_settings/content/common/content_settings_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 "content/public/browser/browser_thread.h"
34 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/navigation_details.h"
36 #include "content/public/browser/navigation_entry.h"
37 #include "content/public/browser/notification_registrar.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/render_frame_host.h"
40 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/web_contents.h"
42 #include "content/public/browser/web_contents_delegate.h"
43 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
44 #include "net/cookies/canonical_cookie.h"
45 #include "storage/common/fileapi/file_system_types.h"
47 using content::BrowserThread
;
48 using content::NavigationController
;
49 using content::NavigationEntry
;
50 using content::WebContents
;
52 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings
);
56 ContentSettingsUsagesState::CommittedDetails
GetCommittedDetails(
57 const content::LoadCommittedDetails
& details
) {
58 ContentSettingsUsagesState::CommittedDetails committed_details
;
59 committed_details
.current_url_valid
= !!details
.entry
;
61 committed_details
.current_url
= details
.entry
->GetURL();
62 committed_details
.previous_url
= details
.previous_url
;
63 return committed_details
;
68 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
69 TabSpecificContentSettings
* tab_specific_content_settings
)
70 : tab_specific_content_settings_(tab_specific_content_settings
) {
71 tab_specific_content_settings_
->AddSiteDataObserver(this);
74 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
75 if (tab_specific_content_settings_
)
76 tab_specific_content_settings_
->RemoveSiteDataObserver(this);
79 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
80 tab_specific_content_settings_
= NULL
;
83 TabSpecificContentSettings::TabSpecificContentSettings(WebContents
* tab
)
84 : content::WebContentsObserver(tab
),
85 allowed_local_shared_objects_(
86 Profile::FromBrowserContext(tab
->GetBrowserContext())),
87 blocked_local_shared_objects_(
88 Profile::FromBrowserContext(tab
->GetBrowserContext())),
89 geolocation_usages_state_(
90 Profile::FromBrowserContext(tab
->GetBrowserContext())
91 ->GetHostContentSettingsMap(),
92 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
93 prefs::kAcceptLanguages
,
94 Profile::FromBrowserContext(tab
->GetBrowserContext())->GetPrefs()),
96 Profile::FromBrowserContext(tab
->GetBrowserContext())
97 ->GetHostContentSettingsMap(),
98 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
99 prefs::kAcceptLanguages
,
100 Profile::FromBrowserContext(tab
->GetBrowserContext())->GetPrefs()),
101 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
102 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
103 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT
),
104 load_plugins_link_enabled_(true),
105 microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED
),
107 ClearBlockedContentSettingsExceptForCookies();
108 ClearCookieSpecificContentSettings();
110 observer_
.Add(Profile::FromBrowserContext(tab
->GetBrowserContext())
111 ->GetHostContentSettingsMap());
114 TabSpecificContentSettings::~TabSpecificContentSettings() {
116 SiteDataObserver
, observer_list_
, ContentSettingsDestroyed());
119 TabSpecificContentSettings
* TabSpecificContentSettings::GetForFrame(
120 int render_process_id
,
121 int render_frame_id
) {
122 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
124 content::RenderFrameHost
* frame
= content::RenderFrameHost::FromID(
125 render_process_id
, render_frame_id
);
126 WebContents
* web_contents
= WebContents::FromRenderFrameHost(frame
);
130 return TabSpecificContentSettings::FromWebContents(web_contents
);
134 void TabSpecificContentSettings::CookiesRead(int render_process_id
,
137 const GURL
& frame_url
,
138 const net::CookieList
& cookie_list
,
139 bool blocked_by_policy
) {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
141 TabSpecificContentSettings
* settings
=
142 GetForFrame(render_process_id
, render_frame_id
);
144 settings
->OnCookiesRead(url
, frame_url
, cookie_list
,
150 void TabSpecificContentSettings::CookieChanged(
151 int render_process_id
,
154 const GURL
& frame_url
,
155 const std::string
& cookie_line
,
156 const net::CookieOptions
& options
,
157 bool blocked_by_policy
) {
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
159 TabSpecificContentSettings
* settings
=
160 GetForFrame(render_process_id
, render_frame_id
);
162 settings
->OnCookieChanged(url
, frame_url
, cookie_line
, options
,
167 void TabSpecificContentSettings::WebDatabaseAccessed(
168 int render_process_id
,
171 const base::string16
& name
,
172 const base::string16
& display_name
,
173 bool blocked_by_policy
) {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
175 TabSpecificContentSettings
* settings
= GetForFrame(
176 render_process_id
, render_frame_id
);
178 settings
->OnWebDatabaseAccessed(url
, name
, display_name
, blocked_by_policy
);
182 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id
,
186 bool blocked_by_policy
) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
188 TabSpecificContentSettings
* settings
= GetForFrame(
189 render_process_id
, render_frame_id
);
191 settings
->OnLocalStorageAccessed(url
, local
, blocked_by_policy
);
195 void TabSpecificContentSettings::IndexedDBAccessed(
196 int render_process_id
,
199 const base::string16
& description
,
200 bool blocked_by_policy
) {
201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
202 TabSpecificContentSettings
* settings
= GetForFrame(
203 render_process_id
, render_frame_id
);
205 settings
->OnIndexedDBAccessed(url
, description
, blocked_by_policy
);
209 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id
,
212 bool blocked_by_policy
) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
214 TabSpecificContentSettings
* settings
= GetForFrame(
215 render_process_id
, render_frame_id
);
217 settings
->OnFileSystemAccessed(url
, blocked_by_policy
);
221 void TabSpecificContentSettings::ServiceWorkerAccessed(int render_process_id
,
224 bool blocked_by_policy
) {
225 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
226 TabSpecificContentSettings
* settings
=
227 GetForFrame(render_process_id
, render_frame_id
);
229 settings
->OnServiceWorkerAccessed(scope
, blocked_by_policy
);
232 bool TabSpecificContentSettings::IsContentBlocked(
233 ContentSettingsType content_type
) const {
234 DCHECK(content_type
!= CONTENT_SETTINGS_TYPE_GEOLOCATION
)
235 << "Geolocation settings handled by ContentSettingGeolocationImageModel";
236 DCHECK(content_type
!= CONTENT_SETTINGS_TYPE_NOTIFICATIONS
)
237 << "Notifications settings handled by "
238 << "ContentSettingsNotificationsImageModel";
240 if (content_type
== CONTENT_SETTINGS_TYPE_IMAGES
||
241 content_type
== CONTENT_SETTINGS_TYPE_JAVASCRIPT
||
242 content_type
== CONTENT_SETTINGS_TYPE_PLUGINS
||
243 content_type
== CONTENT_SETTINGS_TYPE_COOKIES
||
244 content_type
== CONTENT_SETTINGS_TYPE_POPUPS
||
245 content_type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
||
246 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
||
247 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
248 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
||
249 content_type
== CONTENT_SETTINGS_TYPE_PPAPI_BROKER
||
250 content_type
== CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
||
251 content_type
== CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
252 return content_blocked_
[content_type
];
258 bool TabSpecificContentSettings::IsBlockageIndicated(
259 ContentSettingsType content_type
) const {
260 return content_blockage_indicated_to_user_
[content_type
];
263 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
264 ContentSettingsType content_type
) {
265 content_blockage_indicated_to_user_
[content_type
] = true;
268 bool TabSpecificContentSettings::IsContentAllowed(
269 ContentSettingsType content_type
) const {
270 // This method currently only returns meaningful values for the content type
271 // cookies, mediastream, PPAPI broker, and downloads.
272 if (content_type
!= CONTENT_SETTINGS_TYPE_COOKIES
&&
273 content_type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM
&&
274 content_type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
&&
275 content_type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
&&
276 content_type
!= CONTENT_SETTINGS_TYPE_PPAPI_BROKER
&&
277 content_type
!= CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
&&
278 content_type
!= CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
282 return content_allowed_
[content_type
];
285 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type
) {
286 OnContentBlockedWithDetail(type
, base::string16());
289 void TabSpecificContentSettings::OnContentBlockedWithDetail(
290 ContentSettingsType type
,
291 const base::string16
& details
) {
292 DCHECK(type
!= CONTENT_SETTINGS_TYPE_GEOLOCATION
)
293 << "Geolocation settings handled by OnGeolocationPermissionSet";
294 DCHECK(type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
&&
295 type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)
296 << "Media stream settings handled by OnMediaStreamPermissionSet";
297 if (type
< 0 || type
>= CONTENT_SETTINGS_NUM_TYPES
)
300 // TODO(robwu): Should this be restricted to cookies only?
301 // In the past, content_allowed_ was set to false, but this logic was inverted
302 // in https://codereview.chromium.org/13375004 to fix an issue with the cookie
303 // permission UI. This unconditional assignment seems incorrect, because the
304 // flag will now always be true after calling either OnContentBlocked or
305 // OnContentAllowed. Consequently IsContentAllowed will always return true
306 // for every supported setting that is not handled elsewhere.
307 content_allowed_
[type
] = true;
309 #if defined(OS_ANDROID)
310 if (type
== CONTENT_SETTINGS_TYPE_POPUPS
) {
311 // For Android we do not have a persistent button that will always be
312 // visible for blocked popups. Instead we have info bars which could be
313 // dismissed. Have to clear the blocked state so we properly notify the
314 // relevant pieces again.
315 content_blocked_
[type
] = false;
316 content_blockage_indicated_to_user_
[type
] = false;
320 if (type
== CONTENT_SETTINGS_TYPE_PLUGINS
&& !details
.empty() &&
321 std::find(blocked_plugin_names_
.begin(), blocked_plugin_names_
.end(),
322 details
) == blocked_plugin_names_
.end()) {
323 blocked_plugin_names_
.push_back(details
);
326 if (!content_blocked_
[type
]) {
327 content_blocked_
[type
] = true;
328 // TODO: it would be nice to have a way of mocking this in tests.
329 content::NotificationService::current()->Notify(
330 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
331 content::Source
<WebContents
>(web_contents()),
332 content::NotificationService::NoDetails());
334 if (type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
) {
335 content_settings::RecordMixedScriptAction(
336 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD
);
337 content_settings::RecordMixedScriptActionWithRAPPOR(
338 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD
,
339 GURL(base::UTF16ToUTF8(details
)));
344 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type
) {
345 DCHECK(type
!= CONTENT_SETTINGS_TYPE_GEOLOCATION
)
346 << "Geolocation settings handled by OnGeolocationPermissionSet";
347 DCHECK(type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
&&
348 type
!= CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)
349 << "Media stream settings handled by OnMediaStreamPermissionSet";
350 bool access_changed
= false;
351 #if defined(OS_ANDROID)
352 if (type
== CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
&&
353 content_blocked_
[type
]) {
354 // content_allowed_[type] is always set to true in OnContentBlocked, so we
355 // have to use content_blocked_ to detect whether the protected media
356 // setting has changed.
357 content_blocked_
[type
] = false;
358 access_changed
= true;
362 if (!content_allowed_
[type
]) {
363 content_allowed_
[type
] = true;
364 access_changed
= true;
367 if (access_changed
) {
368 content::NotificationService::current()->Notify(
369 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
370 content::Source
<WebContents
>(web_contents()),
371 content::NotificationService::NoDetails());
375 void TabSpecificContentSettings::OnCookiesRead(
377 const GURL
& frame_url
,
378 const net::CookieList
& cookie_list
,
379 bool blocked_by_policy
) {
380 if (cookie_list
.empty())
382 if (blocked_by_policy
) {
383 blocked_local_shared_objects_
.cookies()->AddReadCookies(
384 frame_url
, url
, cookie_list
);
385 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
387 allowed_local_shared_objects_
.cookies()->AddReadCookies(
388 frame_url
, url
, cookie_list
);
389 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
392 NotifySiteDataObservers();
395 void TabSpecificContentSettings::OnCookieChanged(
397 const GURL
& frame_url
,
398 const std::string
& cookie_line
,
399 const net::CookieOptions
& options
,
400 bool blocked_by_policy
) {
401 if (blocked_by_policy
) {
402 blocked_local_shared_objects_
.cookies()->AddChangedCookie(
403 frame_url
, url
, cookie_line
, options
);
404 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
406 allowed_local_shared_objects_
.cookies()->AddChangedCookie(
407 frame_url
, url
, cookie_line
, options
);
408 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
411 NotifySiteDataObservers();
414 void TabSpecificContentSettings::OnIndexedDBAccessed(
416 const base::string16
& description
,
417 bool blocked_by_policy
) {
418 if (blocked_by_policy
) {
419 blocked_local_shared_objects_
.indexed_dbs()->AddIndexedDB(
421 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
423 allowed_local_shared_objects_
.indexed_dbs()->AddIndexedDB(
425 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
428 NotifySiteDataObservers();
431 void TabSpecificContentSettings::OnLocalStorageAccessed(
434 bool blocked_by_policy
) {
435 LocalSharedObjectsContainer
& container
= blocked_by_policy
?
436 blocked_local_shared_objects_
: allowed_local_shared_objects_
;
437 CannedBrowsingDataLocalStorageHelper
* helper
=
438 local
? container
.local_storages() : container
.session_storages();
439 helper
->AddLocalStorage(url
);
441 if (blocked_by_policy
)
442 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
444 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
446 NotifySiteDataObservers();
449 void TabSpecificContentSettings::OnServiceWorkerAccessed(
451 bool blocked_by_policy
) {
452 DCHECK(scope
.is_valid());
453 if (blocked_by_policy
) {
454 blocked_local_shared_objects_
.service_workers()->AddServiceWorker(
455 scope
.GetOrigin(), std::vector
<GURL
>(1, scope
));
456 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
458 allowed_local_shared_objects_
.service_workers()->AddServiceWorker(
459 scope
.GetOrigin(), std::vector
<GURL
>(1, scope
));
460 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
464 void TabSpecificContentSettings::OnWebDatabaseAccessed(
466 const base::string16
& name
,
467 const base::string16
& display_name
,
468 bool blocked_by_policy
) {
469 if (blocked_by_policy
) {
470 blocked_local_shared_objects_
.databases()->AddDatabase(
471 url
, base::UTF16ToUTF8(name
), base::UTF16ToUTF8(display_name
));
472 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
474 allowed_local_shared_objects_
.databases()->AddDatabase(
475 url
, base::UTF16ToUTF8(name
), base::UTF16ToUTF8(display_name
));
476 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
479 NotifySiteDataObservers();
482 void TabSpecificContentSettings::OnFileSystemAccessed(
484 bool blocked_by_policy
) {
485 if (blocked_by_policy
) {
486 blocked_local_shared_objects_
.file_systems()->AddFileSystem(
487 url
, storage::kFileSystemTypeTemporary
, 0);
488 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
490 allowed_local_shared_objects_
.file_systems()->AddFileSystem(
491 url
, storage::kFileSystemTypeTemporary
, 0);
492 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
495 NotifySiteDataObservers();
498 void TabSpecificContentSettings::OnGeolocationPermissionSet(
499 const GURL
& requesting_origin
,
501 geolocation_usages_state_
.OnPermissionSet(requesting_origin
, allowed
);
502 content::NotificationService::current()->Notify(
503 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
504 content::Source
<WebContents
>(web_contents()),
505 content::NotificationService::NoDetails());
508 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
509 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
510 const GURL
& requesting_origin
,
513 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
515 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
520 TabSpecificContentSettings::MicrophoneCameraState
521 TabSpecificContentSettings::GetMicrophoneCameraState() const {
522 MicrophoneCameraState state
= microphone_camera_state_
;
524 // Include capture devices in the state if there are still consumers of the
525 // approved media stream.
526 scoped_refptr
<MediaStreamCaptureIndicator
> media_indicator
=
527 MediaCaptureDevicesDispatcher::GetInstance()->
528 GetMediaStreamCaptureIndicator();
529 if (media_indicator
->IsCapturingAudio(web_contents()))
530 state
|= MICROPHONE_ACCESSED
;
531 if (media_indicator
->IsCapturingVideo(web_contents()))
532 state
|= CAMERA_ACCESSED
;
537 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
538 if ((microphone_camera_state_
& MICROPHONE_ACCESSED
) &&
539 ((microphone_camera_state_
& MICROPHONE_BLOCKED
) ?
540 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
) :
541 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)))
544 if ((microphone_camera_state_
& CAMERA_ACCESSED
) &&
545 ((microphone_camera_state_
& CAMERA_BLOCKED
) ?
546 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) :
547 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
)))
551 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
553 scoped_refptr
<MediaStreamCaptureIndicator
> media_indicator
=
554 MediaCaptureDevicesDispatcher::GetInstance()->
555 GetMediaStreamCaptureIndicator();
557 if ((microphone_camera_state_
& MICROPHONE_ACCESSED
) &&
558 prefs
->GetString(prefs::kDefaultAudioCaptureDevice
) !=
559 media_stream_selected_audio_device() &&
560 media_indicator
->IsCapturingAudio(web_contents()))
563 if ((microphone_camera_state_
& CAMERA_ACCESSED
) &&
564 prefs
->GetString(prefs::kDefaultVideoCaptureDevice
) !=
565 media_stream_selected_video_device() &&
566 media_indicator
->IsCapturingVideo(web_contents()))
572 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
573 const GURL
& request_origin
,
574 MicrophoneCameraState new_microphone_camera_state
,
575 const std::string
& media_stream_selected_audio_device
,
576 const std::string
& media_stream_selected_video_device
,
577 const std::string
& media_stream_requested_audio_device
,
578 const std::string
& media_stream_requested_video_device
) {
579 media_stream_access_origin_
= request_origin
;
581 if (new_microphone_camera_state
& MICROPHONE_ACCESSED
) {
582 media_stream_requested_audio_device_
= media_stream_requested_audio_device
;
583 media_stream_selected_audio_device_
= media_stream_selected_audio_device
;
584 bool mic_blocked
= (new_microphone_camera_state
& MICROPHONE_BLOCKED
) != 0;
585 content_allowed_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
] = !mic_blocked
;
586 content_blocked_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
] = mic_blocked
;
589 if (new_microphone_camera_state
& CAMERA_ACCESSED
) {
590 media_stream_requested_video_device_
= media_stream_requested_video_device
;
591 media_stream_selected_video_device_
= media_stream_selected_video_device
;
592 bool cam_blocked
= (new_microphone_camera_state
& CAMERA_BLOCKED
) != 0;
593 content_allowed_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
] = !cam_blocked
;
594 content_blocked_
[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
] = cam_blocked
;
597 if (microphone_camera_state_
!= new_microphone_camera_state
) {
598 microphone_camera_state_
= new_microphone_camera_state
;
599 content::NotificationService::current()->Notify(
600 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
601 content::Source
<WebContents
>(web_contents()),
602 content::NotificationService::NoDetails());
606 void TabSpecificContentSettings::OnMidiSysExAccessed(
607 const GURL
& requesting_origin
) {
608 midi_usages_state_
.OnPermissionSet(requesting_origin
, true);
609 OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
612 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
613 const GURL
& requesting_origin
) {
614 midi_usages_state_
.OnPermissionSet(requesting_origin
, false);
615 OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
618 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
619 for (size_t i
= 0; i
< arraysize(content_blocked_
); ++i
) {
620 if (i
== CONTENT_SETTINGS_TYPE_COOKIES
)
622 content_blocked_
[i
] = false;
623 content_allowed_
[i
] = false;
624 content_blockage_indicated_to_user_
[i
] = false;
626 microphone_camera_state_
= MICROPHONE_CAMERA_NOT_ACCESSED
;
627 load_plugins_link_enabled_
= true;
628 content::NotificationService::current()->Notify(
629 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
630 content::Source
<WebContents
>(web_contents()),
631 content::NotificationService::NoDetails());
634 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
635 blocked_local_shared_objects_
.Reset();
636 allowed_local_shared_objects_
.Reset();
637 content_blocked_
[CONTENT_SETTINGS_TYPE_COOKIES
] = false;
638 content_allowed_
[CONTENT_SETTINGS_TYPE_COOKIES
] = false;
639 content_blockage_indicated_to_user_
[CONTENT_SETTINGS_TYPE_COOKIES
] = false;
640 content::NotificationService::current()->Notify(
641 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
642 content::Source
<WebContents
>(web_contents()),
643 content::NotificationService::NoDetails());
646 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked
) {
647 content_blocked_
[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
] = blocked
;
648 content_allowed_
[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
] = !blocked
;
649 content_blockage_indicated_to_user_
[
650 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
] = false;
651 content::NotificationService::current()->Notify(
652 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED
,
653 content::Source
<WebContents
>(web_contents()),
654 content::NotificationService::NoDetails());
657 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked
) {
658 content_blocked_
[CONTENT_SETTINGS_TYPE_POPUPS
] = blocked
;
659 content_blockage_indicated_to_user_
[CONTENT_SETTINGS_TYPE_POPUPS
] = 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::SetPepperBrokerAllowed(bool allowed
) {
668 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER
);
670 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER
);
674 void TabSpecificContentSettings::OnContentSettingChanged(
675 const ContentSettingsPattern
& primary_pattern
,
676 const ContentSettingsPattern
& secondary_pattern
,
677 ContentSettingsType content_type
,
678 std::string resource_identifier
) {
679 const ContentSettingsDetails
details(
680 primary_pattern
, secondary_pattern
, content_type
, resource_identifier
);
681 const NavigationController
& controller
= web_contents()->GetController();
682 NavigationEntry
* entry
= controller
.GetVisibleEntry();
685 entry_url
= entry
->GetURL();
686 if (details
.update_all() ||
687 // The visible NavigationEntry is the URL in the URL field of a tab.
688 // Currently this should be matched by the |primary_pattern|.
689 details
.primary_pattern().Matches(entry_url
)) {
691 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
692 const HostContentSettingsMap
* map
= profile
->GetHostContentSettingsMap();
694 if (content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
695 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) {
696 const GURL media_origin
= media_stream_access_origin();
697 ContentSetting setting
= map
->GetContentSetting(media_origin
,
701 content_allowed_
[content_type
] = setting
== CONTENT_SETTING_ALLOW
;
702 content_blocked_
[content_type
] = setting
== CONTENT_SETTING_BLOCK
;
704 RendererContentSettingRules rules
;
705 GetRendererContentSettingRules(map
, &rules
);
706 Send(new ChromeViewMsg_SetContentSettingRules(rules
));
710 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
711 content::RenderFrameHost
* render_frame_host
) {
712 // We want to tell the renderer-side code to ignore content settings for this
714 render_frame_host
->Send(new ChromeViewMsg_SetAsInterstitial(
715 render_frame_host
->GetRoutingID()));
718 bool TabSpecificContentSettings::OnMessageReceived(
719 const IPC::Message
& message
,
720 content::RenderFrameHost
* render_frame_host
) {
722 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings
, message
)
723 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked
,
724 OnContentBlockedWithDetail
)
725 IPC_MESSAGE_UNHANDLED(handled
= false)
726 IPC_END_MESSAGE_MAP()
730 void TabSpecificContentSettings::DidNavigateMainFrame(
731 const content::LoadCommittedDetails
& details
,
732 const content::FrameNavigateParams
& params
) {
733 if (!details
.is_in_page
) {
734 // Clear "blocked" flags.
735 ClearBlockedContentSettingsExceptForCookies();
736 blocked_plugin_names_
.clear();
737 GeolocationDidNavigate(details
);
738 MidiDidNavigate(details
);
742 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
743 content::RenderFrameHost
* render_frame_host
,
744 const GURL
& validated_url
,
746 bool is_iframe_srcdoc
) {
747 if (render_frame_host
->GetParent())
750 // If we're displaying a network error page do not reset the content
751 // settings delegate's cookies so the user has a chance to modify cookie
754 ClearCookieSpecificContentSettings();
755 ClearGeolocationContentSettings();
756 ClearMidiContentSettings();
757 ClearPendingProtocolHandler();
760 void TabSpecificContentSettings::AppCacheAccessed(const GURL
& manifest_url
,
761 bool blocked_by_policy
) {
762 if (blocked_by_policy
) {
763 blocked_local_shared_objects_
.appcaches()->AddAppCache(manifest_url
);
764 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
766 allowed_local_shared_objects_
.appcaches()->AddAppCache(manifest_url
);
767 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
771 void TabSpecificContentSettings::AddSiteDataObserver(
772 SiteDataObserver
* observer
) {
773 observer_list_
.AddObserver(observer
);
776 void TabSpecificContentSettings::RemoveSiteDataObserver(
777 SiteDataObserver
* observer
) {
778 observer_list_
.RemoveObserver(observer
);
781 void TabSpecificContentSettings::NotifySiteDataObservers() {
782 FOR_EACH_OBSERVER(SiteDataObserver
, observer_list_
, OnSiteDataAccessed());
785 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
786 geolocation_usages_state_
.ClearStateMap();
789 void TabSpecificContentSettings::ClearMidiContentSettings() {
790 midi_usages_state_
.ClearStateMap();
793 void TabSpecificContentSettings::GeolocationDidNavigate(
794 const content::LoadCommittedDetails
& details
) {
795 geolocation_usages_state_
.DidNavigate(GetCommittedDetails(details
));
798 void TabSpecificContentSettings::MidiDidNavigate(
799 const content::LoadCommittedDetails
& details
) {
800 midi_usages_state_
.DidNavigate(GetCommittedDetails(details
));