diff options
author | mihaip@chromium.org <mihaip@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 17:02:15 +0000 |
---|---|---|
committer | mihaip@chromium.org <mihaip@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 17:02:15 +0000 |
commit | 022a9850ad8b9e20f99c09a32eeda4a3e6a260c5 (patch) | |
tree | 2724878ae4585bca030dbb02ddd911d8d8a4d017 | |
parent | 3e3bdc930c46fc4d50c1a8ae4403c28ba56b0b76 (diff) | |
download | chromium_src-022a9850ad8b9e20f99c09a32eeda4a3e6a260c5.zip chromium_src-022a9850ad8b9e20f99c09a32eeda4a3e6a260c5.tar.gz chromium_src-022a9850ad8b9e20f99c09a32eeda4a3e6a260c5.tar.bz2 |
Include the allowed and current extension types when displaying INVALID_TYPE warnings.
Instead of:
'app.launch' is not allowed for specified package type (theme, app, etc.).
We now have:
'app.launch' is only allowed for hosted apps and legacy packaged apps, and this is a packaged app.
BUG=145256
R=kalman@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10900012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154178 0039d316-1c4b-4281-b951-d872f2087c98
13 files changed, 212 insertions, 140 deletions
diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc index c1ead1c..0361063 100644 --- a/chrome/common/extensions/api/extension_api.cc +++ b/chrome/common/extensions/api/extension_api.cc @@ -501,7 +501,7 @@ bool ExtensionAPI::IsAvailable(const std::string& full_name, Feature::Availability availability = feature->IsAvailableToContext(extension, context); - if (availability != Feature::IS_AVAILABLE) + if (!availability.is_available()) return false; } diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index a2aa3c5..2491681 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -3380,13 +3380,12 @@ bool Extension::ParsePermissions(const char* key, GetType(), extensions::Feature::ConvertLocation(location()), manifest_version()); - if (availability != extensions::Feature::IS_AVAILABLE) { + if (!availability.is_available()) { // Don't fail, but warn the developer that the manifest contains // unrecognized permissions. This may happen legitimately if the // extensions requests platform- or channel-specific permissions. - install_warnings_.push_back( - InstallWarning(InstallWarning::FORMAT_TEXT, - feature->GetErrorMessage(availability))); + install_warnings_.push_back(InstallWarning( + InstallWarning::FORMAT_TEXT, availability.message())); continue; } diff --git a/chrome/common/extensions/features/feature.cc b/chrome/common/extensions/features/feature.cc index b7485f1..1d2e0c3 100644 --- a/chrome/common/extensions/features/feature.cc +++ b/chrome/common/extensions/features/feature.cc @@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/stringprintf.h" +#include "base/string_util.h" #include "chrome/common/chrome_switches.h" using chrome::VersionInfo; @@ -135,6 +136,29 @@ void ParseEnumSet(const DictionaryValue* value, } } +// Gets a human-readable name for the given extension type. +std::string GetDisplayTypeName(Extension::Type type) { + switch (type) { + case Extension::TYPE_UNKNOWN: + return "unknown"; + case Extension::TYPE_EXTENSION: + return "extension"; + case Extension::TYPE_HOSTED_APP: + return "hosted app"; + case Extension::TYPE_PACKAGED_APP: + return "legacy packaged app"; + case Extension::TYPE_PLATFORM_APP: + return "packaged app"; + case Extension::TYPE_THEME: + return "theme"; + case Extension::TYPE_USER_SCRIPT: + return "user script"; + } + + NOTREACHED(); + return ""; +} + } // namespace namespace extensions { @@ -206,57 +230,6 @@ void Feature::Parse(const DictionaryValue* value) { g_mappings.Get().channels); } -std::string Feature::GetErrorMessage(Feature::Availability result) { - switch (result) { - case IS_AVAILABLE: - return ""; - case NOT_FOUND_IN_WHITELIST: - return base::StringPrintf( - "'%s' is not allowed for specified extension ID.", - name().c_str()); - case INVALID_TYPE: - return base::StringPrintf( - "'%s' is not allowed for specified package type (theme, app, etc.).", - name().c_str()); - case INVALID_CONTEXT: - return base::StringPrintf( - "'%s' is not allowed for specified context type content script, " - " extension page, web page, etc.).", - name().c_str()); - case INVALID_LOCATION: - return base::StringPrintf( - "'%s' is not allowed for specified install location.", - name().c_str()); - case INVALID_PLATFORM: - return base::StringPrintf( - "'%s' is not allowed for specified platform.", - name().c_str()); - case INVALID_MIN_MANIFEST_VERSION: - return base::StringPrintf( - "'%s' requires manifest version of at least %d.", - name().c_str(), - min_manifest_version_); - case INVALID_MAX_MANIFEST_VERSION: - return base::StringPrintf( - "'%s' requires manifest version of %d or lower.", - name().c_str(), - max_manifest_version_); - case NOT_PRESENT: - return base::StringPrintf( - "'%s' requires a different Feature that is not present.", - name().c_str()); - case UNSUPPORTED_CHANNEL: - return base::StringPrintf( - "'%s' requires Google Chrome %s channel or newer, and we're running " - "on the %s channel.", - name().c_str(), - GetChannelName(channel_).c_str(), - GetChannelName(GetCurrentChannel()).c_str()); - } - - return ""; -} - Feature::Availability Feature::IsAvailableToManifest( const std::string& extension_id, Extension::Type type, @@ -265,7 +238,7 @@ Feature::Availability Feature::IsAvailableToManifest( Platform platform) const { // Component extensions can access any feature. if (location == COMPONENT_LOCATION) - return IS_AVAILABLE; + return CreateAvailability(IS_AVAILABLE, type); if (!whitelist_.empty()) { if (whitelist_.find(extension_id) == whitelist_.end()) { @@ -273,37 +246,37 @@ Feature::Availability Feature::IsAvailableToManifest( // whitelist. CommandLine* command_line = CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) - return NOT_FOUND_IN_WHITELIST; + return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); std::string whitelist_switch_value = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kWhitelistedExtensionID); if (extension_id != whitelist_switch_value) - return NOT_FOUND_IN_WHITELIST; + return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); } } if (!extension_types_.empty() && extension_types_.find(type) == extension_types_.end()) { - return INVALID_TYPE; + return CreateAvailability(INVALID_TYPE, type); } if (location_ != UNSPECIFIED_LOCATION && location_ != location) - return INVALID_LOCATION; + return CreateAvailability(INVALID_LOCATION, type); if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) - return INVALID_PLATFORM; + return CreateAvailability(INVALID_PLATFORM, type); if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) - return INVALID_MIN_MANIFEST_VERSION; + return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) - return INVALID_MAX_MANIFEST_VERSION; + return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); if (channel_ < g_current_channel) - return UNSUPPORTED_CHANNEL; + return CreateAvailability(UNSUPPORTED_CHANNEL, type); - return IS_AVAILABLE; + return CreateAvailability(IS_AVAILABLE, type); } Feature::Availability Feature::IsAvailableToContext( @@ -316,15 +289,15 @@ Feature::Availability Feature::IsAvailableToContext( ConvertLocation(extension->location()), extension->manifest_version(), platform); - if (result != IS_AVAILABLE) + if (!result.is_available()) return result; if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) { - return INVALID_CONTEXT; + return CreateAvailability(INVALID_CONTEXT, extension->GetType()); } - return IS_AVAILABLE; + return CreateAvailability(IS_AVAILABLE); } // static @@ -342,4 +315,87 @@ chrome::VersionInfo::Channel Feature::GetDefaultChannel() { return kDefaultChannel; } -} // namespace +Feature::Availability Feature::CreateAvailability( + AvailabilityResult result) const { + return Availability( + result, GetAvailabilityMessage(result, Extension::TYPE_UNKNOWN)); +} + +Feature::Availability Feature::CreateAvailability( + AvailabilityResult result, Extension::Type type) const { + return Availability(result, GetAvailabilityMessage(result, type)); +} + +std::string Feature::GetAvailabilityMessage( + AvailabilityResult result, Extension::Type type) const { + switch (result) { + case IS_AVAILABLE: + return ""; + case NOT_FOUND_IN_WHITELIST: + return base::StringPrintf( + "'%s' is not allowed for specified extension ID.", + name().c_str()); + case INVALID_TYPE: { + std::string allowed_type_names; + // Turn the set of allowed types into a vector so that it's easier to + // inject the appropriate separator into the display string. + std::vector<Extension::Type> extension_types( + extension_types_.begin(), extension_types_.end()); + for (size_t i = 0; i < extension_types.size(); i++) { + // Pluralize type name. + allowed_type_names += GetDisplayTypeName(extension_types[i]) + "s"; + if (i == extension_types_.size() - 2) { + allowed_type_names += " and "; + } else if (i != extension_types_.size() - 1) { + allowed_type_names += ", "; + } + } + + return base::StringPrintf( + "'%s' is only allowed for %s, and this is a %s.", + name().c_str(), + allowed_type_names.c_str(), + GetDisplayTypeName(type).c_str()); + } + case INVALID_CONTEXT: + return base::StringPrintf( + "'%s' is not allowed for specified context type content script, " + " extension page, web page, etc.).", + name().c_str()); + case INVALID_LOCATION: + return base::StringPrintf( + "'%s' is not allowed for specified install location.", + name().c_str()); + case INVALID_PLATFORM: + return base::StringPrintf( + "'%s' is not allowed for specified platform.", + name().c_str()); + case INVALID_MIN_MANIFEST_VERSION: + return base::StringPrintf( + "'%s' requires manifest version of at least %d.", + name().c_str(), + min_manifest_version_); + case INVALID_MAX_MANIFEST_VERSION: + return base::StringPrintf( + "'%s' requires manifest version of %d or lower.", + name().c_str(), + max_manifest_version_); + case NOT_PRESENT: + return base::StringPrintf( + "'%s' requires a different Feature that is not present.", + name().c_str()); + case UNSUPPORTED_CHANNEL: + return base::StringPrintf( + "'%s' requires Google Chrome %s channel or newer, and this is the " + "%s channel.", + name().c_str(), + GetChannelName(channel_).c_str(), + GetChannelName(GetCurrentChannel()).c_str()); + } + + NOTREACHED(); + return ""; +} + + +} // namespace extensions diff --git a/chrome/common/extensions/features/feature.h b/chrome/common/extensions/features/feature.h index f0324ab..4171183 100644 --- a/chrome/common/extensions/features/feature.h +++ b/chrome/common/extensions/features/feature.h @@ -51,7 +51,7 @@ class Feature { // Whether a feature is available in a given situation or not, and if not, // why not. - enum Availability { + enum AvailabilityResult { IS_AVAILABLE, NOT_FOUND_IN_WHITELIST, INVALID_TYPE, @@ -64,6 +64,25 @@ class Feature { UNSUPPORTED_CHANNEL, }; + // Container for AvailabiltyResult that also exposes a user-visible error + // message in cases where the feature is not available. + class Availability { + public: + AvailabilityResult result() const { return result_; } + bool is_available() const { return result_ == IS_AVAILABLE; } + const std::string& message() const { return message_; } + + private: + friend class Feature; + + // Instances should be created via Feature::CreateAvailability. + Availability(AvailabilityResult result, const std::string& message) + : result_(result), message_(message) { } + + const AvailabilityResult result_; + const std::string message_; + }; + Feature(); Feature(const Feature& other); virtual ~Feature(); @@ -158,10 +177,15 @@ class Feature { Context context, Platform platform) const; - // Returns an error message for an Availability code. - std::string GetErrorMessage(Availability result); + protected: + Availability CreateAvailability(AvailabilityResult result) const; + Availability CreateAvailability(AvailabilityResult result, + Extension::Type type) const; private: + std::string GetAvailabilityMessage( + AvailabilityResult result, Extension::Type type) const; + std::string name_; // For clarify and consistency, we handle the default value of each of these diff --git a/chrome/common/extensions/features/feature_unittest.cc b/chrome/common/extensions/features/feature_unittest.cc index a9dcb69..1d4a4aa 100644 --- a/chrome/common/extensions/features/feature_unittest.cc +++ b/chrome/common/extensions/features/feature_unittest.cc @@ -18,7 +18,7 @@ struct IsAvailableTestData { Feature::Location location; Feature::Platform platform; int manifest_version; - Feature::Availability expected_result; + Feature::AvailabilityResult expected_result; }; class ExtensionFeatureTest : public testing::Test { @@ -64,7 +64,7 @@ TEST_F(ExtensionFeatureTest, IsAvailableNullCase) { test.extension_type, test.location, test.manifest_version, - test.platform)); + test.platform).result()); } } @@ -75,22 +75,22 @@ TEST_F(ExtensionFeatureTest, Whitelist) { EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "foo", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "bar", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( "baz", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); feature.extension_types()->insert(Extension::TYPE_PACKAGED_APP); EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( "baz", Extension::TYPE_PACKAGED_APP, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); } TEST_F(ExtensionFeatureTest, PackageType) { @@ -100,17 +100,17 @@ TEST_F(ExtensionFeatureTest, PackageType) { EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_EXTENSION, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_PACKAGED_APP, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::INVALID_TYPE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::INVALID_TYPE, feature.IsAvailableToManifest( "", Extension::TYPE_THEME, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); } TEST_F(ExtensionFeatureTest, Context) { @@ -136,14 +136,14 @@ TEST_F(ExtensionFeatureTest, Context) { feature.whitelist()->insert("monkey"); EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); feature.whitelist()->clear(); feature.extension_types()->clear(); feature.extension_types()->insert(Extension::TYPE_THEME); EXPECT_EQ(Feature::INVALID_TYPE, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); feature.extension_types()->clear(); feature.extension_types()->insert(Extension::TYPE_PACKAGED_APP); @@ -151,30 +151,30 @@ TEST_F(ExtensionFeatureTest, Context) { feature.contexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT); EXPECT_EQ(Feature::INVALID_CONTEXT, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); feature.contexts()->clear(); feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); feature.set_location(Feature::COMPONENT_LOCATION); EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); feature.set_location(Feature::UNSPECIFIED_LOCATION); EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); feature.set_min_manifest_version(22); EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); feature.set_min_manifest_version(21); feature.set_max_manifest_version(18); EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION, feature.IsAvailableToContext( extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); feature.set_max_manifest_version(25); } @@ -186,16 +186,16 @@ TEST_F(ExtensionFeatureTest, Location) { feature.set_location(Feature::COMPONENT_LOCATION); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::COMPONENT_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); // But component extensions can access anything else, whatever their location. feature.set_location(Feature::UNSPECIFIED_LOCATION); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::COMPONENT_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); } TEST_F(ExtensionFeatureTest, Platform) { @@ -203,10 +203,10 @@ TEST_F(ExtensionFeatureTest, Platform) { feature.set_platform(Feature::CHROMEOS_PLATFORM); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::CHROMEOS_PLATFORM)); + Feature::CHROMEOS_PLATFORM).result()); EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, - Feature::UNSPECIFIED_PLATFORM)); + Feature::UNSPECIFIED_PLATFORM).result()); } TEST_F(ExtensionFeatureTest, Version) { @@ -216,32 +216,32 @@ TEST_F(ExtensionFeatureTest, Version) { EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 0, Feature::UNSPECIFIED_PLATFORM)); + 0, Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 4, Feature::UNSPECIFIED_PLATFORM)); + 4, Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 5, Feature::UNSPECIFIED_PLATFORM)); + 5, Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 10, Feature::UNSPECIFIED_PLATFORM)); + 10, Feature::UNSPECIFIED_PLATFORM).result()); feature.set_max_manifest_version(8); EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 10, Feature::UNSPECIFIED_PLATFORM)); + 10, Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 8, Feature::UNSPECIFIED_PLATFORM)); + 8, Feature::UNSPECIFIED_PLATFORM).result()); EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( "", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - 7, Feature::UNSPECIFIED_PLATFORM)); + 7, Feature::UNSPECIFIED_PLATFORM).result()); } TEST_F(ExtensionFeatureTest, ParseNull) { @@ -426,7 +426,7 @@ TEST_F(ExtensionFeatureTest, Equals) { EXPECT_FALSE(feature2.Equals(feature)); } -Feature::Availability IsAvailableInChannel( +Feature::AvailabilityResult IsAvailableInChannel( const std::string& channel, VersionInfo::Channel channel_for_testing) { Feature::ScopedCurrentChannel current_channel(channel_for_testing); @@ -441,7 +441,7 @@ Feature::Availability IsAvailableInChannel( "random-extension", Extension::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, - -1); + -1).result(); } TEST_F(ExtensionFeatureTest, SupportedChannel) { diff --git a/chrome/common/extensions/features/manifest_feature.cc b/chrome/common/extensions/features/manifest_feature.cc index d55e5e5..5d7c5a4 100644 --- a/chrome/common/extensions/features/manifest_feature.cc +++ b/chrome/common/extensions/features/manifest_feature.cc @@ -21,15 +21,15 @@ Feature::Availability ManifestFeature::IsAvailableToContext( Availability availability = Feature::IsAvailableToContext(extension, context, platform); - if (availability != IS_AVAILABLE) + if (!availability.is_available()) return availability; // We know we can skip manifest()->GetKey() here because we just did the same // validation it would do above. if (!extension->manifest()->value()->HasKey(name())) - return NOT_PRESENT; + return CreateAvailability(NOT_PRESENT, extension->GetType()); - return IS_AVAILABLE; + return CreateAvailability(IS_AVAILABLE); } } // namespace diff --git a/chrome/common/extensions/features/permission_feature.cc b/chrome/common/extensions/features/permission_feature.cc index 907fd0a..ea02083 100644 --- a/chrome/common/extensions/features/permission_feature.cc +++ b/chrome/common/extensions/features/permission_feature.cc @@ -19,13 +19,13 @@ Feature::Availability PermissionFeature::IsAvailableToContext( Availability availability = Feature::IsAvailableToContext(extension, context, platform); - if (availability != IS_AVAILABLE) + if (!availability.is_available()) return availability; if (!extension->HasAPIPermission(name())) - return NOT_PRESENT; + return CreateAvailability(NOT_PRESENT, extension->GetType()); - return IS_AVAILABLE; + return CreateAvailability(IS_AVAILABLE); } } // namespace diff --git a/chrome/common/extensions/features/simple_feature_provider_unittest.cc b/chrome/common/extensions/features/simple_feature_provider_unittest.cc index bbb5d71..64d95bb 100644 --- a/chrome/common/extensions/features/simple_feature_provider_unittest.cc +++ b/chrome/common/extensions/features/simple_feature_provider_unittest.cc @@ -36,17 +36,17 @@ TEST(SimpleFeatureProvider, ManifestFeatures) { ASSERT_TRUE(extension.get()); EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToContext( - extension.get(), Feature::UNSPECIFIED_CONTEXT)); + extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); feature = provider->GetFeature("theme"); ASSERT_TRUE(feature); EXPECT_EQ(Feature::INVALID_TYPE, feature->IsAvailableToContext( - extension.get(), Feature::UNSPECIFIED_CONTEXT)); + extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); feature = provider->GetFeature("devtools_page"); ASSERT_TRUE(feature); EXPECT_EQ(Feature::NOT_PRESENT, feature->IsAvailableToContext( - extension.get(), Feature::UNSPECIFIED_CONTEXT)); + extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); } TEST(SimpleFeatureProvider, PermissionFeatures) { @@ -75,17 +75,17 @@ TEST(SimpleFeatureProvider, PermissionFeatures) { ASSERT_TRUE(extension.get()); EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToContext( - extension.get(), Feature::UNSPECIFIED_CONTEXT)); + extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); feature = provider->GetFeature("chromePrivate"); ASSERT_TRUE(feature); EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature->IsAvailableToContext( - extension.get(), Feature::UNSPECIFIED_CONTEXT)); + extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); feature = provider->GetFeature("clipboardWrite"); ASSERT_TRUE(feature); EXPECT_EQ(Feature::NOT_PRESENT, feature->IsAvailableToContext( - extension.get(), Feature::UNSPECIFIED_CONTEXT)); + extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); } TEST(SimpleFeatureProvider, Validation) { diff --git a/chrome/common/extensions/manifest.cc b/chrome/common/extensions/manifest.cc index f790c05..f170c6f 100644 --- a/chrome/common/extensions/manifest.cc +++ b/chrome/common/extensions/manifest.cc @@ -72,10 +72,9 @@ void Manifest::ValidateManifest( Feature::Availability result = feature->IsAvailableToManifest( extension_id_, type_, Feature::ConvertLocation(location_), GetManifestVersion()); - if (result != Feature::IS_AVAILABLE) + if (!result.is_available()) warnings->push_back(Extension::InstallWarning( - Extension::InstallWarning::FORMAT_TEXT, - feature->GetErrorMessage(result))); + Extension::InstallWarning::FORMAT_TEXT, result.message())); } // Also generate warnings for keys that are not features. @@ -170,9 +169,9 @@ bool Manifest::CanAccessKey(const std::string& key) const { if (!feature) return true; - return Feature::IS_AVAILABLE == feature->IsAvailableToManifest( + return feature->IsAvailableToManifest( extension_id_, type_, Feature::ConvertLocation(location_), - GetManifestVersion()); + GetManifestVersion()).is_available(); } } // namespace extensions diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_auth_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_auth_unittest.cc index 3dee04e..e998322 100644 --- a/chrome/common/extensions/manifest_tests/extension_manifests_auth_unittest.cc +++ b/chrome/common/extensions/manifest_tests/extension_manifests_auth_unittest.cc @@ -66,8 +66,8 @@ TEST_F(ExtensionManifestTest, OAuth2SectionParsing) { EXPECT_EQ(1U, extension->install_warnings().size()); const extensions::Extension::InstallWarning& warning = extension->install_warnings()[0]; - EXPECT_EQ("'oauth2' is not allowed for specified package type " - "(theme, app, etc.).", + EXPECT_EQ("'oauth2' is only allowed for extensions, legacy packaged apps " + "and packaged apps, and this is a hosted app.", warning.message); EXPECT_EQ("", extension->oauth2_info().client_id); EXPECT_TRUE(extension->oauth2_info().scopes.empty()); diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc index cad53f8..7323ef8 100644 --- a/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc +++ b/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc @@ -63,11 +63,9 @@ TEST_F(ExtensionManifestTest, BackgroundPage) { EXPECT_EQ("/foo.html", extension->GetBackgroundURL().path()); manifest->SetInteger(keys::kManifestVersion, 2); - Feature* feature = SimpleFeatureProvider::GetManifestFeatures()-> - GetFeature("background_page"); LoadAndExpectWarning( Manifest(manifest.get(), ""), - feature->GetErrorMessage(Feature::INVALID_MAX_MANIFEST_VERSION)); + "'background_page' requires manifest version of 1 or lower."); } TEST_F(ExtensionManifestTest, BackgroundAllowNoJsAccess) { diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc index 2f6dc04..426c0c5 100644 --- a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc +++ b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc @@ -18,11 +18,6 @@ TEST_F(ExtensionManifestTest, PlatformApps) { LoadAndExpectSuccess("init_valid_platform_app.json"); EXPECT_TRUE(extension->is_storage_isolated()); - LoadAndExpectWarning( - "init_invalid_platform_app_1.json", - "'app.launch' is not allowed for specified package type " - "(theme, app, etc.)."); - Testcase error_testcases[] = { Testcase("init_invalid_platform_app_2.json", errors::kBackgroundRequiredForPlatformApps), @@ -34,16 +29,16 @@ TEST_F(ExtensionManifestTest, PlatformApps) { Testcase warning_testcases[] = { Testcase( "init_invalid_platform_app_1.json", - "'app.launch' is not allowed for specified package type " - "(theme, app, etc.)."), + "'app.launch' is only allowed for hosted apps and legacy packaged " + "apps, and this is a packaged app."), Testcase( "init_invalid_platform_app_4.json", - "'background' is not allowed for specified package type " - "(theme, app, etc.)."), + "'background' is only allowed for extensions, hosted apps and legacy " + "packaged apps, and this is a packaged app."), Testcase( "init_invalid_platform_app_5.json", - "'background' is not allowed for specified package type " - "(theme, app, etc.).") + "'background' is only allowed for extensions, hosted apps and legacy " + "packaged apps, and this is a packaged app.") }; RunTestcases( warning_testcases, arraysize(warning_testcases), EXPECT_TYPE_WARNING); diff --git a/chrome/common/extensions/manifest_unittest.cc b/chrome/common/extensions/manifest_unittest.cc index f39d75d..9e6970f 100644 --- a/chrome/common/extensions/manifest_unittest.cc +++ b/chrome/common/extensions/manifest_unittest.cc @@ -97,8 +97,9 @@ TEST_F(ManifestTest, Extension) { Feature feature; feature.set_name("background_page"); feature.set_max_manifest_version(1); - EXPECT_EQ(feature.GetErrorMessage(Feature::INVALID_MAX_MANIFEST_VERSION), - warnings[0].message); + EXPECT_EQ( + "'background_page' requires manifest version of 1 or lower.", + warnings[0].message); } // Test DeepCopy and Equals. |