X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fextensions%2Fcommon%2Ffeatures%2Fsimple_feature.cc;h=e623bcf47d7661c48a2080f85d590f3b9cfc0a48;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=21d4e229b077963ca022b88668a38c7e79e2572d;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/extensions/common/features/simple_feature.cc b/src/extensions/common/features/simple_feature.cc index 21d4e22..e623bcf 100644 --- a/src/extensions/common/features/simple_feature.cc +++ b/src/extensions/common/features/simple_feature.cc @@ -7,6 +7,7 @@ #include #include +#include "base/bind.h" #include "base/command_line.h" #include "base/debug/alias.h" #include "base/lazy_instance.h" @@ -14,12 +15,33 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "extensions/common/extension_api.h" +#include "extensions/common/features/feature_provider.h" #include "extensions/common/switches.h" namespace extensions { namespace { +Feature::Availability IsAvailableToManifestForBind( + const std::string& extension_id, + Manifest::Type type, + Manifest::Location location, + int manifest_version, + Feature::Platform platform, + const Feature* feature) { + return feature->IsAvailableToManifest( + extension_id, type, location, manifest_version, platform); +} + +Feature::Availability IsAvailableToContextForBind(const Extension* extension, + Feature::Context context, + const GURL& url, + Feature::Platform platform, + const Feature* feature) { + return feature->IsAvailableToContext(extension, context, url, platform); +} + struct Mappings { Mappings() { extension_types["extension"] = Manifest::TYPE_EXTENSION; @@ -34,6 +56,7 @@ struct Mappings { contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT; contexts["web_page"] = Feature::WEB_PAGE_CONTEXT; contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT; + contexts["webui"] = Feature::WEBUI_CONTEXT; locations["component"] = SimpleFeature::COMPONENT_LOCATION; locations["policy"] = SimpleFeature::POLICY_LOCATION; @@ -190,6 +213,8 @@ std::string GetDisplayName(Feature::Context context) { return "web page"; case Feature::BLESSED_WEB_PAGE_CONTEXT: return "hosted app"; + case Feature::WEBUI_CONTEXT: + return "webui"; } NOTREACHED(); return ""; @@ -234,6 +259,10 @@ SimpleFeature::SimpleFeature() SimpleFeature::~SimpleFeature() {} +bool SimpleFeature::HasDependencies() { + return !dependencies_.empty(); +} + void SimpleFeature::AddFilter(scoped_ptr filter) { filters_.push_back(make_linked_ptr(filter.release())); } @@ -261,10 +290,14 @@ std::string SimpleFeature::Parse(const base::DictionaryValue* value) { value->GetBoolean("component_extensions_auto_granted", &component_extensions_auto_granted_); - if (matches_.is_empty() && contexts_.count(WEB_PAGE_CONTEXT) != 0) { - return name() + ": Allowing web_page contexts requires supplying a value " + - "for matches."; - } + // NOTE: ideally we'd sanity check that "matches" can be specified if and + // only if there's a "web_page" or "webui" context, but without + // (Simple)Features being aware of their own heirarchy this is impossible. + // + // For example, we might have feature "foo" available to "web_page" context + // and "matches" google.com/*. Then a sub-feature "foo.bar" might override + // "matches" to be chromium.org/*. That sub-feature doesn't need to specify + // "web_page" context because it's inherited, but we don't know that here. for (FilterList::iterator filter_iter = filters_.begin(); filter_iter != filters_.end(); @@ -343,7 +376,12 @@ Feature::Availability SimpleFeature::IsAvailableToManifest( return availability; } - return CreateAvailability(IS_AVAILABLE, type); + return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, + extension_id, + type, + location, + manifest_version, + platform)); } Feature::Availability SimpleFeature::IsAvailableToContext( @@ -364,8 +402,13 @@ Feature::Availability SimpleFeature::IsAvailableToContext( if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) return CreateAvailability(INVALID_CONTEXT, context); - if (!matches_.is_empty() && !matches_.MatchesURL(url)) + // TODO(kalman): Consider checking |matches_| regardless of context type. + // Fewer surprises, and if the feature configuration wants to isolate + // "matches" from say "blessed_extension" then they can use complex features. + if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && + !matches_.MatchesURL(url)) { return CreateAvailability(INVALID_URL, url); + } for (FilterList::const_iterator filter_iter = filters_.begin(); filter_iter != filters_.end(); @@ -376,7 +419,10 @@ Feature::Availability SimpleFeature::IsAvailableToContext( return availability; } - return CreateAvailability(IS_AVAILABLE); + // TODO(kalman): Assert that if the context was a webpage or WebUI context + // then at some point a "matches" restriction was checked. + return CheckDependencies(base::Bind( + &IsAvailableToContextForBind, extension, context, url, platform)); } std::string SimpleFeature::GetAvailabilityMessage( @@ -470,16 +516,10 @@ Feature::Availability SimpleFeature::CreateAvailability( context)); } -std::set* SimpleFeature::GetContexts() { - return &contexts_; -} - bool SimpleFeature::IsInternal() const { return false; } -bool SimpleFeature::IsBlockedInServiceWorker() const { return false; } - bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { return IsIdInList(extension_id, blacklist_); } @@ -522,4 +562,20 @@ bool SimpleFeature::MatchesManifestLocation( return false; } +Feature::Availability SimpleFeature::CheckDependencies( + const base::Callback& checker) const { + for (std::set::const_iterator it = dependencies_.begin(); + it != dependencies_.end(); + ++it) { + Feature* dependency = + ExtensionAPI::GetSharedInstance()->GetFeatureDependency(*it); + if (!dependency) + return CreateAvailability(NOT_PRESENT); + Availability dependency_availability = checker.Run(dependency); + if (!dependency_availability.is_available()) + return dependency_availability; + } + return CreateAvailability(IS_AVAILABLE); +} + } // namespace extensions