diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-02 21:36:42 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-02 21:36:42 +0000 |
commit | be0a2cfd5ff6d24015c34334250515235e7e8638 (patch) | |
tree | 5383bf7c43598fe683b43d4c6dea2aba10b2f8ae /chrome/browser/extensions | |
parent | f2d714796a7ad146ab3591826f1e1c5084a995a6 (diff) | |
download | chromium_src-be0a2cfd5ff6d24015c34334250515235e7e8638.zip chromium_src-be0a2cfd5ff6d24015c34334250515235e7e8638.tar.gz chromium_src-be0a2cfd5ff6d24015c34334250515235e7e8638.tar.bz2 |
Small refactor: have ExtensionInfoMap use ExtensionSet.
BUG=no
TEST=no
Review URL: http://codereview.chromium.org/7066053
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87693 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r-- | chrome/browser/extensions/extension_info_map.cc | 124 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_info_map.h | 55 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_info_map_unittest.cc | 46 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_protocols.cc | 43 |
4 files changed, 71 insertions, 197 deletions
diff --git a/chrome/browser/extensions/extension_info_map.cc b/chrome/browser/extensions/extension_info_map.cc index 8e8980e..c812237 100644 --- a/chrome/browser/extensions/extension_info_map.cc +++ b/chrome/browser/extensions/extension_info_map.cc @@ -5,7 +5,6 @@ #include "chrome/browser/extensions/extension_info_map.h" #include "chrome/common/extensions/extension.h" -#include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" namespace { @@ -24,24 +23,22 @@ ExtensionInfoMap::~ExtensionInfoMap() { void ExtensionInfoMap::AddExtension(const Extension* extension) { CheckOnValidThread(); - extension_info_[extension->id()] = extension; - Map::iterator iter = disabled_extension_info_.find(extension->id()); - if (iter != disabled_extension_info_.end()) - disabled_extension_info_.erase(iter); + extensions_.Insert(extension); + disabled_extensions_.Remove(extension->id()); } void ExtensionInfoMap::RemoveExtension(const std::string& id, const UnloadedExtensionInfo::Reason reason) { CheckOnValidThread(); - Map::iterator iter = extension_info_.find(id); - if (iter != extension_info_.end()) { + const Extension* extension = extensions_.GetByID(id); + if (extension) { if (reason == UnloadedExtensionInfo::DISABLE) - disabled_extension_info_[id] = (*iter).second; - extension_info_.erase(iter); + disabled_extensions_.Insert(extension); + extensions_.Remove(id); } else if (reason != UnloadedExtensionInfo::DISABLE) { // If the extension was uninstalled, make sure it's removed from the map of // disabled extensions. - disabled_extension_info_.erase(id); + disabled_extensions_.Remove(id); } else { // NOTE: This can currently happen if we receive multiple unload // notifications, e.g. setting incognito-enabled state for a @@ -50,110 +47,3 @@ void ExtensionInfoMap::RemoveExtension(const std::string& id, NOTREACHED() << id; } } - - -std::string ExtensionInfoMap::GetNameForExtension(const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - if (iter != extension_info_.end()) - return iter->second->name(); - else - return std::string(); -} - -FilePath ExtensionInfoMap::GetPathForExtension(const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - if (iter != extension_info_.end()) - return iter->second->path(); - else - return FilePath(); -} - -FilePath ExtensionInfoMap::GetPathForDisabledExtension( - const std::string& id) const { - Map::const_iterator iter = disabled_extension_info_.find(id); - if (iter != disabled_extension_info_.end()) - return iter->second->path(); - else - return FilePath(); -} - -std::string ExtensionInfoMap::GetContentSecurityPolicyForExtension( - const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - if (iter != extension_info_.end()) - return iter->second->content_security_policy(); - else - return std::string(); -} - -bool ExtensionInfoMap::ExtensionHasWebExtent(const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - return iter != extension_info_.end() && - !iter->second->web_extent().is_empty(); -} - -bool ExtensionInfoMap::ExtensionCanLoadInIncognito( - const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - // Only split-mode extensions can load in incognito profiles. - return iter != extension_info_.end() && iter->second->incognito_split_mode(); -} - -std::string ExtensionInfoMap::GetDefaultLocaleForExtension( - const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - std::string result; - if (iter != extension_info_.end()) - result = iter->second->default_locale(); - - return result; -} - -URLPatternSet ExtensionInfoMap::GetEffectiveHostPermissionsForExtension( - const std::string& id) const { - Map::const_iterator iter = extension_info_.find(id); - URLPatternSet result; - if (iter != extension_info_.end()) - result = iter->second->GetEffectiveHostPermissions(); - - return result; -} - -bool ExtensionInfoMap::CheckURLAccessToExtensionPermission( - const GURL& url, - const char* permission_name) const { - Map::const_iterator info; - if (url.SchemeIs(chrome::kExtensionScheme)) { - // If the url is an extension scheme, we just look it up by extension id. - std::string id = url.host(); - info = extension_info_.find(id); - } else { - // Otherwise, we scan for a matching extent. Overlapping extents are - // disallowed, so only one will match. - info = extension_info_.begin(); - while (info != extension_info_.end() && - !info->second->web_extent().MatchesURL(url)) - ++info; - } - - if (info == extension_info_.end()) - return false; - - return info->second->api_permissions().count(permission_name) != 0; -} - -bool ExtensionInfoMap::URLIsForExtensionIcon(const GURL& url) const { - DCHECK(url.SchemeIs(chrome::kExtensionScheme)); - - Map::const_iterator iter = extension_info_.find(url.host()); - if (iter == extension_info_.end()) { - iter = disabled_extension_info_.find(url.host()); - if (iter == disabled_extension_info_.end()) - return false; - } - - std::string path = url.path(); - DCHECK(path.length() > 0 && path[0] == '/'); - path = path.substr(1); - return iter->second->icons().ContainsPath(path); -} diff --git a/chrome/browser/extensions/extension_info_map.h b/chrome/browser/extensions/extension_info_map.h index 5d335c0..1c1edb0 100644 --- a/chrome/browser/extensions/extension_info_map.h +++ b/chrome/browser/extensions/extension_info_map.h @@ -6,29 +6,28 @@ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_INFO_MAP_H_ #pragma once -#include <map> #include <string> #include "base/basictypes.h" -#include "base/file_path.h" #include "base/memory/ref_counted.h" #include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/url_pattern_set.h" -#include "googleurl/src/gurl.h" +#include "chrome/common/extensions/extension_set.h" class Extension; // Contains extension data that needs to be accessed on the IO thread. It can // be created/destroyed on any thread, but all other methods must be called on // the IO thread. -// -// TODO(mpcomplete): consider simplifying this class to return the StaticData -// object itself, since most methods are simple property accessors. class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> { public: ExtensionInfoMap(); ~ExtensionInfoMap(); + const ExtensionSet& extensions() const { return extensions_; } + const ExtensionSet& disabled_extensions() const { + return disabled_extensions_; + } + // Callback for when new extensions are loaded. void AddExtension(const Extension* extension); @@ -36,47 +35,9 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> { void RemoveExtension(const std::string& id, const UnloadedExtensionInfo::Reason reason); - // Gets the name for the specified extension. - std::string GetNameForExtension(const std::string& id) const; - - // Gets the path to the directory for the specified extension. - FilePath GetPathForExtension(const std::string& id) const; - - // Gets the path to the directory for the specified disabled extension. - FilePath GetPathForDisabledExtension(const std::string& id) const; - - std::string GetContentSecurityPolicyForExtension( - const std::string& id) const; - - // Returns true if the specified extension exists and has a non-empty web - // extent. - bool ExtensionHasWebExtent(const std::string& id) const; - - // Returns true if the specified extension exists and can load in incognito - // contexts. - bool ExtensionCanLoadInIncognito(const std::string& id) const; - - // Returns an empty string if the extension with |id| doesn't have a default - // locale. - std::string GetDefaultLocaleForExtension(const std::string& id) const; - - // Gets the effective host permissions for the extension with |id|. - URLPatternSet - GetEffectiveHostPermissionsForExtension(const std::string& id) const; - - // Determine whether a URL has access to the specified extension permission. - bool CheckURLAccessToExtensionPermission(const GURL& url, - const char* permission_name) const; - - // Returns true if the specified URL references the icon for an extension. - bool URLIsForExtensionIcon(const GURL& url) const; - private: - // Map of extension info by extension id. - typedef std::map<std::string, scoped_refptr<const Extension> > Map; - - Map extension_info_; - Map disabled_extension_info_; + ExtensionSet extensions_; + ExtensionSet disabled_extensions_; }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INFO_MAP_H_ diff --git a/chrome/browser/extensions/extension_info_map_unittest.cc b/chrome/browser/extensions/extension_info_map_unittest.cc index 659b085..66dcb7c 100644 --- a/chrome/browser/extensions/extension_info_map_unittest.cc +++ b/chrome/browser/extensions/extension_info_map_unittest.cc @@ -112,15 +112,9 @@ TEST_F(ExtensionInfoMapTest, Properties) { info_map->AddExtension(extension1); info_map->AddExtension(extension2); - EXPECT_EQ(extension1->name(), - info_map->GetNameForExtension(extension1->id())); - EXPECT_EQ(extension2->name(), - info_map->GetNameForExtension(extension2->id())); - - EXPECT_EQ(extension1->path().value(), - info_map->GetPathForExtension(extension1->id()).value()); - EXPECT_EQ(extension2->path().value(), - info_map->GetPathForExtension(extension2->id()).value()); + EXPECT_EQ(2u, info_map->extensions().size()); + EXPECT_EQ(extension1.get(), info_map->extensions().GetByID(extension1->id())); + EXPECT_EQ(extension2.get(), info_map->extensions().GetByID(extension2->id())); } // Tests CheckURLAccessToExtensionPermission given both extension and app URLs. @@ -128,9 +122,9 @@ TEST_F(ExtensionInfoMapTest, CheckPermissions) { scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap()); scoped_refptr<Extension> app(LoadManifest("manifest_tests", - "valid_app.json")); + "valid_app.json")); scoped_refptr<Extension> extension(LoadManifest("manifest_tests", - "tabs_extension.json")); + "tabs_extension.json")); GURL app_url("http://www.google.com/mail/foo.html"); ASSERT_TRUE(app->is_app()); @@ -141,24 +135,26 @@ TEST_F(ExtensionInfoMapTest, CheckPermissions) { // The app should have the notifications permission, either from a // chrome-extension URL or from its web extent. - EXPECT_TRUE(info_map->CheckURLAccessToExtensionPermission( - app->GetResourceURL("a.html"), Extension::kNotificationPermission)); - EXPECT_TRUE(info_map->CheckURLAccessToExtensionPermission( - app_url, Extension::kNotificationPermission)); - EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( - app_url, Extension::kTabPermission)); + const Extension* match = info_map->extensions().GetByURL( + app->GetResourceURL("a.html")); + EXPECT_TRUE(match && + match->HasApiPermission(Extension::kNotificationPermission)); + match = info_map->extensions().GetByURL(app_url); + EXPECT_TRUE(match && + match->HasApiPermission(Extension::kNotificationPermission)); + EXPECT_FALSE(match && + match->HasApiPermission(Extension::kTabPermission)); // The extension should have the tabs permission. - EXPECT_TRUE(info_map->CheckURLAccessToExtensionPermission( - extension->GetResourceURL("a.html"), Extension::kTabPermission)); - EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( - extension->GetResourceURL("a.html"), Extension::kNotificationPermission)); + match = info_map->extensions().GetByURL(extension->GetResourceURL("a.html")); + EXPECT_TRUE(match && + match->HasApiPermission(Extension::kTabPermission)); + EXPECT_FALSE(match && + match->HasApiPermission(Extension::kNotificationPermission)); // Random URL should not have any permissions. - EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( - GURL("http://evil.com/a.html"), Extension::kNotificationPermission)); - EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( - GURL("http://evil.com/a.html"), Extension::kTabPermission)); + match = info_map->extensions().GetByURL(GURL("http://evil.com/a.html")); + EXPECT_FALSE(match); } } // namespace diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc index 5c7b47e..1a94cab 100644 --- a/chrome/browser/extensions/extension_protocols.cc +++ b/chrome/browser/extensions/extension_protocols.cc @@ -115,6 +115,14 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { net::HttpResponseInfo response_info_; }; +bool ExtensionCanLoadInIncognito(const std::string& extension_id, + ExtensionInfoMap* extension_info_map) { + const Extension* extension = + extension_info_map->extensions().GetByID(extension_id); + // Only split-mode extensions can load in incognito profiles. + return extension && extension->incognito_split_mode(); +} + // Returns true if an chrome-extension:// resource should be allowed to load. // TODO(aa): This should be moved into ExtensionResourceRequestPolicy, but we // first need to find a way to get CanLoadInIncognito state into the renderers. @@ -137,7 +145,7 @@ bool AllowExtensionResourceLoad(net::URLRequest* request, // incognito tab prevents that. if (is_incognito && info->resource_type() == ResourceType::MAIN_FRAME && - !extension_info_map->ExtensionCanLoadInIncognito(request->url().host())) { + !ExtensionCanLoadInIncognito(request->url().host(), extension_info_map)) { LOG(ERROR) << "Denying load of " << request->url().spec() << " from " << "incognito tab."; return false; @@ -146,6 +154,20 @@ bool AllowExtensionResourceLoad(net::URLRequest* request, return true; } +// Returns true if the given URL references an icon in the given extension. +bool URLIsForExtensionIcon(const GURL& url, const Extension* extension) { + DCHECK(url.SchemeIs(chrome::kExtensionScheme)); + + if (!extension) + return false; + + std::string path = url.path(); + DCHECK_EQ(url.host(), extension->id()); + DCHECK(path.length() > 0 && path[0] == '/'); + path = path.substr(1); + return extension->icons().ContainsPath(path); +} + class ExtensionProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { public: @@ -177,20 +199,25 @@ ExtensionProtocolHandler::MaybeCreateJob(net::URLRequest* request) const { // chrome-extension://extension-id/resource/path.js const std::string& extension_id = request->url().host(); - FilePath directory_path = extension_info_map_-> - GetPathForExtension(extension_id); + const Extension* extension = + extension_info_map_->extensions().GetByID(extension_id); + FilePath directory_path; + if (extension) + directory_path = extension->path(); if (directory_path.value().empty()) { - if (extension_info_map_->URLIsForExtensionIcon(request->url())) - directory_path = extension_info_map_-> - GetPathForDisabledExtension(extension_id); + const Extension* disabled_extension = + extension_info_map_->disabled_extensions().GetByID(extension_id); + if (URLIsForExtensionIcon(request->url(), disabled_extension)) + directory_path = disabled_extension->path(); if (directory_path.value().empty()) { LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id; return NULL; } } - const std::string& content_security_policy = extension_info_map_-> - GetContentSecurityPolicyForExtension(extension_id); + std::string content_security_policy; + if (extension) + content_security_policy = extension->content_security_policy(); FilePath resources_path; if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) && |