Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: extensions/common/features/simple_feature.cc

Issue 2202733003: [Extensions] Remove JSONFeatureProvider, SimpleFeature::Parse (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Lei's Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/common/features/simple_feature.h" 5 #include "extensions/common/features/simple_feature.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 } 46 }
47 47
48 Feature::Availability IsAvailableToContextForBind(const Extension* extension, 48 Feature::Availability IsAvailableToContextForBind(const Extension* extension,
49 Feature::Context context, 49 Feature::Context context,
50 const GURL& url, 50 const GURL& url,
51 Feature::Platform platform, 51 Feature::Platform platform,
52 const Feature* feature) { 52 const Feature* feature) {
53 return feature->IsAvailableToContext(extension, context, url, platform); 53 return feature->IsAvailableToContext(extension, context, url, platform);
54 } 54 }
55 55
56 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff?
57
58 void ParseVector(const base::Value* value,
59 std::vector<std::string>* vector) {
60 const base::ListValue* list_value = NULL;
61 if (!value->GetAsList(&list_value))
62 return;
63
64 vector->clear();
65 size_t list_size = list_value->GetSize();
66 vector->reserve(list_size);
67 for (size_t i = 0; i < list_size; ++i) {
68 std::string str_val;
69 CHECK(list_value->GetString(i, &str_val));
70 vector->push_back(str_val);
71 }
72 std::sort(vector->begin(), vector->end());
73 }
74
75 template<typename T>
76 void ParseEnum(const std::string& string_value,
77 T* enum_value,
78 const std::map<std::string, T>& mapping) {
79 const auto& iter = mapping.find(string_value);
80 if (iter == mapping.end())
81 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value);
82 *enum_value = iter->second;
83 }
84
85 template <typename T>
86 void ParseEnum(const base::Value* value,
87 T* enum_value,
88 const std::map<std::string, T>& mapping) {
89 std::string string_value;
90 if (!value->GetAsString(&string_value))
91 return;
92
93 ParseEnum(string_value, enum_value, mapping);
94 }
95
96 template<typename T>
97 void ParseEnumVector(const base::Value* value,
98 std::vector<T>* enum_vector,
99 const std::map<std::string, T>& mapping) {
100 enum_vector->clear();
101 std::string property_string;
102 if (value->GetAsString(&property_string)) {
103 if (property_string == "all") {
104 enum_vector->reserve(mapping.size());
105 for (const auto& it : mapping)
106 enum_vector->push_back(it.second);
107 }
108 std::sort(enum_vector->begin(), enum_vector->end());
109 return;
110 }
111
112 std::vector<std::string> string_vector;
113 ParseVector(value, &string_vector);
114 enum_vector->reserve(string_vector.size());
115 for (const auto& str : string_vector) {
116 T enum_value = static_cast<T>(0);
117 ParseEnum(str, &enum_value, mapping);
118 enum_vector->push_back(enum_value);
119 }
120 std::sort(enum_vector->begin(), enum_vector->end());
121 }
122
123 void ParseURLPatterns(const base::DictionaryValue* value,
124 const std::string& key,
125 URLPatternSet* set) {
126 const base::ListValue* matches = NULL;
127 if (value->GetList(key, &matches)) {
128 set->ClearPatterns();
129 for (size_t i = 0; i < matches->GetSize(); ++i) {
130 std::string pattern;
131 CHECK(matches->GetString(i, &pattern));
132 set->AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern));
133 }
134 }
135 }
136
137 // Gets a human-readable name for the given extension type, suitable for giving 56 // Gets a human-readable name for the given extension type, suitable for giving
138 // to developers in an error message. 57 // to developers in an error message.
139 std::string GetDisplayName(Manifest::Type type) { 58 std::string GetDisplayName(Manifest::Type type) {
140 switch (type) { 59 switch (type) {
141 case Manifest::TYPE_UNKNOWN: 60 case Manifest::TYPE_UNKNOWN:
142 return "unknown"; 61 return "unknown";
143 case Manifest::TYPE_EXTENSION: 62 case Manifest::TYPE_EXTENSION:
144 return "extension"; 63 return "extension";
145 case Manifest::TYPE_HOSTED_APP: 64 case Manifest::TYPE_HOSTED_APP:
146 return "hosted app"; 65 return "hosted app";
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 const std::string& id) 177 const std::string& id)
259 : previous_id_(g_whitelisted_extension_id) { 178 : previous_id_(g_whitelisted_extension_id) {
260 g_whitelisted_extension_id = new std::string(id); 179 g_whitelisted_extension_id = new std::string(id);
261 } 180 }
262 181
263 SimpleFeature::ScopedWhitelistForTest::~ScopedWhitelistForTest() { 182 SimpleFeature::ScopedWhitelistForTest::~ScopedWhitelistForTest() {
264 delete g_whitelisted_extension_id; 183 delete g_whitelisted_extension_id;
265 g_whitelisted_extension_id = previous_id_; 184 g_whitelisted_extension_id = previous_id_;
266 } 185 }
267 186
268 struct SimpleFeature::Mappings {
269 Mappings() {
270 extension_types["extension"] = Manifest::TYPE_EXTENSION;
271 extension_types["theme"] = Manifest::TYPE_THEME;
272 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP;
273 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP;
274 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP;
275 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE;
276
277 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT;
278 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT;
279 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT;
280 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT;
281 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT;
282 contexts["webui"] = Feature::WEBUI_CONTEXT;
283 contexts["extension_service_worker"] = Feature::SERVICE_WORKER_CONTEXT;
284
285 locations["component"] = SimpleFeature::COMPONENT_LOCATION;
286 locations["external_component"] =
287 SimpleFeature::EXTERNAL_COMPONENT_LOCATION;
288 locations["policy"] = SimpleFeature::POLICY_LOCATION;
289
290 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM;
291 platforms["linux"] = Feature::LINUX_PLATFORM;
292 platforms["mac"] = Feature::MACOSX_PLATFORM;
293 platforms["win"] = Feature::WIN_PLATFORM;
294
295 channels["trunk"] = version_info::Channel::UNKNOWN;
296 channels["canary"] = version_info::Channel::CANARY;
297 channels["dev"] = version_info::Channel::DEV;
298 channels["beta"] = version_info::Channel::BETA;
299 channels["stable"] = version_info::Channel::STABLE;
300 }
301
302 std::map<std::string, Manifest::Type> extension_types;
303 std::map<std::string, Feature::Context> contexts;
304 std::map<std::string, SimpleFeature::Location> locations;
305 std::map<std::string, Feature::Platform> platforms;
306 std::map<std::string, version_info::Channel> channels;
307 };
308
309 SimpleFeature::SimpleFeature() 187 SimpleFeature::SimpleFeature()
310 : location_(UNSPECIFIED_LOCATION), 188 : location_(UNSPECIFIED_LOCATION),
311 min_manifest_version_(0), 189 min_manifest_version_(0),
312 max_manifest_version_(0), 190 max_manifest_version_(0),
313 component_extensions_auto_granted_(true), 191 component_extensions_auto_granted_(true),
314 is_internal_(false) {} 192 is_internal_(false) {}
315 193
316 SimpleFeature::~SimpleFeature() {} 194 SimpleFeature::~SimpleFeature() {}
317 195
318 void SimpleFeature::Parse(const base::DictionaryValue* dictionary) {
319 static base::LazyInstance<SimpleFeature::Mappings> mappings =
320 LAZY_INSTANCE_INITIALIZER;
321
322 no_parent_ = false;
323 for (base::DictionaryValue::Iterator it(*dictionary);
324 !it.IsAtEnd();
325 it.Advance()) {
326 const std::string& key = it.key();
327 const base::Value* value = &it.value();
328 if (key == "matches") {
329 ParseURLPatterns(dictionary, "matches", &matches_);
330 } else if (key == "blacklist") {
331 ParseVector(value, &blacklist_);
332 } else if (key == "whitelist") {
333 ParseVector(value, &whitelist_);
334 } else if (key == "dependencies") {
335 ParseVector(value, &dependencies_);
336 } else if (key == "extension_types") {
337 ParseEnumVector<Manifest::Type>(value, &extension_types_,
338 mappings.Get().extension_types);
339 } else if (key == "contexts") {
340 ParseEnumVector<Context>(value, &contexts_,
341 mappings.Get().contexts);
342 } else if (key == "location") {
343 ParseEnum<Location>(value, &location_, mappings.Get().locations);
344 } else if (key == "platforms") {
345 ParseEnumVector<Platform>(value, &platforms_,
346 mappings.Get().platforms);
347 } else if (key == "min_manifest_version") {
348 dictionary->GetInteger("min_manifest_version", &min_manifest_version_);
349 } else if (key == "max_manifest_version") {
350 dictionary->GetInteger("max_manifest_version", &max_manifest_version_);
351 } else if (key == "noparent") {
352 dictionary->GetBoolean("noparent", &no_parent_);
353 } else if (key == "component_extensions_auto_granted") {
354 dictionary->GetBoolean("component_extensions_auto_granted",
355 &component_extensions_auto_granted_);
356 } else if (key == "command_line_switch") {
357 dictionary->GetString("command_line_switch", &command_line_switch_);
358 } else if (key == "channel") {
359 channel_.reset(new version_info::Channel(version_info::Channel::UNKNOWN));
360 ParseEnum<version_info::Channel>(value, channel_.get(),
361 mappings.Get().channels);
362 } else if (key == "internal") {
363 value->GetAsBoolean(&is_internal_);
364 }
365 }
366
367 // NOTE: ideally we'd sanity check that "matches" can be specified if and
368 // only if there's a "web_page" or "webui" context, but without
369 // (Simple)Features being aware of their own heirarchy this is impossible.
370 //
371 // For example, we might have feature "foo" available to "web_page" context
372 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override
373 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify
374 // "web_page" context because it's inherited, but we don't know that here.
375 }
376
377 bool SimpleFeature::Validate(std::string* error) {
378 DCHECK(error);
379 // All features must be channel-restricted, either directly or through
380 // dependents.
381 if (!channel_ && dependencies_.empty()) {
382 *error = name() + ": Must supply a value for channel or dependencies.";
383 return false;
384 }
385
386 return true;
387 }
388
389 Feature::Availability SimpleFeature::IsAvailableToManifest( 196 Feature::Availability SimpleFeature::IsAvailableToManifest(
390 const std::string& extension_id, 197 const std::string& extension_id,
391 Manifest::Type type, 198 Manifest::Type type,
392 Manifest::Location location, 199 Manifest::Location location,
393 int manifest_version, 200 int manifest_version,
394 Platform platform) const { 201 Platform platform) const {
395 // Check extension type first to avoid granting platform app permissions 202 // Check extension type first to avoid granting platform app permissions
396 // to component extensions. 203 // to component extensions.
397 // HACK(kalman): user script -> extension. Solve this in a more generic way 204 // HACK(kalman): user script -> extension. Solve this in a more generic way
398 // when we compile feature files. 205 // when we compile feature files.
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 void SimpleFeature::set_platforms(std::initializer_list<Platform> platforms) { 508 void SimpleFeature::set_platforms(std::initializer_list<Platform> platforms) {
702 platforms_ = platforms; 509 platforms_ = platforms;
703 } 510 }
704 511
705 void SimpleFeature::set_whitelist( 512 void SimpleFeature::set_whitelist(
706 std::initializer_list<const char* const> whitelist) { 513 std::initializer_list<const char* const> whitelist) {
707 whitelist_.assign(whitelist.begin(), whitelist.end()); 514 whitelist_.assign(whitelist.begin(), whitelist.end());
708 } 515 }
709 516
710 } // namespace extensions 517 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/common/features/simple_feature.h ('k') | extensions/common/features/simple_feature_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698