Upstream version 9.38.198.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/strings/utf_string_conversions.h"
12 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
13 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
14 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
15 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
18 #include "chrome/browser/browsing_data/cookies_tree_model.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/content_settings/content_settings_details.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/prerender/prerender_manager.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/render_messages.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/navigation_controller.h"
29 #include "content/public/browser/navigation_details.h"
30 #include "content/public/browser/navigation_entry.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/browser/render_view_host.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_contents_delegate.h"
36 #include "net/cookies/canonical_cookie.h"
37 #include "webkit/common/fileapi/file_system_types.h"
38
39 using content::BrowserThread;
40 using content::NavigationController;
41 using content::NavigationEntry;
42 using content::RenderViewHost;
43 using content::WebContents;
44
45 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings);
46
47 TabSpecificContentSettings::SiteDataObserver::SiteDataObserver(
48     TabSpecificContentSettings* tab_specific_content_settings)
49     : tab_specific_content_settings_(tab_specific_content_settings) {
50   tab_specific_content_settings_->AddSiteDataObserver(this);
51 }
52
53 TabSpecificContentSettings::SiteDataObserver::~SiteDataObserver() {
54   if (tab_specific_content_settings_)
55     tab_specific_content_settings_->RemoveSiteDataObserver(this);
56 }
57
58 void TabSpecificContentSettings::SiteDataObserver::ContentSettingsDestroyed() {
59   tab_specific_content_settings_ = NULL;
60 }
61
62 TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab)
63     : content::WebContentsObserver(tab),
64       profile_(Profile::FromBrowserContext(tab->GetBrowserContext())),
65       allowed_local_shared_objects_(profile_),
66       blocked_local_shared_objects_(profile_),
67       geolocation_usages_state_(profile_, CONTENT_SETTINGS_TYPE_GEOLOCATION),
68       midi_usages_state_(profile_, CONTENT_SETTINGS_TYPE_MIDI_SYSEX),
69       pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
70       previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
71       pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
72       load_plugins_link_enabled_(true) {
73   ClearBlockedContentSettingsExceptForCookies();
74   ClearCookieSpecificContentSettings();
75
76   registrar_.Add(this, chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED,
77                  content::Source<HostContentSettingsMap>(
78                      profile_->GetHostContentSettingsMap()));
79 }
80
81 TabSpecificContentSettings::~TabSpecificContentSettings() {
82   FOR_EACH_OBSERVER(
83       SiteDataObserver, observer_list_, ContentSettingsDestroyed());
84 }
85
86 TabSpecificContentSettings* TabSpecificContentSettings::Get(
87     int render_process_id, int render_view_id) {
88   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89
90   RenderViewHost* view = RenderViewHost::FromID(render_process_id,
91                                                 render_view_id);
92   if (!view)
93     return NULL;
94
95   WebContents* web_contents = WebContents::FromRenderViewHost(view);
96   if (!web_contents)
97     return NULL;
98
99   return TabSpecificContentSettings::FromWebContents(web_contents);
100 }
101
102 TabSpecificContentSettings* TabSpecificContentSettings::GetForFrame(
103     int render_process_id, int render_frame_id) {
104   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
105
106   content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
107       render_process_id, render_frame_id);
108   WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
109   if (!web_contents)
110     return NULL;
111
112   return TabSpecificContentSettings::FromWebContents(web_contents);
113 }
114
115 // static
116 void TabSpecificContentSettings::CookiesRead(int render_process_id,
117                                              int render_frame_id,
118                                              const GURL& url,
119                                              const GURL& frame_url,
120                                              const net::CookieList& cookie_list,
121                                              bool blocked_by_policy,
122                                              bool is_for_blocking_resource) {
123   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124   TabSpecificContentSettings* settings =
125       GetForFrame(render_process_id, render_frame_id);
126   if (settings) {
127     settings->OnCookiesRead(url, frame_url, cookie_list,
128                             blocked_by_policy);
129   }
130   prerender::PrerenderManager::RecordCookieEvent(
131       render_process_id,
132       render_frame_id,
133       url,
134       frame_url,
135       is_for_blocking_resource,
136       prerender::PrerenderContents::COOKIE_EVENT_SEND,
137       &cookie_list);
138 }
139
140 // static
141 void TabSpecificContentSettings::CookieChanged(
142     int render_process_id,
143     int render_frame_id,
144     const GURL& url,
145     const GURL& frame_url,
146     const std::string& cookie_line,
147     const net::CookieOptions& options,
148     bool blocked_by_policy) {
149   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
150   TabSpecificContentSettings* settings =
151       GetForFrame(render_process_id, render_frame_id);
152   if (settings)
153     settings->OnCookieChanged(url, frame_url, cookie_line, options,
154                               blocked_by_policy);
155   prerender::PrerenderManager::RecordCookieEvent(
156       render_process_id,
157       render_frame_id,
158       url,
159       frame_url,
160       false /*is_critical_request*/,
161       prerender::PrerenderContents::COOKIE_EVENT_CHANGE,
162       NULL);
163 }
164
165 // static
166 void TabSpecificContentSettings::WebDatabaseAccessed(
167     int render_process_id,
168     int render_frame_id,
169     const GURL& url,
170     const base::string16& name,
171     const base::string16& display_name,
172     bool blocked_by_policy) {
173   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
174   TabSpecificContentSettings* settings = GetForFrame(
175       render_process_id, render_frame_id);
176   if (settings)
177     settings->OnWebDatabaseAccessed(url, name, display_name, blocked_by_policy);
178 }
179
180 // static
181 void TabSpecificContentSettings::DOMStorageAccessed(int render_process_id,
182                                                     int render_frame_id,
183                                                     const GURL& url,
184                                                     bool local,
185                                                     bool blocked_by_policy) {
186   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
187   TabSpecificContentSettings* settings = GetForFrame(
188       render_process_id, render_frame_id);
189   if (settings)
190     settings->OnLocalStorageAccessed(url, local, blocked_by_policy);
191 }
192
193 // static
194 void TabSpecificContentSettings::IndexedDBAccessed(
195     int render_process_id,
196     int render_frame_id,
197     const GURL& url,
198     const base::string16& description,
199     bool blocked_by_policy) {
200   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
201   TabSpecificContentSettings* settings = GetForFrame(
202       render_process_id, render_frame_id);
203   if (settings)
204     settings->OnIndexedDBAccessed(url, description, blocked_by_policy);
205 }
206
207 // static
208 void TabSpecificContentSettings::FileSystemAccessed(int render_process_id,
209                                                     int render_frame_id,
210                                                     const GURL& url,
211                                                     bool blocked_by_policy) {
212   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
213   TabSpecificContentSettings* settings = GetForFrame(
214       render_process_id, render_frame_id);
215   if (settings)
216     settings->OnFileSystemAccessed(url, blocked_by_policy);
217 }
218
219 bool TabSpecificContentSettings::IsContentBlocked(
220     ContentSettingsType content_type) const {
221   DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
222       << "Geolocation settings handled by ContentSettingGeolocationImageModel";
223   DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
224       << "Notifications settings handled by "
225       << "ContentSettingsNotificationsImageModel";
226
227   if (content_type == CONTENT_SETTINGS_TYPE_IMAGES ||
228       content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT ||
229       content_type == CONTENT_SETTINGS_TYPE_PLUGINS ||
230       content_type == CONTENT_SETTINGS_TYPE_COOKIES ||
231       content_type == CONTENT_SETTINGS_TYPE_POPUPS ||
232       content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
233       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
234       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
235       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
236       content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
237       content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS ||
238       content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
239     return content_blocked_[content_type];
240   }
241
242   return false;
243 }
244
245 bool TabSpecificContentSettings::IsBlockageIndicated(
246     ContentSettingsType content_type) const {
247   return content_blockage_indicated_to_user_[content_type];
248 }
249
250 void TabSpecificContentSettings::SetBlockageHasBeenIndicated(
251     ContentSettingsType content_type) {
252   content_blockage_indicated_to_user_[content_type] = true;
253 }
254
255 bool TabSpecificContentSettings::IsContentAllowed(
256     ContentSettingsType content_type) const {
257   // This method currently only returns meaningful values for the content type
258   // cookies, mediastream, PPAPI broker, and downloads.
259   if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
260       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
261       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
262       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
263       content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
264       content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS &&
265       content_type != CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
266     return false;
267   }
268
269   return content_allowed_[content_type];
270 }
271
272 void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) {
273   DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
274       << "Geolocation settings handled by OnGeolocationPermissionSet";
275   if (type < 0 || type >= CONTENT_SETTINGS_NUM_TYPES)
276     return;
277
278   // Media is different from other content setting types since it allows new
279   // setting to kick in without reloading the page, and the UI for media is
280   // always reflecting the newest permission setting.
281   switch (type) {
282     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
283     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
284 #if defined(OS_ANDROID)
285     case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
286 #endif
287       content_allowed_[type] = false;
288       break;
289     default:
290       content_allowed_[type] = true;
291       break;
292   }
293
294 #if defined(OS_ANDROID)
295   if (type == CONTENT_SETTINGS_TYPE_POPUPS) {
296     // For Android we do not have a persistent button that will always be
297     // visible for blocked popups.  Instead we have info bars which could be
298     // dismissed.  Have to clear the blocked state so we properly notify the
299     // relevant pieces again.
300     content_blocked_[type] = false;
301     content_blockage_indicated_to_user_[type] = false;
302   }
303 #endif
304
305   if (!content_blocked_[type]) {
306     content_blocked_[type] = true;
307     // TODO: it would be nice to have a way of mocking this in tests.
308     content::NotificationService::current()->Notify(
309         chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
310         content::Source<WebContents>(web_contents()),
311         content::NotificationService::NoDetails());
312   }
313 }
314
315 void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) {
316   DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION)
317       << "Geolocation settings handled by OnGeolocationPermissionSet";
318   bool access_changed = false;
319   switch (type) {
320     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
321     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
322 #if defined(OS_ANDROID)
323     case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
324 #endif
325       // The setting for media is overwritten here because media does not need
326       // to reload the page to have the new setting kick in. See issue/175993.
327       if (content_blocked_[type]) {
328         content_blocked_[type] = false;
329         access_changed = true;
330       }
331       break;
332     default:
333       break;
334   }
335
336   if (!content_allowed_[type]) {
337     content_allowed_[type] = true;
338     access_changed = true;
339   }
340
341   if (access_changed) {
342     content::NotificationService::current()->Notify(
343         chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
344         content::Source<WebContents>(web_contents()),
345         content::NotificationService::NoDetails());
346   }
347 }
348
349 void TabSpecificContentSettings::OnCookiesRead(
350     const GURL& url,
351     const GURL& frame_url,
352     const net::CookieList& cookie_list,
353     bool blocked_by_policy) {
354   if (cookie_list.empty())
355     return;
356   if (blocked_by_policy) {
357     blocked_local_shared_objects_.cookies()->AddReadCookies(
358         frame_url, url, cookie_list);
359     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
360   } else {
361     allowed_local_shared_objects_.cookies()->AddReadCookies(
362         frame_url, url, cookie_list);
363     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
364   }
365
366   NotifySiteDataObservers();
367 }
368
369 void TabSpecificContentSettings::OnCookieChanged(
370     const GURL& url,
371     const GURL& frame_url,
372     const std::string& cookie_line,
373     const net::CookieOptions& options,
374     bool blocked_by_policy) {
375   if (blocked_by_policy) {
376     blocked_local_shared_objects_.cookies()->AddChangedCookie(
377         frame_url, url, cookie_line, options);
378     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
379   } else {
380     allowed_local_shared_objects_.cookies()->AddChangedCookie(
381         frame_url, url, cookie_line, options);
382     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
383   }
384
385   NotifySiteDataObservers();
386 }
387
388 void TabSpecificContentSettings::OnIndexedDBAccessed(
389     const GURL& url,
390     const base::string16& description,
391     bool blocked_by_policy) {
392   if (blocked_by_policy) {
393     blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB(
394         url, description);
395     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
396   } else {
397     allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB(
398         url, description);
399     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
400   }
401
402   NotifySiteDataObservers();
403 }
404
405 void TabSpecificContentSettings::OnLocalStorageAccessed(
406     const GURL& url,
407     bool local,
408     bool blocked_by_policy) {
409   LocalSharedObjectsContainer& container = blocked_by_policy ?
410       blocked_local_shared_objects_ : allowed_local_shared_objects_;
411   CannedBrowsingDataLocalStorageHelper* helper =
412       local ? container.local_storages() : container.session_storages();
413   helper->AddLocalStorage(url);
414
415   if (blocked_by_policy)
416     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
417   else
418     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
419
420   NotifySiteDataObservers();
421 }
422
423 void TabSpecificContentSettings::OnWebDatabaseAccessed(
424     const GURL& url,
425     const base::string16& name,
426     const base::string16& display_name,
427     bool blocked_by_policy) {
428   if (blocked_by_policy) {
429     blocked_local_shared_objects_.databases()->AddDatabase(
430         url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
431     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
432   } else {
433     allowed_local_shared_objects_.databases()->AddDatabase(
434         url, base::UTF16ToUTF8(name), base::UTF16ToUTF8(display_name));
435     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
436   }
437
438   NotifySiteDataObservers();
439 }
440
441 void TabSpecificContentSettings::OnFileSystemAccessed(
442     const GURL& url,
443     bool blocked_by_policy) {
444   if (blocked_by_policy) {
445     blocked_local_shared_objects_.file_systems()->AddFileSystem(url,
446         fileapi::kFileSystemTypeTemporary, 0);
447     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
448   } else {
449     allowed_local_shared_objects_.file_systems()->AddFileSystem(url,
450         fileapi::kFileSystemTypeTemporary, 0);
451     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
452   }
453
454   NotifySiteDataObservers();
455 }
456
457 void TabSpecificContentSettings::OnGeolocationPermissionSet(
458     const GURL& requesting_origin,
459     bool allowed) {
460   geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
461   content::NotificationService::current()->Notify(
462       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
463       content::Source<WebContents>(web_contents()),
464       content::NotificationService::NoDetails());
465 }
466
467 #if defined(OS_ANDROID)
468 void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet(
469     const GURL& requesting_origin,
470     bool allowed) {
471   if (allowed) {
472     OnContentAllowed(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
473   } else {
474     OnContentBlocked(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
475   }
476 }
477 #endif
478
479 TabSpecificContentSettings::MicrophoneCameraState
480 TabSpecificContentSettings::GetMicrophoneCameraState() const {
481   if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
482       IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) {
483     return MICROPHONE_CAMERA_ACCESSED;
484   } else if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) {
485     return MICROPHONE_ACCESSED;
486   } else if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) {
487     return CAMERA_ACCESSED;
488   }
489
490   if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
491       IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) {
492     return MICROPHONE_CAMERA_BLOCKED;
493   } else if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) {
494     return MICROPHONE_BLOCKED;
495   } else if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) {
496     return CAMERA_BLOCKED;
497   }
498
499   return MICROPHONE_CAMERA_NOT_ACCESSED;
500 }
501
502 void TabSpecificContentSettings::OnMediaStreamPermissionSet(
503     const GURL& request_origin,
504     const MediaStreamDevicesController::MediaStreamTypeSettingsMap&
505         request_permissions) {
506   media_stream_access_origin_ = request_origin;
507
508   MediaStreamDevicesController::MediaStreamTypeSettingsMap::const_iterator it =
509       request_permissions.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
510   if (it != request_permissions.end()) {
511     media_stream_requested_audio_device_ = it->second.requested_device_id;
512     switch (it->second.permission) {
513       case MediaStreamDevicesController::MEDIA_NONE:
514         NOTREACHED();
515         break;
516       case MediaStreamDevicesController::MEDIA_ALLOWED:
517         OnContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
518         break;
519       // TODO(grunell): UI should show for what reason access has been blocked.
520       case MediaStreamDevicesController::MEDIA_BLOCKED_BY_POLICY:
521       case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER_SETTING:
522       case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER:
523         OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
524         break;
525     }
526   }
527
528   it = request_permissions.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
529   if (it != request_permissions.end()) {
530     media_stream_requested_video_device_ = it->second.requested_device_id;
531     switch (it->second.permission) {
532       case MediaStreamDevicesController::MEDIA_NONE:
533         NOTREACHED();
534         break;
535       case MediaStreamDevicesController::MEDIA_ALLOWED:
536         OnContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
537         break;
538       // TODO(grunell): UI should show for what reason access has been blocked.
539       case MediaStreamDevicesController::MEDIA_BLOCKED_BY_POLICY:
540       case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER_SETTING:
541       case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER:
542         OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
543         break;
544     }
545   }
546 }
547
548 void TabSpecificContentSettings::OnMidiSysExAccessed(
549     const GURL& requesting_origin) {
550   midi_usages_state_.OnPermissionSet(requesting_origin, true);
551   OnContentAllowed(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
552 }
553
554 void TabSpecificContentSettings::OnMidiSysExAccessBlocked(
555     const GURL& requesting_origin) {
556   midi_usages_state_.OnPermissionSet(requesting_origin, false);
557   OnContentBlocked(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
558 }
559
560 void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() {
561   for (size_t i = 0; i < arraysize(content_blocked_); ++i) {
562     if (i == CONTENT_SETTINGS_TYPE_COOKIES)
563       continue;
564     content_blocked_[i] = false;
565     content_allowed_[i] = false;
566     content_blockage_indicated_to_user_[i] = false;
567   }
568   load_plugins_link_enabled_ = true;
569   content::NotificationService::current()->Notify(
570       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
571       content::Source<WebContents>(web_contents()),
572       content::NotificationService::NoDetails());
573 }
574
575 void TabSpecificContentSettings::ClearCookieSpecificContentSettings() {
576   blocked_local_shared_objects_.Reset();
577   allowed_local_shared_objects_.Reset();
578   content_blocked_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
579   content_allowed_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
580   content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_COOKIES] = false;
581   content::NotificationService::current()->Notify(
582       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
583       content::Source<WebContents>(web_contents()),
584       content::NotificationService::NoDetails());
585 }
586
587 void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked) {
588   content_blocked_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = blocked;
589   content_allowed_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = !blocked;
590   content_blockage_indicated_to_user_[
591     CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = false;
592   content::NotificationService::current()->Notify(
593       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
594       content::Source<WebContents>(web_contents()),
595       content::NotificationService::NoDetails());
596 }
597
598 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked) {
599   content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked;
600   content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false;
601   content::NotificationService::current()->Notify(
602       chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
603       content::Source<WebContents>(web_contents()),
604       content::NotificationService::NoDetails());
605 }
606
607 void TabSpecificContentSettings::GeolocationDidNavigate(
608       const content::LoadCommittedDetails& details) {
609   geolocation_usages_state_.DidNavigate(details);
610 }
611
612 void TabSpecificContentSettings::MidiDidNavigate(
613     const content::LoadCommittedDetails& details) {
614   midi_usages_state_.DidNavigate(details);
615 }
616
617 void TabSpecificContentSettings::ClearGeolocationContentSettings() {
618   geolocation_usages_state_.ClearStateMap();
619 }
620
621 void TabSpecificContentSettings::ClearMidiContentSettings() {
622   midi_usages_state_.ClearStateMap();
623 }
624
625 void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
626   if (allowed) {
627     OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
628   } else {
629     OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
630   }
631 }
632
633 void TabSpecificContentSettings::RenderFrameForInterstitialPageCreated(
634     content::RenderFrameHost* render_frame_host) {
635   // We want to tell the renderer-side code to ignore content settings for this
636   // page.
637   render_frame_host->Send(new ChromeViewMsg_SetAsInterstitial(
638       render_frame_host->GetRoutingID()));
639 }
640
641 bool TabSpecificContentSettings::OnMessageReceived(
642     const IPC::Message& message,
643     content::RenderFrameHost* render_frame_host) {
644   bool handled = true;
645   IPC_BEGIN_MESSAGE_MAP(TabSpecificContentSettings, message)
646     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked)
647     IPC_MESSAGE_UNHANDLED(handled = false)
648   IPC_END_MESSAGE_MAP()
649   return handled;
650 }
651
652 void TabSpecificContentSettings::DidNavigateMainFrame(
653     const content::LoadCommittedDetails& details,
654     const content::FrameNavigateParams& params) {
655   if (!details.is_in_page) {
656     // Clear "blocked" flags.
657     ClearBlockedContentSettingsExceptForCookies();
658     GeolocationDidNavigate(details);
659     MidiDidNavigate(details);
660   }
661 }
662
663 void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
664     content::RenderFrameHost* render_frame_host,
665     const GURL& validated_url,
666     bool is_error_page,
667     bool is_iframe_srcdoc) {
668   if (render_frame_host->GetParent())
669     return;
670
671   // If we're displaying a network error page do not reset the content
672   // settings delegate's cookies so the user has a chance to modify cookie
673   // settings.
674   if (!is_error_page)
675     ClearCookieSpecificContentSettings();
676   ClearGeolocationContentSettings();
677   ClearMidiContentSettings();
678   ClearPendingProtocolHandler();
679 }
680
681 void TabSpecificContentSettings::AppCacheAccessed(const GURL& manifest_url,
682                                                   bool blocked_by_policy) {
683   if (blocked_by_policy) {
684     blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
685     OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
686   } else {
687     allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url);
688     OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
689   }
690 }
691
692 void TabSpecificContentSettings::Observe(
693     int type,
694     const content::NotificationSource& source,
695     const content::NotificationDetails& details) {
696   DCHECK(type == chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED);
697
698   content::Details<const ContentSettingsDetails> settings_details(details);
699   const NavigationController& controller = web_contents()->GetController();
700   NavigationEntry* entry = controller.GetVisibleEntry();
701   GURL entry_url;
702   if (entry)
703     entry_url = entry->GetURL();
704   if (settings_details.ptr()->update_all() ||
705       // The visible NavigationEntry is the URL in the URL field of a tab.
706       // Currently this should be matched by the |primary_pattern|.
707       settings_details.ptr()->primary_pattern().Matches(entry_url)) {
708     Profile* profile =
709         Profile::FromBrowserContext(web_contents()->GetBrowserContext());
710     RendererContentSettingRules rules;
711     GetRendererContentSettingRules(profile->GetHostContentSettingsMap(),
712                                    &rules);
713     Send(new ChromeViewMsg_SetContentSettingRules(rules));
714   }
715 }
716
717 void TabSpecificContentSettings::AddSiteDataObserver(
718     SiteDataObserver* observer) {
719   observer_list_.AddObserver(observer);
720 }
721
722 void TabSpecificContentSettings::RemoveSiteDataObserver(
723     SiteDataObserver* observer) {
724   observer_list_.RemoveObserver(observer);
725 }
726
727 void TabSpecificContentSettings::NotifySiteDataObservers() {
728   FOR_EACH_OBSERVER(SiteDataObserver, observer_list_, OnSiteDataAccessed());
729 }