Record eTLD+1 for pages that show the mixed content shield.
[chromium-blink-merge.git] / chrome / browser / content_settings / tab_specific_content_settings.cc
blob579b217d409e90c5d524f853790edd3150966a3c
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"
7 #include <list>
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);
56 namespace {
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);
66 if (!web_contents)
67 return nullptr;
69 return TabSpecificContentSettings::FromWebContents(web_contents);
72 } // namespace
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),
100 midi_usages_state_(
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),
110 observer_(this) {
111 ClearBlockedContentSettingsExceptForCookies();
112 ClearCookieSpecificContentSettings();
114 observer_.Add(Profile::FromBrowserContext(tab->GetBrowserContext())
115 ->GetHostContentSettingsMap());
118 TabSpecificContentSettings::~TabSpecificContentSettings() {
119 FOR_EACH_OBSERVER(
120 SiteDataObserver, observer_list_, ContentSettingsDestroyed());
123 // static
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,
129 render_view_id);
130 if (!view)
131 return NULL;
133 WebContents* web_contents = WebContents::FromRenderViewHost(view);
134 if (!web_contents)
135 return NULL;
137 return TabSpecificContentSettings::FromWebContents(web_contents);
140 // static
141 void TabSpecificContentSettings::CookiesRead(int render_process_id,
142 int render_frame_id,
143 const GURL& url,
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);
151 if (settings) {
152 settings->OnCookiesRead(url, frame_url, cookie_list,
153 blocked_by_policy);
155 prerender::PrerenderManager::RecordCookieEvent(
156 render_process_id,
157 render_frame_id,
158 url,
159 frame_url,
160 is_for_blocking_resource,
161 prerender::PrerenderContents::COOKIE_EVENT_SEND,
162 &cookie_list);
165 // static
166 void TabSpecificContentSettings::CookieChanged(
167 int render_process_id,
168 int render_frame_id,
169 const GURL& url,
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);
177 if (settings)
178 settings->OnCookieChanged(url, frame_url, cookie_line, options,
179 blocked_by_policy);
180 prerender::PrerenderManager::RecordCookieEvent(
181 render_process_id,
182 render_frame_id,
183 url,
184 frame_url,
185 false /*is_critical_request*/,
186 prerender::PrerenderContents::COOKIE_EVENT_CHANGE,
187 NULL);
190 // static
191 void TabSpecificContentSettings::WebDatabaseAccessed(
192 int render_process_id,
193 int render_frame_id,
194 const GURL& url,
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);
201 if (settings)
202 settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy);
205 // static
206 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id,
207 int render_frame_id,
208 const GURL& url,
209 bool local,
210 bool blocked_by_policy) {
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
212 TabSpecificContentSettings* settings = GetForFrame(
213 render_process_id, render_frame_id);
214 if (settings)
215 settings->OnLocalStorageAccessed(url, local, blocked_by_policy);
218 // static
219 void TabSpecificContentSettings::IndexedDBAccessed(
220 int render_process_id,
221 int render_frame_id,
222 const GURL& url,
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);
228 if (settings)
229 settings->OnIndexedDBAccessed(url, description, blocked_by_policy);
232 // static
233 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id,
234 int render_frame_id,
235 const GURL& url,
236 bool blocked_by_policy) {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 TabSpecificContentSettings* settings = GetForFrame(
239 render_process_id, render_frame_id);
240 if (settings)
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];
271 return false;
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) {
295 return false;
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)
314 return;
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;
334 #endif
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;
384 #endif
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(
400 const GURL& url,
401 const GURL& frame_url,
402 const net::CookieList& cookie_list,
403 bool blocked_by_policy) {
404 if (cookie_list.empty())
405 return;
406 if (blocked_by_policy) {
407 blocked_local_shared_objects_.cookies()->AddReadCookies(
408 frame_url, url, cookie_list);
409 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
410 } else {
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(
420 const GURL& url,
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);
429 } else {
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(
439 const GURL& url,
440 const base::string16& description,
441 bool blocked_by_policy) {
442 if (blocked_by_policy) {
443 blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
444 url, description);
445 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
446 } else {
447 allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
448 url, description);
449 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
452 NotifySiteDataObservers();
455 void TabSpecificContentSettings::OnLocalStorageAccessed(
456 const GURL& url,
457 bool local,
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);
467 else
468 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
470 NotifySiteDataObservers();
473 void TabSpecificContentSettings::OnWebDatabaseAccessed(
474 const GURL& url,
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);
482 } else {
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(
492 const GURL& url,
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);
498 } else {
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,
509 bool allowed) {
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,
520 bool allowed) {
521 if (allowed) {
522 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
523 } else {
524 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
527 #endif
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;
543 return state;
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)))
551 return true;
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)))
557 return true;
559 PrefService* prefs =
560 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
561 GetPrefs();
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()))
570 return true;
572 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
573 prefs->GetString(prefs::kDefaultVideoCaptureDevice) !=
574 media_stream_selected_video_device() &&
575 media_indicator->IsCapturingVideo(web_contents()))
576 return true;
578 return false;
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)
630 continue;
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) {
676 if (allowed) {
677 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
678 } else {
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();
692 GURL entry_url;
693 if (entry)
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)) {
699 Profile* profile =
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,
707 media_origin,
708 content_type,
709 std::string());
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
722 // page.
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) {
730 bool handled = true;
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()
736 return handled;
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,
754 bool is_error_page,
755 bool is_iframe_srcdoc) {
756 if (render_frame_host->GetParent())
757 return;
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
761 // settings.
762 if (!is_error_page)
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);
774 } else {
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);