Chromium Code Reviews| Index: extensions/common/features/simple_feature.cc |
| diff --git a/extensions/common/features/simple_feature.cc b/extensions/common/features/simple_feature.cc |
| index ebb9cb21fd43de212945780a7b52296ac0182708..92b41b4120832b9da4287a4fb44e47f7415c09da 100644 |
| --- a/extensions/common/features/simple_feature.cc |
| +++ b/extensions/common/features/simple_feature.cc |
| @@ -21,31 +21,36 @@ namespace { |
| struct Mappings { |
| Mappings() { |
| - extension_types["extension"] = Manifest::TYPE_EXTENSION; |
| - extension_types["theme"] = Manifest::TYPE_THEME; |
| - extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; |
| - extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; |
| - extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; |
| - extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; |
| - |
| - contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; |
| - contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT; |
| - contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT; |
| - contexts["web_page"] = Feature::WEB_PAGE_CONTEXT; |
| - contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT; |
| - |
| - locations["component"] = Feature::COMPONENT_LOCATION; |
| - |
| - platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; |
| - platforms["linux"] = Feature::LINUX_PLATFORM; |
| - platforms["mac"] = Feature::MACOSX_PLATFORM; |
| - platforms["win"] = Feature::WIN_PLATFORM; |
| + extension_types["extension"].push_back(Manifest::TYPE_EXTENSION); |
|
not at google - send to devlin
2014/04/17 21:33:14
I'm not... super happy about these changes.
Yoyo Zhou
2014/04/17 21:53:12
Can you replace Manifest::Location with something
not at google - send to devlin
2014/04/17 21:59:31
I found the old way of doing that a bit awkward; e
Yoyo Zhou
2014/04/17 22:00:30
You don't have to expose it. Just pass in the Mani
|
| + extension_types["theme"].push_back(Manifest::TYPE_THEME); |
| + extension_types["legacy_packaged_app"].push_back( |
| + Manifest::TYPE_LEGACY_PACKAGED_APP); |
| + extension_types["hosted_app"].push_back(Manifest::TYPE_HOSTED_APP); |
| + extension_types["platform_app"].push_back(Manifest::TYPE_PLATFORM_APP); |
| + extension_types["shared_module"].push_back(Manifest::TYPE_SHARED_MODULE); |
| + |
| + contexts["blessed_extension"].push_back(Feature::BLESSED_EXTENSION_CONTEXT); |
| + contexts["unblessed_extension"].push_back( |
| + Feature::UNBLESSED_EXTENSION_CONTEXT); |
| + contexts["content_script"].push_back(Feature::CONTENT_SCRIPT_CONTEXT); |
| + contexts["web_page"].push_back(Feature::WEB_PAGE_CONTEXT); |
| + contexts["blessed_web_page"].push_back(Feature::BLESSED_WEB_PAGE_CONTEXT); |
| + |
| + locations["component"].push_back(Manifest::COMPONENT); |
| + locations["component"].push_back(Manifest::EXTERNAL_COMPONENT); |
| + locations["policy"].push_back(Manifest::EXTERNAL_POLICY_DOWNLOAD); |
| + locations["policy"].push_back(Manifest::EXTERNAL_POLICY); |
| + |
| + platforms["chromeos"].push_back(Feature::CHROMEOS_PLATFORM); |
| + platforms["linux"].push_back(Feature::LINUX_PLATFORM); |
| + platforms["mac"].push_back(Feature::MACOSX_PLATFORM); |
| + platforms["win"].push_back(Feature::WIN_PLATFORM); |
| } |
| - std::map<std::string, Manifest::Type> extension_types; |
| - std::map<std::string, Feature::Context> contexts; |
| - std::map<std::string, Feature::Location> locations; |
| - std::map<std::string, Feature::Platform> platforms; |
| + std::map<std::string, std::vector<Manifest::Type> > extension_types; |
| + std::map<std::string, std::vector<Feature::Context> > contexts; |
| + std::map<std::string, std::vector<Manifest::Location> > locations; |
| + std::map<std::string, std::vector<Feature::Platform> > platforms; |
| }; |
| base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER; |
| @@ -67,33 +72,29 @@ void ParseSet(const base::DictionaryValue* value, |
| } |
| } |
| -template<typename T> |
| -void ParseEnum(const std::string& string_value, |
| - T* enum_value, |
| - const std::map<std::string, T>& mapping) { |
| - typename std::map<std::string, T>::const_iterator iter = |
| +template <typename T> |
| +void ParseEnumHelper(const std::string& string_value, |
| + const std::map<std::string, std::vector<T> >& mapping, |
| + std::set<T>* enum_set) { |
| + typename std::map<std::string, std::vector<T> >::const_iterator iter = |
| mapping.find(string_value); |
| CHECK(iter != mapping.end()) << string_value; |
| - *enum_value = iter->second; |
| + enum_set->insert(iter->second.begin(), iter->second.end()); |
| } |
| -template<typename T> |
| -void ParseEnum(const base::DictionaryValue* value, |
| - const std::string& property, |
| - T* enum_value, |
| - const std::map<std::string, T>& mapping) { |
| - std::string string_value; |
| - if (!value->GetString(property, &string_value)) |
| - return; |
| - |
| - ParseEnum(string_value, enum_value, mapping); |
| +template <typename T> |
| +void ParseEnum(const std::string& string_value, |
| + const std::map<std::string, std::vector<T> >& mapping, |
| + std::set<T>* enum_set) { |
| + enum_set->clear(); |
| + ParseEnumHelper(string_value, mapping, enum_set); |
| } |
| -template<typename T> |
| +template <typename T> |
| void ParseEnumSet(const base::DictionaryValue* value, |
| const std::string& property, |
| - std::set<T>* enum_set, |
| - const std::map<std::string, T>& mapping) { |
| + const std::map<std::string, std::vector<T> >& mapping, |
| + std::set<T>* enum_set) { |
| if (!value->HasKey(property)) |
| return; |
| @@ -102,9 +103,11 @@ void ParseEnumSet(const base::DictionaryValue* value, |
| std::string property_string; |
| if (value->GetString(property, &property_string)) { |
| if (property_string == "all") { |
| - for (typename std::map<std::string, T>::const_iterator j = |
| - mapping.begin(); j != mapping.end(); ++j) { |
| - enum_set->insert(j->second); |
| + for (typename std::map<std::string, std::vector<T> >::const_iterator j = |
| + mapping.begin(); |
| + j != mapping.end(); |
| + ++j) { |
| + enum_set->insert(j->second.begin(), j->second.end()); |
| } |
| } |
| return; |
| @@ -114,9 +117,7 @@ void ParseEnumSet(const base::DictionaryValue* value, |
| ParseSet(value, property, &string_set); |
| for (std::set<std::string>::iterator iter = string_set.begin(); |
| iter != string_set.end(); ++iter) { |
| - T enum_value = static_cast<T>(0); |
| - ParseEnum(*iter, &enum_value, mapping); |
| - enum_set->insert(enum_value); |
| + ParseEnumHelper(*iter, mapping, enum_set); |
| } |
| } |
| @@ -215,10 +216,8 @@ std::string HashExtensionId(const std::string& extension_id) { |
| } // namespace |
| SimpleFeature::SimpleFeature() |
| - : location_(UNSPECIFIED_LOCATION), |
| - min_manifest_version_(0), |
| - max_manifest_version_(0), |
| - has_parent_(false) {} |
| + : min_manifest_version_(0), max_manifest_version_(0), has_parent_(false) { |
| +} |
| SimpleFeature::~SimpleFeature() {} |
| @@ -230,14 +229,21 @@ std::string SimpleFeature::Parse(const base::DictionaryValue* value) { |
| ParseURLPatterns(value, "matches", &matches_); |
| ParseSet(value, "whitelist", &whitelist_); |
| ParseSet(value, "dependencies", &dependencies_); |
| - ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, |
| - g_mappings.Get().extension_types); |
| - ParseEnumSet<Context>(value, "contexts", &contexts_, |
| - g_mappings.Get().contexts); |
| - ParseEnum<Location>(value, "location", &location_, |
| - g_mappings.Get().locations); |
| - ParseEnumSet<Platform>(value, "platforms", &platforms_, |
| - g_mappings.Get().platforms); |
| + ParseEnumSet<Manifest::Type>(value, |
| + "extension_types", |
| + g_mappings.Get().extension_types, |
| + &extension_types_); |
| + // Only a single value is supported for "location", but it expands to |
| + // multiple possible values. |
| + std::string location; |
| + if (value->GetStringWithoutPathExpansion("location", &location)) { |
| + ParseEnum<Manifest::Location>( |
| + location, g_mappings.Get().locations, &locations_); |
| + } |
| + ParseEnumSet<Context>( |
| + value, "contexts", g_mappings.Get().contexts, &contexts_); |
| + ParseEnumSet<Platform>( |
| + value, "platforms", g_mappings.Get().platforms, &platforms_); |
| value->GetInteger("min_manifest_version", &min_manifest_version_); |
| value->GetInteger("max_manifest_version", &max_manifest_version_); |
| @@ -264,23 +270,19 @@ std::string SimpleFeature::Parse(const base::DictionaryValue* value) { |
| Feature::Availability SimpleFeature::IsAvailableToManifest( |
| const std::string& extension_id, |
| Manifest::Type type, |
| - Location location, |
| + Manifest::Location location, |
| int manifest_version, |
| Platform platform) const { |
| - // Check extension type first to avoid granting platform app permissions |
| - // to component extensions. |
| - // HACK(kalman): user script -> extension. Solve this in a more generic way |
| - // when we compile feature files. |
| - Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? |
| - Manifest::TYPE_EXTENSION : type; |
| if (!extension_types_.empty() && |
| - extension_types_.find(type_to_check) == extension_types_.end()) { |
| + extension_types_.find(type) == extension_types_.end()) { |
| return CreateAvailability(INVALID_TYPE, type); |
| } |
| // Component extensions can access any feature. |
| - if (location == COMPONENT_LOCATION) |
| + if (location == Manifest::COMPONENT || |
| + location == Manifest::EXTERNAL_COMPONENT) { |
| return CreateAvailability(IS_AVAILABLE, type); |
| + } |
| if (!whitelist_.empty()) { |
| if (!IsIdInWhitelist(extension_id)) { |
| @@ -298,7 +300,7 @@ Feature::Availability SimpleFeature::IsAvailableToManifest( |
| } |
| } |
| - if (location_ != UNSPECIFIED_LOCATION && location_ != location) |
| + if (!locations_.empty() && locations_.find(location) == locations_.end()) |
|
Yoyo Zhou
2014/04/17 21:53:12
Change this test to be something like location_cla
not at google - send to devlin
2014/04/17 23:18:11
done sort of. I went back to how the code was befo
|
| return CreateAvailability(INVALID_LOCATION, type); |
| if (!platforms_.empty() && |
| @@ -329,12 +331,11 @@ Feature::Availability SimpleFeature::IsAvailableToContext( |
| const GURL& url, |
| SimpleFeature::Platform platform) const { |
| if (extension) { |
| - Availability result = IsAvailableToManifest( |
| - extension->id(), |
| - extension->GetType(), |
| - ConvertLocation(extension->location()), |
| - extension->manifest_version(), |
| - platform); |
| + Availability result = IsAvailableToManifest(extension->id(), |
| + extension->GetType(), |
| + extension->location(), |
| + extension->manifest_version(), |
| + platform); |
| if (!result.is_available()) |
| return result; |
| } |