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

Unified Diff: chrome/common/extensions/api/extension_api.cc

Issue 12846011: Implement API features for the Extension API feature system (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed memory leak Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/api/extension_api.cc
diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc
index c2a9cce97931c24a04b16ad3b7f1e8a911e57e13..d2c2b78d50a18a6c29fe2f72e38bfba67a69b4be 100644
--- a/chrome/common/extensions/api/extension_api.cc
+++ b/chrome/common/extensions/api/extension_api.cc
@@ -234,11 +234,6 @@ void ExtensionAPI::SplitDependencyName(const std::string& full_name,
*feature_name = full_name.substr(colon_index + 1);
}
-bool ExtensionAPI::UsesFeatureSystem(const std::string& full_name) {
- std::string api_name = GetAPINameFromFullName(full_name, NULL);
- return features_.find(api_name) != features_.end();
-}
-
void ExtensionAPI::LoadSchema(const std::string& name,
const base::StringPiece& schema) {
scoped_ptr<ListValue> schema_list(LoadSchemaList(name, schema));
@@ -332,10 +327,6 @@ void ExtensionAPI::LoadSchema(const std::string& name,
}
ExtensionAPI::ExtensionAPI() {
- RegisterDependencyProvider("api", this);
-
- // TODO(aa): Can remove this when all JSON files are converted.
- RegisterDependencyProvider("", this);
}
ExtensionAPI::~ExtensionAPI() {
@@ -343,6 +334,8 @@ ExtensionAPI::~ExtensionAPI() {
void ExtensionAPI::InitDefaultConfiguration() {
RegisterDependencyProvider(
+ "api", BaseFeatureProvider::GetApiFeatures());
+ RegisterDependencyProvider(
"manifest", BaseFeatureProvider::GetManifestFeatures());
RegisterDependencyProvider(
"permission", BaseFeatureProvider::GetPermissionFeatures());
@@ -422,27 +415,34 @@ Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name,
const Extension* extension,
Feature::Context context,
const GURL& url) {
- std::set<std::string> dependency_names;
- dependency_names.insert(full_name);
- ResolveDependencies(&dependency_names);
+ std::string feature_type;
+ std::string feature_name;
+ SplitDependencyName(full_name, &feature_type, &feature_name);
+
+ std::string child_name;
+ std::string api_name = GetAPINameFromFullName(feature_name, &child_name);
+
+ Feature* feature = GetFeatureDependency(full_name);
// Check APIs not using the feature system first.
- if (!UsesFeatureSystem(full_name)) {
- return IsNonFeatureAPIAvailable(full_name, context, extension, url) ?
+ if (!feature) {
+ return IsNonFeatureAPIAvailable(api_name, context, extension, url) ?
Feature::CreateAvailability(Feature::IS_AVAILABLE, "") :
Feature::CreateAvailability(Feature::INVALID_CONTEXT,
kUnavailableMessage);
}
- for (std::set<std::string>::iterator iter = dependency_names.begin();
- iter != dependency_names.end(); ++iter) {
- Feature* feature = GetFeatureDependency(*iter);
- CHECK(feature) << *iter;
-
- Feature::Availability availability =
- feature->IsAvailableToContext(extension, context, url);
- if (!availability.is_available())
- return availability;
+ Feature::Availability availability =
+ feature->IsAvailableToContext(extension, context, url);
+ if (!availability.is_available())
+ return availability;
+
+ for (std::set<std::string>::iterator iter = feature->dependencies().begin();
+ iter != feature->dependencies().end(); ++iter) {
+ Feature::Availability dependency_availability =
+ IsAvailable(*iter, extension, context, url);
+ if (!dependency_availability.is_available())
+ return dependency_availability;
}
return Feature::CreateAvailability(Feature::IS_AVAILABLE, "");
@@ -451,33 +451,21 @@ Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name,
bool ExtensionAPI::IsPrivileged(const std::string& full_name) {
std::string child_name;
std::string api_name = GetAPINameFromFullName(full_name, &child_name);
+ Feature* feature = GetFeatureDependency(full_name);
// First try to use the feature system.
- Feature* feature(GetFeature(full_name));
if (feature) {
- // An API is 'privileged' if it or any of its dependencies can only be run
- // in a blessed context.
- std::set<std::string> resolved_dependencies;
- resolved_dependencies.insert(full_name);
- ResolveDependencies(&resolved_dependencies);
- for (std::set<std::string>::iterator iter = resolved_dependencies.begin();
- iter != resolved_dependencies.end(); ++iter) {
- Feature* dependency = GetFeatureDependency(*iter);
- for (std::set<Feature::Context>::iterator context =
- dependency->GetContexts()->begin();
- context != dependency->GetContexts()->end(); ++context) {
- if (*context != Feature::BLESSED_EXTENSION_CONTEXT)
- return false;
- }
- }
- return true;
+ // An API is 'privileged' if it can only be run in a blessed context.
+ return feature->GetContexts()->size() ==
+ feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT);
}
+ // Get the schema now to populate |completely_unprivileged_apis_|.
+ const DictionaryValue* schema = GetSchema(api_name);
// If this API hasn't been converted yet, fall back to the old system.
if (completely_unprivileged_apis_.count(api_name))
return false;
- const DictionaryValue* schema = GetSchema(api_name);
if (partially_unprivileged_apis_.count(api_name))
return IsChildNamePrivileged(schema, child_name);
@@ -549,6 +537,8 @@ bool ExtensionAPI::IsNonFeatureAPIAvailable(const std::string& name,
Feature::Context context,
const Extension* extension,
const GURL& url) {
+ // Make sure schema is loaded.
+ GetSchema(name);
switch (context) {
case Feature::UNSPECIFIED_CONTEXT:
break;
@@ -597,36 +587,6 @@ std::set<std::string> ExtensionAPI::GetAllAPINames() {
return result;
}
-Feature* ExtensionAPI::GetFeature(const std::string& full_name) {
- // Ensure it's loaded.
- GetSchema(full_name);
-
- std::string child_name;
- std::string api_namespace = GetAPINameFromFullName(full_name, &child_name);
-
- APIFeatureMap::iterator feature_map = features_.find(api_namespace);
- if (feature_map == features_.end())
- return NULL;
-
- Feature* result = NULL;
- FeatureMap::iterator child_feature = feature_map->second->find(child_name);
- if (child_feature != feature_map->second->end()) {
- result = child_feature->second.get();
- } else {
- FeatureMap::iterator parent_feature = feature_map->second->find("");
- CHECK(parent_feature != feature_map->second->end());
- result = parent_feature->second.get();
- }
-
- if (result->GetContexts()->empty()) {
- LOG(ERROR) << "API feature '" << full_name
- << "' must specify at least one context.";
- return NULL;
- }
-
- return result;
-}
-
Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) {
std::string feature_type;
std::string feature_name;
@@ -634,11 +594,16 @@ Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) {
FeatureProviderMap::iterator provider =
dependency_providers_.find(feature_type);
- CHECK(provider != dependency_providers_.end()) << full_name;
+ if (provider == dependency_providers_.end())
+ return NULL;
Feature* feature = provider->second->GetFeature(feature_name);
- CHECK(feature) << full_name;
-
+ // Try getting the feature for the parent API, if this was a child.
+ if (!feature) {
+ std::string child_name;
+ feature = provider->second->GetFeature(
+ GetAPINameFromFullName(feature_name, &child_name));
+ }
return feature;
}
@@ -678,47 +643,6 @@ bool ExtensionAPI::IsAPIAllowed(const std::string& name,
extension->optional_permission_set()->HasAnyAccessToAPI(name);
}
-void ExtensionAPI::ResolveDependencies(std::set<std::string>* out) {
- std::set<std::string> missing_dependencies;
- for (std::set<std::string>::iterator i = out->begin(); i != out->end(); ++i)
- GetMissingDependencies(*i, *out, &missing_dependencies);
-
- while (missing_dependencies.size()) {
- std::string next = *missing_dependencies.begin();
- missing_dependencies.erase(next);
- out->insert(next);
- GetMissingDependencies(next, *out, &missing_dependencies);
- }
-}
-
-void ExtensionAPI::GetMissingDependencies(
- const std::string& api_name,
- const std::set<std::string>& excluding,
- std::set<std::string>* out) {
- std::string feature_type;
- std::string feature_name;
- SplitDependencyName(api_name, &feature_type, &feature_name);
-
- // Only API features can have dependencies for now.
- if (feature_type != "api")
- return;
-
- const DictionaryValue* schema = GetSchema(feature_name);
- CHECK(schema) << "Schema for " << feature_name << " not found";
-
- const ListValue* dependencies = NULL;
- if (!schema->GetList("dependencies", &dependencies))
- return;
-
- for (size_t i = 0; i < dependencies->GetSize(); ++i) {
- std::string dependency_name;
- if (dependencies->GetString(i, &dependency_name) &&
- !excluding.count(dependency_name)) {
- out->insert(dependency_name);
- }
- }
-}
-
bool ExtensionAPI::IsPrivilegedAPI(const std::string& name) {
return completely_unprivileged_apis_.count(name) ||
partially_unprivileged_apis_.count(name);
« no previous file with comments | « chrome/common/extensions/api/extension_api.h ('k') | chrome/common/extensions/api/extension_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698