TabSpecificContentSettings::MicrophoneCameraState should be an enum
[chromium-blink-merge.git] / chrome / browser / content_settings / tab_specific_content_settings.cc
blob9a69272397efcff94bc01718b2399df505797381
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/metrics/histogram.h"
12 #include "base/prefs/pref_service.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/media/media_stream_capture_indicator.h"
23 #include "chrome/browser/prerender/prerender_manager.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/render_messages.h"
28 #include "components/content_settings/core/browser/content_settings_details.h"
29 #include "components/content_settings/core/browser/content_settings_utils.h"
30 #include "components/content_settings/core/browser/host_content_settings_map.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/navigation_controller.h"
33 #include "content/public/browser/navigation_details.h"
34 #include "content/public/browser/navigation_entry.h"
35 #include "content/public/browser/notification_registrar.h"
36 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/render_frame_host.h"
38 #include "content/public/browser/render_view_host.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/browser/web_contents_delegate.h"
41 #include "net/cookies/canonical_cookie.h"
42 #include "storage/common/fileapi/file_system_types.h"
44 using content::BrowserThread;
45 using content::NavigationController;
46 using content::NavigationEntry;
47 using content::RenderViewHost;
48 using content::WebContents;
50 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
52 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
53 TabSpecificContentSettings* tab_specific_content_settings)
54 : tab_specific_content_settings_(tab_specific_content_settings) {
55 tab_specific_content_settings_->AddSiteDataObserver(this);
58 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
59 if (tab_specific_content_settings_)
60 tab_specific_content_settings_->RemoveSiteDataObserver(this);
63 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
64 tab_specific_content_settings_ = NULL;
67 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
68 : content::WebContentsObserver(tab),
69 allowed_local_shared_objects_(
70 Profile::FromBrowserContext(tab->GetBrowserContext())),
71 blocked_local_shared_objects_(
72 Profile::FromBrowserContext(tab->GetBrowserContext())),
73 geolocation_usages_state_(
74 Profile::FromBrowserContext(tab->GetBrowserContext())
75 ->GetHostContentSettingsMap(),
76 Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs(),
77 CONTENT_SETTINGS_TYPE_GEOLOCATION),
78 midi_usages_state_(
79 Profile::FromBrowserContext(tab->GetBrowserContext())
80 ->GetHostContentSettingsMap(),
81 Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs(),
82 CONTENT_SETTINGS_TYPE_MIDI_SYSEX),
83 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
84 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
85 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
86 load_plugins_link_enabled_(true),
87 microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED),
88 observer_(this) {
89 ClearBlockedContentSettingsExceptForCookies();
90 ClearCookieSpecificContentSettings();
92 observer_.Add(Profile::FromBrowserContext(tab->GetBrowserContext())
93 ->GetHostContentSettingsMap());
96 TabSpecificContentSettings::~TabSpecificContentSettings() {
97 FOR_EACH_OBSERVER(
98 SiteDataObserver, observer_list_, ContentSettingsDestroyed());
101 void TabSpecificContentSettings::RecordMixedScriptAction(
102 MixedScriptAction action) {
103 UMA_HISTOGRAM_ENUMERATION("ContentSettings.MixedScript",
104 action,
105 MIXED_SCRIPT_ACTION_COUNT);
108 TabSpecificContentSettings* TabSpecificContentSettings::Get(
109 int render_process_id, int render_view_id) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 RenderViewHost* view = RenderViewHost::FromID(render_process_id,
113 render_view_id);
114 if (!view)
115 return NULL;
117 WebContents* web_contents = WebContents::FromRenderViewHost(view);
118 if (!web_contents)
119 return NULL;
121 return TabSpecificContentSettings::FromWebContents(web_contents);
124 TabSpecificContentSettings* TabSpecificContentSettings::GetForFrame(
125 int render_process_id, int render_frame_id) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128 content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
129 render_process_id, render_frame_id);
130 WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
131 if (!web_contents)
132 return NULL;
134 return TabSpecificContentSettings::FromWebContents(web_contents);
137 // static
138 void TabSpecificContentSettings::CookiesRead(int render_process_id,
139 int render_frame_id,
140 const GURL& url,
141 const GURL& frame_url,
142 const net::CookieList& cookie_list,
143 bool blocked_by_policy,
144 bool is_for_blocking_resource) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
146 TabSpecificContentSettings* settings =
147 GetForFrame(render_process_id, render_frame_id);
148 if (settings) {
149 settings->OnCookiesRead(url, frame_url, cookie_list,
150 blocked_by_policy);
152 prerender::PrerenderManager::RecordCookieEvent(
153 render_process_id,
154 render_frame_id,
155 url,
156 frame_url,
157 is_for_blocking_resource,
158 prerender::PrerenderContents::COOKIE_EVENT_SEND,
159 &cookie_list);
162 // static
163 void TabSpecificContentSettings::CookieChanged(
164 int render_process_id,
165 int render_frame_id,
166 const GURL& url,
167 const GURL& frame_url,
168 const std::string& cookie_line,
169 const net::CookieOptions& options,
170 bool blocked_by_policy) {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
172 TabSpecificContentSettings* settings =
173 GetForFrame(render_process_id, render_frame_id);
174 if (settings)
175 settings->OnCookieChanged(url, frame_url, cookie_line, options,
176 blocked_by_policy);
177 prerender::PrerenderManager::RecordCookieEvent(
178 render_process_id,
179 render_frame_id,
180 url,
181 frame_url,
182 false /*is_critical_request*/,
183 prerender::PrerenderContents::COOKIE_EVENT_CHANGE,
184 NULL);
187 // static
188 void TabSpecificContentSettings::WebDatabaseAccessed(
189 int render_process_id,
190 int render_frame_id,
191 const GURL& url,
192 const base::string16& name,
193 const base::string16& display_name,
194 bool blocked_by_policy) {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
196 TabSpecificContentSettings* settings = GetForFrame(
197 render_process_id, render_frame_id);
198 if (settings)
199 settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy);
202 // static
203 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id,
204 int render_frame_id,
205 const GURL& url,
206 bool local,
207 bool blocked_by_policy) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 TabSpecificContentSettings* settings = GetForFrame(
210 render_process_id, render_frame_id);
211 if (settings)
212 settings->OnLocalStorageAccessed(url, local, blocked_by_policy);
215 // static
216 void TabSpecificContentSettings::IndexedDBAccessed(
217 int render_process_id,
218 int render_frame_id,
219 const GURL& url,
220 const base::string16& description,
221 bool blocked_by_policy) {
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
223 TabSpecificContentSettings* settings = GetForFrame(
224 render_process_id, render_frame_id);
225 if (settings)
226 settings->OnIndexedDBAccessed(url, description, blocked_by_policy);
229 // static
230 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id,
231 int render_frame_id,
232 const GURL& url,
233 bool blocked_by_policy) {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235 TabSpecificContentSettings* settings = GetForFrame(
236 render_process_id, render_frame_id);
237 if (settings)
238 settings->OnFileSystemAccessed(url, blocked_by_policy);
241 bool TabSpecificContentSettings::IsContentBlocked(
242 ContentSettingsType content_type) const {
243 DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
244 << "Geolocation settings handled by ContentSettingGeolocationImageModel";
245 DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
246 << "Notifications settings handled by "
247 << "ContentSettingsNotificationsImageModel";
249 if (content_type == CONTENT_SETTINGS_TYPE_IMAGES ||
250 content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT ||
251 content_type == CONTENT_SETTINGS_TYPE_PLUGINS ||
252 content_type == CONTENT_SETTINGS_TYPE_COOKIES ||
253 content_type == CONTENT_SETTINGS_TYPE_POPUPS ||
254 content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
255 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
256 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
257 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
258 content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
259 content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS ||
260 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
261 return content_blocked_[content_type];
264 return false;
267 bool TabSpecificContentSettings::IsBlockageIndicated(
268 ContentSettingsType content_type) const {
269 return content_blockage_indicated_to_user_[content_type];
272 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
273 ContentSettingsType content_type) {
274 content_blockage_indicated_to_user_[content_type] = true;
277 bool TabSpecificContentSettings::IsContentAllowed(
278 ContentSettingsType content_type) const {
279 // This method currently only returns meaningful values for the content type
280 // cookies, mediastream, PPAPI broker, and downloads.
281 if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
282 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
283 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
284 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
285 content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
286 content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS &&
287 content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
288 return false;
291 return content_allowed_[content_type];
294 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) {
295 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
296 << "Geolocation settings handled by OnGeolocationPermissionSet";
297 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
298 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
299 << "Media stream settings handled by OnMediaStreamPermissionSet";
300 if (type < 0 || type >= CONTENT_SETTINGS_NUM_TYPES)
301 return;
303 // TODO(robwu): Should this be restricted to cookies only?
304 // In the past, content_allowed_ was set to false, but this logic was inverted
305 // in https://codereview.chromium.org/13375004 to fix an issue with the cookie
306 // permission UI. This unconditional assignment seems incorrect, because the
307 // flag will now always be true after calling either OnContentBlocked or
308 // OnContentAllowed. Consequently IsContentAllowed will always return true
309 // for every supported setting that is not handled elsewhere.
310 content_allowed_[type] = true;
312 #if defined(OS_ANDROID)
313 if (type == CONTENT_SETTINGS_TYPE_POPUPS) {
314 // For Android we do not have a persistent button that will always be
315 // visible for blocked popups. Instead we have info bars which could be
316 // dismissed. Have to clear the blocked state so we properly notify the
317 // relevant pieces again.
318 content_blocked_[type] = false;
319 content_blockage_indicated_to_user_[type] = false;
321 #endif
323 if (!content_blocked_[type]) {
324 content_blocked_[type] = true;
325 // TODO: it would be nice to have a way of mocking this in tests.
326 content::NotificationService::current()->Notify(
327 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
328 content::Source<WebContents>(web_contents()),
329 content::NotificationService::NoDetails());
331 if (type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)
332 RecordMixedScriptAction(MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD);
336 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) {
337 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
338 << "Geolocation settings handled by OnGeolocationPermissionSet";
339 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
340 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
341 << "Media stream settings handled by OnMediaStreamPermissionSet";
342 bool access_changed = false;
343 #if defined(OS_ANDROID)
344 if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
345 content_blocked_[type]) {
346 // content_allowed_[type] is always set to true in OnContentBlocked, so we
347 // have to use content_blocked_ to detect whether the protected media
348 // setting has changed.
349 content_blocked_[type] = false;
350 access_changed = true;
352 #endif
354 if (!content_allowed_[type]) {
355 content_allowed_[type] = true;
356 access_changed = true;
359 if (access_changed) {
360 content::NotificationService::current()->Notify(
361 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
362 content::Source<WebContents>(web_contents()),
363 content::NotificationService::NoDetails());
367 void TabSpecificContentSettings::OnCookiesRead(
368 const GURL& url,
369 const GURL& frame_url,
370 const net::CookieList& cookie_list,
371 bool blocked_by_policy) {
372 if (cookie_list.empty())
373 return;
374 if (blocked_by_policy) {
375 blocked_local_shared_objects_.cookies()->AddReadCookies(
376 frame_url, url, cookie_list);
377 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
378 } else {
379 allowed_local_shared_objects_.cookies()->AddReadCookies(
380 frame_url, url, cookie_list);
381 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
384 NotifySiteDataObservers();
387 void TabSpecificContentSettings::OnCookieChanged(
388 const GURL& url,
389 const GURL& frame_url,
390 const std::string& cookie_line,
391 const net::CookieOptions& options,
392 bool blocked_by_policy) {
393 if (blocked_by_policy) {
394 blocked_local_shared_objects_.cookies()->AddChangedCookie(
395 frame_url, url, cookie_line, options);
396 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
397 } else {
398 allowed_local_shared_objects_.cookies()->AddChangedCookie(
399 frame_url, url, cookie_line, options);
400 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
403 NotifySiteDataObservers();
406 void TabSpecificContentSettings::OnIndexedDBAccessed(
407 const GURL& url,
408 const base::string16& description,
409 bool blocked_by_policy) {
410 if (blocked_by_policy) {
411 blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
412 url, description);
413 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
414 } else {
415 allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
416 url, description);
417 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
420 NotifySiteDataObservers();
423 void TabSpecificContentSettings::OnLocalStorageAccessed(
424 const GURL& url,
425 bool local,
426 bool blocked_by_policy) {
427 LocalSharedObjectsContainer& container = blocked_by_policy ?
428 blocked_local_shared_objects_ : allowed_local_shared_objects_;
429 CannedBrowsingDataLocalStorageHelper* helper =
430 local ? container.local_storages() : container.session_storages();
431 helper->AddLocalStorage(url);
433 if (blocked_by_policy)
434 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
435 else
436 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
438 NotifySiteDataObservers();
441 void TabSpecificContentSettings::OnWebDatabaseAccessed(
442 const GURL& url,
443 const base::string16& name,
444 const base::string16& display_name,
445 bool blocked_by_policy) {
446 if (blocked_by_policy) {
447 blocked_local_shared_objects_.databases()->AddDatabase(
448 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
449 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
450 } else {
451 allowed_local_shared_objects_.databases()->AddDatabase(
452 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
453 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
456 NotifySiteDataObservers();
459 void TabSpecificContentSettings::OnFileSystemAccessed(
460 const GURL& url,
461 bool blocked_by_policy) {
462 if (blocked_by_policy) {
463 blocked_local_shared_objects_.file_systems()->AddFileSystem(
464 url, storage::kFileSystemTypeTemporary, 0);
465 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
466 } else {
467 allowed_local_shared_objects_.file_systems()->AddFileSystem(
468 url, storage::kFileSystemTypeTemporary, 0);
469 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
472 NotifySiteDataObservers();
475 void TabSpecificContentSettings::OnGeolocationPermissionSet(
476 const GURL& requesting_origin,
477 bool allowed) {
478 geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
479 content::NotificationService::current()->Notify(
480 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
481 content::Source<WebContents>(web_contents()),
482 content::NotificationService::NoDetails());
485 #if defined(OS_ANDROID)
486 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
487 const GURL& requesting_origin,
488 bool allowed) {
489 if (allowed) {
490 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
491 } else {
492 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
495 #endif
497 TabSpecificContentSettings::MicrophoneCameraState
498 TabSpecificContentSettings::GetMicrophoneCameraState() const {
499 MicrophoneCameraState state = microphone_camera_state_;
501 // Include capture devices in the state if there are still consumers of the
502 // approved media stream.
503 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
504 MediaCaptureDevicesDispatcher::GetInstance()->
505 GetMediaStreamCaptureIndicator();
506 if (media_indicator->IsCapturingAudio(web_contents()))
507 state |= MICROPHONE_ACCESSED;
508 if (media_indicator->IsCapturingVideo(web_contents()))
509 state |= CAMERA_ACCESSED;
511 return state;
514 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
515 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
516 ((microphone_camera_state_& MICROPHONE_BLOCKED) ?
517 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) :
518 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)))
519 return true;
521 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
522 ((microphone_camera_state_ & CAMERA_BLOCKED) ?
523 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) :
524 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)))
525 return true;
527 PrefService* prefs =
528 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
529 GetPrefs();
530 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
531 MediaCaptureDevicesDispatcher::GetInstance()->
532 GetMediaStreamCaptureIndicator();
534 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
535 prefs->GetString(prefs::kDefaultAudioCaptureDevice) !=
536 media_stream_selected_audio_device() &&
537 media_indicator->IsCapturingAudio(web_contents()))
538 return true;
540 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
541 prefs->GetString(prefs::kDefaultVideoCaptureDevice) !=
542 media_stream_selected_video_device() &&
543 media_indicator->IsCapturingVideo(web_contents()))
544 return true;
546 return false;
549 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
550 const GURL& request_origin,
551 MicrophoneCameraState new_microphone_camera_state,
552 const std::string& media_stream_selected_audio_device,
553 const std::string& media_stream_selected_video_device,
554 const std::string& media_stream_requested_audio_device,
555 const std::string& media_stream_requested_video_device) {
556 media_stream_access_origin_ = request_origin;
558 if (new_microphone_camera_state & MICROPHONE_ACCESSED) {
559 media_stream_requested_audio_device_ = media_stream_requested_audio_device;
560 media_stream_selected_audio_device_ = media_stream_selected_audio_device;
561 bool mic_blocked = (new_microphone_camera_state & MICROPHONE_BLOCKED) != 0;
562 content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = !mic_blocked;
563 content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = mic_blocked;
566 if (new_microphone_camera_state & CAMERA_ACCESSED) {
567 media_stream_requested_video_device_ = media_stream_requested_video_device;
568 media_stream_selected_video_device_ = media_stream_selected_video_device;
569 bool cam_blocked = (new_microphone_camera_state & CAMERA_BLOCKED) != 0;
570 content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = !cam_blocked;
571 content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = cam_blocked;
574 if (microphone_camera_state_ != new_microphone_camera_state) {
575 microphone_camera_state_ = new_microphone_camera_state;
576 content::NotificationService::current()->Notify(
577 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
578 content::Source<WebContents>(web_contents()),
579 content::NotificationService::NoDetails());
583 void TabSpecificContentSettings::OnMidiSysExAccessed(
584 const GURL& requesting_origin) {
585 midi_usages_state_.OnPermissionSet(requesting_origin, true);
586 OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
589 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
590 const GURL& requesting_origin) {
591 midi_usages_state_.OnPermissionSet(requesting_origin, false);
592 OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
595 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
596 for (size_t i = 0; i < arraysize(content_blocked_); ++i) {
597 if (i == CONTENT_SETTINGS_TYPE_COOKIES)
598 continue;
599 content_blocked_[i] = false;
600 content_allowed_[i] = false;
601 content_blockage_indicated_to_user_[i] = false;
603 microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED;
604 load_plugins_link_enabled_ = true;
605 content::NotificationService::current()->Notify(
606 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
607 content::Source<WebContents>(web_contents()),
608 content::NotificationService::NoDetails());
611 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
612 blocked_local_shared_objects_.Reset();
613 allowed_local_shared_objects_.Reset();
614 content_blocked_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
615 content_allowed_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
616 content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
617 content::NotificationService::current()->Notify(
618 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
619 content::Source<WebContents>(web_contents()),
620 content::NotificationService::NoDetails());
623 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked) {
624 content_blocked_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = blocked;
625 content_allowed_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = !blocked;
626 content_blockage_indicated_to_user_[
627 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = false;
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::SetPopupsBlocked(bool blocked) {
635 content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked;
636 content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false;
637 content::NotificationService::current()->Notify(
638 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
639 content::Source<WebContents>(web_contents()),
640 content::NotificationService::NoDetails());
643 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
644 if (allowed) {
645 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
646 } else {
647 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
651 void TabSpecificContentSettings::OnContentSettingChanged(
652 const ContentSettingsPattern& primary_pattern,
653 const ContentSettingsPattern& secondary_pattern,
654 ContentSettingsType content_type,
655 std::string resource_identifier) {
656 const ContentSettingsDetails details(
657 primary_pattern, secondary_pattern, content_type, resource_identifier);
658 const NavigationController& controller = web_contents()->GetController();
659 NavigationEntry* entry = controller.GetVisibleEntry();
660 GURL entry_url;
661 if (entry)
662 entry_url = entry->GetURL();
663 if (details.update_all() ||
664 // The visible NavigationEntry is the URL in the URL field of a tab.
665 // Currently this should be matched by the |primary_pattern|.
666 details.primary_pattern().Matches(entry_url)) {
667 Profile* profile =
668 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
669 const HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
671 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
672 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
673 const GURL media_origin = media_stream_access_origin();
674 ContentSetting setting = map->GetContentSetting(media_origin,
675 media_origin,
676 content_type,
677 std::string());
678 content_allowed_[content_type] = setting == CONTENT_SETTING_ALLOW;
679 content_blocked_[content_type] = setting == CONTENT_SETTING_BLOCK;
681 RendererContentSettingRules rules;
682 GetRendererContentSettingRules(map, &rules);
683 Send(new ChromeViewMsg_SetContentSettingRules(rules));
687 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
688 content::RenderFrameHost* render_frame_host) {
689 // We want to tell the renderer-side code to ignore content settings for this
690 // page.
691 render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial(
692 render_frame_host->GetRoutingID()));
695 bool TabSpecificContentSettings::OnMessageReceived(
696 const IPC::Message& message,
697 content::RenderFrameHost* render_frame_host) {
698 bool handled = true;
699 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message)
700 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked)
701 IPC_MESSAGE_UNHANDLED(handled = false)
702 IPC_END_MESSAGE_MAP()
703 return handled;
706 void TabSpecificContentSettings::DidNavigateMainFrame(
707 const content::LoadCommittedDetails& details,
708 const content::FrameNavigateParams& params) {
709 if (!details.is_in_page) {
710 // Clear "blocked" flags.
711 ClearBlockedContentSettingsExceptForCookies();
712 GeolocationDidNavigate(details);
713 MidiDidNavigate(details);
717 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
718 content::RenderFrameHost* render_frame_host,
719 const GURL& validated_url,
720 bool is_error_page,
721 bool is_iframe_srcdoc) {
722 if (render_frame_host->GetParent())
723 return;
725 // If we're displaying a network error page do not reset the content
726 // settings delegate's cookies so the user has a chance to modify cookie
727 // settings.
728 if (!is_error_page)
729 ClearCookieSpecificContentSettings();
730 ClearGeolocationContentSettings();
731 ClearMidiContentSettings();
732 ClearPendingProtocolHandler();
735 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
736 bool blocked_by_policy) {
737 if (blocked_by_policy) {
738 blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
739 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
740 } else {
741 allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
742 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
746 void TabSpecificContentSettings::AddSiteDataObserver(
747 SiteDataObserver* observer) {
748 observer_list_.AddObserver(observer);
751 void TabSpecificContentSettings::RemoveSiteDataObserver(
752 SiteDataObserver* observer) {
753 observer_list_.RemoveObserver(observer);
756 void TabSpecificContentSettings::NotifySiteDataObservers() {
757 FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
760 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
761 geolocation_usages_state_.ClearStateMap();
764 void TabSpecificContentSettings::ClearMidiContentSettings() {
765 midi_usages_state_.ClearStateMap();
768 void TabSpecificContentSettings::GeolocationDidNavigate(
769 const content::LoadCommittedDetails& details) {
770 geolocation_usages_state_.DidNavigate(details);
773 void TabSpecificContentSettings::MidiDidNavigate(
774 const content::LoadCommittedDetails& details) {
775 midi_usages_state_.DidNavigate(details);