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