OLD | NEW |
---|---|
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> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/sha1.h" | 15 #include "base/sha1.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
20 #include "components/crx_file/id_util.h" | 20 #include "components/crx_file/id_util.h" |
21 #include "extensions/common/extension_api.h" | 21 #include "extensions/common/extension_api.h" |
22 #include "extensions/common/features/feature_channel.h" | |
22 #include "extensions/common/features/feature_provider.h" | 23 #include "extensions/common/features/feature_provider.h" |
23 #include "extensions/common/features/feature_util.h" | 24 #include "extensions/common/features/feature_util.h" |
24 #include "extensions/common/switches.h" | 25 #include "extensions/common/switches.h" |
25 | 26 |
26 using crx_file::id_util::HashedIdInHex; | 27 using crx_file::id_util::HashedIdInHex; |
27 | 28 |
28 namespace extensions { | 29 namespace extensions { |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 template<typename T> | 75 template<typename T> |
75 void ParseEnum(const std::string& string_value, | 76 void ParseEnum(const std::string& string_value, |
76 T* enum_value, | 77 T* enum_value, |
77 const std::map<std::string, T>& mapping) { | 78 const std::map<std::string, T>& mapping) { |
78 const auto& iter = mapping.find(string_value); | 79 const auto& iter = mapping.find(string_value); |
79 if (iter == mapping.end()) | 80 if (iter == mapping.end()) |
80 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value); | 81 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value); |
81 *enum_value = iter->second; | 82 *enum_value = iter->second; |
82 } | 83 } |
83 | 84 |
84 template<typename T> | 85 template <typename T> |
85 void ParseEnum(const base::DictionaryValue* value, | 86 void ParseEnum(const base::Value* value, |
86 const std::string& property, | |
87 T* enum_value, | 87 T* enum_value, |
88 const std::map<std::string, T>& mapping) { | 88 const std::map<std::string, T>& mapping) { |
89 std::string string_value; | 89 std::string string_value; |
90 if (!value->GetString(property, &string_value)) | 90 if (!value->GetAsString(&string_value)) |
91 return; | 91 return; |
92 | 92 |
93 ParseEnum(string_value, enum_value, mapping); | 93 ParseEnum(string_value, enum_value, mapping); |
94 } | 94 } |
95 | 95 |
96 template<typename T> | 96 template<typename T> |
97 void ParseEnumVector(const base::Value* value, | 97 void ParseEnumVector(const base::Value* value, |
98 std::vector<T>* enum_vector, | 98 std::vector<T>* enum_vector, |
99 const std::map<std::string, T>& mapping) { | 99 const std::map<std::string, T>& mapping) { |
100 enum_vector->clear(); | 100 enum_vector->clear(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 return "hosted app"; | 183 return "hosted app"; |
184 case Feature::WEBUI_CONTEXT: | 184 case Feature::WEBUI_CONTEXT: |
185 return "webui"; | 185 return "webui"; |
186 case Feature::SERVICE_WORKER_CONTEXT: | 186 case Feature::SERVICE_WORKER_CONTEXT: |
187 return "service worker"; | 187 return "service worker"; |
188 } | 188 } |
189 NOTREACHED(); | 189 NOTREACHED(); |
190 return ""; | 190 return ""; |
191 } | 191 } |
192 | 192 |
193 std::string GetDisplayName(version_info::Channel channel) { | |
194 switch (channel) { | |
195 case version_info::Channel::UNKNOWN: | |
196 return "trunk"; | |
197 case version_info::Channel::CANARY: | |
198 return "canary"; | |
199 case version_info::Channel::DEV: | |
200 return "dev"; | |
201 case version_info::Channel::BETA: | |
202 return "beta"; | |
203 case version_info::Channel::STABLE: | |
204 return "stable"; | |
205 } | |
206 NOTREACHED(); | |
207 return ""; | |
208 } | |
209 | |
193 // Gets a human-readable list of the display names (pluralized, comma separated | 210 // Gets a human-readable list of the display names (pluralized, comma separated |
194 // with the "and" in the correct place) for each of |enum_types|. | 211 // with the "and" in the correct place) for each of |enum_types|. |
195 template <typename EnumType> | 212 template <typename EnumType> |
196 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { | 213 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { |
197 std::string display_name_list; | 214 std::string display_name_list; |
198 for (size_t i = 0; i < enum_types.size(); ++i) { | 215 for (size_t i = 0; i < enum_types.size(); ++i) { |
199 // Pluralize type name. | 216 // Pluralize type name. |
200 display_name_list += GetDisplayName(enum_types[i]) + "s"; | 217 display_name_list += GetDisplayName(enum_types[i]) + "s"; |
201 // Comma-separate entries, with an Oxford comma if there is more than 2 | 218 // Comma-separate entries, with an Oxford comma if there is more than 2 |
202 // total entries. | 219 // total entries. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 | 284 |
268 locations["component"] = SimpleFeature::COMPONENT_LOCATION; | 285 locations["component"] = SimpleFeature::COMPONENT_LOCATION; |
269 locations["external_component"] = | 286 locations["external_component"] = |
270 SimpleFeature::EXTERNAL_COMPONENT_LOCATION; | 287 SimpleFeature::EXTERNAL_COMPONENT_LOCATION; |
271 locations["policy"] = SimpleFeature::POLICY_LOCATION; | 288 locations["policy"] = SimpleFeature::POLICY_LOCATION; |
272 | 289 |
273 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; | 290 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; |
274 platforms["linux"] = Feature::LINUX_PLATFORM; | 291 platforms["linux"] = Feature::LINUX_PLATFORM; |
275 platforms["mac"] = Feature::MACOSX_PLATFORM; | 292 platforms["mac"] = Feature::MACOSX_PLATFORM; |
276 platforms["win"] = Feature::WIN_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; | |
277 } | 300 } |
278 | 301 |
279 std::map<std::string, Manifest::Type> extension_types; | 302 std::map<std::string, Manifest::Type> extension_types; |
303 std::map<std::string, version_info::Channel> channels; | |
lazyboy
2016/07/12 00:35:13
nit: any reason this is here and not after |platfo
Devlin
2016/07/12 19:10:00
Nope, moved.
| |
280 std::map<std::string, Feature::Context> contexts; | 304 std::map<std::string, Feature::Context> contexts; |
281 std::map<std::string, SimpleFeature::Location> locations; | 305 std::map<std::string, SimpleFeature::Location> locations; |
282 std::map<std::string, Feature::Platform> platforms; | 306 std::map<std::string, Feature::Platform> platforms; |
283 }; | 307 }; |
284 | 308 |
285 SimpleFeature::SimpleFeature() | 309 SimpleFeature::SimpleFeature() |
286 : location_(UNSPECIFIED_LOCATION), | 310 : location_(UNSPECIFIED_LOCATION), |
287 min_manifest_version_(0), | 311 min_manifest_version_(0), |
288 max_manifest_version_(0), | 312 max_manifest_version_(0), |
289 component_extensions_auto_granted_(true) {} | 313 component_extensions_auto_granted_(true) {} |
290 | 314 |
291 SimpleFeature::~SimpleFeature() {} | 315 SimpleFeature::~SimpleFeature() {} |
292 | 316 |
293 bool SimpleFeature::HasDependencies() const { | |
294 return !dependencies_.empty(); | |
295 } | |
296 | |
297 void SimpleFeature::AddFilter(std::unique_ptr<SimpleFeatureFilter> filter) { | |
lazyboy
2016/07/12 00:35:12
As we're not using SimpleFeatureFilter anymore, we
Devlin
2016/07/12 19:10:00
Whoops! Meant to do that, but looks like I only g
| |
298 filters_.push_back(std::move(filter)); | |
299 } | |
300 | |
301 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) { | 317 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) { |
302 static base::LazyInstance<SimpleFeature::Mappings> mappings = | 318 static base::LazyInstance<SimpleFeature::Mappings> mappings = |
303 LAZY_INSTANCE_INITIALIZER; | 319 LAZY_INSTANCE_INITIALIZER; |
304 | 320 |
305 no_parent_ = false; | 321 no_parent_ = false; |
306 for (base::DictionaryValue::Iterator it(*dictionary); | 322 for (base::DictionaryValue::Iterator it(*dictionary); |
307 !it.IsAtEnd(); | 323 !it.IsAtEnd(); |
308 it.Advance()) { | 324 it.Advance()) { |
309 std::string key = it.key(); | 325 std::string key = it.key(); |
310 const base::Value* value = &it.value(); | 326 const base::Value* value = &it.value(); |
311 if (key == "matches") { | 327 if (key == "matches") { |
312 ParseURLPatterns(dictionary, "matches", &matches_); | 328 ParseURLPatterns(dictionary, "matches", &matches_); |
313 } else if (key == "blacklist") { | 329 } else if (key == "blacklist") { |
314 ParseVector(value, &blacklist_); | 330 ParseVector(value, &blacklist_); |
315 } else if (key == "whitelist") { | 331 } else if (key == "whitelist") { |
316 ParseVector(value, &whitelist_); | 332 ParseVector(value, &whitelist_); |
317 } else if (key == "dependencies") { | 333 } else if (key == "dependencies") { |
318 ParseVector(value, &dependencies_); | 334 ParseVector(value, &dependencies_); |
319 } else if (key == "extension_types") { | 335 } else if (key == "extension_types") { |
320 ParseEnumVector<Manifest::Type>(value, &extension_types_, | 336 ParseEnumVector<Manifest::Type>(value, &extension_types_, |
321 mappings.Get().extension_types); | 337 mappings.Get().extension_types); |
322 } else if (key == "contexts") { | 338 } else if (key == "contexts") { |
323 ParseEnumVector<Context>(value, &contexts_, | 339 ParseEnumVector<Context>(value, &contexts_, |
324 mappings.Get().contexts); | 340 mappings.Get().contexts); |
325 } else if (key == "location") { | 341 } else if (key == "location") { |
326 ParseEnum<Location>(dictionary, "location", &location_, | 342 ParseEnum<Location>(value, &location_, mappings.Get().locations); |
327 mappings.Get().locations); | |
328 } else if (key == "platforms") { | 343 } else if (key == "platforms") { |
329 ParseEnumVector<Platform>(value, &platforms_, | 344 ParseEnumVector<Platform>(value, &platforms_, |
330 mappings.Get().platforms); | 345 mappings.Get().platforms); |
331 } else if (key == "min_manifest_version") { | 346 } else if (key == "min_manifest_version") { |
332 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); | 347 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); |
333 } else if (key == "max_manifest_version") { | 348 } else if (key == "max_manifest_version") { |
334 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); | 349 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); |
335 } else if (key == "noparent") { | 350 } else if (key == "noparent") { |
336 dictionary->GetBoolean("noparent", &no_parent_); | 351 dictionary->GetBoolean("noparent", &no_parent_); |
337 } else if (key == "component_extensions_auto_granted") { | 352 } else if (key == "component_extensions_auto_granted") { |
338 dictionary->GetBoolean("component_extensions_auto_granted", | 353 dictionary->GetBoolean("component_extensions_auto_granted", |
339 &component_extensions_auto_granted_); | 354 &component_extensions_auto_granted_); |
340 } else if (key == "command_line_switch") { | 355 } else if (key == "command_line_switch") { |
341 dictionary->GetString("command_line_switch", &command_line_switch_); | 356 dictionary->GetString("command_line_switch", &command_line_switch_); |
357 } else if (key == "channel") { | |
358 channel_.reset(new version_info::Channel(version_info::Channel::UNKNOWN)); | |
359 ParseEnum<version_info::Channel>(value, channel_.get(), | |
360 mappings.Get().channels); | |
342 } | 361 } |
343 } | 362 } |
344 | 363 |
345 // NOTE: ideally we'd sanity check that "matches" can be specified if and | 364 // NOTE: ideally we'd sanity check that "matches" can be specified if and |
346 // only if there's a "web_page" or "webui" context, but without | 365 // only if there's a "web_page" or "webui" context, but without |
347 // (Simple)Features being aware of their own heirarchy this is impossible. | 366 // (Simple)Features being aware of their own heirarchy this is impossible. |
348 // | 367 // |
349 // For example, we might have feature "foo" available to "web_page" context | 368 // For example, we might have feature "foo" available to "web_page" context |
350 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override | 369 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override |
351 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify | 370 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify |
352 // "web_page" context because it's inherited, but we don't know that here. | 371 // "web_page" context because it's inherited, but we don't know that here. |
353 | 372 |
354 std::string result; | 373 // All features must be channel-restricted, either directly or through |
355 for (const auto& filter : filters_) { | 374 // dependents. |
356 result = filter->Parse(dictionary); | 375 if (!channel_ && dependencies_.empty()) |
357 if (!result.empty()) | 376 return name() + ": Must supply a value for channel or dependencies."; |
358 break; | |
359 } | |
360 | 377 |
361 return result; | 378 return std::string(); |
362 } | 379 } |
363 | 380 |
364 Feature::Availability SimpleFeature::IsAvailableToManifest( | 381 Feature::Availability SimpleFeature::IsAvailableToManifest( |
365 const std::string& extension_id, | 382 const std::string& extension_id, |
366 Manifest::Type type, | 383 Manifest::Type type, |
367 Manifest::Location location, | 384 Manifest::Location location, |
368 int manifest_version, | 385 int manifest_version, |
369 Platform platform) const { | 386 Platform platform) const { |
370 // Check extension type first to avoid granting platform app permissions | 387 // Check extension type first to avoid granting platform app permissions |
371 // to component extensions. | 388 // to component extensions. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 420 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
404 | 421 |
405 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) | 422 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) |
406 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); | 423 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); |
407 | 424 |
408 if (!command_line_switch_.empty() && | 425 if (!command_line_switch_.empty() && |
409 !IsCommandLineSwitchEnabled(command_line_switch_)) { | 426 !IsCommandLineSwitchEnabled(command_line_switch_)) { |
410 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); | 427 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); |
411 } | 428 } |
412 | 429 |
413 for (const auto& filter : filters_) { | 430 if (channel_ && *channel_ < GetCurrentChannel()) { |
lazyboy
2016/07/12 00:35:13
nit: drop {}
Devlin
2016/07/12 19:10:00
Done.
| |
414 Availability availability = filter->IsAvailableToManifest( | 431 return CreateAvailability(UNSUPPORTED_CHANNEL, *channel_); |
415 extension_id, type, location, manifest_version, platform); | |
416 if (!availability.is_available()) | |
417 return availability; | |
418 } | 432 } |
419 | 433 |
420 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, | 434 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, |
421 extension_id, | 435 extension_id, |
422 type, | 436 type, |
423 location, | 437 location, |
424 manifest_version, | 438 manifest_version, |
425 platform)); | 439 platform)); |
426 } | 440 } |
427 | 441 |
(...skipping 20 matching lines...) Expand all Loading... | |
448 return CreateAvailability(INVALID_CONTEXT, context); | 462 return CreateAvailability(INVALID_CONTEXT, context); |
449 | 463 |
450 // TODO(kalman): Consider checking |matches_| regardless of context type. | 464 // TODO(kalman): Consider checking |matches_| regardless of context type. |
451 // Fewer surprises, and if the feature configuration wants to isolate | 465 // Fewer surprises, and if the feature configuration wants to isolate |
452 // "matches" from say "blessed_extension" then they can use complex features. | 466 // "matches" from say "blessed_extension" then they can use complex features. |
453 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && | 467 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && |
454 !matches_.MatchesURL(url)) { | 468 !matches_.MatchesURL(url)) { |
455 return CreateAvailability(INVALID_URL, url); | 469 return CreateAvailability(INVALID_URL, url); |
456 } | 470 } |
457 | 471 |
458 for (const auto& filter : filters_) { | |
459 Availability availability = | |
460 filter->IsAvailableToContext(extension, context, url, platform); | |
461 if (!availability.is_available()) | |
462 return availability; | |
463 } | |
464 | |
465 // TODO(kalman): Assert that if the context was a webpage or WebUI context | 472 // TODO(kalman): Assert that if the context was a webpage or WebUI context |
466 // then at some point a "matches" restriction was checked. | 473 // then at some point a "matches" restriction was checked. |
467 return CheckDependencies(base::Bind( | 474 return CheckDependencies(base::Bind( |
468 &IsAvailableToContextForBind, extension, context, url, platform)); | 475 &IsAvailableToContextForBind, extension, context, url, platform)); |
469 } | 476 } |
470 | 477 |
471 std::string SimpleFeature::GetAvailabilityMessage( | 478 std::string SimpleFeature::GetAvailabilityMessage( |
472 AvailabilityResult result, | 479 AvailabilityResult result, |
473 Manifest::Type type, | 480 Manifest::Type type, |
474 const GURL& url, | 481 const GURL& url, |
475 Context context) const { | 482 Context context, |
483 version_info::Channel channel) const { | |
476 switch (result) { | 484 switch (result) { |
477 case IS_AVAILABLE: | 485 case IS_AVAILABLE: |
478 return std::string(); | 486 return std::string(); |
479 case NOT_FOUND_IN_WHITELIST: | 487 case NOT_FOUND_IN_WHITELIST: |
480 case FOUND_IN_BLACKLIST: | 488 case FOUND_IN_BLACKLIST: |
481 return base::StringPrintf( | 489 return base::StringPrintf( |
482 "'%s' is not allowed for specified extension ID.", | 490 "'%s' is not allowed for specified extension ID.", |
483 name().c_str()); | 491 name().c_str()); |
484 case INVALID_URL: | 492 case INVALID_URL: |
485 return base::StringPrintf("'%s' is not allowed on %s.", | 493 return base::StringPrintf("'%s' is not allowed on %s.", |
(...skipping 29 matching lines...) Expand all Loading... | |
515 return base::StringPrintf( | 523 return base::StringPrintf( |
516 "'%s' requires manifest version of %d or lower.", | 524 "'%s' requires manifest version of %d or lower.", |
517 name().c_str(), | 525 name().c_str(), |
518 max_manifest_version_); | 526 max_manifest_version_); |
519 case NOT_PRESENT: | 527 case NOT_PRESENT: |
520 return base::StringPrintf( | 528 return base::StringPrintf( |
521 "'%s' requires a different Feature that is not present.", | 529 "'%s' requires a different Feature that is not present.", |
522 name().c_str()); | 530 name().c_str()); |
523 case UNSUPPORTED_CHANNEL: | 531 case UNSUPPORTED_CHANNEL: |
524 return base::StringPrintf( | 532 return base::StringPrintf( |
525 "'%s' is unsupported in this version of the platform.", | 533 "'%s' requires %s channel or newer, but this is the %s channel.", |
526 name().c_str()); | 534 name().c_str(), GetDisplayName(channel).c_str(), |
535 GetDisplayName(GetCurrentChannel()).c_str()); | |
527 case MISSING_COMMAND_LINE_SWITCH: | 536 case MISSING_COMMAND_LINE_SWITCH: |
528 return base::StringPrintf( | 537 return base::StringPrintf( |
529 "'%s' requires the '%s' command line switch to be enabled.", | 538 "'%s' requires the '%s' command line switch to be enabled.", |
530 name().c_str(), command_line_switch_.c_str()); | 539 name().c_str(), command_line_switch_.c_str()); |
531 } | 540 } |
532 | 541 |
533 NOTREACHED(); | 542 NOTREACHED(); |
534 return std::string(); | 543 return std::string(); |
535 } | 544 } |
536 | 545 |
537 Feature::Availability SimpleFeature::CreateAvailability( | 546 Feature::Availability SimpleFeature::CreateAvailability( |
538 AvailabilityResult result) const { | 547 AvailabilityResult result) const { |
539 return Availability( | 548 return Availability( |
540 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 549 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
541 UNSPECIFIED_CONTEXT)); | 550 UNSPECIFIED_CONTEXT, |
551 version_info::Channel::UNKNOWN)); | |
542 } | 552 } |
543 | 553 |
544 Feature::Availability SimpleFeature::CreateAvailability( | 554 Feature::Availability SimpleFeature::CreateAvailability( |
545 AvailabilityResult result, Manifest::Type type) const { | 555 AvailabilityResult result, Manifest::Type type) const { |
546 return Availability(result, GetAvailabilityMessage(result, type, GURL(), | 556 return Availability( |
547 UNSPECIFIED_CONTEXT)); | 557 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT, |
558 version_info::Channel::UNKNOWN)); | |
548 } | 559 } |
549 | 560 |
550 Feature::Availability SimpleFeature::CreateAvailability( | 561 Feature::Availability SimpleFeature::CreateAvailability( |
551 AvailabilityResult result, | 562 AvailabilityResult result, |
552 const GURL& url) const { | 563 const GURL& url) const { |
553 return Availability( | 564 return Availability( |
554 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, | 565 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, |
555 UNSPECIFIED_CONTEXT)); | 566 UNSPECIFIED_CONTEXT, |
567 version_info::Channel::UNKNOWN)); | |
556 } | 568 } |
557 | 569 |
558 Feature::Availability SimpleFeature::CreateAvailability( | 570 Feature::Availability SimpleFeature::CreateAvailability( |
559 AvailabilityResult result, | 571 AvailabilityResult result, |
560 Context context) const { | 572 Context context) const { |
561 return Availability( | 573 return Availability( |
562 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 574 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
563 context)); | 575 context, version_info::Channel::UNKNOWN)); |
576 } | |
577 | |
578 Feature::Availability SimpleFeature::CreateAvailability( | |
579 AvailabilityResult result, | |
580 version_info::Channel channel) const { | |
581 return Availability( | |
582 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | |
583 UNSPECIFIED_CONTEXT, channel)); | |
564 } | 584 } |
565 | 585 |
566 bool SimpleFeature::IsInternal() const { | 586 bool SimpleFeature::IsInternal() const { |
567 return false; | 587 return false; |
568 } | 588 } |
569 | 589 |
570 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { | 590 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { |
571 return IsIdInList(extension_id, blacklist_); | 591 return IsIdInList(extension_id, blacklist_); |
572 } | 592 } |
573 | 593 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
634 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { | 654 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { |
635 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 655 // Belt-and-suspenders philosophy here. We should be pretty confident by this |
636 // point that we've validated the extension ID format, but in case something | 656 // point that we've validated the extension ID format, but in case something |
637 // slips through, we avoid a class of attack where creative ID manipulation | 657 // slips through, we avoid a class of attack where creative ID manipulation |
638 // leads to hash collisions. | 658 // leads to hash collisions. |
639 // 128 bits / 4 = 32 mpdecimal characters | 659 // 128 bits / 4 = 32 mpdecimal characters |
640 return (extension_id.length() == 32); | 660 return (extension_id.length() == 32); |
641 } | 661 } |
642 | 662 |
643 } // namespace extensions | 663 } // namespace extensions |
OLD | NEW |