Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / content_settings / tab_specific_content_settings.cc
blobd52e41d19b0c58e9e29c09dab70820ce11dffb55
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/utf_string_conversions.h"
13 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
14 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
15 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
19 #include "chrome/browser/browsing_data/cookies_tree_model.h"
20 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/content_settings/content_settings_utils.h"
22 #include "chrome/browser/content_settings/host_content_settings_map.h"
23 #include "chrome/browser/media/media_stream_capture_indicator.h"
24 #include "chrome/browser/prerender/prerender_manager.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/core/browser/content_settings_details.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/navigation_controller.h"
32 #include "content/public/browser/navigation_details.h"
33 #include "content/public/browser/navigation_entry.h"
34 #include "content/public/browser/notification_registrar.h"
35 #include "content/public/browser/notification_service.h"
36 #include "content/public/browser/render_frame_host.h"
37 #include "content/public/browser/render_view_host.h"
38 #include "content/public/browser/web_contents.h"
39 #include "content/public/browser/web_contents_delegate.h"
40 #include "net/cookies/canonical_cookie.h"
41 #include "storage/common/fileapi/file_system_types.h"
43 using content::BrowserThread;
44 using content::NavigationController;
45 using content::NavigationEntry;
46 using content::RenderViewHost;
47 using content::WebContents;
49 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
50 STATIC_CONST_MEMBER_DEFINITION const
51 TabSpecificContentSettings::MicrophoneCameraState
52 TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED;
53 STATIC_CONST_MEMBER_DEFINITION const
54 TabSpecificContentSettings::MicrophoneCameraState
55 TabSpecificContentSettings::MICROPHONE_ACCESSED;
56 STATIC_CONST_MEMBER_DEFINITION const
57 TabSpecificContentSettings::MicrophoneCameraState
58 TabSpecificContentSettings::MICROPHONE_BLOCKED;
59 STATIC_CONST_MEMBER_DEFINITION const
60 TabSpecificContentSettings::MicrophoneCameraState
61 TabSpecificContentSettings::CAMERA_ACCESSED;
62 STATIC_CONST_MEMBER_DEFINITION const
63 TabSpecificContentSettings::MicrophoneCameraState
64 TabSpecificContentSettings::CAMERA_BLOCKED;
66 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
67 TabSpecificContentSettings* tab_specific_content_settings)
68 : tab_specific_content_settings_(tab_specific_content_settings) {
69 tab_specific_content_settings_->AddSiteDataObserver(this);
72 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
73 if (tab_specific_content_settings_)
74 tab_specific_content_settings_->RemoveSiteDataObserver(this);
77 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
78 tab_specific_content_settings_ = NULL;
81 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
82 : content::WebContentsObserver(tab),
83 profile_(Profile::FromBrowserContext(tab->GetBrowserContext())),
84 allowed_local_shared_objects_(profile_),
85 blocked_local_shared_objects_(profile_),
86 geolocation_usages_state_(profile_, CONTENT_SETTINGS_TYPE_GEOLOCATION),
87 midi_usages_state_(profile_, CONTENT_SETTINGS_TYPE_MIDI_SYSEX),
88 pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
89 previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
90 pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
91 load_plugins_link_enabled_(true),
92 microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED),
93 observer_(this) {
94 ClearBlockedContentSettingsExceptForCookies();
95 ClearCookieSpecificContentSettings();
97 observer_.Add(profile_->GetHostContentSettingsMap());
100 TabSpecificContentSettings::~TabSpecificContentSettings() {
101 FOR_EACH_OBSERVER(
102 SiteDataObserver, observer_list_, ContentSettingsDestroyed());
105 TabSpecificContentSettings* TabSpecificContentSettings::Get(
106 int render_process_id, int render_view_id) {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 RenderViewHost* view = RenderViewHost::FromID(render_process_id,
110 render_view_id);
111 if (!view)
112 return NULL;
114 WebContents* web_contents = WebContents::FromRenderViewHost(view);
115 if (!web_contents)
116 return NULL;
118 return TabSpecificContentSettings::FromWebContents(web_contents);
121 TabSpecificContentSettings* TabSpecificContentSettings::GetForFrame(
122 int render_process_id, int render_frame_id) {
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
126 render_process_id, render_frame_id);
127 WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
128 if (!web_contents)
129 return NULL;
131 return TabSpecificContentSettings::FromWebContents(web_contents);
134 // static
135 void TabSpecificContentSettings::CookiesRead(int render_process_id,
136 int render_frame_id,
137 const GURL& url,
138 const GURL& frame_url,
139 const net::CookieList& cookie_list,
140 bool blocked_by_policy,
141 bool is_for_blocking_resource) {
142 DCHECK(BrowserThread::CurrentlyOn(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);
149 prerender::PrerenderManager::RecordCookieEvent(
150 render_process_id,
151 render_frame_id,
152 url,
153 frame_url,
154 is_for_blocking_resource,
155 prerender::PrerenderContents::COOKIE_EVENT_SEND,
156 &cookie_list);
159 // static
160 void TabSpecificContentSettings::CookieChanged(
161 int render_process_id,
162 int render_frame_id,
163 const GURL& url,
164 const GURL& frame_url,
165 const std::string& cookie_line,
166 const net::CookieOptions& options,
167 bool blocked_by_policy) {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
169 TabSpecificContentSettings* settings =
170 GetForFrame(render_process_id, render_frame_id);
171 if (settings)
172 settings->OnCookieChanged(url, frame_url, cookie_line, options,
173 blocked_by_policy);
174 prerender::PrerenderManager::RecordCookieEvent(
175 render_process_id,
176 render_frame_id,
177 url,
178 frame_url,
179 false /*is_critical_request*/,
180 prerender::PrerenderContents::COOKIE_EVENT_CHANGE,
181 NULL);
184 // static
185 void TabSpecificContentSettings::WebDatabaseAccessed(
186 int render_process_id,
187 int render_frame_id,
188 const GURL& url,
189 const base::string16& name,
190 const base::string16& display_name,
191 bool blocked_by_policy) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 TabSpecificContentSettings* settings = GetForFrame(
194 render_process_id, render_frame_id);
195 if (settings)
196 settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy);
199 // static
200 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id,
201 int render_frame_id,
202 const GURL& url,
203 bool local,
204 bool blocked_by_policy) {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
206 TabSpecificContentSettings* settings = GetForFrame(
207 render_process_id, render_frame_id);
208 if (settings)
209 settings->OnLocalStorageAccessed(url, local, blocked_by_policy);
212 // static
213 void TabSpecificContentSettings::IndexedDBAccessed(
214 int render_process_id,
215 int render_frame_id,
216 const GURL& url,
217 const base::string16& description,
218 bool blocked_by_policy) {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 TabSpecificContentSettings* settings = GetForFrame(
221 render_process_id, render_frame_id);
222 if (settings)
223 settings->OnIndexedDBAccessed(url, description, blocked_by_policy);
226 // static
227 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id,
228 int render_frame_id,
229 const GURL& url,
230 bool blocked_by_policy) {
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
232 TabSpecificContentSettings* settings = GetForFrame(
233 render_process_id, render_frame_id);
234 if (settings)
235 settings->OnFileSystemAccessed(url, blocked_by_policy);
238 bool TabSpecificContentSettings::IsContentBlocked(
239 ContentSettingsType content_type) const {
240 DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
241 << "Geolocation settings handled by ContentSettingGeolocationImageModel";
242 DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
243 << "Notifications settings handled by "
244 << "ContentSettingsNotificationsImageModel";
246 if (content_type == CONTENT_SETTINGS_TYPE_IMAGES ||
247 content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT ||
248 content_type == CONTENT_SETTINGS_TYPE_PLUGINS ||
249 content_type == CONTENT_SETTINGS_TYPE_COOKIES ||
250 content_type == CONTENT_SETTINGS_TYPE_POPUPS ||
251 content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
252 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
253 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
254 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
255 content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
256 content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS ||
257 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
258 return content_blocked_[content_type];
261 return false;
264 bool TabSpecificContentSettings::IsBlockageIndicated(
265 ContentSettingsType content_type) const {
266 return content_blockage_indicated_to_user_[content_type];
269 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
270 ContentSettingsType content_type) {
271 content_blockage_indicated_to_user_[content_type] = true;
274 bool TabSpecificContentSettings::IsContentAllowed(
275 ContentSettingsType content_type) const {
276 // This method currently only returns meaningful values for the content type
277 // cookies, mediastream, PPAPI broker, and downloads.
278 if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
279 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
280 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
281 content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
282 content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
283 content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS &&
284 content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
285 return false;
288 return content_allowed_[content_type];
291 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) {
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 (!content_blocked_[type]) {
321 content_blocked_[type] = true;
322 // TODO: it would be nice to have a way of mocking this in tests.
323 content::NotificationService::current()->Notify(
324 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
325 content::Source<WebContents>(web_contents()),
326 content::NotificationService::NoDetails());
330 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) {
331 DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
332 << "Geolocation settings handled by OnGeolocationPermissionSet";
333 DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
334 type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
335 << "Media stream settings handled by OnMediaStreamPermissionSet";
336 bool access_changed = false;
337 #if defined(OS_ANDROID)
338 if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
339 content_blocked_[type]) {
340 // content_allowed_[type] is always set to true in OnContentBlocked, so we
341 // have to use content_blocked_ to detect whether the protected media
342 // setting has changed.
343 content_blocked_[type] = false;
344 access_changed = true;
346 #endif
348 if (!content_allowed_[type]) {
349 content_allowed_[type] = true;
350 access_changed = true;
353 if (access_changed) {
354 content::NotificationService::current()->Notify(
355 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
356 content::Source<WebContents>(web_contents()),
357 content::NotificationService::NoDetails());
361 void TabSpecificContentSettings::OnCookiesRead(
362 const GURL& url,
363 const GURL& frame_url,
364 const net::CookieList& cookie_list,
365 bool blocked_by_policy) {
366 if (cookie_list.empty())
367 return;
368 if (blocked_by_policy) {
369 blocked_local_shared_objects_.cookies()->AddReadCookies(
370 frame_url, url, cookie_list);
371 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
372 } else {
373 allowed_local_shared_objects_.cookies()->AddReadCookies(
374 frame_url, url, cookie_list);
375 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
378 NotifySiteDataObservers();
381 void TabSpecificContentSettings::OnCookieChanged(
382 const GURL& url,
383 const GURL& frame_url,
384 const std::string& cookie_line,
385 const net::CookieOptions& options,
386 bool blocked_by_policy) {
387 if (blocked_by_policy) {
388 blocked_local_shared_objects_.cookies()->AddChangedCookie(
389 frame_url, url, cookie_line, options);
390 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
391 } else {
392 allowed_local_shared_objects_.cookies()->AddChangedCookie(
393 frame_url, url, cookie_line, options);
394 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
397 NotifySiteDataObservers();
400 void TabSpecificContentSettings::OnIndexedDBAccessed(
401 const GURL& url,
402 const base::string16& description,
403 bool blocked_by_policy) {
404 if (blocked_by_policy) {
405 blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
406 url, description);
407 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
408 } else {
409 allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
410 url, description);
411 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
414 NotifySiteDataObservers();
417 void TabSpecificContentSettings::OnLocalStorageAccessed(
418 const GURL& url,
419 bool local,
420 bool blocked_by_policy) {
421 LocalSharedObjectsContainer& container = blocked_by_policy ?
422 blocked_local_shared_objects_ : allowed_local_shared_objects_;
423 CannedBrowsingDataLocalStorageHelper* helper =
424 local ? container.local_storages() : container.session_storages();
425 helper->AddLocalStorage(url);
427 if (blocked_by_policy)
428 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
429 else
430 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
432 NotifySiteDataObservers();
435 void TabSpecificContentSettings::OnWebDatabaseAccessed(
436 const GURL& url,
437 const base::string16& name,
438 const base::string16& display_name,
439 bool blocked_by_policy) {
440 if (blocked_by_policy) {
441 blocked_local_shared_objects_.databases()->AddDatabase(
442 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
443 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
444 } else {
445 allowed_local_shared_objects_.databases()->AddDatabase(
446 url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
447 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
450 NotifySiteDataObservers();
453 void TabSpecificContentSettings::OnFileSystemAccessed(
454 const GURL& url,
455 bool blocked_by_policy) {
456 if (blocked_by_policy) {
457 blocked_local_shared_objects_.file_systems()->AddFileSystem(
458 url, storage::kFileSystemTypeTemporary, 0);
459 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
460 } else {
461 allowed_local_shared_objects_.file_systems()->AddFileSystem(
462 url, storage::kFileSystemTypeTemporary, 0);
463 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
466 NotifySiteDataObservers();
469 void TabSpecificContentSettings::OnGeolocationPermissionSet(
470 const GURL& requesting_origin,
471 bool allowed) {
472 geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
473 content::NotificationService::current()->Notify(
474 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
475 content::Source<WebContents>(web_contents()),
476 content::NotificationService::NoDetails());
479 #if defined(OS_ANDROID)
480 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
481 const GURL& requesting_origin,
482 bool allowed) {
483 if (allowed) {
484 OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
485 } else {
486 OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
489 #endif
491 TabSpecificContentSettings::MicrophoneCameraState
492 TabSpecificContentSettings::GetMicrophoneCameraState() const {
493 return microphone_camera_state_;
496 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
497 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
498 ((microphone_camera_state_& MICROPHONE_BLOCKED) ?
499 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) :
500 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)))
501 return true;
503 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
504 ((microphone_camera_state_ & CAMERA_BLOCKED) ?
505 !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) :
506 !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)))
507 return true;
509 PrefService* prefs =
510 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
511 GetPrefs();
512 scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
513 MediaCaptureDevicesDispatcher::GetInstance()->
514 GetMediaStreamCaptureIndicator();
516 if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
517 prefs->GetString(prefs::kDefaultAudioCaptureDevice) !=
518 media_stream_selected_audio_device() &&
519 media_indicator->IsCapturingAudio(web_contents()))
520 return true;
522 if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
523 prefs->GetString(prefs::kDefaultVideoCaptureDevice) !=
524 media_stream_selected_video_device() &&
525 media_indicator->IsCapturingVideo(web_contents()))
526 return true;
528 return false;
531 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
532 const GURL& request_origin,
533 const MediaStreamDevicesController::MediaStreamTypeSettingsMap&
534 request_permissions) {
535 media_stream_access_origin_ = request_origin;
536 MicrophoneCameraState prev_microphone_camera_state = microphone_camera_state_;
537 microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED;
539 PrefService* prefs =
540 Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
541 GetPrefs();
542 MediaStreamDevicesController::MediaStreamTypeSettingsMap::const_iterator it =
543 request_permissions.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
544 if (it != request_permissions.end()) {
545 media_stream_requested_audio_device_ = it->second.requested_device_id;
546 media_stream_selected_audio_device_ =
547 media_stream_requested_audio_device_.empty() ?
548 prefs->GetString(prefs::kDefaultAudioCaptureDevice) :
549 media_stream_requested_audio_device_;
550 DCHECK_NE(MediaStreamDevicesController::MEDIA_NONE, it->second.permission);
551 bool mic_allowed =
552 it->second.permission == MediaStreamDevicesController::MEDIA_ALLOWED;
553 content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = mic_allowed;
554 content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = !mic_allowed;
555 microphone_camera_state_ |=
556 MICROPHONE_ACCESSED | (mic_allowed ? 0 : MICROPHONE_BLOCKED);
559 it = request_permissions.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
560 if (it != request_permissions.end()) {
561 media_stream_requested_video_device_ = it->second.requested_device_id;
562 media_stream_selected_video_device_ =
563 media_stream_requested_video_device_.empty() ?
564 prefs->GetString(prefs::kDefaultVideoCaptureDevice) :
565 media_stream_requested_video_device_;
566 DCHECK_NE(MediaStreamDevicesController::MEDIA_NONE, it->second.permission);
567 bool cam_allowed =
568 it->second.permission == MediaStreamDevicesController::MEDIA_ALLOWED;
569 content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = cam_allowed;
570 content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = !cam_allowed;
571 microphone_camera_state_ |=
572 CAMERA_ACCESSED | (cam_allowed ? 0 : CAMERA_BLOCKED);
575 if (microphone_camera_state_ != prev_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::GeolocationDidNavigate(
644 const content::LoadCommittedDetails& details) {
645 geolocation_usages_state_.DidNavigate(details);
648 void TabSpecificContentSettings::MidiDidNavigate(
649 const content::LoadCommittedDetails& details) {
650 midi_usages_state_.DidNavigate(details);
653 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
654 geolocation_usages_state_.ClearStateMap();
657 void TabSpecificContentSettings::ClearMidiContentSettings() {
658 midi_usages_state_.ClearStateMap();
661 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
662 if (allowed) {
663 OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
664 } else {
665 OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
669 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
670 content::RenderFrameHost* render_frame_host) {
671 // We want to tell the renderer-side code to ignore content settings for this
672 // page.
673 render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial(
674 render_frame_host->GetRoutingID()));
677 bool TabSpecificContentSettings::OnMessageReceived(
678 const IPC::Message& message,
679 content::RenderFrameHost* render_frame_host) {
680 bool handled = true;
681 IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message)
682 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked)
683 IPC_MESSAGE_UNHANDLED(handled = false)
684 IPC_END_MESSAGE_MAP()
685 return handled;
688 void TabSpecificContentSettings::DidNavigateMainFrame(
689 const content::LoadCommittedDetails& details,
690 const content::FrameNavigateParams& params) {
691 if (!details.is_in_page) {
692 // Clear "blocked" flags.
693 ClearBlockedContentSettingsExceptForCookies();
694 GeolocationDidNavigate(details);
695 MidiDidNavigate(details);
699 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
700 content::RenderFrameHost* render_frame_host,
701 const GURL& validated_url,
702 bool is_error_page,
703 bool is_iframe_srcdoc) {
704 if (render_frame_host->GetParent())
705 return;
707 // If we're displaying a network error page do not reset the content
708 // settings delegate's cookies so the user has a chance to modify cookie
709 // settings.
710 if (!is_error_page)
711 ClearCookieSpecificContentSettings();
712 ClearGeolocationContentSettings();
713 ClearMidiContentSettings();
714 ClearPendingProtocolHandler();
717 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
718 bool blocked_by_policy) {
719 if (blocked_by_policy) {
720 blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
721 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
722 } else {
723 allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
724 OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
728 void TabSpecificContentSettings::OnContentSettingChanged(
729 const ContentSettingsPattern& primary_pattern,
730 const ContentSettingsPattern& secondary_pattern,
731 ContentSettingsType content_type,
732 std::string resource_identifier) {
733 const ContentSettingsDetails details(
734 primary_pattern, secondary_pattern, content_type, resource_identifier);
735 const NavigationController& controller = web_contents()->GetController();
736 NavigationEntry* entry = controller.GetVisibleEntry();
737 GURL entry_url;
738 if (entry)
739 entry_url = entry->GetURL();
740 if (details.update_all() ||
741 // The visible NavigationEntry is the URL in the URL field of a tab.
742 // Currently this should be matched by the |primary_pattern|.
743 details.primary_pattern().Matches(entry_url)) {
744 Profile* profile =
745 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
746 const HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
748 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
749 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
750 const GURL media_origin = media_stream_access_origin();
751 ContentSetting setting = map->GetContentSetting(media_origin,
752 media_origin,
753 content_type,
754 std::string());
755 content_allowed_[content_type] = setting == CONTENT_SETTING_ALLOW;
756 content_blocked_[content_type] = setting == CONTENT_SETTING_BLOCK;
758 RendererContentSettingRules rules;
759 GetRendererContentSettingRules(map, &rules);
760 Send(new ChromeViewMsg_SetContentSettingRules(rules));
764 void TabSpecificContentSettings::AddSiteDataObserver(
765 SiteDataObserver* observer) {
766 observer_list_.AddObserver(observer);
769 void TabSpecificContentSettings::RemoveSiteDataObserver(
770 SiteDataObserver* observer) {
771 observer_list_.RemoveObserver(observer);
774 void TabSpecificContentSettings::NotifySiteDataObservers() {
775 FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());