Commit 2501ca5d authored by kalman@chromium.org's avatar kalman@chromium.org

Remove GetContexts() from the public interface of extensions::Feature. It was

being misused in such a way that makes it impossible to add other trusted
extension context types. It's also a nice cleanup, though requires rewriting
the ExtensionAPI::IsPrivileged function with sightly different semantics.

BUG=391944
R=rockot@chromium.org

Review URL: https://codereview.chromium.org/377753003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282437 0039d316-1c4b-4281-b951-d872f2087c98
parent f72e58b2
...@@ -85,43 +85,73 @@ TEST(ExtensionAPITest, SplitDependencyName) { ...@@ -85,43 +85,73 @@ TEST(ExtensionAPITest, SplitDependencyName) {
} }
} }
TEST(ExtensionAPITest, IsPrivileged) { TEST(ExtensionAPITest, IsAvailableInUntrustedContext) {
scoped_ptr<ExtensionAPI> extension_api( scoped_ptr<ExtensionAPI> extension_api(
ExtensionAPI::CreateWithDefaultConfiguration()); ExtensionAPI::CreateWithDefaultConfiguration());
scoped_refptr<const Extension> extension =
EXPECT_FALSE(extension_api->IsPrivileged("runtime.connect")); ExtensionBuilder()
EXPECT_FALSE(extension_api->IsPrivileged("runtime.onConnect")); .SetManifest(DictionaryBuilder()
EXPECT_FALSE(extension_api->IsPrivileged("runtime.lastError")); .Set("name", "extension")
.Set("version", "1")
.Set("permissions", ListBuilder().Append("storage"))
.Set("manifest_version", 2))
.Build();
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("runtime.connect",
extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("runtime.onConnect",
extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("runtime.lastError",
extension.get()));
// Exists, but privileged. // Exists, but privileged.
EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews")); EXPECT_FALSE(extension_api->IsAvailableInUntrustedContext(
EXPECT_TRUE(extension_api->IsPrivileged("history.search")); "extension.getViews", extension.get()));
EXPECT_FALSE(extension_api->IsAvailableInUntrustedContext("history.search",
extension.get()));
// Whole APIs that are unprivileged. // Whole APIs that are unprivileged.
EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails")); EXPECT_TRUE(
EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled")); extension_api->IsAvailableInUntrustedContext("app", extension.get()));
EXPECT_FALSE(extension_api->IsPrivileged("storage.local")); EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("app.getDetails",
EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged")); extension.get()));
EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set")); // There is no feature "app.isInstalled" (it's "app.getIsInstalled") but
EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS")); // this should be available nonetheless.
EXPECT_FALSE(extension_api->IsPrivileged("storage.set")); EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("app.isInstalled",
extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("storage.local",
extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext(
"storage.local.onChanged", extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("storage.local.set",
extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext(
"storage.local.MAX_ITEMS", extension.get()));
EXPECT_TRUE(extension_api->IsAvailableInUntrustedContext("storage.set",
extension.get()));
// APIs which override unprivileged APIs.
EXPECT_FALSE(extension_api->IsAvailableInUntrustedContext("app.runtime",
extension.get()));
EXPECT_FALSE(extension_api->IsAvailableInUntrustedContext("app.window",
extension.get()));
} }
TEST(ExtensionAPITest, IsPrivilegedFeatures) { TEST(ExtensionAPITest, IsAvailableInUntrustedContextFeatures) {
struct { struct {
std::string api_full_name; std::string api_full_name;
bool expect_is_privilged; bool expect_is_available;
} test_data[] = { } test_data[] = {{"test1", true},
{ "test1", false }, {"test1.foo", false},
{ "test1.foo", true }, {"test2", false},
{ "test2", true }, {"test2.foo", true},
{ "test2.foo", false }, {"test2.bar", true},
{ "test2.bar", false }, {"test2.baz", false},
{ "test2.baz", true }, {"test2.qux", false},
{ "test3", false }, {"test3", true},
{ "test3.foo", true }, {"test3.foo", false},
{ "test4", false } {"test4", true},
}; {"test5", true}};
base::FilePath api_features_path; base::FilePath api_features_path;
PathService::Get(chrome::DIR_TEST_DATA, &api_features_path); PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
...@@ -137,11 +167,16 @@ TEST(ExtensionAPITest, IsPrivilegedFeatures) { ...@@ -137,11 +167,16 @@ TEST(ExtensionAPITest, IsPrivilegedFeatures) {
base::JSONReader::Read(api_features_str))); base::JSONReader::Read(api_features_str)));
BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature); BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
scoped_refptr<Extension> extension =
BuildExtension(ExtensionBuilder().Pass()).Build();
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
ExtensionAPI api; ExtensionAPI api;
api.RegisterDependencyProvider("api", &api_feature_provider); api.RegisterDependencyProvider("api", &api_feature_provider);
EXPECT_EQ(test_data[i].expect_is_privilged, EXPECT_EQ(test_data[i].expect_is_available,
api.IsPrivileged(test_data[i].api_full_name)) << i; api.IsAvailableInUntrustedContext(test_data[i].api_full_name,
extension.get()))
<< i;
} }
} }
...@@ -708,10 +743,6 @@ TEST(ExtensionAPITest, DefaultConfigurationFeatures) { ...@@ -708,10 +743,6 @@ TEST(ExtensionAPITest, DefaultConfigurationFeatures) {
EXPECT_TRUE(feature->whitelist()->empty()); EXPECT_TRUE(feature->whitelist()->empty());
EXPECT_TRUE(feature->extension_types()->empty()); EXPECT_TRUE(feature->extension_types()->empty());
EXPECT_EQ(1u, feature->GetContexts()->size());
EXPECT_TRUE(feature->GetContexts()->count(
Feature::BLESSED_EXTENSION_CONTEXT));
EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION, feature->location()); EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION, feature->location());
EXPECT_TRUE(feature->platforms()->empty()); EXPECT_TRUE(feature->platforms()->empty());
EXPECT_EQ(0, feature->min_manifest_version()); EXPECT_EQ(0, feature->min_manifest_version());
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
"contexts": ["blessed_extension"] "contexts": ["blessed_extension"]
}, },
"test2": { "test2": {
"contexts": ["blessed_extension"], "channel": "trunk",
"dependencies": ["api:test1"] "contexts": ["blessed_extension"]
}, },
"test2.foo": { "test2.foo": {
"channel": "trunk", "channel": "trunk",
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
"contexts": ["content_script", "blessed_extension"] "contexts": ["content_script", "blessed_extension"]
}, },
"test2.baz": { "test2.baz": {
"contexts": ["blessed_extension"], "channel": "trunk",
"dependencies": ["api:test2.foo"] "contexts": ["blessed_extension"]
}, },
"test3": { "test3": {
"channel": "trunk", "channel": "trunk",
...@@ -32,7 +32,12 @@ ...@@ -32,7 +32,12 @@
"contexts": ["blessed_extension"] "contexts": ["blessed_extension"]
}, },
"test4": { "test4": {
"contexts": ["content_script"], "channel": "trunk",
"dependencies": ["api:test1.foo"] "contexts": ["web_page"],
"matches": ["<all_urls>"]
},
"test5": {
"channel": "trunk",
"contexts": ["blessed_web_page"]
} }
} }
...@@ -525,8 +525,9 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id, ...@@ -525,8 +525,9 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id,
ProcessMap* process_map = ProcessMap::Get(listener_context); ProcessMap* process_map = ProcessMap::Get(listener_context);
// If the event is privileged, only send to extension processes. Otherwise, // If the event is privileged, only send to extension processes. Otherwise,
// it's OK to send to normal renderers (e.g., for content scripts). // it's OK to send to normal renderers (e.g., for content scripts).
if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && if (!process_map->Contains(extension->id(), process->GetID()) &&
!process_map->Contains(extension->id(), process->GetID())) { !ExtensionAPI::GetSharedInstance()->IsAvailableInUntrustedContext(
event->event_name, extension)) {
return; return;
} }
......
...@@ -474,7 +474,7 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( ...@@ -474,7 +474,7 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction(
// Privileged APIs can only be called from the process the extension // Privileged APIs can only be called from the process the extension
// is running in. // is running in.
if (allowed && api->IsPrivileged(params.name)) if (allowed && !api->IsAvailableInUntrustedContext(params.name, extension))
allowed = process_map.Contains(extension->id(), requesting_process_id); allowed = process_map.Contains(extension->id(), requesting_process_id);
if (!allowed) { if (!allowed) {
......
...@@ -262,6 +262,7 @@ bool ExtensionAPI::IsAnyFeatureAvailableToContext(const Feature& api, ...@@ -262,6 +262,7 @@ bool ExtensionAPI::IsAnyFeatureAvailableToContext(const Feature& api,
const GURL& url) { const GURL& url) {
FeatureProviderMap::iterator provider = dependency_providers_.find("api"); FeatureProviderMap::iterator provider = dependency_providers_.find("api");
CHECK(provider != dependency_providers_.end()); CHECK(provider != dependency_providers_.end());
if (api.IsAvailableToContext(extension, context, url).is_available()) if (api.IsAvailableToContext(extension, context, url).is_available())
return true; return true;
...@@ -289,13 +290,17 @@ Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, ...@@ -289,13 +290,17 @@ Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name,
return feature->IsAvailableToContext(extension, context, url); return feature->IsAvailableToContext(extension, context, url);
} }
bool ExtensionAPI::IsPrivileged(const std::string& full_name) { bool ExtensionAPI::IsAvailableInUntrustedContext(const std::string& name,
Feature* feature = GetFeatureDependency(full_name); const Extension* extension) {
CHECK(feature) << full_name; return IsAvailable(name, extension, Feature::CONTENT_SCRIPT_CONTEXT, GURL())
DCHECK(!feature->GetContexts()->empty()) << full_name; .is_available() ||
// An API is 'privileged' if it can only be run in a blessed context. IsAvailable(
return feature->GetContexts()->size() == name, extension, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL())
feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT); .is_available() ||
IsAvailable(name, extension, Feature::BLESSED_WEB_PAGE_CONTEXT, GURL())
.is_available() ||
IsAvailable(name, extension, Feature::WEB_PAGE_CONTEXT, GURL())
.is_available();
} }
const base::DictionaryValue* ExtensionAPI::GetSchema( const base::DictionaryValue* ExtensionAPI::GetSchema(
......
...@@ -104,11 +104,10 @@ class ExtensionAPI { ...@@ -104,11 +104,10 @@ class ExtensionAPI {
Feature::Context context, Feature::Context context,
const GURL& url); const GURL& url);
// Returns true if |name| is a privileged API path. Privileged paths can only // Returns true if |name| is available to |extension| in any untrusted
// be called from extension code which is running in its own designated // extension context, such as content scripts, iframes, or web pages.
// extension process. They cannot be called from extension code running in bool IsAvailableInUntrustedContext(const std::string& name,
// content scripts, or other low-privileged contexts. const Extension* extension);
bool IsPrivileged(const std::string& name);
// Gets the schema for the extension API with namespace |full_name|. // Gets the schema for the extension API with namespace |full_name|.
// Ownership remains with this object. // Ownership remains with this object.
......
...@@ -36,7 +36,8 @@ bool ExtensionAPI::IsAnyFeatureAvailableToContext(const Feature& api, ...@@ -36,7 +36,8 @@ bool ExtensionAPI::IsAnyFeatureAvailableToContext(const Feature& api,
return false; return false;
} }
bool ExtensionAPI::IsPrivileged(const std::string& full_name) { bool ExtensionAPI::IsAvailableInUntrustedContext(const std::string& full_name,
const Extension* extension) {
return false; return false;
} }
......
...@@ -28,7 +28,7 @@ std::string APIFeature::Parse(const base::DictionaryValue* value) { ...@@ -28,7 +28,7 @@ std::string APIFeature::Parse(const base::DictionaryValue* value) {
value->GetBoolean("internal", &internal_); value->GetBoolean("internal", &internal_);
value->GetBoolean("blocked_in_service_worker", &blocked_in_service_worker_); value->GetBoolean("blocked_in_service_worker", &blocked_in_service_worker_);
if (GetContexts()->empty()) if (contexts()->empty())
return name() + ": API features must specify at least one context."; return name() + ": API features must specify at least one context.";
return std::string(); return std::string();
......
...@@ -12,18 +12,14 @@ ComplexFeature::ComplexFeature(scoped_ptr<FeatureList> features) { ...@@ -12,18 +12,14 @@ ComplexFeature::ComplexFeature(scoped_ptr<FeatureList> features) {
no_parent_ = features_[0]->no_parent(); no_parent_ = features_[0]->no_parent();
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
// Verify GetContexts, IsInternal, & IsBlockedInServiceWorker are consistent // Verify IsInternal and IsBlockedInServiceWorker are consistent across all
// across all features. // features.
std::set<Feature::Context>* first_contexts = features_[0]->GetContexts();
bool first_is_internal = features_[0]->IsInternal(); bool first_is_internal = features_[0]->IsInternal();
bool first_blocked_in_service_worker = bool first_blocked_in_service_worker =
features_[0]->IsBlockedInServiceWorker(); features_[0]->IsBlockedInServiceWorker();
for (FeatureList::const_iterator it = features_.begin() + 1; for (FeatureList::const_iterator it = features_.begin() + 1;
it != features_.end(); it != features_.end();
++it) { ++it) {
DCHECK(*first_contexts == *(*it)->GetContexts())
<< "Complex feature must have consistent values of "
"contexts across all sub features.";
DCHECK(first_is_internal == (*it)->IsInternal()) DCHECK(first_is_internal == (*it)->IsInternal())
<< "Complex feature must have consistent values of " << "Complex feature must have consistent values of "
"internal across all sub features."; "internal across all sub features.";
...@@ -112,16 +108,9 @@ bool ComplexFeature::IsBlockedInServiceWorker() const { ...@@ -112,16 +108,9 @@ bool ComplexFeature::IsBlockedInServiceWorker() const {
return features_[0]->IsBlockedInServiceWorker(); return features_[0]->IsBlockedInServiceWorker();
} }
std::set<Feature::Context>* ComplexFeature::GetContexts() {
// TODO(justinlin): Current use cases for ComplexFeatures are simple (e.g.
// allow API in dev channel for everyone but stable channel for a whitelist),
// but if they get more complicated, we need to return some meaningful context
// set. Either that or remove this method from the Feature interface.
return features_[0]->GetContexts();
}
bool ComplexFeature::IsInternal() const { bool ComplexFeature::IsInternal() const {
// TODO(justinlin): Same as the above TODO. // Constructor verifies that composed features are consistent, thus we can
// return just the first feature's value.
return features_[0]->IsInternal(); return features_[0]->IsInternal();
} }
......
...@@ -49,8 +49,6 @@ class ComplexFeature : public Feature { ...@@ -49,8 +49,6 @@ class ComplexFeature : public Feature {
const GURL& url, const GURL& url,
Context context) const OVERRIDE; Context context) const OVERRIDE;
virtual std::set<Context>* GetContexts() OVERRIDE;
virtual bool IsInternal() const OVERRIDE; virtual bool IsInternal() const OVERRIDE;
private: private:
......
...@@ -108,8 +108,6 @@ class Feature { ...@@ -108,8 +108,6 @@ class Feature {
// Gets the platform the code is currently running on. // Gets the platform the code is currently running on.
static Platform GetCurrentPlatform(); static Platform GetCurrentPlatform();
virtual std::set<Context>* GetContexts() = 0;
// Tests whether this is an internal API or not. // Tests whether this is an internal API or not.
virtual bool IsInternal() const = 0; virtual bool IsInternal() const = 0;
......
...@@ -44,7 +44,7 @@ std::string ManifestFeature::Parse(const base::DictionaryValue* value) { ...@@ -44,7 +44,7 @@ std::string ManifestFeature::Parse(const base::DictionaryValue* value) {
"value for extension_types."; "value for extension_types.";
} }
if (!GetContexts()->empty()) if (value->HasKey("contexts"))
return name() + ": Manifest features do not support contexts."; return name() + ": Manifest features do not support contexts.";
return std::string(); return std::string();
......
...@@ -43,7 +43,7 @@ std::string PermissionFeature::Parse(const base::DictionaryValue* value) { ...@@ -43,7 +43,7 @@ std::string PermissionFeature::Parse(const base::DictionaryValue* value) {
"value for extension_types."; "value for extension_types.";
} }
if (!GetContexts()->empty()) if (value->HasKey("contexts"))
return name() + ": Permission features do not support contexts."; return name() + ": Permission features do not support contexts.";
return std::string(); return std::string();
......
...@@ -287,10 +287,14 @@ std::string SimpleFeature::Parse(const base::DictionaryValue* value) { ...@@ -287,10 +287,14 @@ std::string SimpleFeature::Parse(const base::DictionaryValue* value) {
value->GetBoolean("component_extensions_auto_granted", value->GetBoolean("component_extensions_auto_granted",
&component_extensions_auto_granted_); &component_extensions_auto_granted_);
if (matches_.is_empty() && contexts_.count(WEB_PAGE_CONTEXT) != 0) { // NOTE: ideally we'd sanity check that "matches" can be specified if and
return name() + ": Allowing web_page contexts requires supplying a value " + // only if there's a "web_page" context, but without (Simple)Features being
"for matches."; // aware of their own heirarchy this is impossible.
} //
// For example, we might have feature "foo" available to "web_page" context
// and "matches" google.com/*. Then a sub-feature "foo.bar" might override
// "matches" to be chromium.org/*. That sub-feature doesn't need to specify
// "web_page" context because it's inherited, but we don't know that here.
for (FilterList::iterator filter_iter = filters_.begin(); for (FilterList::iterator filter_iter = filters_.begin();
filter_iter != filters_.end(); filter_iter != filters_.end();
...@@ -395,7 +399,7 @@ Feature::Availability SimpleFeature::IsAvailableToContext( ...@@ -395,7 +399,7 @@ Feature::Availability SimpleFeature::IsAvailableToContext(
if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) if (!contexts_.empty() && contexts_.find(context) == contexts_.end())
return CreateAvailability(INVALID_CONTEXT, context); return CreateAvailability(INVALID_CONTEXT, context);
if (!matches_.is_empty() && !matches_.MatchesURL(url)) if (context == WEB_PAGE_CONTEXT && !matches_.MatchesURL(url))
return CreateAvailability(INVALID_URL, url); return CreateAvailability(INVALID_URL, url);
for (FilterList::const_iterator filter_iter = filters_.begin(); for (FilterList::const_iterator filter_iter = filters_.begin();
...@@ -502,10 +506,6 @@ Feature::Availability SimpleFeature::CreateAvailability( ...@@ -502,10 +506,6 @@ Feature::Availability SimpleFeature::CreateAvailability(
context)); context));
} }
std::set<Feature::Context>* SimpleFeature::GetContexts() {
return &contexts_;
}
bool SimpleFeature::IsInternal() const { bool SimpleFeature::IsInternal() const {
return false; return false;
} }
......
...@@ -55,6 +55,7 @@ class SimpleFeature : public Feature { ...@@ -55,6 +55,7 @@ class SimpleFeature : public Feature {
std::set<std::string>* blacklist() { return &blacklist_; } std::set<std::string>* blacklist() { return &blacklist_; }
std::set<std::string>* whitelist() { return &whitelist_; } std::set<std::string>* whitelist() { return &whitelist_; }
std::set<Manifest::Type>* extension_types() { return &extension_types_; } std::set<Manifest::Type>* extension_types() { return &extension_types_; }
std::set<Context>* contexts() { return &contexts_; }
// Dependency resolution is a property of Features that is preferrably // Dependency resolution is a property of Features that is preferrably
// handled internally to avoid temptation, but FeatureFilters may need // handled internally to avoid temptation, but FeatureFilters may need
...@@ -104,8 +105,6 @@ class SimpleFeature : public Feature { ...@@ -104,8 +105,6 @@ class SimpleFeature : public Feature {
const GURL& url, const GURL& url,
Context context) const OVERRIDE; Context context) const OVERRIDE;
virtual std::set<Context>* GetContexts() OVERRIDE;
virtual bool IsInternal() const OVERRIDE; virtual bool IsInternal() const OVERRIDE;
virtual bool IsBlockedInServiceWorker() const OVERRIDE; virtual bool IsBlockedInServiceWorker() const OVERRIDE;
......
...@@ -289,7 +289,7 @@ TEST_F(ExtensionSimpleFeatureTest, PackageType) { ...@@ -289,7 +289,7 @@ TEST_F(ExtensionSimpleFeatureTest, PackageType) {
TEST_F(ExtensionSimpleFeatureTest, Context) { TEST_F(ExtensionSimpleFeatureTest, Context) {
SimpleFeature feature; SimpleFeature feature;
feature.set_name("somefeature"); feature.set_name("somefeature");
feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP); feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
feature.platforms()->insert(Feature::CHROMEOS_PLATFORM); feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
feature.set_min_manifest_version(21); feature.set_min_manifest_version(21);
...@@ -328,9 +328,9 @@ TEST_F(ExtensionSimpleFeatureTest, Context) { ...@@ -328,9 +328,9 @@ TEST_F(ExtensionSimpleFeatureTest, Context) {
feature.extension_types()->clear(); feature.extension_types()->clear();
feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP); feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
feature.GetContexts()->clear(); feature.contexts()->clear();
feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT); feature.contexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
feature.GetContexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT); feature.contexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT);
{ {
Feature::Availability availability = feature.IsAvailableToContext( Feature::Availability availability = feature.IsAvailableToContext(
extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
...@@ -341,7 +341,7 @@ TEST_F(ExtensionSimpleFeatureTest, Context) { ...@@ -341,7 +341,7 @@ TEST_F(ExtensionSimpleFeatureTest, Context) {
availability.message()); availability.message());
} }
feature.GetContexts()->insert(Feature::WEB_PAGE_CONTEXT); feature.contexts()->insert(Feature::WEB_PAGE_CONTEXT);
{ {
Feature::Availability availability = feature.IsAvailableToContext( Feature::Availability availability = feature.IsAvailableToContext(
extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
...@@ -352,8 +352,8 @@ TEST_F(ExtensionSimpleFeatureTest, Context) { ...@@ -352,8 +352,8 @@ TEST_F(ExtensionSimpleFeatureTest, Context) {
availability.message()); availability.message());
} }
feature.GetContexts()->clear(); feature.contexts()->clear();
feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
feature.set_location(SimpleFeature::COMPONENT_LOCATION); feature.set_location(SimpleFeature::COMPONENT_LOCATION);
EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext( EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext(
extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
...@@ -496,7 +496,7 @@ TEST_F(ExtensionSimpleFeatureTest, ParseNull) { ...@@ -496,7 +496,7 @@ TEST_F(ExtensionSimpleFeatureTest, ParseNull) {
feature->Parse(value.get()); feature->Parse(value.get());
EXPECT_TRUE(feature->whitelist()->empty()); EXPECT_TRUE(feature->whitelist()->empty());
EXPECT_TRUE(feature->extension_types()->empty()); EXPECT_TRUE(feature->extension_types()->empty());
EXPECT_TRUE(feature->GetContexts()->empty()); EXPECT_TRUE(feature->contexts()->empty());
EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION, feature->location()); EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION, feature->location());
EXPECT_TRUE(feature->platforms()->empty()); EXPECT_TRUE(feature->platforms()->empty());
EXPECT_EQ(0, feature->min_manifest_version()); EXPECT_EQ(0, feature->min_manifest_version());
...@@ -554,22 +554,17 @@ TEST_F(ExtensionSimpleFeatureTest, ParseContexts) { ...@@ -554,22 +554,17 @@ TEST_F(ExtensionSimpleFeatureTest, ParseContexts) {
value->Set("contexts", contexts); value->Set("contexts", contexts);
scoped_ptr<SimpleFeature> feature(new SimpleFeature()); scoped_ptr<SimpleFeature> feature(new SimpleFeature());
feature->Parse(value.get()); feature->Parse(value.get());
EXPECT_EQ(5u, feature->GetContexts()->size()); EXPECT_EQ(5u, feature->contexts()->size());
EXPECT_TRUE( EXPECT_TRUE(feature->contexts()->count(Feature::BLESSED_EXTENSION_CONTEXT));
feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT)); EXPECT_TRUE(feature->contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
EXPECT_TRUE( EXPECT_TRUE(feature->contexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
feature->GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT)); EXPECT_TRUE(feature->contexts()->count(Feature::WEB_PAGE_CONTEXT));
EXPECT_TRUE( EXPECT_TRUE(feature->contexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT));
feature->GetContexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
EXPECT_TRUE(
feature->GetContexts()->count(Feature::WEB_PAGE_CONTEXT));
EXPECT_TRUE(
feature->GetContexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT));
value->SetString("contexts", "all"); value->SetString("contexts", "all");
scoped_ptr<SimpleFeature> feature2(new SimpleFeature()); scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
feature2->Parse(value.get()); feature2->Parse(value.get());
EXPECT_EQ(*(feature->GetContexts()), *(feature2->GetContexts())); EXPECT_EQ(*(feature->contexts()), *(feature2->contexts()));
} }
TEST_F(ExtensionSimpleFeatureTest, ParseLocation) { TEST_F(ExtensionSimpleFeatureTest, ParseLocation) {
...@@ -625,7 +620,7 @@ TEST_F(ExtensionSimpleFeatureTest, Inheritance) { ...@@ -625,7 +620,7 @@ TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
SimpleFeature feature; SimpleFeature feature;
feature.whitelist()->insert("foo"); feature.whitelist()->insert("foo");
feature.extension_types()->insert(Manifest::TYPE_THEME); feature.extension_types()->insert(Manifest::TYPE_THEME);
feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
feature.set_location(SimpleFeature::COMPONENT_LOCATION); feature.set_location(SimpleFeature::COMPONENT_LOCATION);
feature.platforms()->insert(Feature::CHROMEOS_PLATFORM); feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
feature.set_min_manifest_version(1); feature.set_min_manifest_version(1);
...@@ -637,7 +632,7 @@ TEST_F(ExtensionSimpleFeatureTest, Inheritance) { ...@@ -637,7 +632,7 @@ TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
feature.Parse(&definition); feature.Parse(&definition);
EXPECT_EQ(1u, feature.whitelist()->size()); EXPECT_EQ(1u, feature.whitelist()->size());
EXPECT_EQ(1u, feature.extension_types()->size()); EXPECT_EQ(1u, feature.extension_types()->size());
EXPECT_EQ(1u, feature.GetContexts()->size()); EXPECT_EQ(1u, feature.contexts()->size());
EXPECT_EQ(1u, feature.whitelist()->count("foo")); EXPECT_EQ(1u, feature.whitelist()->count("foo"));
EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature.location()); EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature.location());
EXPECT_EQ(1u, feature.platforms()->size()); EXPECT_EQ(1u, feature.platforms()->size());
...@@ -661,11 +656,11 @@ TEST_F(ExtensionSimpleFeatureTest, Inheritance) { ...@@ -661,11 +656,11 @@ TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
feature.Parse(&definition); feature.Parse(&definition);
EXPECT_EQ(1u, feature.whitelist()->size()); EXPECT_EQ(1u, feature.whitelist()->size());
EXPECT_EQ(1u, feature.extension_types()->size()); EXPECT_EQ(1u, feature.extension_types()->size());
EXPECT_EQ(1u, feature.GetContexts()->size()); EXPECT_EQ(1u, feature.contexts()->size());
EXPECT_EQ(1u, feature.whitelist()->count("bar")); EXPECT_EQ(1u, feature.whitelist()->count("bar"));
EXPECT_EQ(1u, feature.extension_types()->count(Manifest::TYPE_EXTENSION)); EXPECT_EQ(1u, feature.extension_types()->count(Manifest::TYPE_EXTENSION));
EXPECT_EQ(1u, EXPECT_EQ(1u,
feature.GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT)); feature.contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
EXPECT_EQ(2, feature.min_manifest_version()); EXPECT_EQ(2, feature.min_manifest_version());
EXPECT_EQ(3, feature.max_manifest_version()); EXPECT_EQ(3, feature.max_manifest_version());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment