ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / content_settings / tab_specific_content_settings.cc
blobf41deb05b860cb57c23f4e1e9a7d0c2cc957cac8
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
7 #include <list>
9 #include "base/command_line.h"
10 #include "base/lazy_instance.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
19 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
20 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
21 #include "chrome/browser/browsing_data/cookies_tree_model.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
24 #include "chrome/browser/media/media_stream_capture_indicator.h"
25 #include "chrome/browser/prerender/prerender_manager.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/common/render_messages.h"
30 #include "components/content_settings/core/browser/content_settings_details.h"
31 #include "components/content_settings/core/browser/content_settings_utils.h"
32 #include "components/content_settings/core/browser/host_content_settings_map.h"
33 #include "components/rappor/rappor_service.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/navigation_details.h"
37 #include "content/public/browser/navigation_entry.h"
38 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/render_frame_host.h"
41 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/browser/web_contents_delegate.h"
44 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
45 #include "net/cookies/canonical_cookie.h"
46 #include "storage/common/fileapi/file_system_types.h"
48 using content::BrowserThread;
49 using content::NavigationController;
50 using content::NavigationEntry;
51 using content::RenderViewHost;
52 using content::WebContents;
54 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
56 namespace {
58 // Returns the object given a render frame's id.
59 TabSpecificContentSettings* GetForFrame(int render_process_id,
60 int render_frame_id) {
61 DCHECK_CURRENTLY_ON(BrowserThread::UI);
63 content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
64 render_process_id, render_frame_id);
65 WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
66 if (!web_contents)
67 return nullptr;
69 return TabSpecificContentSettings::FromWebContents(web_contents);
72 ContentSettingsUsagesState::CommittedDetails GetCommittedDetails(
73 const content::LoadCommittedDetails& details) {
74 ContentSettingsUsagesState::CommittedDetails committed_details;
75 committed_details.current_url_valid = !!details.entry;
76 if (details.entry)
77 committed_details.current_url = details.entry->GetURL();
78 committed_details.previous_url = details.previous_url;
79 return committed_details;
82 } // namespace
84 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
85 TabSpecificContentSettings* tab_specific_content_settings)
86 : tab_specific_content_settings_(tab_specific_content_settings) {
87 tab_specific_content_settings_->AddSiteDataObserver(this);
90 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
91 if (tab_specific_content_settings_)
92 tab_specific_content_settings_->RemoveSiteDataObserver(this);
95 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
96 tab_specific_content_settings_ = NULL;
99 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
100 : content::WebContentsObserver(tab),
101 allowed_local_shared_objects_(
102 Profile::FromBrowserContext(tab->GetBrowserContext())),
103 blocked_local_shared_objects_(
104 Profile::FromBrowserContext(tab->GetBrowserContext())),
105 geolocation_usages_state_(
106 Profile::FromBrowserContext(tab->GetBrowserContext())
107 ->GetHostContentSettingsMap(),
108 CONTENT_SETTINGS_TYPE_GEOLOCATION,
109 prefs::kAcceptLanguages,
110 Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs()),
111 midi_usages_state_(
112 Profile::FromBrowserContext(tab->GetBrowserContext())
113 ->GetHostContentSettingsMap(),
114 CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
115 prefs::kAcceptLanguages,
116 Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs()),
117 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
118 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
119 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
120 load_plugins_link_enabled_(true),
121 microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED),
122 observer_(this) {
123 ClearBlockedContentSettingsExceptForCookies();
124 ClearCookieSpecificContentSettings();
126 observer_.Add(Profile::FromBrowserContext(tab->GetBrowserContext())
127 ->GetHostContentSettingsMap());
130 TabSpecificContentSettings::~TabSpecificContentSettings() {
131 FOR_EACH_OBSERVER(
132 SiteDataObserver, observer_list_, ContentSettingsDestroyed());
135 // static
136 TabSpecificContentSettings* TabSpecificContentSettings::Get(
137 int render_process_id, int render_view_id) {
138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140 RenderViewHost* view = RenderViewHost::FromID(render_process_id,
141 render_view_id);
142 if (!view)
143 return NULL;
145 WebContents* web_contents = WebContents::FromRenderViewHost(view);
146 if (!web_contents)
147 return NULL;
149 return TabSpecificContentSettings::FromWebContents(web_contents);
152 // static
153 void TabSpecificContentSettings::CookiesRead(int render_process_id,
154 int render_frame_id,
155 const GURL& url,
156 const GURL& frame_url,
157 const net::CookieList& cookie_list,
158 bool blocked_by_policy,
159 bool is_for_blocking_resource) {
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161 TabSpecificContentSettings* settings =
162 GetForFrame(render_process_id, render_frame_id);
163 if (settings) {
164 settings->OnCookiesRead(url, frame_url, cookie_list,
165 blocked_by_policy);
167 prerender::PrerenderManager::RecordCookieEvent(
168 render_process_id,
169 render_frame_id,
170 url,
171 frame_url,
172 is_for_blocking_resource,
173 prerender::PrerenderContents::COOKIE_EVENT_SEND,
174 &cookie_list);
177 // static
178 void TabSpecificContentSettings::CookieChanged(
179 int render_process_id,
180 int render_frame_id,
181 const GURL& url,
182 const GURL& frame_url,
183 const std::string& cookie_line,
184 const net::CookieOptions& options,
185 bool blocked_by_policy) {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
187 TabSpecificContentSettings* settings =
188 GetForFrame(render_process_id, render_frame_id);
189 if (settings)
190 settings->OnCookieChanged(url, frame_url, cookie_line, options,
191 blocked_by_policy);
192 prerender::PrerenderManager::RecordCookieEvent(
193 render_process_id,
194 render_frame_id,
195 url,
196 frame_url,
197 false /*is_critical_request*/,
198 prerender::PrerenderContents::COOKIE_EVENT_CHANGE,
199 NULL);
202 // static
203 void TabSpecificContentSettings::WebDatabaseAccessed(
204 int render_process_id,
205 int render_frame_id,
206 const GURL& url,
207 const base::string16& name,
208 const base::string16& display_name,
209 bool blocked_by_policy) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 TabSpecificContentSettings* settings = GetForFrame(
212 render_process_id, render_frame_id);
213 if (settings)
214 settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy);
217 // static
218 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id,
219 int render_frame_id,
220 const GURL& url,
221 bool local,
222 bool blocked_by_policy) {
223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
224 TabSpecificContentSettings* settings = GetForFrame(
225 render_process_id, render_frame_id);
226 if (settings)
227 settings->OnLocalStorageAccessed(url, local, blocked_by_policy);
230 // static
231 void TabSpecificContentSettings::IndexedDBAccessed(
232 int render_process_id,
233 int render_frame_id,
234 const GURL& url,
235 const base::string16& description,
236 bool blocked_by_policy) {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 TabSpecificContentSettings* settings = GetForFrame(
239 render_process_id, render_frame_id);
240 if (settings)
241 settings->OnIndexedDBAccessed(url, description, blocked_by_policy);
244 // static
245 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id,
246 int render_frame_id,
247 const GURL& url,
248 bool blocked_by_policy) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250 TabSpecificContentSettings* settings = GetForFrame(
251 render_process_id, render_frame_id);
252 if (settings)
253 settings->OnFileSystemAccessed(url, blocked_by_policy);
256 const base::string16 TabSpecificContentSettings::GetBlockedPluginNames() const {
257 return JoinString(blocked_plugin_names_, base::ASCIIToUTF16(", "));
260 bool TabSpecificContentSettings::IsContentBlocked(
261 ContentSettingsType content_type) const {
262 DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
263 << "Geolocation settings handled by ContentSettingGeolocationImageModel";
264 DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
265 << "Notifications settings handled by "
266 << "ContentSettingsNotificationsImageModel";
268 if (content_type == CONTENT_SETTINGS_TYPE_IMAGES ||
269 content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT ||
270 content_type == CONTENT_SETTINGS_TYPE_PLUGINS ||
271 content_type == CONTENT_SETTINGS_TYPE_COOKIES ||
272 content_type == CONTENT_SETTINGS_TYPE_POPUPS ||
273 content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
274 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
275 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
276 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
277 content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
278 content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS ||
279 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
280 return content_blocked_[content_type];
283 return false;
286 bool TabSpecificContentSettings::IsBlockageIndicated(
287 ContentSettingsType content_type) const {
288 return content_blockage_indicated_to_user_[content_type];
291 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
292 ContentSettingsType content_type) {
293 content_blockage_indicated_to_user_[content_type] = true;
296 bool TabSpecificContentSettings::IsContentAllowed(
297 ContentSettingsType content_type) const {
298 // This method currently only returns meaningful values for the content type
299 // cookies, mediastream, PPAPI broker, and downloads.
300 if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
301 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
302 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
303 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
304 content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
305 content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS &&
306 content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
307 return false;
310 return content_allowed_[content_type];
313 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) {
314 OnContentBlockedWithDetail(type, base::string16());
317 void TabSpecificContentSettings::OnContentBlockedWithDetail(
318 ContentSettingsType type,
319 const base::string16& details) {
320 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
321 << "Geolocation settings handled by OnGeolocationPermissionSet";
322 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
323 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
324 << "Media stream settings handled by OnMediaStreamPermissionSet";
325 if (type < 0 || type >= CONTENT_SETTINGS_NUM_TYPES)
326 return;
328 // TODO(robwu): Should this be restricted to cookies only?
329 // In the past, content_allowed_ was set to false, but this logic was inverted
330 // in https://codereview.chromium.org/13375004 to fix an issue with the cookie
331 // permission UI. This unconditional assignment seems incorrect, because the
332 // flag will now always be true after calling either OnContentBlocked or
333 // OnContentAllowed. Consequently IsContentAllowed will always return true
334 // for every supported setting that is not handled elsewhere.
335 content_allowed_[type] = true;
337 #if defined(OS_ANDROID)
338 if (type == CONTENT_SETTINGS_TYPE_POPUPS) {
339 // For Android we do not have a persistent button that will always be
340 // visible for blocked popups. Instead we have info bars which could be
341 // dismissed. Have to clear the blocked state so we properly notify the
342 // relevant pieces again.
343 content_blocked_[type] = false;
344 content_blockage_indicated_to_user_[type] = false;
346 #endif
348 if (type == CONTENT_SETTINGS_TYPE_PLUGINS && !details.empty() &&
349 std::find(blocked_plugin_names_.begin(), blocked_plugin_names_.end(),
350 details) == blocked_plugin_names_.end()) {
351 blocked_plugin_names_.push_back(details);
354 if (!content_blocked_[type]) {
355 content_blocked_[type] = true;
356 // TODO: it would be nice to have a way of mocking this in tests.
357 content::NotificationService::current()->Notify(
358 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
359 content::Source<WebContents>(web_contents()),
360 content::NotificationService::NoDetails());
362 if (type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) {
363 content_settings::RecordMixedScriptAction(
364 content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD);
366 rappor::RapporService* rappor_service =
367 g_browser_process->rappor_service();
368 if (rappor_service) {
369 rappor_service->RecordSample(
370 "ContentSettings.MixedScript.DisplayedShield",
371 rappor::ETLD_PLUS_ONE_RAPPOR_TYPE,
372 net::registry_controlled_domains::GetDomainAndRegistry(
373 base::UTF16ToUTF8(details),
374 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
380 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) {
381 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
382 << "Geolocation settings handled by OnGeolocationPermissionSet";
383 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
384 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
385 << "Media stream settings handled by OnMediaStreamPermissionSet";
386 bool access_changed = false;
387 #if defined(OS_ANDROID)
388 if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
389 content_blocked_[type]) {
390 // content_allowed_[type] is always set to true in OnContentBlocked, so we
391 // have to use content_blocked_ to detect whether the protected media
392 // setting has changed.
393 content_blocked_[type] = false;
394 access_changed = true;
396 #endif
398 if (!content_allowed_[type]) {
399 content_allowed_[type] = true;
400 access_changed = true;
403 if (access_changed) {
404 content::NotificationService::current()->Notify(
405 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
406 content::Source<WebContents>(web_contents()),
407 content::NotificationService::NoDetails());
411 void TabSpecificContentSettings::OnCookiesRead(
412 const GURL& url,
413 const GURL& frame_url,
414 const net::CookieList& cookie_list,
415 bool blocked_by_policy) {
416 if (cookie_list.empty())
417 return;
418 if (blocked_by_policy) {
419 blocked_local_shared_objects_.cookies()->AddReadCookies(
420 frame_url, url, cookie_list);
421 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
422 } else {
423 allowed_local_shared_objects_.cookies()->AddReadCookies(
424 frame_url, url, cookie_list);
425 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
428 NotifySiteDataObservers();
431 void TabSpecificContentSettings::OnCookieChanged(
432 const GURL& url,
433 const GURL& frame_url,
434 const std::string& cookie_line,
435 const net::CookieOptions& options,
436 bool blocked_by_policy) {
437 if (blocked_by_policy) {
438 blocked_local_shared_objects_.cookies()->AddChangedCookie(
439 frame_url, url, cookie_line, options);
440 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
441 } else {
442 allowed_local_shared_objects_.cookies()->AddChangedCookie(
443 frame_url, url, cookie_line, options);
444 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
447 NotifySiteDataObservers();
450 void TabSpecificContentSettings::OnIndexedDBAccessed(
451 const GURL& url,
452 const base::string16& description,
453 bool blocked_by_policy) {
454 if (blocked_by_policy) {
455 blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
456 url, description);
457 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
458 } else {
459 allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
460 url, description);
461 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
464 NotifySiteDataObservers();
467 void TabSpecificContentSettings::OnLocalStorageAccessed(
468 const GURL& url,
469 bool local,
470 bool blocked_by_policy) {
471 LocalSharedObjectsContainer& container = blocked_by_policy ?
472 blocked_local_shared_objects_ : allowed_local_shared_objects_;
473 CannedBrowsingDataLocalStorageHelper* helper =
474 local ? container.local_storages() : container.session_storages();
475 helper->AddLocalStorage(url);
477 if (blocked_by_policy)
478 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
479 else
480 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
482 NotifySiteDataObservers();
485 void TabSpecificContentSettings::OnWebDatabaseAccessed(
486 const GURL& url,
487 const base::string16& name,
488 const base::string16& display_name,
489 bool blocked_by_policy) {
490 if (blocked_by_policy) {
491 blocked_local_shared_objects_.databases()->AddDatabase(
492 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
493 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
494 } else {
495 allowed_local_shared_objects_.databases()->AddDatabase(
496 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
497 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
500 NotifySiteDataObservers();
503 void TabSpecificContentSettings::OnFileSystemAccessed(
504 const GURL& url,
505 bool blocked_by_policy) {
506 if (blocked_by_policy) {
507 blocked_local_shared_objects_.file_systems()->AddFileSystem(
508 url, storage::kFileSystemTypeTemporary, 0);
509 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
510 } else {
511 allowed_local_shared_objects_.file_systems()->AddFileSystem(
512 url, storage::kFileSystemTypeTemporary, 0);
513 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
516 NotifySiteDataObservers();
519 void TabSpecificContentSettings::OnGeolocationPermissionSet(
520 const GURL& requesting_origin,
521 bool allowed) {
522 geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
523 content::NotificationService::current()->Notify(
524 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
525 content::Source<WebContents>(web_contents()),
526 content::NotificationService::NoDetails());
529 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
530 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
531 const GURL& requesting_origin,
532 bool allowed) {
533 if (allowed) {
534 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
535 } else {
536 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
539 #endif
541 TabSpecificContentSettings::MicrophoneCameraState
542 TabSpecificContentSettings::GetMicrophoneCameraState() const {
543 MicrophoneCameraState state = microphone_camera_state_;
545 // Include capture devices in the state if there are still consumers of the
546 // approved media stream.
547 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
548 MediaCaptureDevicesDispatcher::GetInstance()->
549 GetMediaStreamCaptureIndicator();
550 if (media_indicator->IsCapturingAudio(web_contents()))
551 state |= MICROPHONE_ACCESSED;
552 if (media_indicator->IsCapturingVideo(web_contents()))
553 state |= CAMERA_ACCESSED;
555 return state;
558 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
559 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
560 ((microphone_camera_state_& MICROPHONE_BLOCKED) ?
561 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) :
562 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)))
563 return true;
565 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
566 ((microphone_camera_state_ & CAMERA_BLOCKED) ?
567 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) :
568 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)))
569 return true;
571 PrefService* prefs =
572 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
573 GetPrefs();
574 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
575 MediaCaptureDevicesDispatcher::GetInstance()->
576 GetMediaStreamCaptureIndicator();
578 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
579 prefs->GetString(prefs::kDefaultAudioCaptureDevice) !=
580 media_stream_selected_audio_device() &&
581 media_indicator->IsCapturingAudio(web_contents()))
582 return true;
584 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
585 prefs->GetString(prefs::kDefaultVideoCaptureDevice) !=
586 media_stream_selected_video_device() &&
587 media_indicator->IsCapturingVideo(web_contents()))
588 return true;
590 return false;
593 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
594 const GURL& request_origin,
595 MicrophoneCameraState new_microphone_camera_state,
596 const std::string& media_stream_selected_audio_device,
597 const std::string& media_stream_selected_video_device,
598 const std::string& media_stream_requested_audio_device,
599 const std::string& media_stream_requested_video_device) {
600 media_stream_access_origin_ = request_origin;
602 if (new_microphone_camera_state & MICROPHONE_ACCESSED) {
603 media_stream_requested_audio_device_ = media_stream_requested_audio_device;
604 media_stream_selected_audio_device_ = media_stream_selected_audio_device;
605 bool mic_blocked = (new_microphone_camera_state & MICROPHONE_BLOCKED) != 0;
606 content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = !mic_blocked;
607 content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = mic_blocked;
610 if (new_microphone_camera_state & CAMERA_ACCESSED) {
611 media_stream_requested_video_device_ = media_stream_requested_video_device;
612 media_stream_selected_video_device_ = media_stream_selected_video_device;
613 bool cam_blocked = (new_microphone_camera_state & CAMERA_BLOCKED) != 0;
614 content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = !cam_blocked;
615 content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = cam_blocked;
618 if (microphone_camera_state_ != new_microphone_camera_state) {
619 microphone_camera_state_ = new_microphone_camera_state;
620 content::NotificationService::current()->Notify(
621 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
622 content::Source<WebContents>(web_contents()),
623 content::NotificationService::NoDetails());
627 void TabSpecificContentSettings::OnMidiSysExAccessed(
628 const GURL& requesting_origin) {
629 midi_usages_state_.OnPermissionSet(requesting_origin, true);
630 OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
633 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
634 const GURL& requesting_origin) {
635 midi_usages_state_.OnPermissionSet(requesting_origin, false);
636 OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
639 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
640 for (size_t i = 0; i < arraysize(content_blocked_); ++i) {
641 if (i == CONTENT_SETTINGS_TYPE_COOKIES)
642 continue;
643 content_blocked_[i] = false;
644 content_allowed_[i] = false;
645 content_blockage_indicated_to_user_[i] = false;
647 microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED;
648 load_plugins_link_enabled_ = true;
649 content::NotificationService::current()->Notify(
650 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
651 content::Source<WebContents>(web_contents()),
652 content::NotificationService::NoDetails());
655 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
656 blocked_local_shared_objects_.Reset();
657 allowed_local_shared_objects_.Reset();
658 content_blocked_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
659 content_allowed_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
660 content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_COOKIES] = 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 content_blocked_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = blocked;
669 content_allowed_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = !blocked;
670 content_blockage_indicated_to_user_[
671 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = 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 content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked;
680 content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false;
681 content::NotificationService::current()->Notify(
682 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
683 content::Source<WebContents>(web_contents()),
684 content::NotificationService::NoDetails());
687 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
688 if (allowed) {
689 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
690 } else {
691 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
695 void TabSpecificContentSettings::OnContentSettingChanged(
696 const ContentSettingsPattern& primary_pattern,
697 const ContentSettingsPattern& secondary_pattern,
698 ContentSettingsType content_type,
699 std::string resource_identifier) {
700 const ContentSettingsDetails details(
701 primary_pattern, secondary_pattern, content_type, resource_identifier);
702 const NavigationController& controller = web_contents()->GetController();
703 NavigationEntry* entry = controller.GetVisibleEntry();
704 GURL entry_url;
705 if (entry)
706 entry_url = entry->GetURL();
707 if (details.update_all() ||
708 // The visible NavigationEntry is the URL in the URL field of a tab.
709 // Currently this should be matched by the |primary_pattern|.
710 details.primary_pattern().Matches(entry_url)) {
711 Profile* profile =
712 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
713 const HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
715 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
716 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
717 const GURL media_origin = media_stream_access_origin();
718 ContentSetting setting = map->GetContentSetting(media_origin,
719 media_origin,
720 content_type,
721 std::string());
722 content_allowed_[content_type] = setting == CONTENT_SETTING_ALLOW;
723 content_blocked_[content_type] = setting == CONTENT_SETTING_BLOCK;
725 RendererContentSettingRules rules;
726 GetRendererContentSettingRules(map, &rules);
727 Send(new ChromeViewMsg_SetContentSettingRules(rules));
731 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
732 content::RenderFrameHost* render_frame_host) {
733 // We want to tell the renderer-side code to ignore content settings for this
734 // page.
735 render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial(
736 render_frame_host->GetRoutingID()));
739 bool TabSpecificContentSettings::OnMessageReceived(
740 const IPC::Message& message,
741 content::RenderFrameHost* render_frame_host) {
742 bool handled = true;
743 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message)
744 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked,
745 OnContentBlockedWithDetail)
746 IPC_MESSAGE_UNHANDLED(handled = false)
747 IPC_END_MESSAGE_MAP()
748 return handled;
751 void TabSpecificContentSettings::DidNavigateMainFrame(
752 const content::LoadCommittedDetails& details,
753 const content::FrameNavigateParams& params) {
754 if (!details.is_in_page) {
755 // Clear "blocked" flags.
756 ClearBlockedContentSettingsExceptForCookies();
757 blocked_plugin_names_.clear();
758 GeolocationDidNavigate(details);
759 MidiDidNavigate(details);
763 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
764 content::RenderFrameHost* render_frame_host,
765 const GURL& validated_url,
766 bool is_error_page,
767 bool is_iframe_srcdoc) {
768 if (render_frame_host->GetParent())
769 return;
771 // If we're displaying a network error page do not reset the content
772 // settings delegate's cookies so the user has a chance to modify cookie
773 // settings.
774 if (!is_error_page)
775 ClearCookieSpecificContentSettings();
776 ClearGeolocationContentSettings();
777 ClearMidiContentSettings();
778 ClearPendingProtocolHandler();
781 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
782 bool blocked_by_policy) {
783 if (blocked_by_policy) {
784 blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
785 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
786 } else {
787 allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
788 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
792 void TabSpecificContentSettings::AddSiteDataObserver(
793 SiteDataObserver* observer) {
794 observer_list_.AddObserver(observer);
797 void TabSpecificContentSettings::RemoveSiteDataObserver(
798 SiteDataObserver* observer) {
799 observer_list_.RemoveObserver(observer);
802 void TabSpecificContentSettings::NotifySiteDataObservers() {
803 FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
806 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
807 geolocation_usages_state_.ClearStateMap();
810 void TabSpecificContentSettings::ClearMidiContentSettings() {
811 midi_usages_state_.ClearStateMap();
814 void TabSpecificContentSettings::GeolocationDidNavigate(
815 const content::LoadCommittedDetails& details) {
816 geolocation_usages_state_.DidNavigate(GetCommittedDetails(details));
819 void TabSpecificContentSettings::MidiDidNavigate(
820 const content::LoadCommittedDetails& details) {
821 midi_usages_state_.DidNavigate(GetCommittedDetails(details));