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