| 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> |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 return "dev"; | 200 return "dev"; |
| 201 case version_info::Channel::BETA: | 201 case version_info::Channel::BETA: |
| 202 return "beta"; | 202 return "beta"; |
| 203 case version_info::Channel::STABLE: | 203 case version_info::Channel::STABLE: |
| 204 return "stable"; | 204 return "stable"; |
| 205 } | 205 } |
| 206 NOTREACHED(); | 206 NOTREACHED(); |
| 207 return ""; | 207 return ""; |
| 208 } | 208 } |
| 209 | 209 |
| 210 std::string GetSessionTypeDisplayName(FeatureSessionType session_type) { |
| 211 switch (session_type) { |
| 212 case FeatureSessionType::UNKNOWN: |
| 213 return "unknown"; |
| 214 case FeatureSessionType::KIOSK: |
| 215 return "kiosk app"; |
| 216 case FeatureSessionType::REGULAR: |
| 217 return "regular user"; |
| 218 default: |
| 219 return ""; |
| 220 } |
| 221 } |
| 222 |
| 210 // Gets a human-readable list of the display names (pluralized, comma separated | 223 // Gets a human-readable list of the display names (pluralized, comma separated |
| 211 // with the "and" in the correct place) for each of |enum_types|. | 224 // with the "and" in the correct place) for each of |enum_types|. |
| 212 template <typename EnumType> | 225 template <typename EnumType> |
| 213 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { | 226 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { |
| 214 std::string display_name_list; | 227 std::string display_name_list; |
| 215 for (size_t i = 0; i < enum_types.size(); ++i) { | 228 for (size_t i = 0; i < enum_types.size(); ++i) { |
| 216 // Pluralize type name. | 229 // Pluralize type name. |
| 217 display_name_list += GetDisplayName(enum_types[i]) + "s"; | 230 display_name_list += GetDisplayName(enum_types[i]) + "s"; |
| 218 // Comma-separate entries, with an Oxford comma if there is more than 2 | 231 // Comma-separate entries, with an Oxford comma if there is more than 2 |
| 219 // total entries. | 232 // total entries. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; | 303 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; |
| 291 platforms["linux"] = Feature::LINUX_PLATFORM; | 304 platforms["linux"] = Feature::LINUX_PLATFORM; |
| 292 platforms["mac"] = Feature::MACOSX_PLATFORM; | 305 platforms["mac"] = Feature::MACOSX_PLATFORM; |
| 293 platforms["win"] = Feature::WIN_PLATFORM; | 306 platforms["win"] = Feature::WIN_PLATFORM; |
| 294 | 307 |
| 295 channels["trunk"] = version_info::Channel::UNKNOWN; | 308 channels["trunk"] = version_info::Channel::UNKNOWN; |
| 296 channels["canary"] = version_info::Channel::CANARY; | 309 channels["canary"] = version_info::Channel::CANARY; |
| 297 channels["dev"] = version_info::Channel::DEV; | 310 channels["dev"] = version_info::Channel::DEV; |
| 298 channels["beta"] = version_info::Channel::BETA; | 311 channels["beta"] = version_info::Channel::BETA; |
| 299 channels["stable"] = version_info::Channel::STABLE; | 312 channels["stable"] = version_info::Channel::STABLE; |
| 313 |
| 314 session_types["regular"] = FeatureSessionType::REGULAR; |
| 315 session_types["kiosk"] = FeatureSessionType::KIOSK; |
| 300 } | 316 } |
| 301 | 317 |
| 302 std::map<std::string, Manifest::Type> extension_types; | 318 std::map<std::string, Manifest::Type> extension_types; |
| 303 std::map<std::string, Feature::Context> contexts; | 319 std::map<std::string, Feature::Context> contexts; |
| 304 std::map<std::string, SimpleFeature::Location> locations; | 320 std::map<std::string, SimpleFeature::Location> locations; |
| 305 std::map<std::string, Feature::Platform> platforms; | 321 std::map<std::string, Feature::Platform> platforms; |
| 306 std::map<std::string, version_info::Channel> channels; | 322 std::map<std::string, version_info::Channel> channels; |
| 323 std::map<std::string, FeatureSessionType> session_types; |
| 307 }; | 324 }; |
| 308 | 325 |
| 309 SimpleFeature::SimpleFeature() | 326 SimpleFeature::SimpleFeature() |
| 310 : location_(UNSPECIFIED_LOCATION), | 327 : location_(UNSPECIFIED_LOCATION), |
| 311 min_manifest_version_(0), | 328 min_manifest_version_(0), |
| 312 max_manifest_version_(0), | 329 max_manifest_version_(0), |
| 313 component_extensions_auto_granted_(true), | 330 component_extensions_auto_granted_(true), |
| 314 is_internal_(false) {} | 331 is_internal_(false) {} |
| 315 | 332 |
| 316 SimpleFeature::~SimpleFeature() {} | 333 SimpleFeature::~SimpleFeature() {} |
| (...skipping 15 matching lines...) Expand all Loading... |
| 332 } else if (key == "whitelist") { | 349 } else if (key == "whitelist") { |
| 333 ParseVector(value, &whitelist_); | 350 ParseVector(value, &whitelist_); |
| 334 } else if (key == "dependencies") { | 351 } else if (key == "dependencies") { |
| 335 ParseVector(value, &dependencies_); | 352 ParseVector(value, &dependencies_); |
| 336 } else if (key == "extension_types") { | 353 } else if (key == "extension_types") { |
| 337 ParseEnumVector<Manifest::Type>(value, &extension_types_, | 354 ParseEnumVector<Manifest::Type>(value, &extension_types_, |
| 338 mappings.Get().extension_types); | 355 mappings.Get().extension_types); |
| 339 } else if (key == "contexts") { | 356 } else if (key == "contexts") { |
| 340 ParseEnumVector<Context>(value, &contexts_, | 357 ParseEnumVector<Context>(value, &contexts_, |
| 341 mappings.Get().contexts); | 358 mappings.Get().contexts); |
| 359 } else if (key == "session_types") { |
| 360 ParseEnumVector<FeatureSessionType>(value, &session_types_, |
| 361 mappings.Get().session_types); |
| 342 } else if (key == "location") { | 362 } else if (key == "location") { |
| 343 ParseEnum<Location>(value, &location_, mappings.Get().locations); | 363 ParseEnum<Location>(value, &location_, mappings.Get().locations); |
| 344 } else if (key == "platforms") { | 364 } else if (key == "platforms") { |
| 345 ParseEnumVector<Platform>(value, &platforms_, | 365 ParseEnumVector<Platform>(value, &platforms_, |
| 346 mappings.Get().platforms); | 366 mappings.Get().platforms); |
| 347 } else if (key == "min_manifest_version") { | 367 } else if (key == "min_manifest_version") { |
| 348 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); | 368 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); |
| 349 } else if (key == "max_manifest_version") { | 369 } else if (key == "max_manifest_version") { |
| 350 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); | 370 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); |
| 351 } else if (key == "noparent") { | 371 } else if (key == "noparent") { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, | 461 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, |
| 442 extension_id, | 462 extension_id, |
| 443 type, | 463 type, |
| 444 location, | 464 location, |
| 445 manifest_version, | 465 manifest_version, |
| 446 platform)); | 466 platform)); |
| 447 } | 467 } |
| 448 | 468 |
| 449 Feature::Availability SimpleFeature::IsAvailableToContext( | 469 Feature::Availability SimpleFeature::IsAvailableToContext( |
| 450 const Extension* extension, | 470 const Extension* extension, |
| 451 SimpleFeature::Context context, | 471 Feature::Context context, |
| 452 const GURL& url, | 472 const GURL& url, |
| 453 SimpleFeature::Platform platform) const { | 473 SimpleFeature::Platform platform) const { |
| 454 if (extension) { | 474 if (extension) { |
| 455 Availability result = IsAvailableToManifest(extension->id(), | 475 Availability result = IsAvailableToManifest(extension->id(), |
| 456 extension->GetType(), | 476 extension->GetType(), |
| 457 extension->location(), | 477 extension->location(), |
| 458 extension->manifest_version(), | 478 extension->manifest_version(), |
| 459 platform); | 479 platform); |
| 460 if (!result.is_available()) | 480 if (!result.is_available()) |
| 461 return result; | 481 return result; |
| 462 } | 482 } |
| 463 | 483 |
| 464 // TODO(lazyboy): This isn't quite right for Extension Service Worker | 484 // TODO(lazyboy): This isn't quite right for Extension Service Worker |
| 465 // extension API calls, since there's no guarantee that the extension is | 485 // extension API calls, since there's no guarantee that the extension is |
| 466 // "active" in current renderer process when the API permission check is | 486 // "active" in current renderer process when the API permission check is |
| 467 // done. | 487 // done. |
| 468 if (!contexts_.empty() && !base::ContainsValue(contexts_, context)) | 488 if (!contexts_.empty() && !base::ContainsValue(contexts_, context)) |
| 469 return CreateAvailability(INVALID_CONTEXT, context); | 489 return CreateAvailability(INVALID_CONTEXT, context); |
| 470 | 490 |
| 471 // TODO(kalman): Consider checking |matches_| regardless of context type. | 491 // TODO(kalman): Consider checking |matches_| regardless of context type. |
| 472 // Fewer surprises, and if the feature configuration wants to isolate | 492 // Fewer surprises, and if the feature configuration wants to isolate |
| 473 // "matches" from say "blessed_extension" then they can use complex features. | 493 // "matches" from say "blessed_extension" then they can use complex features. |
| 474 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && | 494 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && |
| 475 !matches_.MatchesURL(url)) { | 495 !matches_.MatchesURL(url)) { |
| 476 return CreateAvailability(INVALID_URL, url); | 496 return CreateAvailability(INVALID_URL, url); |
| 477 } | 497 } |
| 478 | 498 |
| 499 FeatureSessionType session_type = GetCurrentFeatureSessionType(); |
| 500 if (!session_types_.empty() && |
| 501 !base::ContainsValue(session_types_, session_type)) { |
| 502 return CreateAvailability(INVALID_SESSION_TYPE, session_type); |
| 503 } |
| 504 |
| 479 // TODO(kalman): Assert that if the context was a webpage or WebUI context | 505 // TODO(kalman): Assert that if the context was a webpage or WebUI context |
| 480 // then at some point a "matches" restriction was checked. | 506 // then at some point a "matches" restriction was checked. |
| 481 return CheckDependencies(base::Bind( | 507 return CheckDependencies(base::Bind(&IsAvailableToContextForBind, extension, |
| 482 &IsAvailableToContextForBind, extension, context, url, platform)); | 508 context, url, platform)); |
| 483 } | 509 } |
| 484 | 510 |
| 485 std::string SimpleFeature::GetAvailabilityMessage( | 511 std::string SimpleFeature::GetAvailabilityMessage( |
| 486 AvailabilityResult result, | 512 AvailabilityResult result, |
| 487 Manifest::Type type, | 513 Manifest::Type type, |
| 488 const GURL& url, | 514 const GURL& url, |
| 489 Context context, | 515 Context context, |
| 490 version_info::Channel channel) const { | 516 version_info::Channel channel, |
| 517 FeatureSessionType session_type) const { |
| 491 switch (result) { | 518 switch (result) { |
| 492 case IS_AVAILABLE: | 519 case IS_AVAILABLE: |
| 493 return std::string(); | 520 return std::string(); |
| 494 case NOT_FOUND_IN_WHITELIST: | 521 case NOT_FOUND_IN_WHITELIST: |
| 495 case FOUND_IN_BLACKLIST: | 522 case FOUND_IN_BLACKLIST: |
| 496 return base::StringPrintf( | 523 return base::StringPrintf( |
| 497 "'%s' is not allowed for specified extension ID.", | 524 "'%s' is not allowed for specified extension ID.", |
| 498 name().c_str()); | 525 name().c_str()); |
| 499 case INVALID_URL: | 526 case INVALID_URL: |
| 500 return base::StringPrintf("'%s' is not allowed on %s.", | 527 return base::StringPrintf("'%s' is not allowed on %s.", |
| (...skipping 23 matching lines...) Expand all Loading... |
| 524 case INVALID_MIN_MANIFEST_VERSION: | 551 case INVALID_MIN_MANIFEST_VERSION: |
| 525 return base::StringPrintf( | 552 return base::StringPrintf( |
| 526 "'%s' requires manifest version of at least %d.", | 553 "'%s' requires manifest version of at least %d.", |
| 527 name().c_str(), | 554 name().c_str(), |
| 528 min_manifest_version_); | 555 min_manifest_version_); |
| 529 case INVALID_MAX_MANIFEST_VERSION: | 556 case INVALID_MAX_MANIFEST_VERSION: |
| 530 return base::StringPrintf( | 557 return base::StringPrintf( |
| 531 "'%s' requires manifest version of %d or lower.", | 558 "'%s' requires manifest version of %d or lower.", |
| 532 name().c_str(), | 559 name().c_str(), |
| 533 max_manifest_version_); | 560 max_manifest_version_); |
| 561 case INVALID_SESSION_TYPE: |
| 562 return base::StringPrintf( |
| 563 "'%s' is not allowed in %s session", name().c_str(), |
| 564 GetSessionTypeDisplayName(session_type).c_str()); |
| 534 case NOT_PRESENT: | 565 case NOT_PRESENT: |
| 535 return base::StringPrintf( | 566 return base::StringPrintf( |
| 536 "'%s' requires a different Feature that is not present.", | 567 "'%s' requires a different Feature that is not present.", |
| 537 name().c_str()); | 568 name().c_str()); |
| 538 case UNSUPPORTED_CHANNEL: | 569 case UNSUPPORTED_CHANNEL: |
| 539 return base::StringPrintf( | 570 return base::StringPrintf( |
| 540 "'%s' requires %s channel or newer, but this is the %s channel.", | 571 "'%s' requires %s channel or newer, but this is the %s channel.", |
| 541 name().c_str(), GetDisplayName(channel).c_str(), | 572 name().c_str(), GetDisplayName(channel).c_str(), |
| 542 GetDisplayName(GetCurrentChannel()).c_str()); | 573 GetDisplayName(GetCurrentChannel()).c_str()); |
| 543 case MISSING_COMMAND_LINE_SWITCH: | 574 case MISSING_COMMAND_LINE_SWITCH: |
| 544 return base::StringPrintf( | 575 return base::StringPrintf( |
| 545 "'%s' requires the '%s' command line switch to be enabled.", | 576 "'%s' requires the '%s' command line switch to be enabled.", |
| 546 name().c_str(), command_line_switch_.c_str()); | 577 name().c_str(), command_line_switch_.c_str()); |
| 547 } | 578 } |
| 548 | 579 |
| 549 NOTREACHED(); | 580 NOTREACHED(); |
| 550 return std::string(); | 581 return std::string(); |
| 551 } | 582 } |
| 552 | 583 |
| 553 Feature::Availability SimpleFeature::CreateAvailability( | 584 Feature::Availability SimpleFeature::CreateAvailability( |
| 554 AvailabilityResult result) const { | 585 AvailabilityResult result) const { |
| 555 return Availability( | 586 return Availability( |
| 556 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 587 result, GetAvailabilityMessage( |
| 557 UNSPECIFIED_CONTEXT, | 588 result, Manifest::TYPE_UNKNOWN, GURL(), UNSPECIFIED_CONTEXT, |
| 558 version_info::Channel::UNKNOWN)); | 589 version_info::Channel::UNKNOWN, FeatureSessionType::UNKNOWN)); |
| 559 } | 590 } |
| 560 | 591 |
| 561 Feature::Availability SimpleFeature::CreateAvailability( | 592 Feature::Availability SimpleFeature::CreateAvailability( |
| 562 AvailabilityResult result, Manifest::Type type) const { | 593 AvailabilityResult result, Manifest::Type type) const { |
| 563 return Availability( | 594 return Availability( |
| 564 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT, | 595 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT, |
| 565 version_info::Channel::UNKNOWN)); | 596 version_info::Channel::UNKNOWN, |
| 597 FeatureSessionType::UNKNOWN)); |
| 566 } | 598 } |
| 567 | 599 |
| 568 Feature::Availability SimpleFeature::CreateAvailability( | 600 Feature::Availability SimpleFeature::CreateAvailability( |
| 569 AvailabilityResult result, | 601 AvailabilityResult result, |
| 570 const GURL& url) const { | 602 const GURL& url) const { |
| 571 return Availability( | 603 return Availability( |
| 572 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, | 604 result, GetAvailabilityMessage( |
| 573 UNSPECIFIED_CONTEXT, | 605 result, Manifest::TYPE_UNKNOWN, url, UNSPECIFIED_CONTEXT, |
| 574 version_info::Channel::UNKNOWN)); | 606 version_info::Channel::UNKNOWN, FeatureSessionType::UNKNOWN)); |
| 575 } | 607 } |
| 576 | 608 |
| 577 Feature::Availability SimpleFeature::CreateAvailability( | 609 Feature::Availability SimpleFeature::CreateAvailability( |
| 578 AvailabilityResult result, | 610 AvailabilityResult result, |
| 579 Context context) const { | 611 Context context) const { |
| 580 return Availability( | 612 return Availability( |
| 581 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 613 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
| 582 context, version_info::Channel::UNKNOWN)); | 614 context, version_info::Channel::UNKNOWN, |
| 615 FeatureSessionType::UNKNOWN)); |
| 583 } | 616 } |
| 584 | 617 |
| 585 Feature::Availability SimpleFeature::CreateAvailability( | 618 Feature::Availability SimpleFeature::CreateAvailability( |
| 586 AvailabilityResult result, | 619 AvailabilityResult result, |
| 587 version_info::Channel channel) const { | 620 version_info::Channel channel) const { |
| 588 return Availability( | 621 return Availability( |
| 589 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 622 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
| 590 UNSPECIFIED_CONTEXT, channel)); | 623 UNSPECIFIED_CONTEXT, channel, |
| 624 FeatureSessionType::UNKNOWN)); |
| 625 } |
| 626 |
| 627 Feature::Availability SimpleFeature::CreateAvailability( |
| 628 AvailabilityResult result, |
| 629 FeatureSessionType session_type) const { |
| 630 return Availability( |
| 631 result, GetAvailabilityMessage( |
| 632 result, Manifest::TYPE_UNKNOWN, GURL(), UNSPECIFIED_CONTEXT, |
| 633 version_info::Channel::UNKNOWN, session_type)); |
| 591 } | 634 } |
| 592 | 635 |
| 593 bool SimpleFeature::IsInternal() const { | 636 bool SimpleFeature::IsInternal() const { |
| 594 return is_internal_; | 637 return is_internal_; |
| 595 } | 638 } |
| 596 | 639 |
| 597 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { | 640 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { |
| 598 return IsIdInList(extension_id, blacklist_); | 641 return IsIdInList(extension_id, blacklist_); |
| 599 } | 642 } |
| 600 | 643 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 void SimpleFeature::set_dependencies( | 727 void SimpleFeature::set_dependencies( |
| 685 std::initializer_list<const char* const> dependencies) { | 728 std::initializer_list<const char* const> dependencies) { |
| 686 dependencies_.assign(dependencies.begin(), dependencies.end()); | 729 dependencies_.assign(dependencies.begin(), dependencies.end()); |
| 687 } | 730 } |
| 688 | 731 |
| 689 void SimpleFeature::set_extension_types( | 732 void SimpleFeature::set_extension_types( |
| 690 std::initializer_list<Manifest::Type> types) { | 733 std::initializer_list<Manifest::Type> types) { |
| 691 extension_types_ = types; | 734 extension_types_ = types; |
| 692 } | 735 } |
| 693 | 736 |
| 737 void SimpleFeature::set_session_types( |
| 738 std::initializer_list<FeatureSessionType> types) { |
| 739 session_types_ = types; |
| 740 } |
| 741 |
| 694 void SimpleFeature::set_matches( | 742 void SimpleFeature::set_matches( |
| 695 std::initializer_list<const char* const> matches) { | 743 std::initializer_list<const char* const> matches) { |
| 696 matches_.ClearPatterns(); | 744 matches_.ClearPatterns(); |
| 697 for (const auto* pattern : matches) | 745 for (const auto* pattern : matches) |
| 698 matches_.AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern)); | 746 matches_.AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern)); |
| 699 } | 747 } |
| 700 | 748 |
| 701 void SimpleFeature::set_platforms(std::initializer_list<Platform> platforms) { | 749 void SimpleFeature::set_platforms(std::initializer_list<Platform> platforms) { |
| 702 platforms_ = platforms; | 750 platforms_ = platforms; |
| 703 } | 751 } |
| 704 | 752 |
| 705 void SimpleFeature::set_whitelist( | 753 void SimpleFeature::set_whitelist( |
| 706 std::initializer_list<const char* const> whitelist) { | 754 std::initializer_list<const char* const> whitelist) { |
| 707 whitelist_.assign(whitelist.begin(), whitelist.end()); | 755 whitelist_.assign(whitelist.begin(), whitelist.end()); |
| 708 } | 756 } |
| 709 | 757 |
| 710 } // namespace extensions | 758 } // namespace extensions |
| OLD | NEW |