Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / content_settings / tab_specific_content_settings.cc
blob4f1e1aa16de0e1244ef6dbf6ddb47486a1f3f4f5
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/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/content_settings/host_content_settings_map_factory.h"
24 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
25 #include "chrome/browser/media/media_stream_capture_indicator.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/content/common/content_settings_messages.h"
31 #include "components/content_settings/core/browser/content_settings_details.h"
32 #include "components/content_settings/core/browser/content_settings_info.h"
33 #include "components/content_settings/core/browser/content_settings_registry.h"
34 #include "components/content_settings/core/browser/content_settings_utils.h"
35 #include "components/content_settings/core/browser/host_content_settings_map.h"
36 #include "content/public/browser/browser_thread.h"
37 #include "content/public/browser/navigation_controller.h"
38 #include "content/public/browser/navigation_details.h"
39 #include "content/public/browser/navigation_entry.h"
40 #include "content/public/browser/notification_registrar.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/render_frame_host.h"
43 #include "content/public/browser/render_view_host.h"
44 #include "content/public/browser/web_contents.h"
45 #include "content/public/browser/web_contents_delegate.h"
46 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
47 #include "net/cookies/canonical_cookie.h"
48 #include "storage/common/fileapi/file_system_types.h"
50 using content::BrowserThread;
51 using content::NavigationController;
52 using content::NavigationEntry;
53 using content::WebContents;
55 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
57 namespace {
59 ContentSettingsUsagesState::CommittedDetails GetCommittedDetails(
60 const content::LoadCommittedDetails& details) {
61 ContentSettingsUsagesState::CommittedDetails committed_details;
62 committed_details.current_url_valid = !!details.entry;
63 if (details.entry)
64 committed_details.current_url = details.entry->GetURL();
65 committed_details.previous_url = details.previous_url;
66 return committed_details;
69 } // namespace
71 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
72 TabSpecificContentSettings* tab_specific_content_settings)
73 : tab_specific_content_settings_(tab_specific_content_settings) {
74 tab_specific_content_settings_->AddSiteDataObserver(this);
77 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
78 if (tab_specific_content_settings_)
79 tab_specific_content_settings_->RemoveSiteDataObserver(this);
82 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
83 tab_specific_content_settings_ = NULL;
86 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
87 : content::WebContentsObserver(tab),
88 allowed_local_shared_objects_(
89 Profile::FromBrowserContext(tab->GetBrowserContext())),
90 blocked_local_shared_objects_(
91 Profile::FromBrowserContext(tab->GetBrowserContext())),
92 geolocation_usages_state_(
93 HostContentSettingsMapFactory::GetForProfile(
94 Profile::FromBrowserContext(tab->GetBrowserContext())),
95 CONTENT_SETTINGS_TYPE_GEOLOCATION,
96 prefs::kAcceptLanguages,
97 Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs()),
98 midi_usages_state_(
99 HostContentSettingsMapFactory::GetForProfile(
100 Profile::FromBrowserContext(tab->GetBrowserContext())),
101 CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
102 prefs::kAcceptLanguages,
103 Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs()),
104 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
105 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
106 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
107 load_plugins_link_enabled_(true),
108 microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED),
109 observer_(this) {
110 ClearBlockedContentSettingsExceptForCookies();
111 ClearCookieSpecificContentSettings();
113 observer_.Add(HostContentSettingsMapFactory::GetForProfile(
114 Profile::FromBrowserContext(tab->GetBrowserContext())));
117 TabSpecificContentSettings::~TabSpecificContentSettings() {
118 FOR_EACH_OBSERVER(
119 SiteDataObserver, observer_list_, ContentSettingsDestroyed());
122 TabSpecificContentSettings* TabSpecificContentSettings::GetForFrame(
123 int render_process_id,
124 int render_frame_id) {
125 DCHECK_CURRENTLY_ON(BrowserThread::UI);
127 content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
128 render_process_id, render_frame_id);
129 WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
130 if (!web_contents)
131 return nullptr;
133 return TabSpecificContentSettings::FromWebContents(web_contents);
136 // static
137 void TabSpecificContentSettings::CookiesRead(int render_process_id,
138 int render_frame_id,
139 const GURL& url,
140 const GURL& frame_url,
141 const net::CookieList& cookie_list,
142 bool blocked_by_policy) {
143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 TabSpecificContentSettings* settings =
145 GetForFrame(render_process_id, render_frame_id);
146 if (settings) {
147 settings->OnCookiesRead(url, frame_url, cookie_list,
148 blocked_by_policy);
152 // static
153 void TabSpecificContentSettings::CookieChanged(
154 int render_process_id,
155 int render_frame_id,
156 const GURL& url,
157 const GURL& frame_url,
158 const std::string& cookie_line,
159 const net::CookieOptions& options,
160 bool blocked_by_policy) {
161 DCHECK_CURRENTLY_ON(BrowserThread::UI);
162 TabSpecificContentSettings* settings =
163 GetForFrame(render_process_id, render_frame_id);
164 if (settings)
165 settings->OnCookieChanged(url, frame_url, cookie_line, options,
166 blocked_by_policy);
169 // static
170 void TabSpecificContentSettings::WebDatabaseAccessed(
171 int render_process_id,
172 int render_frame_id,
173 const GURL& url,
174 const base::string16& name,
175 const base::string16& display_name,
176 bool blocked_by_policy) {
177 DCHECK_CURRENTLY_ON(BrowserThread::UI);
178 TabSpecificContentSettings* settings = GetForFrame(
179 render_process_id, render_frame_id);
180 if (settings)
181 settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy);
184 // static
185 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id,
186 int render_frame_id,
187 const GURL& url,
188 bool local,
189 bool blocked_by_policy) {
190 DCHECK_CURRENTLY_ON(BrowserThread::UI);
191 TabSpecificContentSettings* settings = GetForFrame(
192 render_process_id, render_frame_id);
193 if (settings)
194 settings->OnLocalStorageAccessed(url, local, blocked_by_policy);
197 // static
198 void TabSpecificContentSettings::IndexedDBAccessed(
199 int render_process_id,
200 int render_frame_id,
201 const GURL& url,
202 const base::string16& description,
203 bool blocked_by_policy) {
204 DCHECK_CURRENTLY_ON(BrowserThread::UI);
205 TabSpecificContentSettings* settings = GetForFrame(
206 render_process_id, render_frame_id);
207 if (settings)
208 settings->OnIndexedDBAccessed(url, description, blocked_by_policy);
211 // static
212 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id,
213 int render_frame_id,
214 const GURL& url,
215 bool blocked_by_policy) {
216 DCHECK_CURRENTLY_ON(BrowserThread::UI);
217 TabSpecificContentSettings* settings = GetForFrame(
218 render_process_id, render_frame_id);
219 if (settings)
220 settings->OnFileSystemAccessed(url, blocked_by_policy);
223 // static
224 void TabSpecificContentSettings::ServiceWorkerAccessed(int render_process_id,
225 int render_frame_id,
226 const GURL& scope,
227 bool blocked_by_policy) {
228 DCHECK_CURRENTLY_ON(BrowserThread::UI);
229 TabSpecificContentSettings* settings =
230 GetForFrame(render_process_id, render_frame_id);
231 if (settings)
232 settings->OnServiceWorkerAccessed(scope, blocked_by_policy);
235 bool TabSpecificContentSettings::IsContentBlocked(
236 ContentSettingsType content_type) const {
237 DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
238 << "Geolocation settings handled by ContentSettingGeolocationImageModel";
239 DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
240 << "Notifications settings handled by "
241 << "ContentSettingsNotificationsImageModel";
243 if (content_type == CONTENT_SETTINGS_TYPE_IMAGES ||
244 content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT ||
245 content_type == CONTENT_SETTINGS_TYPE_PLUGINS ||
246 content_type == CONTENT_SETTINGS_TYPE_COOKIES ||
247 content_type == CONTENT_SETTINGS_TYPE_POPUPS ||
248 content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
249 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
250 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
251 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
252 content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
253 content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS ||
254 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
255 const auto& it = content_settings_status_.find(content_type);
256 if (it != content_settings_status_.end())
257 return it->second.blocked;
260 return false;
263 bool TabSpecificContentSettings::IsBlockageIndicated(
264 ContentSettingsType content_type) const {
265 const auto& it = content_settings_status_.find(content_type);
266 if (it != content_settings_status_.end())
267 return it->second.blockage_indicated_to_user;
268 return false;
271 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
272 ContentSettingsType content_type) {
273 content_settings_status_[content_type].blockage_indicated_to_user = true;
276 bool TabSpecificContentSettings::IsContentAllowed(
277 ContentSettingsType content_type) const {
278 // This method currently only returns meaningful values for the content type
279 // cookies, mediastream, PPAPI broker, and downloads.
280 if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
281 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
282 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
283 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
284 content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
285 content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS &&
286 content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
287 return false;
290 const auto& it = content_settings_status_.find(content_type);
291 if (it != content_settings_status_.end())
292 return it->second.allowed;
293 return false;
296 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) {
297 OnContentBlockedWithDetail(type, base::string16());
300 void TabSpecificContentSettings::OnContentBlockedWithDetail(
301 ContentSettingsType type,
302 const base::string16& details) {
303 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
304 << "Geolocation settings handled by OnGeolocationPermissionSet";
305 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
306 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
307 << "Media stream settings handled by OnMediaStreamPermissionSet";
308 if (!content_settings::ContentSettingsRegistry::GetInstance()->Get(type))
309 return;
311 // TODO(robwu): Should this be restricted to cookies only?
312 // In the past, content_settings_status_[type].allowed was set to false, but
313 // this logic was inverted in https://codereview.chromium.org/13375004 to
314 // fix an issue with the cookie permission UI. This unconditional assignment
315 // seems incorrect, because the flag will now always be true after calling
316 // either OnContentBlocked or OnContentAllowed. Consequently IsContentAllowed
317 // will always return true for every supported setting that is not handled
318 // elsewhere.
319 ContentSettingsStatus& status = content_settings_status_[type];
320 status.allowed = true;
322 #if defined(OS_ANDROID)
323 if (type == CONTENT_SETTINGS_TYPE_POPUPS) {
324 // For Android we do not have a persistent button that will always be
325 // visible for blocked popups. Instead we have info bars which could be
326 // dismissed. Have to clear the blocked state so we properly notify the
327 // relevant pieces again.
328 status.blocked = false;
329 status.blockage_indicated_to_user = false;
331 #endif
333 if (type == CONTENT_SETTINGS_TYPE_PLUGINS && !details.empty() &&
334 std::find(blocked_plugin_names_.begin(), blocked_plugin_names_.end(),
335 details) == blocked_plugin_names_.end()) {
336 blocked_plugin_names_.push_back(details);
339 if (!status.blocked) {
340 status.blocked = true;
341 // TODO: it would be nice to have a way of mocking this in tests.
342 content::NotificationService::current()->Notify(
343 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
344 content::Source<WebContents>(web_contents()),
345 content::NotificationService::NoDetails());
347 if (type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) {
348 content_settings::RecordMixedScriptAction(
349 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD);
350 content_settings::RecordMixedScriptActionWithRAPPOR(
351 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD,
352 GURL(base::UTF16ToUTF8(details)));
357 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) {
358 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
359 << "Geolocation settings handled by OnGeolocationPermissionSet";
360 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
361 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
362 << "Media stream settings handled by OnMediaStreamPermissionSet";
363 bool access_changed = false;
364 ContentSettingsStatus& status = content_settings_status_[type];
365 #if defined(OS_ANDROID)
366 if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
367 status.blocked) {
368 // content_settings_status_[type].allowed is always set to true in
369 // OnContentBlocked, so we have to use
370 // content_settings_status_[type].blocked to detect whether the protected
371 // media setting has changed.
372 status.blocked = false;
373 access_changed = true;
375 #endif
377 if (!status.allowed) {
378 status.allowed = true;
379 access_changed = true;
382 if (access_changed) {
383 content::NotificationService::current()->Notify(
384 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
385 content::Source<WebContents>(web_contents()),
386 content::NotificationService::NoDetails());
390 void TabSpecificContentSettings::OnCookiesRead(
391 const GURL& url,
392 const GURL& frame_url,
393 const net::CookieList& cookie_list,
394 bool blocked_by_policy) {
395 if (cookie_list.empty())
396 return;
397 if (blocked_by_policy) {
398 blocked_local_shared_objects_.cookies()->AddReadCookies(
399 frame_url, url, cookie_list);
400 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
401 } else {
402 allowed_local_shared_objects_.cookies()->AddReadCookies(
403 frame_url, url, cookie_list);
404 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
407 NotifySiteDataObservers();
410 void TabSpecificContentSettings::OnCookieChanged(
411 const GURL& url,
412 const GURL& frame_url,
413 const std::string& cookie_line,
414 const net::CookieOptions& options,
415 bool blocked_by_policy) {
416 if (blocked_by_policy) {
417 blocked_local_shared_objects_.cookies()->AddChangedCookie(
418 frame_url, url, cookie_line, options);
419 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
420 } else {
421 allowed_local_shared_objects_.cookies()->AddChangedCookie(
422 frame_url, url, cookie_line, options);
423 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
426 NotifySiteDataObservers();
429 void TabSpecificContentSettings::OnIndexedDBAccessed(
430 const GURL& url,
431 const base::string16& description,
432 bool blocked_by_policy) {
433 if (blocked_by_policy) {
434 blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
435 url, description);
436 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
437 } else {
438 allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
439 url, description);
440 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
443 NotifySiteDataObservers();
446 void TabSpecificContentSettings::OnLocalStorageAccessed(
447 const GURL& url,
448 bool local,
449 bool blocked_by_policy) {
450 LocalSharedObjectsContainer& container = blocked_by_policy ?
451 blocked_local_shared_objects_ : allowed_local_shared_objects_;
452 CannedBrowsingDataLocalStorageHelper* helper =
453 local ? container.local_storages() : container.session_storages();
454 helper->AddLocalStorage(url);
456 if (blocked_by_policy)
457 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
458 else
459 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
461 NotifySiteDataObservers();
464 void TabSpecificContentSettings::OnServiceWorkerAccessed(
465 const GURL& scope,
466 bool blocked_by_policy) {
467 DCHECK(scope.is_valid());
468 if (blocked_by_policy) {
469 blocked_local_shared_objects_.service_workers()->AddServiceWorker(
470 scope.GetOrigin(), std::vector<GURL>(1, scope));
471 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
472 } else {
473 allowed_local_shared_objects_.service_workers()->AddServiceWorker(
474 scope.GetOrigin(), std::vector<GURL>(1, scope));
475 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
479 void TabSpecificContentSettings::OnWebDatabaseAccessed(
480 const GURL& url,
481 const base::string16& name,
482 const base::string16& display_name,
483 bool blocked_by_policy) {
484 if (blocked_by_policy) {
485 blocked_local_shared_objects_.databases()->AddDatabase(
486 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
487 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
488 } else {
489 allowed_local_shared_objects_.databases()->AddDatabase(
490 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
491 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
494 NotifySiteDataObservers();
497 void TabSpecificContentSettings::OnFileSystemAccessed(
498 const GURL& url,
499 bool blocked_by_policy) {
500 if (blocked_by_policy) {
501 blocked_local_shared_objects_.file_systems()->AddFileSystem(
502 url, storage::kFileSystemTypeTemporary, 0);
503 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
504 } else {
505 allowed_local_shared_objects_.file_systems()->AddFileSystem(
506 url, storage::kFileSystemTypeTemporary, 0);
507 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
510 NotifySiteDataObservers();
513 void TabSpecificContentSettings::OnGeolocationPermissionSet(
514 const GURL& requesting_origin,
515 bool allowed) {
516 geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
517 content::NotificationService::current()->Notify(
518 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
519 content::Source<WebContents>(web_contents()),
520 content::NotificationService::NoDetails());
523 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
524 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
525 const GURL& requesting_origin,
526 bool allowed) {
527 if (allowed) {
528 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
529 } else {
530 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
533 #endif
535 TabSpecificContentSettings::MicrophoneCameraState
536 TabSpecificContentSettings::GetMicrophoneCameraState() const {
537 MicrophoneCameraState state = microphone_camera_state_;
539 // Include capture devices in the state if there are still consumers of the
540 // approved media stream.
541 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
542 MediaCaptureDevicesDispatcher::GetInstance()->
543 GetMediaStreamCaptureIndicator();
544 if (media_indicator->IsCapturingAudio(web_contents()))
545 state |= MICROPHONE_ACCESSED;
546 if (media_indicator->IsCapturingVideo(web_contents()))
547 state |= CAMERA_ACCESSED;
549 return state;
552 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
553 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
554 ((microphone_camera_state_& MICROPHONE_BLOCKED) ?
555 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) :
556 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)))
557 return true;
559 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
560 ((microphone_camera_state_ & CAMERA_BLOCKED) ?
561 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) :
562 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)))
563 return true;
565 PrefService* prefs =
566 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
567 GetPrefs();
568 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
569 MediaCaptureDevicesDispatcher::GetInstance()->
570 GetMediaStreamCaptureIndicator();
572 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
573 prefs->GetString(prefs::kDefaultAudioCaptureDevice) !=
574 media_stream_selected_audio_device() &&
575 media_indicator->IsCapturingAudio(web_contents()))
576 return true;
578 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
579 prefs->GetString(prefs::kDefaultVideoCaptureDevice) !=
580 media_stream_selected_video_device() &&
581 media_indicator->IsCapturingVideo(web_contents()))
582 return true;
584 return false;
587 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
588 const GURL& request_origin,
589 MicrophoneCameraState new_microphone_camera_state,
590 const std::string& media_stream_selected_audio_device,
591 const std::string& media_stream_selected_video_device,
592 const std::string& media_stream_requested_audio_device,
593 const std::string& media_stream_requested_video_device) {
594 media_stream_access_origin_ = request_origin;
596 if (new_microphone_camera_state & MICROPHONE_ACCESSED) {
597 media_stream_requested_audio_device_ = media_stream_requested_audio_device;
598 media_stream_selected_audio_device_ = media_stream_selected_audio_device;
599 bool mic_blocked = (new_microphone_camera_state & MICROPHONE_BLOCKED) != 0;
600 ContentSettingsStatus& status =
601 content_settings_status_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC];
602 status.allowed = !mic_blocked;
603 status.blocked = mic_blocked;
606 if (new_microphone_camera_state & CAMERA_ACCESSED) {
607 media_stream_requested_video_device_ = media_stream_requested_video_device;
608 media_stream_selected_video_device_ = media_stream_selected_video_device;
609 bool cam_blocked = (new_microphone_camera_state & CAMERA_BLOCKED) != 0;
610 ContentSettingsStatus& status =
611 content_settings_status_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA];
612 status.allowed = !cam_blocked;
613 status.blocked = cam_blocked;
616 if (microphone_camera_state_ != new_microphone_camera_state) {
617 microphone_camera_state_ = new_microphone_camera_state;
618 content::NotificationService::current()->Notify(
619 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
620 content::Source<WebContents>(web_contents()),
621 content::NotificationService::NoDetails());
625 void TabSpecificContentSettings::OnMidiSysExAccessed(
626 const GURL& requesting_origin) {
627 midi_usages_state_.OnPermissionSet(requesting_origin, true);
628 OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
631 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
632 const GURL& requesting_origin) {
633 midi_usages_state_.OnPermissionSet(requesting_origin, false);
634 OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
637 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
638 for (auto& status : content_settings_status_) {
639 if (status.first == CONTENT_SETTINGS_TYPE_COOKIES)
640 continue;
641 status.second.blocked = false;
642 status.second.blockage_indicated_to_user = false;
643 status.second.allowed = false;
645 microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED;
646 load_plugins_link_enabled_ = true;
647 content::NotificationService::current()->Notify(
648 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
649 content::Source<WebContents>(web_contents()),
650 content::NotificationService::NoDetails());
653 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
654 blocked_local_shared_objects_.Reset();
655 allowed_local_shared_objects_.Reset();
656 ContentSettingsStatus& status =
657 content_settings_status_[CONTENT_SETTINGS_TYPE_COOKIES];
658 status.blocked = false;
659 status.blockage_indicated_to_user = false;
660 status.allowed = false;
661 content::NotificationService::current()->Notify(
662 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
663 content::Source<WebContents>(web_contents()),
664 content::NotificationService::NoDetails());
667 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked) {
668 ContentSettingsStatus& status =
669 content_settings_status_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS];
670 status.blocked = blocked;
671 status.allowed = !blocked;
672 status.blockage_indicated_to_user = false;
673 content::NotificationService::current()->Notify(
674 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
675 content::Source<WebContents>(web_contents()),
676 content::NotificationService::NoDetails());
679 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked) {
680 ContentSettingsStatus& status =
681 content_settings_status_[CONTENT_SETTINGS_TYPE_POPUPS];
682 status.blocked = blocked;
683 status.blockage_indicated_to_user = false;
684 content::NotificationService::current()->Notify(
685 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
686 content::Source<WebContents>(web_contents()),
687 content::NotificationService::NoDetails());
690 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
691 if (allowed) {
692 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
693 } else {
694 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
698 void TabSpecificContentSettings::OnContentSettingChanged(
699 const ContentSettingsPattern& primary_pattern,
700 const ContentSettingsPattern& secondary_pattern,
701 ContentSettingsType content_type,
702 std::string resource_identifier) {
703 const ContentSettingsDetails details(
704 primary_pattern, secondary_pattern, content_type, resource_identifier);
705 const NavigationController& controller = web_contents()->GetController();
706 NavigationEntry* entry = controller.GetVisibleEntry();
707 GURL entry_url;
708 if (entry)
709 entry_url = entry->GetURL();
710 if (details.update_all() ||
711 // The visible NavigationEntry is the URL in the URL field of a tab.
712 // Currently this should be matched by the |primary_pattern|.
713 details.primary_pattern().Matches(entry_url)) {
714 Profile* profile =
715 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
716 const HostContentSettingsMap* map =
717 HostContentSettingsMapFactory::GetForProfile(profile);
719 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
720 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
721 const GURL media_origin = media_stream_access_origin();
722 ContentSetting setting = map->GetContentSetting(media_origin,
723 media_origin,
724 content_type,
725 std::string());
726 ContentSettingsStatus& status = content_settings_status_[content_type];
727 status.allowed = setting == CONTENT_SETTING_ALLOW;
728 status.blocked = setting == CONTENT_SETTING_BLOCK;
730 RendererContentSettingRules rules;
731 GetRendererContentSettingRules(map, &rules);
732 Send(new ChromeViewMsg_SetContentSettingRules(rules));
736 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
737 content::RenderFrameHost* render_frame_host) {
738 // We want to tell the renderer-side code to ignore content settings for this
739 // page.
740 render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial(
741 render_frame_host->GetRoutingID()));
744 bool TabSpecificContentSettings::OnMessageReceived(
745 const IPC::Message& message,
746 content::RenderFrameHost* render_frame_host) {
747 bool handled = true;
748 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message)
749 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked,
750 OnContentBlockedWithDetail)
751 IPC_MESSAGE_UNHANDLED(handled = false)
752 IPC_END_MESSAGE_MAP()
753 return handled;
756 void TabSpecificContentSettings::DidNavigateMainFrame(
757 const content::LoadCommittedDetails& details,
758 const content::FrameNavigateParams& params) {
759 if (!details.is_in_page) {
760 // Clear "blocked" flags.
761 ClearBlockedContentSettingsExceptForCookies();
762 blocked_plugin_names_.clear();
763 GeolocationDidNavigate(details);
764 MidiDidNavigate(details);
768 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
769 content::RenderFrameHost* render_frame_host,
770 const GURL& validated_url,
771 bool is_error_page,
772 bool is_iframe_srcdoc) {
773 if (render_frame_host->GetParent())
774 return;
776 // If we're displaying a network error page do not reset the content
777 // settings delegate's cookies so the user has a chance to modify cookie
778 // settings.
779 if (!is_error_page)
780 ClearCookieSpecificContentSettings();
781 ClearGeolocationContentSettings();
782 ClearMidiContentSettings();
783 ClearPendingProtocolHandler();
786 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
787 bool blocked_by_policy) {
788 if (blocked_by_policy) {
789 blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
790 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
791 } else {
792 allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
793 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
797 void TabSpecificContentSettings::AddSiteDataObserver(
798 SiteDataObserver* observer) {
799 observer_list_.AddObserver(observer);
802 void TabSpecificContentSettings::RemoveSiteDataObserver(
803 SiteDataObserver* observer) {
804 observer_list_.RemoveObserver(observer);
807 void TabSpecificContentSettings::NotifySiteDataObservers() {
808 FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
811 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
812 geolocation_usages_state_.ClearStateMap();
815 void TabSpecificContentSettings::ClearMidiContentSettings() {
816 midi_usages_state_.ClearStateMap();
819 void TabSpecificContentSettings::GeolocationDidNavigate(
820 const content::LoadCommittedDetails& details) {
821 geolocation_usages_state_.DidNavigate(GetCommittedDetails(details));
824 void TabSpecificContentSettings::MidiDidNavigate(
825 const content::LoadCommittedDetails& details) {
826 midi_usages_state_.DidNavigate(GetCommittedDetails(details));