// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/tab_contents/tab_specific_content_settings.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browsing_data_appcache_helper.h" #include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" #include "chrome/browser/cookies_tree_model.h" #include "net/base/cookie_monster.h" bool TabSpecificContentSettings::LocalSharedObjectsContainer::empty() const { return cookies_->GetAllCookies().empty() && appcaches_->empty() && databases_->empty() && indexed_dbs_->empty() && local_storages_->empty() && session_storages_->empty(); } bool TabSpecificContentSettings::IsContentBlocked( ContentSettingsType content_type) const { DCHECK(content_type != CONTENT_SETTINGS_TYPE_GEOLOCATION) << "Geolocation settings handled by ContentSettingGeolocationImageModel"; DCHECK(content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS) << "Notifications settings handled by " << "ContentSettingsNotificationsImageModel"; if (content_type == CONTENT_SETTINGS_TYPE_IMAGES || content_type == CONTENT_SETTINGS_TYPE_JAVASCRIPT || content_type == CONTENT_SETTINGS_TYPE_PLUGINS || content_type == CONTENT_SETTINGS_TYPE_COOKIES || content_type == CONTENT_SETTINGS_TYPE_POPUPS) return content_blocked_[content_type]; NOTREACHED(); return false; } bool TabSpecificContentSettings::IsBlockageIndicated( ContentSettingsType content_type) const { return content_blockage_indicated_to_user_[content_type]; } void TabSpecificContentSettings::SetBlockageHasBeenIndicated( ContentSettingsType content_type) { content_blockage_indicated_to_user_[content_type] = true; } bool TabSpecificContentSettings::IsContentAccessed( ContentSettingsType content_type) const { // This method currently only returns meaningful values for cookies. if (content_type != CONTENT_SETTINGS_TYPE_COOKIES) return false; return content_accessed_[content_type]; } const std::set<std::string>& TabSpecificContentSettings::BlockedResourcesForType( ContentSettingsType content_type) const { if (blocked_resources_[content_type].get()) { return *blocked_resources_[content_type]; } else { static std::set<std::string> empty_set; return empty_set; } } void TabSpecificContentSettings::AddBlockedResource( ContentSettingsType content_type, const std::string& resource_identifier) { if (!blocked_resources_[content_type].get()) blocked_resources_[content_type].reset(new std::set<std::string>()); blocked_resources_[content_type]->insert(resource_identifier); } void TabSpecificContentSettings::OnContentBlocked( ContentSettingsType type, const std::string& resource_identifier) { DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION) << "Geolocation settings handled by OnGeolocationPermissionSet"; content_accessed_[type] = true; if (!resource_identifier.empty()) AddBlockedResource(type, resource_identifier); if (!content_blocked_[type]) { content_blocked_[type] = true; if (delegate_) delegate_->OnContentSettingsAccessed(true); } } void TabSpecificContentSettings::OnContentAccessed(ContentSettingsType type) { DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION) << "Geolocation settings handled by OnGeolocationPermissionSet"; if (!content_accessed_[type]) { content_accessed_[type] = true; if (delegate_) delegate_->OnContentSettingsAccessed(false); } } void TabSpecificContentSettings::OnCookiesRead( const GURL& url, const net::CookieList& cookie_list, bool blocked_by_policy) { if (cookie_list.empty()) return; LocalSharedObjectsContainer& container = blocked_by_policy ? blocked_local_shared_objects_ : allowed_local_shared_objects_; typedef net::CookieList::const_iterator cookie_iterator; for (cookie_iterator cookie = cookie_list.begin(); cookie != cookie_list.end(); ++cookie) { container.cookies()->SetCookieWithDetails(url, cookie->Name(), cookie->Value(), cookie->Domain(), cookie->Path(), cookie->ExpiryDate(), cookie->IsSecure(), cookie->IsHttpOnly()); } if (blocked_by_policy) OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()); else OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES); } void TabSpecificContentSettings::OnCookieChanged( const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, bool blocked_by_policy) { if (blocked_by_policy) { blocked_local_shared_objects_.cookies()->SetCookieWithOptions( url, cookie_line, options); OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()); } else { allowed_local_shared_objects_.cookies()->SetCookieWithOptions( url, cookie_line, options); OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES); } } void TabSpecificContentSettings::OnIndexedDBAccessed( const GURL& url, const string16& description, bool blocked_by_policy) { if (blocked_by_policy) { blocked_local_shared_objects_.indexed_dbs()->AddIndexedDB( url, description); OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()); }else { allowed_local_shared_objects_.indexed_dbs()->AddIndexedDB( url, description); OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES); } } void TabSpecificContentSettings::OnLocalStorageAccessed( const GURL& url, DOMStorageType storage_type, bool blocked_by_policy) { LocalSharedObjectsContainer& container = blocked_by_policy ? blocked_local_shared_objects_ : allowed_local_shared_objects_; CannedBrowsingDataLocalStorageHelper* helper = storage_type == DOM_STORAGE_LOCAL ? container.local_storages() : container.session_storages(); helper->AddLocalStorage(url); if (blocked_by_policy) OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()); else OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES); } void TabSpecificContentSettings::OnWebDatabaseAccessed( const GURL& url, const string16& name, const string16& display_name, unsigned long estimated_size, bool blocked_by_policy) { if (blocked_by_policy) { blocked_local_shared_objects_.databases()->AddDatabase( url, UTF16ToUTF8(name), UTF16ToUTF8(display_name)); OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()); } else { allowed_local_shared_objects_.databases()->AddDatabase( url, UTF16ToUTF8(name), UTF16ToUTF8(display_name)); OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES); } } void TabSpecificContentSettings::OnAppCacheAccessed( const GURL& manifest_url, bool blocked_by_policy) { if (blocked_by_policy) { blocked_local_shared_objects_.appcaches()->AddAppCache(manifest_url); OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()); } else { allowed_local_shared_objects_.appcaches()->AddAppCache(manifest_url); OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES); } } void TabSpecificContentSettings::OnGeolocationPermissionSet( const GURL& requesting_origin, bool allowed) { geolocation_settings_state_.OnGeolocationPermissionSet(requesting_origin, allowed); if (delegate_) delegate_->OnContentSettingsAccessed(!allowed); } TabSpecificContentSettings::TabSpecificContentSettings( Delegate* delegate, Profile* profile) : allowed_local_shared_objects_(profile), blocked_local_shared_objects_(profile), geolocation_settings_state_(profile), load_plugins_link_enabled_(true), delegate_(NULL) { ClearBlockedContentSettingsExceptForCookies(); ClearCookieSpecificContentSettings(); delegate_ = delegate; } void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() { for (size_t i = 0; i < arraysize(content_blocked_); ++i) { if (i == CONTENT_SETTINGS_TYPE_COOKIES) continue; blocked_resources_[i].reset(); content_blocked_[i] = false; content_accessed_[i] = false; content_blockage_indicated_to_user_[i] = false; } load_plugins_link_enabled_ = true; if (delegate_) delegate_->OnContentSettingsAccessed(false); } void TabSpecificContentSettings::ClearCookieSpecificContentSettings() { blocked_local_shared_objects_.Reset(); allowed_local_shared_objects_.Reset(); content_blocked_[CONTENT_SETTINGS_TYPE_COOKIES] = false; content_accessed_[CONTENT_SETTINGS_TYPE_COOKIES] = false; content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_COOKIES] = false; if (delegate_) delegate_->OnContentSettingsAccessed(false); } void TabSpecificContentSettings::SetPopupsBlocked(bool blocked) { content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked; content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false; if (delegate_) delegate_->OnContentSettingsAccessed(blocked); } void TabSpecificContentSettings::GeolocationDidNavigate( const NavigationController::LoadCommittedDetails& details) { geolocation_settings_state_.DidNavigate(details); } void TabSpecificContentSettings::ClearGeolocationContentSettings() { geolocation_settings_state_.ClearStateMap(); } CookiesTreeModel* TabSpecificContentSettings::GetAllowedCookiesTreeModel() { return allowed_local_shared_objects_.GetCookiesTreeModel(); } CookiesTreeModel* TabSpecificContentSettings::GetBlockedCookiesTreeModel() { return blocked_local_shared_objects_.GetCookiesTreeModel(); } TabSpecificContentSettings::LocalSharedObjectsContainer:: LocalSharedObjectsContainer(Profile* profile) : cookies_(new net::CookieMonster(NULL, NULL)), appcaches_(new CannedBrowsingDataAppCacheHelper(profile)), databases_(new CannedBrowsingDataDatabaseHelper(profile)), indexed_dbs_(new CannedBrowsingDataIndexedDBHelper(profile)), local_storages_(new CannedBrowsingDataLocalStorageHelper(profile)), session_storages_(new CannedBrowsingDataLocalStorageHelper(profile)) { cookies_->SetCookieableSchemes( net::CookieMonster::kDefaultCookieableSchemes, net::CookieMonster::kDefaultCookieableSchemesCount); cookies_->SetKeepExpiredCookies(); } TabSpecificContentSettings::LocalSharedObjectsContainer:: ~LocalSharedObjectsContainer() { } void TabSpecificContentSettings::LocalSharedObjectsContainer::Reset() { cookies_ = new net::CookieMonster(NULL, NULL); cookies_->SetCookieableSchemes( net::CookieMonster::kDefaultCookieableSchemes, net::CookieMonster::kDefaultCookieableSchemesCount); cookies_->SetKeepExpiredCookies(); appcaches_->Reset(); databases_->Reset(); indexed_dbs_->Reset(); local_storages_->Reset(); session_storages_->Reset(); } CookiesTreeModel* TabSpecificContentSettings::LocalSharedObjectsContainer::GetCookiesTreeModel() { return new CookiesTreeModel(cookies_, databases_->Clone(), local_storages_->Clone(), session_storages_->Clone(), appcaches_->Clone(), indexed_dbs_->Clone(), true); }