diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 12:41:28 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 12:41:28 +0000 |
commit | 6787d0c8ea33ceb8094db48d1b5bc24208bad433 (patch) | |
tree | 075db87129cb882dcb5117aaa7cb7684cd5882ef | |
parent | 8b6c5a26007dae63d32e0fcaec9bd687a2e3e8b7 (diff) | |
download | chromium_src-6787d0c8ea33ceb8094db48d1b5bc24208bad433.zip chromium_src-6787d0c8ea33ceb8094db48d1b5bc24208bad433.tar.gz chromium_src-6787d0c8ea33ceb8094db48d1b5bc24208bad433.tar.bz2 |
Implement HostContentSettingsMap
This map stores whether a given host may load images or use plugins and javascript. And makes this information available to the render view
BUG=32782
TEST=none
Review URL: http://codereview.chromium.org/551149
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37508 0039d316-1c4b-4281-b951-d872f2087c98
23 files changed, 550 insertions, 36 deletions
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc index 8e78310..85f35a0 100644 --- a/chrome/browser/browser_prefs.cc +++ b/chrome/browser/browser_prefs.cc @@ -17,6 +17,7 @@ #include "chrome/browser/external_protocol_handler.h" #include "chrome/browser/form_field_history_manager.h" #include "chrome/browser/google_url_tracker.h" +#include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/host_zoom_map.h" #include "chrome/browser/intranet_redirect_detector.h" #include "chrome/browser/metrics/metrics_service.h" @@ -93,6 +94,7 @@ void RegisterUserPrefs(PrefService* user_prefs) { ExtensionsUI::RegisterUserPrefs(user_prefs); NewTabUI::RegisterUserPrefs(user_prefs); BlockedPopupContainer::RegisterUserPrefs(user_prefs); + HostContentSettingsMap::RegisterUserPrefs(user_prefs); HostZoomMap::RegisterUserPrefs(user_prefs); DevToolsManager::RegisterUserPrefs(user_prefs); Blacklist::RegisterUserPrefs(user_prefs); diff --git a/chrome/browser/content_settings_types.h b/chrome/browser/content_settings_types.h deleted file mode 100644 index 1532a08..0000000 --- a/chrome/browser/content_settings_types.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2010 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. - -#ifndef CHROME_BROWSER_CONTENT_SETTINGS_TYPES_H_ -#define CHROME_BROWSER_CONTENT_SETTINGS_TYPES_H_ - -// A particular type of content to care about. We give the user various types -// of controls over each of these. -enum ContentSettingsType { - // "DEFAULT" is only used as an argument to the Content Settings Window - // opener; there it means "whatever was last shown". - CONTENT_SETTINGS_TYPE_DEFAULT = -1, - CONTENT_SETTINGS_FIRST_TYPE = 0, - CONTENT_SETTINGS_TYPE_COOKIES = CONTENT_SETTINGS_FIRST_TYPE, - CONTENT_SETTINGS_TYPE_IMAGES, - CONTENT_SETTINGS_TYPE_JAVASCRIPT, - CONTENT_SETTINGS_TYPE_PLUGINS, - CONTENT_SETTINGS_TYPE_POPUPS, - CONTENT_SETTINGS_NUM_TYPES -}; - -#endif // CHROME_BROWSER_CONTENT_SETTINGS_TYPES_H_ - diff --git a/chrome/browser/host_content_settings_map.cc b/chrome/browser/host_content_settings_map.cc new file mode 100644 index 0000000..24c64bb --- /dev/null +++ b/chrome/browser/host_content_settings_map.cc @@ -0,0 +1,174 @@ +// Copyright (c) 2010 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/host_content_settings_map.h" + +#include "base/utf_string_conversions.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/profile.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" + +HostContentSettingsMap::HostContentSettingsMap(Profile* profile) + : profile_(profile) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + const DictionaryValue* host_content_dictionary = + profile_->GetPrefs()->GetDictionary(prefs::kPerHostContentSettings); + // Careful: The returned value could be NULL if the pref has never been set. + if (host_content_dictionary != NULL) { + for (DictionaryValue::key_iterator i(host_content_dictionary->begin_keys()); + i != host_content_dictionary->end_keys(); ++i) { + std::wstring wide_host(*i); + int content_settings = 0; + bool success = host_content_dictionary->GetIntegerWithoutPathExpansion( + wide_host, &content_settings); + DCHECK(success); + host_content_settings_[WideToUTF8(wide_host)] = + ContentPermissions::FromInteger(content_settings); + } + } + default_content_settings_ = ContentPermissions::FromInteger( + profile_->GetPrefs()->GetInteger(prefs::kDefaultContentSettings)); +} + +// static +void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings); + prefs->RegisterIntegerPref(prefs::kDefaultContentSettings, + ContentPermissions::ToInteger( + ContentPermissions())); +} + +void HostContentSettingsMap::ResetToDefaults() { + default_content_settings_ = ContentPermissions(); + host_content_settings_.clear(); + profile_->GetPrefs()->ClearPref(prefs::kDefaultContentSettings); + profile_->GetPrefs()->ClearPref(prefs::kPerHostContentSettings); +} + +HostContentSettingsMap::HostContentPermissions + HostContentSettingsMap::GetAllPerHostContentPermissions( + ContentSettingsType content_type) const { + HostContentPermissions result; + for (HostContentSettings::const_iterator i(host_content_settings_.begin()); + i != host_content_settings_.end(); ++i) + if (i->second.permissions[content_type] != + CONTENT_PERMISSION_TYPE_DEFAULT) + result[i->first] = i->second.permissions[content_type]; + return result; +} + +ContentPermissions HostContentSettingsMap::GetPerHostContentSettings( + const std::string& host) const { + AutoLock auto_lock(lock_); + HostContentSettings::const_iterator i(host_content_settings_.find(host)); + ContentPermissions result = default_content_settings_; + if (i != host_content_settings_.end()) { + for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) + if (i->second.permissions[j] != CONTENT_PERMISSION_TYPE_DEFAULT) + result.permissions[j] = i->second.permissions[j]; + } + return result; +} + +bool HostContentSettingsMap::SetDefaultContentPermission( + ContentSettingsType type, ContentPermissionType permission) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + if (permission == CONTENT_PERMISSION_TYPE_DEFAULT) + return false; + + { + AutoLock auto_lock(lock_); + default_content_settings_.permissions[type] = permission; + } + + // Persist new content settings if we're not off the record. + if (!profile_->IsOffTheRecord()) { + profile_->GetPrefs()->SetInteger(prefs::kDefaultContentSettings, + ContentPermissions::ToInteger(default_content_settings_)); + } + return true; +} + +void HostContentSettingsMap::SetPerHostContentPermission( + const std::string& host, ContentSettingsType type, + ContentPermissionType permission) { + + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + if (host.empty()) + return; + + bool erase_entry = true; + ContentPermissions permissions; + + { + AutoLock auto_lock(lock_); + HostContentSettings::const_iterator i(host_content_settings_.find(host)); + if (i == host_content_settings_.end()) { + for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) + permissions.permissions[j] = CONTENT_PERMISSION_TYPE_DEFAULT; + } else { + permissions = i->second; + } + permissions.permissions[type] = permission; + for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) + if (permissions.permissions[j] != CONTENT_PERMISSION_TYPE_DEFAULT) + erase_entry = false; + if (erase_entry) + host_content_settings_.erase(host); + else + host_content_settings_[host] = permissions; + } + + // Persist new content settings if we're not off the record. + if (!profile_->IsOffTheRecord()) { + DictionaryValue* host_content_dictionary = + profile_->GetPrefs()->GetMutableDictionary( + prefs::kPerHostContentSettings); + std::wstring wide_host(UTF8ToWide(host)); + if (erase_entry) { + host_content_dictionary->RemoveWithoutPathExpansion(wide_host, NULL); + } else { + host_content_dictionary->SetWithoutPathExpansion(wide_host, + Value::CreateIntegerValue(ContentPermissions::ToInteger(permissions))); + } + } +} + +void HostContentSettingsMap::SetPerHostContentSettings(const std::string& host, + const ContentPermissions& permissions) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + if (host.empty()) + return; + + bool erase_entry = true; + + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) + if (permissions.permissions[i] != CONTENT_PERMISSION_TYPE_DEFAULT) + erase_entry = false; + + { + AutoLock auto_lock(lock_); + if (erase_entry) + host_content_settings_.erase(host); + else + host_content_settings_[host] = permissions; + } + + // Persist new content settings if we're not off the record. + if (!profile_->IsOffTheRecord()) { + DictionaryValue* host_content_dictionary = + profile_->GetPrefs()->GetMutableDictionary( + prefs::kPerHostContentSettings); + std::wstring wide_host(UTF8ToWide(host)); + if (erase_entry) { + host_content_dictionary->RemoveWithoutPathExpansion(wide_host, NULL); + } else { + host_content_dictionary->SetWithoutPathExpansion(wide_host, + Value::CreateIntegerValue(ContentPermissions::ToInteger(permissions))); + } + } +} diff --git a/chrome/browser/host_content_settings_map.h b/chrome/browser/host_content_settings_map.h new file mode 100644 index 0000000..bed78b5 --- /dev/null +++ b/chrome/browser/host_content_settings_map.h @@ -0,0 +1,98 @@ +// Copyright (c) 2010 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. + +// Maps hostnames to custom zoom levels. Written on the UI thread and read on +// the IO thread. One instance per profile. + +#ifndef CHROME_BROWSER_HOST_CONTENT_SETTINGS_MAP_H_ +#define CHROME_BROWSER_HOST_CONTENT_SETTINGS_MAP_H_ + +#include <map> +#include <string> + +#include "base/basictypes.h" +#include "base/lock.h" +#include "chrome/common/content_permission_types.h" + +class PrefService; +class Profile; + +class HostContentSettingsMap { + public: + typedef std::map<std::string, ContentPermissionType> HostContentPermissions; + + explicit HostContentSettingsMap(Profile* profile); + + static void RegisterUserPrefs(PrefService* prefs); + + void ResetToDefaults(); + + // Returns a map of all hostnames with per host content settings to + // their respective settings where a given |content_type| differs + // from CONTENT_PERMISSION_TYPE_DEFAULT + // + // This may be called on any thread. + HostContentPermissions GetAllPerHostContentPermissions( + ContentSettingsType content_type) const; + + // Returns the default ContentPermissions for a specific ContentSettingsType. + // + // This may be called on any thread. + ContentPermissionType GetDefaultContentPermission( + ContentSettingsType type) const { + return default_content_settings_.permissions[type]; + } + + // Returns the ContentPermissions for a specific ContentSettingsType. + // + // This may be called on any thread. + ContentPermissionType GetPerHostContentPermission(const std::string& host, + ContentSettingsType type) const { + return GetPerHostContentSettings(host).permissions[type]; + } + + // Returns the ContentPermissions which apply to a given host. + // + // This may be called on any thread. + ContentPermissions GetPerHostContentSettings(const std::string& host) const; + + // Sets the default ContentPermissions. Returns true on success. + // + // This should only be called on the UI thread. + bool SetDefaultContentPermission(ContentSettingsType type, + ContentPermissionType permission); + + // Sets per host ContentPermissions for a given host and CotentSettings. To + // remove an exception for the host, set the permissions to + // CONTENT_PERMISSIONS_TYPE_DEFAULT. + // + // This should only be called on the UI thread. + void SetPerHostContentPermission(const std::string& host, + ContentSettingsType type, + ContentPermissionType permission); + + // Sets per host ContentPermissions for a given host. + // + // This should only be called on the UI thread. + void SetPerHostContentSettings(const std::string& host, + const ContentPermissions& permissions); + + private: + typedef std::map<std::string, ContentPermissions> HostContentSettings; + + // The profile we're associated with. + Profile* profile_; + + // Copy of the pref data, so that we can read it on the IO thread. + HostContentSettings host_content_settings_; + ContentPermissions default_content_settings_; + + // Used around accesses to |host_content_settings_| to guarantee thread + // safety. + mutable Lock lock_; + + DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap); +}; + +#endif // CHROME_BROWSER_HOST_CONTENT_SETTINGS_MAP_H_ diff --git a/chrome/browser/host_content_settings_map_unittest.cc b/chrome/browser/host_content_settings_map_unittest.cc new file mode 100644 index 0000000..721a68e --- /dev/null +++ b/chrome/browser/host_content_settings_map_unittest.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2010 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/host_content_settings_map.h" + +#include "chrome/test/testing_profile.h" +#include "testing/gtest/include/gtest/gtest.h" + + +namespace { + +class HostContentSettingsMapTest : public testing::Test { + public: + HostContentSettingsMapTest() + : ui_thread_(ChromeThread::UI, &message_loop_) {} + + protected: + MessageLoop message_loop_; + ChromeThread ui_thread_; +}; + +TEST_F(HostContentSettingsMapTest, DefaultValues) { + TestingProfile profile; + HostContentSettingsMap* host_content_settings_map = + profile.GetHostContentSettingsMap(); + + // Check setting of default permissions. + ContentPermissions perm; + ASSERT_TRUE(host_content_settings_map->SetDefaultContentPermission( + CONTENT_SETTINGS_TYPE_IMAGES, CONTENT_PERMISSION_TYPE_BLOCK)); + ASSERT_TRUE(host_content_settings_map->SetDefaultContentPermission( + CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_PERMISSION_TYPE_ASK)); + ASSERT_FALSE(host_content_settings_map->SetDefaultContentPermission( + CONTENT_SETTINGS_TYPE_JAVASCRIPT, + CONTENT_PERMISSION_TYPE_DEFAULT)); + ASSERT_TRUE(host_content_settings_map->SetDefaultContentPermission( + CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_PERMISSION_TYPE_ALLOW)); + + // Check per host permissions returned. + perm.permissions[CONTENT_SETTINGS_TYPE_IMAGES] = + CONTENT_PERMISSION_TYPE_DEFAULT; + perm.permissions[CONTENT_SETTINGS_TYPE_PLUGINS] = + CONTENT_PERMISSION_TYPE_ALLOW; + perm.permissions[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = + CONTENT_PERMISSION_TYPE_ALLOW; + host_content_settings_map->SetPerHostContentSettings("example.com", perm); + perm = host_content_settings_map->GetPerHostContentSettings("example.com"); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_BLOCK, + perm.permissions[CONTENT_SETTINGS_TYPE_IMAGES]); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_ALLOW, + perm.permissions[CONTENT_SETTINGS_TYPE_PLUGINS]); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_ALLOW, + perm.permissions[CONTENT_SETTINGS_TYPE_JAVASCRIPT]); + perm = host_content_settings_map->GetPerHostContentSettings("example.org"); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_BLOCK, + perm.permissions[CONTENT_SETTINGS_TYPE_IMAGES]); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_ASK, + perm.permissions[CONTENT_SETTINGS_TYPE_PLUGINS]); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_ALLOW, + perm.permissions[CONTENT_SETTINGS_TYPE_JAVASCRIPT]); + + // Check returning settings for a given resource. + HostContentSettingsMap::HostContentPermissions permissions; + permissions = host_content_settings_map->GetAllPerHostContentPermissions( + CONTENT_SETTINGS_TYPE_IMAGES); + EXPECT_EQ(0U, permissions.size()); + permissions = host_content_settings_map->GetAllPerHostContentPermissions( + CONTENT_SETTINGS_TYPE_PLUGINS); + EXPECT_EQ(1U, permissions.size()); + EXPECT_EQ("example.com", permissions.begin()->first); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_ALLOW, permissions.begin()->second); +} + +TEST_F(HostContentSettingsMapTest, ContentPermissions) { + ContentPermissions perm; + perm.permissions[CONTENT_SETTINGS_TYPE_IMAGES] = + CONTENT_PERMISSION_TYPE_BLOCK; + perm.permissions[CONTENT_SETTINGS_TYPE_PLUGINS] = + CONTENT_PERMISSION_TYPE_ASK; + perm.permissions[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = + CONTENT_PERMISSION_TYPE_ALLOW; + + int serialized = ContentPermissions::ToInteger(perm); + ContentPermissions result = ContentPermissions::FromInteger(serialized); + + EXPECT_EQ(perm.permissions[CONTENT_SETTINGS_TYPE_IMAGES], + result.permissions[CONTENT_SETTINGS_TYPE_IMAGES]); + EXPECT_EQ(perm.permissions[CONTENT_SETTINGS_TYPE_PLUGINS], + result.permissions[CONTENT_SETTINGS_TYPE_PLUGINS]); + EXPECT_EQ(perm.permissions[CONTENT_SETTINGS_TYPE_JAVASCRIPT], + result.permissions[CONTENT_SETTINGS_TYPE_JAVASCRIPT]); +} + +} // namespace diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 9e5286a..a50013d 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -779,6 +779,7 @@ ChromeURLRequestContext::ChromeURLRequestContext( extension_info_ = other->extension_info_; user_script_dir_path_ = other->user_script_dir_path_; appcache_service_ = other->appcache_service_; + host_content_settings_map_ = other->host_content_settings_map_; host_zoom_map_ = other->host_zoom_map_; privacy_blacklist_ = other->privacy_blacklist_; is_media_ = other->is_media_; @@ -857,6 +858,8 @@ ChromeURLRequestContextFactory::ChromeURLRequestContextFactory(Profile* profile) cookie_policy_type_ = net::CookiePolicy::FromInt( prefs->GetInteger(prefs::kCookieBehavior)); + host_content_settings_map_ = profile->GetHostContentSettingsMap(); + host_zoom_map_ = profile->GetHostZoomMap(); privacy_blacklist_ = profile->GetPrivacyBlacklist(); @@ -903,6 +906,7 @@ void ChromeURLRequestContextFactory::ApplyProfileParametersToContext( context->set_cookie_policy_type(cookie_policy_type_); context->set_extension_info(extension_info_); context->set_user_script_dir_path(user_script_dir_path_); + context->set_host_content_settings_map(host_content_settings_map_); context->set_host_zoom_map(host_zoom_map_); context->set_privacy_blacklist(privacy_blacklist_); context->set_transport_security_state( diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index 3a3c1bb..d1953ef 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -7,6 +7,7 @@ #include "base/file_path.h" #include "base/linked_ptr.h" +#include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/host_zoom_map.h" #include "chrome/browser/net/url_request_context_getter.h" #include "chrome/common/appcache/chrome_appcache_service.h" @@ -98,6 +99,10 @@ class ChromeURLRequestContext : public URLRequestContext { virtual bool InterceptResponseCookie(const URLRequest* request, const std::string& cookie) const; + const HostContentSettingsMap* host_content_settings_map() const { + return host_content_settings_map_; + } + const HostZoomMap* host_zoom_map() const { return host_zoom_map_; } // Gets the Privacy Blacklist, if any for this context. @@ -169,6 +174,10 @@ class ChromeURLRequestContext : public URLRequestContext { void set_is_media(bool is_media) { is_media_ = is_media; } + void set_host_content_settings_map( + HostContentSettingsMap* host_content_settings_map) { + host_content_settings_map_ = host_content_settings_map; + } void set_host_zoom_map(HostZoomMap* host_zoom_map) { host_zoom_map_ = host_zoom_map; } @@ -193,6 +202,7 @@ class ChromeURLRequestContext : public URLRequestContext { FilePath user_script_dir_path_; scoped_refptr<ChromeAppCacheService> appcache_service_; + HostContentSettingsMap* host_content_settings_map_; scoped_refptr<HostZoomMap> host_zoom_map_; const Blacklist* privacy_blacklist_; @@ -363,6 +373,7 @@ class ChromeURLRequestContextFactory { // TODO(aa): I think this can go away now as we no longer support standalone // user scripts. FilePath user_script_dir_path_; + HostContentSettingsMap* host_content_settings_map_; scoped_refptr<HostZoomMap> host_zoom_map_; const Blacklist* privacy_blacklist_; net::TransportSecurityState* transport_security_state_; diff --git a/chrome/browser/options_util.cc b/chrome/browser/options_util.cc index 94732ea..6562c3d 100644 --- a/chrome/browser/options_util.cc +++ b/chrome/browser/options_util.cc @@ -7,6 +7,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profile.h" #include "chrome/browser/download/download_manager.h" +#include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/metrics/metrics_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" @@ -64,6 +65,7 @@ void OptionsUtil::ResetToDefaults(Profile* profile) { prefs::kWebKitSerifFontFamily, }; profile->GetDownloadManager()->ResetAutoOpenFiles(); + profile->GetHostContentSettingsMap()->ResetToDefaults(); for (size_t i = 0; i < arraysize(kUserPrefs); ++i) prefs->ClearPref(kUserPrefs[i]); diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index a6861e9..c197a78 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -29,6 +29,7 @@ #include "chrome/browser/spellcheck_host.h" #include "chrome/browser/transport_security_persister.h" #include "chrome/browser/history/history.h" +#include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/host_zoom_map.h" #include "chrome/browser/in_process_webkit/webkit_context.h" #include "chrome/browser/net/chrome_url_request_context.h" @@ -405,6 +406,14 @@ class OffTheRecordProfileImpl : public Profile, return GetOriginalProfile()->GetSSLConfigService(); } + virtual HostContentSettingsMap* GetHostContentSettingsMap() { + // Need to use a separate map from the normal one to avoid persisting + // content setting changes in OTR mode. + if (!host_content_settings_map_.get()) + host_content_settings_map_.reset(new HostContentSettingsMap(this)); + return host_content_settings_map_.get(); + } + virtual HostZoomMap* GetHostZoomMap() { // Need to use a separate map from the normal one to avoid persisting zoom // changes in OTR mode. @@ -535,6 +544,8 @@ class OffTheRecordProfileImpl : public Profile, scoped_refptr<ChromeURLRequestContextGetter> extensions_request_context_; + scoped_ptr<HostContentSettingsMap> host_content_settings_map_; + scoped_refptr<HostZoomMap> host_zoom_map_; // The download manager that only stores downloaded items in memory. @@ -572,6 +583,7 @@ ProfileImpl::ProfileImpl(const FilePath& path) request_context_(NULL), media_request_context_(NULL), extensions_request_context_(NULL), + host_content_settings_map_(NULL), host_zoom_map_(NULL), history_service_created_(false), favicon_service_created_(false), @@ -961,6 +973,12 @@ net::SSLConfigService* ProfileImpl::GetSSLConfigService() { return ssl_config_service_manager_->Get(); } +HostContentSettingsMap* ProfileImpl::GetHostContentSettingsMap() { + if (!host_content_settings_map_.get()) + host_content_settings_map_.reset(new HostContentSettingsMap(this)); + return host_content_settings_map_.get(); +} + HostZoomMap* ProfileImpl::GetHostZoomMap() { if (!host_zoom_map_) host_zoom_map_ = new HostZoomMap(this); diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h index 0cc0e16..6f97fec 100644 --- a/chrome/browser/profile.h +++ b/chrome/browser/profile.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -43,6 +43,7 @@ class ExtensionMessageService; class ExtensionsService; class FaviconService; class HistoryService; +class HostContentSettingsMap; class HostZoomMap; class NavigationController; class NTPResourceCache; @@ -288,6 +289,9 @@ class Profile { // Returns the SSLConfigService for this profile. virtual net::SSLConfigService* GetSSLConfigService() = 0; + // Returns the Hostname <-> Content settings map for this profile. + virtual HostContentSettingsMap* GetHostContentSettingsMap() = 0; + // Returns the Hostname <-> Zoom Level map for this profile. virtual HostZoomMap* GetHostZoomMap() = 0; @@ -437,6 +441,7 @@ class ProfileImpl : public Profile, virtual URLRequestContextGetter* GetRequestContextForMedia(); virtual URLRequestContextGetter* GetRequestContextForExtensions(); virtual net::SSLConfigService* GetSSLConfigService(); + virtual HostContentSettingsMap* GetHostContentSettingsMap(); virtual HostZoomMap* GetHostZoomMap(); virtual Blacklist* GetPrivacyBlacklist(); virtual SessionService* GetSessionService(); @@ -521,6 +526,7 @@ class ProfileImpl : public Profile, scoped_ptr<SSLConfigServiceManager> ssl_config_service_manager_; + scoped_ptr<HostContentSettingsMap> host_content_settings_map_; scoped_refptr<HostZoomMap> host_zoom_map_; scoped_ptr<Blacklist> privacy_blacklist_; scoped_refptr<DownloadManager> download_manager_; diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index 7b5e8c2..8e69f65 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -104,7 +104,7 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, // level before the request actually commits. This way the renderer will be // able to set the zoom level precisely at the time the request commits, // avoiding the possibility of zooming the old content or of having to layout - // the new content twice. + // the new content twice. Also send the per host content settings. URLRequest* request = rdh_->GetURLRequest( GlobalRequestID(process_id_, request_id)); ResourceDispatcherHostRequestInfo* info = rdh_->InfoForRequest(request); @@ -115,6 +115,10 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, if (!host.empty() && context) { receiver_->Send(new ViewMsg_SetZoomLevelForLoadingHost(info->route_id(), host, context->host_zoom_map()->GetZoomLevel(host))); + receiver_->Send(new ViewMsg_SetContentSettingsForLoadingHost( + info->route_id(), host, ContentPermissions::ToInteger( + context->host_content_settings_map()->GetPerHostContentSettings( + host)))); } } diff --git a/chrome/browser/views/options/content_settings_window_view.h b/chrome/browser/views/options/content_settings_window_view.h index 7bb5ec1..164e580 100644 --- a/chrome/browser/views/options/content_settings_window_view.h +++ b/chrome/browser/views/options/content_settings_window_view.h @@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_SETTINGS_WINDOW_VIEW_H_ #define CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_SETTINGS_WINDOW_VIEW_H_ +#include "chrome/common/content_permission_types.h" #include "chrome/common/pref_member.h" -#include "chrome/browser/content_settings_types.h" #include "views/controls/tabbed_pane/tabbed_pane.h" #include "views/view.h" #include "views/window/dialog_delegate.h" diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index fb0db67..ed01725 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -608,7 +608,6 @@ 'browser/cocoa/window_size_autosaver.mm', 'browser/command_updater.cc', 'browser/command_updater.h', - 'browser/content_settings_types.h', 'browser/cookies_tree_model.cc', 'browser/cookies_tree_model.h', 'browser/cross_site_request_manager.cc', @@ -1098,6 +1097,8 @@ 'browser/history/visit_tracker.h', 'browser/history/visitsegment_database.cc', 'browser/history/visitsegment_database.h', + 'browser/host_content_settings_map.cc', + 'browser/host_content_settings_map.h', 'browser/host_zoom_map.cc', 'browser/host_zoom_map.h', 'browser/hung_renderer_dialog.h', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index e2c7d87..ffb4bb3 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -1,4 +1,4 @@ -# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Copyright (c) 2010 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. @@ -199,6 +199,7 @@ 'common/command_buffer_messages.h', 'common/command_buffer_messages_internal.h', 'common/common_glue.cc', + 'common/content_permission_types.h' 'common/css_colors.h', 'common/db_message_filter.cc', 'common/db_message_filter.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 74274ac..3611dae3 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -715,6 +715,7 @@ 'browser/history/text_database_unittest.cc', 'browser/history/thumbnail_database_unittest.cc', 'browser/history/top_sites_unittest.cc', + 'browser/host_content_settings_map_unittest.cc', 'browser/thumbnail_store_unittest.cc', 'browser/history/url_database_unittest.cc', 'browser/history/visit_database_unittest.cc', diff --git a/chrome/common/content_permission_types.h b/chrome/common/content_permission_types.h new file mode 100644 index 0000000..2b5acec --- /dev/null +++ b/chrome/common/content_permission_types.h @@ -0,0 +1,71 @@ +// Copyright (c) 2010 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. + +#ifndef CHROME_COMMON_CONTENT_PERMISSION_TYPES_H_ +#define CHROME_COMMON_CONTENT_PERMISSION_TYPES_H_ + +// Indicates different permission levels that can be assigned for a given +// resource. +enum ContentPermissionType { + CONTENT_PERMISSION_FIRST_TYPE = 0, + CONTENT_PERMISSION_TYPE_BLOCK = CONTENT_PERMISSION_FIRST_TYPE, + CONTENT_PERMISSION_TYPE_ALLOW, + CONTENT_PERMISSION_TYPE_ASK, + CONTENT_PERMISSION_TYPE_DEFAULT, + CONTENT_PERMISSION_NUM_TYPES +}; + +// A particular type of content to care about. We give the user various types +// of controls over each of these. +enum ContentSettingsType { + // "DEFAULT" is only used as an argument to the Content Settings Window + // opener; there it means "whatever was last shown". + CONTENT_SETTINGS_TYPE_DEFAULT = -1, + CONTENT_SETTINGS_FIRST_TYPE = 0, + CONTENT_SETTINGS_TYPE_COOKIES = CONTENT_SETTINGS_FIRST_TYPE, + CONTENT_SETTINGS_TYPE_IMAGES, + CONTENT_SETTINGS_TYPE_JAVASCRIPT, + CONTENT_SETTINGS_TYPE_PLUGINS, + CONTENT_SETTINGS_TYPE_POPUPS, + CONTENT_SETTINGS_NUM_TYPES +}; + +// Aggregates the permissions for the different content types. +struct ContentPermissions { + ContentPermissionType permissions[CONTENT_SETTINGS_NUM_TYPES]; + + ContentPermissions() { + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) + permissions[i] = CONTENT_PERMISSION_TYPE_ALLOW; + } + + // Converts the struct into an integer used for storing in preferences and + // sending over IPC. + static int ToInteger(const ContentPermissions& permissions) { + int result = 0; + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) + result = ((result << CONTENT_PERMISSION_NUM_TYPES) + + (1 << permissions.permissions[i])); + return result; + } + + // Converts an integer as stored in preferences or sent over IPC to + // ContentPermissions. + static ContentPermissions FromInteger(int settings) { + ContentPermissions result; + for (int i = CONTENT_SETTINGS_NUM_TYPES - 1; i >= 0; --i) { + int bitmask = (settings & ((1 << CONTENT_PERMISSION_NUM_TYPES) - 1)); + settings >>= CONTENT_PERMISSION_NUM_TYPES; + int value = 0; + while (bitmask != 1) { + value++; + bitmask >>= 1; + } + result.permissions[i] = static_cast<ContentPermissionType>(value); + } + return result; + } +}; + +#endif // CHROME_COMMON_CONTENT_PERMISSION_TYPES_H_ diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 3824985..ad07566 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -295,6 +295,13 @@ const wchar_t kDesktopNotificationAllowedOrigins[] = const wchar_t kDesktopNotificationDeniedOrigins[] = L"profile.notification_denied_sites"; +// Bitmask of content settings applied to hosts per default. +const wchar_t kDefaultContentSettings[] = L"profile.default_content_settings"; + +// Dictionary that maps hostnames to content related settings. Default +// settings will be applied to hosts not in this pref. +const wchar_t kPerHostContentSettings[] = L"profile.per_host_content_settings"; + // Dictionary that maps hostnames to zoom levels. Hosts not in this pref will // be displayed at the default zoom level. const wchar_t kPerHostZoomLevels[] = L"profile.per_host_zoom_levels"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e81dd00..2afb1e5 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -118,6 +118,8 @@ extern const wchar_t kNTPPromoLineRemaining[]; extern const wchar_t kNTPPromoImageRemaining[]; extern const wchar_t kDesktopNotificationAllowedOrigins[]; extern const wchar_t kDesktopNotificationDeniedOrigins[]; +extern const wchar_t kDefaultContentSettings[]; +extern const wchar_t kPerHostContentSettings[]; extern const wchar_t kPerHostZoomLevels[]; extern const wchar_t kAutoFillInfoBarShown[]; extern const wchar_t kAutoFillEnabled[]; diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index e51f867..5f2fcd0 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -364,6 +364,13 @@ IPC_BEGIN_MESSAGES(View) std::string /* host */, int /* zoom_level */) + // Set the content settings for a particular hostname that the renderer is in + // the process of loading. This will be stored, to be used if the load + // commits and ignored otherwise. + IPC_MESSAGE_ROUTED2(ViewMsg_SetContentSettingsForLoadingHost, + std::string /* host */, + int /* content_settings */) + // Change encoding of page in the renderer. IPC_MESSAGE_ROUTED1(ViewMsg_SetPageEncoding, std::string /*new encoding name*/) diff --git a/chrome/renderer/navigation_state.h b/chrome/renderer/navigation_state.h index 12580f8..7d4271ea 100644 --- a/chrome/renderer/navigation_state.h +++ b/chrome/renderer/navigation_state.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -7,6 +7,7 @@ #include "base/scoped_ptr.h" #include "base/time.h" +#include "chrome/common/content_permission_types.h" #include "chrome/common/page_transition_types.h" #include "chrome/renderer/user_script_idle_scheduler.h" #include "third_party/WebKit/WebKit/chromium/public/WebDataSource.h" @@ -207,6 +208,13 @@ class NavigationState : public WebKit::WebDataSource::ExtraData { void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; } bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; } + void set_content_permissions(const ContentPermissions& value) { + content_permissions_ = value; + } + ContentPermissions content_permissions() const { + return content_permissions_; + } + private: NavigationState(PageTransition::Type transition_type, const base::Time& request_time, @@ -254,6 +262,8 @@ class NavigationState : public WebKit::WebDataSource::ExtraData { bool was_fetched_via_spdy_; + ContentPermissions content_permissions_; + DISALLOW_COPY_AND_ASSIGN(NavigationState); }; diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index a27792f4..c101235 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -494,6 +494,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand) IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind) IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom) + IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingHost, + OnSetContentSettingsForLoadingHost) IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingHost, OnSetZoomLevelForLoadingHost) IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding) @@ -3136,6 +3138,18 @@ void RenderView::OnZoom(PageZoom::Function function) { Send(new ViewHostMsg_DidZoomHost(host, new_zoom_level)); } +void RenderView::OnSetContentSettingsForLoadingHost(std::string host, + int content_settings) { + WebFrame* main_frame = webview()->mainFrame(); + DCHECK(main_frame); + WebDataSource* ds = main_frame->provisionalDataSource(); + DCHECK(ds); + NavigationState* navigation_state = NavigationState::FromDataSource(ds); + DCHECK(navigation_state); + navigation_state->set_content_permissions( + ContentPermissions::FromInteger(content_settings)); +} + void RenderView::OnSetZoomLevelForLoadingHost(std::string host, int zoom_level) { host_zoom_levels_[host] = zoom_level; diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index dfc4cdb..233be9a 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -581,6 +581,8 @@ class RenderView : public RenderWidget, void OnFind(int request_id, const string16&, const WebKit::WebFindOptions&); void OnDeterminePageLanguage(); void OnZoom(PageZoom::Function function); + void OnSetContentSettingsForLoadingHost(std::string host, + int content_settings); void OnSetZoomLevelForLoadingHost(std::string host, int zoom_level); void OnSetPageEncoding(const std::string& encoding_name); void OnResetPageEncodingToDefault(); diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index c88e574..86aa2dd 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -12,6 +12,7 @@ #include "chrome/browser/browser_prefs.h" #include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/favicon_service.h" +#include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/history/history.h" #include "chrome/browser/in_process_webkit/webkit_context.h" #include "chrome/browser/net/url_request_context_getter.h" @@ -177,6 +178,11 @@ class TestingProfile : public Profile { virtual net::SSLConfigService* GetSSLConfigService() { return NULL; } virtual Blacklist* GetPrivacyBlacklist() { return NULL; } + virtual HostContentSettingsMap* GetHostContentSettingsMap() { + if (!host_content_settings_map_.get()) + host_content_settings_map_.reset(new HostContentSettingsMap(this)); + return host_content_settings_map_.get(); + } virtual HostZoomMap* GetHostZoomMap() { return NULL; } void set_session_service(SessionService* session_service) { session_service_ = session_service; @@ -293,6 +299,8 @@ class TestingProfile : public Profile { // WebKitContext, lazily initialized by GetWebKitContext(). scoped_refptr<WebKitContext> webkit_context_; + + scoped_ptr<HostContentSettingsMap> host_content_settings_map_; }; // A profile that derives from another profile. This does not actually |