Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / content_settings / tab_specific_content_settings.cc
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.
4
5 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
6
7 #include <list>
8
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"
43
44 using content::BrowserThread;
45 using content::NavigationController;
46 using content::NavigationEntry;
47 using content::RenderViewHost;
48 using content::WebContents;
49
50 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
51 STATIC_CONST_MEMBER_DEFINITION const
52     TabSpecificContentSettings::MicrophoneCameraState
53     TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED;
54 STATIC_CONST_MEMBER_DEFINITION const
55     TabSpecificContentSettings::MicrophoneCameraState
56     TabSpecificContentSettings::MICROPHONE_ACCESSED;
57 STATIC_CONST_MEMBER_DEFINITION const
58     TabSpecificContentSettings::MicrophoneCameraState
59     TabSpecificContentSettings::MICROPHONE_BLOCKED;
60 STATIC_CONST_MEMBER_DEFINITION const
61     TabSpecificContentSettings::MicrophoneCameraState
62     TabSpecificContentSettings::CAMERA_ACCESSED;
63 STATIC_CONST_MEMBER_DEFINITION const
64     TabSpecificContentSettings::MicrophoneCameraState
65     TabSpecificContentSettings::CAMERA_BLOCKED;
66
67 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
68     TabSpecificContentSettings* tab_specific_content_settings)
69     : tab_specific_content_settings_(tab_specific_content_settings) {
70   tab_specific_content_settings_->AddSiteDataObserver(this);
71 }
72
73 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
74   if (tab_specific_content_settings_)
75     tab_specific_content_settings_->RemoveSiteDataObserver(this);
76 }
77
78 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
79   tab_specific_content_settings_ = NULL;
80 }
81
82 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
83     : content::WebContentsObserver(tab),
84       allowed_local_shared_objects_(
85           Profile::FromBrowserContext(tab->GetBrowserContext())),
86       blocked_local_shared_objects_(
87           Profile::FromBrowserContext(tab->GetBrowserContext())),
88       geolocation_usages_state_(
89           Profile::FromBrowserContext(tab->GetBrowserContext())
90               ->GetHostContentSettingsMap(),
91           Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs(),
92           CONTENT_SETTINGS_TYPE_GEOLOCATION),
93       midi_usages_state_(
94           Profile::FromBrowserContext(tab->GetBrowserContext())
95               ->GetHostContentSettingsMap(),
96           Profile::FromBrowserContext(tab->GetBrowserContext())->GetPrefs(),
97           CONTENT_SETTINGS_TYPE_MIDI_SYSEX),
98       pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
99       previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
100       pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
101       load_plugins_link_enabled_(true),
102       microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED),
103       observer_(this) {
104   ClearBlockedContentSettingsExceptForCookies();
105   ClearCookieSpecificContentSettings();
106
107   observer_.Add(Profile::FromBrowserContext(tab->GetBrowserContext())
108                     ->GetHostContentSettingsMap());
109 }
110
111 TabSpecificContentSettings::~TabSpecificContentSettings() {
112   FOR_EACH_OBSERVER(
113       SiteDataObserver, observer_list_, ContentSettingsDestroyed());
114 }
115
116 void TabSpecificContentSettings::RecordMixedScriptAction(
117     MixedScriptAction action) {
118   UMA_HISTOGRAM_ENUMERATION("ContentSettings.MixedScript",
119                             action,
120                             MIXED_SCRIPT_ACTION_COUNT);
121 }
122
123 TabSpecificContentSettings* TabSpecificContentSettings::Get(
124     int render_process_id, int render_view_id) {
125   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126
127   RenderViewHost* view = RenderViewHost::FromID(render_process_id,
128                                                 render_view_id);
129   if (!view)
130     return NULL;
131
132   WebContents* web_contents = WebContents::FromRenderViewHost(view);
133   if (!web_contents)
134     return NULL;
135
136   return TabSpecificContentSettings::FromWebContents(web_contents);
137 }
138
139 TabSpecificContentSettings* TabSpecificContentSettings::GetForFrame(
140     int render_process_id, int render_frame_id) {
141   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
142
143   content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
144       render_process_id, render_frame_id);
145   WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
146   if (!web_contents)
147     return NULL;
148
149   return TabSpecificContentSettings::FromWebContents(web_contents);
150 }
151
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);
166   }
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);
175 }
176
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);
200 }
201
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);
215 }
216
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);
228 }
229
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);
242 }
243
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);
254 }
255
256 bool TabSpecificContentSettings::IsContentBlocked(
257     ContentSettingsType content_type) const {
258   DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
259       << "Geolocation settings handled by ContentSettingGeolocationImageModel";
260   DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
261       << "Notifications settings handled by "
262       << "ContentSettingsNotificationsImageModel";
263
264   if (content_type == CONTENT_SETTINGS_TYPE_IMAGES ||
265       content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT ||
266       content_type == CONTENT_SETTINGS_TYPE_PLUGINS ||
267       content_type == CONTENT_SETTINGS_TYPE_COOKIES ||
268       content_type == CONTENT_SETTINGS_TYPE_POPUPS ||
269       content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
270       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
271       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
272       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
273       content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
274       content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS ||
275       content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
276     return content_blocked_[content_type];
277   }
278
279   return false;
280 }
281
282 bool TabSpecificContentSettings::IsBlockageIndicated(
283     ContentSettingsType content_type) const {
284   return content_blockage_indicated_to_user_[content_type];
285 }
286
287 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
288     ContentSettingsType content_type) {
289   content_blockage_indicated_to_user_[content_type] = true;
290 }
291
292 bool TabSpecificContentSettings::IsContentAllowed(
293     ContentSettingsType content_type) const {
294   // This method currently only returns meaningful values for the content type
295   // cookies, mediastream, PPAPI broker, and downloads.
296   if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
297       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
298       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
299       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
300       content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
301       content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS &&
302       content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
303     return false;
304   }
305
306   return content_allowed_[content_type];
307 }
308
309 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) {
310   DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
311       << "Geolocation settings handled by OnGeolocationPermissionSet";
312   DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
313          type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
314       << "Media stream settings handled by OnMediaStreamPermissionSet";
315   if (type < 0 || type >= CONTENT_SETTINGS_NUM_TYPES)
316     return;
317
318   // TODO(robwu): Should this be restricted to cookies only?
319   // In the past, content_allowed_ was set to false, but this logic was inverted
320   // in https://codereview.chromium.org/13375004 to fix an issue with the cookie
321   // permission UI. This unconditional assignment seems incorrect, because the
322   // flag will now always be true after calling either OnContentBlocked or
323   // OnContentAllowed. Consequently IsContentAllowed will always return true
324   // for every supported setting that is not handled elsewhere.
325   content_allowed_[type] = true;
326
327 #if defined(OS_ANDROID)
328   if (type == CONTENT_SETTINGS_TYPE_POPUPS) {
329     // For Android we do not have a persistent button that will always be
330     // visible for blocked popups.  Instead we have info bars which could be
331     // dismissed.  Have to clear the blocked state so we properly notify the
332     // relevant pieces again.
333     content_blocked_[type] = false;
334     content_blockage_indicated_to_user_[type] = false;
335   }
336 #endif
337
338   if (!content_blocked_[type]) {
339     content_blocked_[type] = true;
340     // TODO: it would be nice to have a way of mocking this in tests.
341     content::NotificationService::current()->Notify(
342         chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
343         content::Source<WebContents>(web_contents()),
344         content::NotificationService::NoDetails());
345
346     if (type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)
347       RecordMixedScriptAction(MIXED_SCRIPT_ACTION_DISPLAYED_SHIELD);
348   }
349 }
350
351 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) {
352   DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
353       << "Geolocation settings handled by OnGeolocationPermissionSet";
354   DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
355          type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
356       << "Media stream settings handled by OnMediaStreamPermissionSet";
357   bool access_changed = false;
358 #if defined(OS_ANDROID)
359   if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
360     content_blocked_[type]) {
361     // content_allowed_[type] is always set to true in OnContentBlocked, so we
362     // have to use content_blocked_ to detect whether the protected media
363     // setting has changed.
364     content_blocked_[type] = false;
365     access_changed = true;
366   }
367 #endif
368
369   if (!content_allowed_[type]) {
370     content_allowed_[type] = true;
371     access_changed = true;
372   }
373
374   if (access_changed) {
375     content::NotificationService::current()->Notify(
376         chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
377         content::Source<WebContents>(web_contents()),
378         content::NotificationService::NoDetails());
379   }
380 }
381
382 void TabSpecificContentSettings::OnCookiesRead(
383     const GURL& url,
384     const GURL& frame_url,
385     const net::CookieList& cookie_list,
386     bool blocked_by_policy) {
387   if (cookie_list.empty())
388     return;
389   if (blocked_by_policy) {
390     blocked_local_shared_objects_.cookies()->AddReadCookies(
391         frame_url, url, cookie_list);
392     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
393   } else {
394     allowed_local_shared_objects_.cookies()->AddReadCookies(
395         frame_url, url, cookie_list);
396     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
397   }
398
399   NotifySiteDataObservers();
400 }
401
402 void TabSpecificContentSettings::OnCookieChanged(
403     const GURL& url,
404     const GURL& frame_url,
405     const std::string& cookie_line,
406     const net::CookieOptions& options,
407     bool blocked_by_policy) {
408   if (blocked_by_policy) {
409     blocked_local_shared_objects_.cookies()->AddChangedCookie(
410         frame_url, url, cookie_line, options);
411     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
412   } else {
413     allowed_local_shared_objects_.cookies()->AddChangedCookie(
414         frame_url, url, cookie_line, options);
415     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
416   }
417
418   NotifySiteDataObservers();
419 }
420
421 void TabSpecificContentSettings::OnIndexedDBAccessed(
422     const GURL& url,
423     const base::string16& description,
424     bool blocked_by_policy) {
425   if (blocked_by_policy) {
426     blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
427         url, description);
428     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
429   } else {
430     allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
431         url, description);
432     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
433   }
434
435   NotifySiteDataObservers();
436 }
437
438 void TabSpecificContentSettings::OnLocalStorageAccessed(
439     const GURL& url,
440     bool local,
441     bool blocked_by_policy) {
442   LocalSharedObjectsContainer& container = blocked_by_policy ?
443       blocked_local_shared_objects_ : allowed_local_shared_objects_;
444   CannedBrowsingDataLocalStorageHelper* helper =
445       local ? container.local_storages() : container.session_storages();
446   helper->AddLocalStorage(url);
447
448   if (blocked_by_policy)
449     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
450   else
451     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
452
453   NotifySiteDataObservers();
454 }
455
456 void TabSpecificContentSettings::OnWebDatabaseAccessed(
457     const GURL& url,
458     const base::string16& name,
459     const base::string16& display_name,
460     bool blocked_by_policy) {
461   if (blocked_by_policy) {
462     blocked_local_shared_objects_.databases()->AddDatabase(
463         url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
464     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
465   } else {
466     allowed_local_shared_objects_.databases()->AddDatabase(
467         url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
468     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
469   }
470
471   NotifySiteDataObservers();
472 }
473
474 void TabSpecificContentSettings::OnFileSystemAccessed(
475     const GURL& url,
476     bool blocked_by_policy) {
477   if (blocked_by_policy) {
478     blocked_local_shared_objects_.file_systems()->AddFileSystem(
479         url, storage::kFileSystemTypeTemporary, 0);
480     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
481   } else {
482     allowed_local_shared_objects_.file_systems()->AddFileSystem(
483         url, storage::kFileSystemTypeTemporary, 0);
484     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
485   }
486
487   NotifySiteDataObservers();
488 }
489
490 void TabSpecificContentSettings::OnGeolocationPermissionSet(
491     const GURL& requesting_origin,
492     bool allowed) {
493   geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
494   content::NotificationService::current()->Notify(
495       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
496       content::Source<WebContents>(web_contents()),
497       content::NotificationService::NoDetails());
498 }
499
500 #if defined(OS_ANDROID)
501 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
502     const GURL& requesting_origin,
503     bool allowed) {
504   if (allowed) {
505     OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
506   } else {
507     OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
508   }
509 }
510 #endif
511
512 TabSpecificContentSettings::MicrophoneCameraState
513 TabSpecificContentSettings::GetMicrophoneCameraState() const {
514   MicrophoneCameraState state = microphone_camera_state_;
515
516   // Include capture devices in the state if there are still consumers of the
517   // approved media stream.
518   scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
519       MediaCaptureDevicesDispatcher::GetInstance()->
520         GetMediaStreamCaptureIndicator();
521   if (media_indicator->IsCapturingAudio(web_contents()))
522     state |= MICROPHONE_ACCESSED;
523   if (media_indicator->IsCapturingVideo(web_contents()))
524     state |= CAMERA_ACCESSED;
525
526   return state;
527 }
528
529 bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
530   if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
531       ((microphone_camera_state_& MICROPHONE_BLOCKED) ?
532         !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) :
533         !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)))
534     return true;
535
536   if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
537       ((microphone_camera_state_ & CAMERA_BLOCKED) ?
538         !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) :
539         !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)))
540     return true;
541
542   PrefService* prefs =
543       Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
544           GetPrefs();
545   scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
546       MediaCaptureDevicesDispatcher::GetInstance()->
547           GetMediaStreamCaptureIndicator();
548
549   if ((microphone_camera_state_ & MICROPHONE_ACCESSED) &&
550       prefs->GetString(prefs::kDefaultAudioCaptureDevice) !=
551       media_stream_selected_audio_device() &&
552       media_indicator->IsCapturingAudio(web_contents()))
553     return true;
554
555   if ((microphone_camera_state_ & CAMERA_ACCESSED) &&
556       prefs->GetString(prefs::kDefaultVideoCaptureDevice) !=
557       media_stream_selected_video_device() &&
558       media_indicator->IsCapturingVideo(web_contents()))
559     return true;
560
561   return false;
562 }
563
564 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
565     const GURL& request_origin,
566     MicrophoneCameraState new_microphone_camera_state,
567     const std::string& media_stream_selected_audio_device,
568     const std::string& media_stream_selected_video_device,
569     const std::string& media_stream_requested_audio_device,
570     const std::string& media_stream_requested_video_device) {
571   media_stream_access_origin_ = request_origin;
572
573   if (new_microphone_camera_state & MICROPHONE_ACCESSED) {
574     media_stream_requested_audio_device_ = media_stream_requested_audio_device;
575     media_stream_selected_audio_device_ = media_stream_selected_audio_device;
576     bool mic_blocked = (new_microphone_camera_state & MICROPHONE_BLOCKED) != 0;
577     content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = !mic_blocked;
578     content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = mic_blocked;
579   }
580
581   if (new_microphone_camera_state & CAMERA_ACCESSED) {
582     media_stream_requested_video_device_ = media_stream_requested_video_device;
583     media_stream_selected_video_device_ = media_stream_selected_video_device;
584     bool cam_blocked = (new_microphone_camera_state & CAMERA_BLOCKED) != 0;
585     content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = !cam_blocked;
586     content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = cam_blocked;
587   }
588
589   if (microphone_camera_state_ != new_microphone_camera_state) {
590     microphone_camera_state_ = new_microphone_camera_state;
591     content::NotificationService::current()->Notify(
592         chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
593         content::Source<WebContents>(web_contents()),
594         content::NotificationService::NoDetails());
595   }
596 }
597
598 void TabSpecificContentSettings::OnMidiSysExAccessed(
599     const GURL& requesting_origin) {
600   midi_usages_state_.OnPermissionSet(requesting_origin, true);
601   OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
602 }
603
604 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
605     const GURL& requesting_origin) {
606   midi_usages_state_.OnPermissionSet(requesting_origin, false);
607   OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
608 }
609
610 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
611   for (size_t i = 0; i < arraysize(content_blocked_); ++i) {
612     if (i == CONTENT_SETTINGS_TYPE_COOKIES)
613       continue;
614     content_blocked_[i] = false;
615     content_allowed_[i] = false;
616     content_blockage_indicated_to_user_[i] = false;
617   }
618   microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED;
619   load_plugins_link_enabled_ = true;
620   content::NotificationService::current()->Notify(
621       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
622       content::Source<WebContents>(web_contents()),
623       content::NotificationService::NoDetails());
624 }
625
626 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
627   blocked_local_shared_objects_.Reset();
628   allowed_local_shared_objects_.Reset();
629   content_blocked_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
630   content_allowed_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
631   content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
632   content::NotificationService::current()->Notify(
633       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
634       content::Source<WebContents>(web_contents()),
635       content::NotificationService::NoDetails());
636 }
637
638 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked) {
639   content_blocked_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = blocked;
640   content_allowed_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = !blocked;
641   content_blockage_indicated_to_user_[
642     CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = false;
643   content::NotificationService::current()->Notify(
644       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
645       content::Source<WebContents>(web_contents()),
646       content::NotificationService::NoDetails());
647 }
648
649 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked) {
650   content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked;
651   content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false;
652   content::NotificationService::current()->Notify(
653       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
654       content::Source<WebContents>(web_contents()),
655       content::NotificationService::NoDetails());
656 }
657
658 void TabSpecificContentSettings::GeolocationDidNavigate(
659       const content::LoadCommittedDetails& details) {
660   geolocation_usages_state_.DidNavigate(details);
661 }
662
663 void TabSpecificContentSettings::MidiDidNavigate(
664     const content::LoadCommittedDetails& details) {
665   midi_usages_state_.DidNavigate(details);
666 }
667
668 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
669   geolocation_usages_state_.ClearStateMap();
670 }
671
672 void TabSpecificContentSettings::ClearMidiContentSettings() {
673   midi_usages_state_.ClearStateMap();
674 }
675
676 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
677   if (allowed) {
678     OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
679   } else {
680     OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
681   }
682 }
683
684 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
685     content::RenderFrameHost* render_frame_host) {
686   // We want to tell the renderer-side code to ignore content settings for this
687   // page.
688   render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial(
689       render_frame_host->GetRoutingID()));
690 }
691
692 bool TabSpecificContentSettings::OnMessageReceived(
693     const IPC::Message& message,
694     content::RenderFrameHost* render_frame_host) {
695   bool handled = true;
696   IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message)
697     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked)
698     IPC_MESSAGE_UNHANDLED(handled = false)
699   IPC_END_MESSAGE_MAP()
700   return handled;
701 }
702
703 void TabSpecificContentSettings::DidNavigateMainFrame(
704     const content::LoadCommittedDetails& details,
705     const content::FrameNavigateParams& params) {
706   if (!details.is_in_page) {
707     // Clear "blocked" flags.
708     ClearBlockedContentSettingsExceptForCookies();
709     GeolocationDidNavigate(details);
710     MidiDidNavigate(details);
711   }
712 }
713
714 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
715     content::RenderFrameHost* render_frame_host,
716     const GURL& validated_url,
717     bool is_error_page,
718     bool is_iframe_srcdoc) {
719   if (render_frame_host->GetParent())
720     return;
721
722   // If we're displaying a network error page do not reset the content
723   // settings delegate's cookies so the user has a chance to modify cookie
724   // settings.
725   if (!is_error_page)
726     ClearCookieSpecificContentSettings();
727   ClearGeolocationContentSettings();
728   ClearMidiContentSettings();
729   ClearPendingProtocolHandler();
730 }
731
732 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
733                                                   bool blocked_by_policy) {
734   if (blocked_by_policy) {
735     blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
736     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
737   } else {
738     allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
739     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
740   }
741 }
742
743 void TabSpecificContentSettings::OnContentSettingChanged(
744     const ContentSettingsPattern& primary_pattern,
745     const ContentSettingsPattern& secondary_pattern,
746     ContentSettingsType content_type,
747     std::string resource_identifier) {
748   const ContentSettingsDetails details(
749       primary_pattern, secondary_pattern, content_type, resource_identifier);
750   const NavigationController& controller = web_contents()->GetController();
751   NavigationEntry* entry = controller.GetVisibleEntry();
752   GURL entry_url;
753   if (entry)
754     entry_url = entry->GetURL();
755   if (details.update_all() ||
756       // The visible NavigationEntry is the URL in the URL field of a tab.
757       // Currently this should be matched by the |primary_pattern|.
758       details.primary_pattern().Matches(entry_url)) {
759     Profile* profile =
760         Profile::FromBrowserContext(web_contents()->GetBrowserContext());
761     const HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
762
763     if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
764         content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
765       const GURL media_origin = media_stream_access_origin();
766       ContentSetting setting = map->GetContentSetting(media_origin,
767                                                       media_origin,
768                                                       content_type,
769                                                       std::string());
770       content_allowed_[content_type] = setting == CONTENT_SETTING_ALLOW;
771       content_blocked_[content_type] = setting == CONTENT_SETTING_BLOCK;
772     }
773     RendererContentSettingRules rules;
774     GetRendererContentSettingRules(map, &rules);
775     Send(new ChromeViewMsg_SetContentSettingRules(rules));
776   }
777 }
778
779 void TabSpecificContentSettings::AddSiteDataObserver(
780     SiteDataObserver* observer) {
781   observer_list_.AddObserver(observer);
782 }
783
784 void TabSpecificContentSettings::RemoveSiteDataObserver(
785     SiteDataObserver* observer) {
786   observer_list_.RemoveObserver(observer);
787 }
788
789 void TabSpecificContentSettings::NotifySiteDataObservers() {
790   FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
791 }