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

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

Issue 9460002: Convert app_bindings.js to the schema_generated_bindings.js infrastructure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix koz bool thing Created 8 years, 10 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 14a6562b99de513511a1df06b2e63b78147958c1..5d87014bb4c770c1e0a68b33296d725463a8e439 100644
--- a/chrome/common/extensions/api/extension_api.cc
+++ b/chrome/common/extensions/api/extension_api.cc
@@ -15,6 +15,7 @@
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_permission_set.h"
+#include "googleurl/src/gurl.h"
#include "grit/common_resources.h"
#include "ui/base/resource/resource_bundle.h"
@@ -22,22 +23,6 @@ namespace extensions {
namespace {
-// Adds any APIs listed in "dependencies" found in |schema| but not in
-// |reference| to |out|.
-void GetMissingDependencies(
- const DictionaryValue& schema,
- const ExtensionAPI::SchemaMap& reference,
- std::set<std::string>* out) {
- ListValue* dependencies = NULL;
- if (!schema.GetList("dependencies", &dependencies))
- return;
- for (size_t i = 0; i < dependencies->GetSize(); ++i) {
- std::string api_name;
- if (dependencies->GetString(i, &api_name) && !reference.count(api_name))
- out->insert(api_name);
- }
-}
-
// Returns whether the list at |name_space_node|.|child_kind| contains any
// children with an { "unprivileged": true } property.
bool HasUnprivilegedChild(const DictionaryValue* name_space_node,
@@ -95,6 +80,7 @@ void ExtensionAPI::LoadSchemaFromResource(int resource_id) {
ExtensionAPI::ExtensionAPI() {
static int kJsonApiResourceIds[] = {
+ IDR_EXTENSION_API_JSON_APP,
IDR_EXTENSION_API_JSON_BOOKMARKS,
IDR_EXTENSION_API_JSON_BROWSERACTION,
IDR_EXTENSION_API_JSON_BROWSING_DATA,
@@ -177,6 +163,27 @@ ExtensionAPI::ExtensionAPI() {
partially_unprivileged_apis_.insert(it->first);
}
}
+
+ // Populate |url_matching_apis_|.
+ for (SchemaMap::const_iterator it = schemas_.begin();
+ it != schemas_.end(); ++it) {
+ ListValue* matches = NULL;
+ {
+ Value* matches_value = NULL;
+ if (!it->second->Get("matches", &matches_value))
+ continue;
+ CHECK_EQ(Value::TYPE_LIST, matches_value->GetType());
+ matches = static_cast<ListValue*>(matches_value);
+ }
+ URLPatternSet pattern_set;
+ for (size_t i = 0; i < matches->GetSize(); ++i) {
+ std::string pattern;
+ CHECK(matches->GetString(i, &pattern));
+ pattern_set.AddPattern(
+ URLPattern(UserScript::kValidUserScriptSchemes, pattern));
+ }
+ url_matching_apis_[it->first] = pattern_set;
+ }
}
ExtensionAPI::~ExtensionAPI() {
@@ -218,22 +225,6 @@ bool ExtensionAPI::IsPrivileged(const std::string& full_name) const {
return true;
}
-DictionaryValue* ExtensionAPI::FindListItem(
- const base::ListValue* list,
- const std::string& property_name,
- const std::string& property_value) const {
- for (size_t i = 0; i < list->GetSize(); ++i) {
- DictionaryValue* item = NULL;
- CHECK(list->GetDictionary(i, &item))
- << property_value << "/" << property_name;
- std::string value;
- if (item->GetString(property_name, &value) && value == property_value)
- return item;
- }
-
- return NULL;
-}
-
bool ExtensionAPI::IsChildNamePrivileged(const DictionaryValue* name_space_node,
const std::string& child_kind,
const std::string& child_name) const {
@@ -250,65 +241,126 @@ bool ExtensionAPI::IsChildNamePrivileged(const DictionaryValue* name_space_node,
return !unprivileged;
}
+DictionaryValue* ExtensionAPI::FindListItem(
+ const base::ListValue* list,
Aaron Boodman 2012/03/06 01:17:21 Why move? Just makes things hard to review.
not at google - send to devlin 2012/03/06 03:53:00 Dunno. Moved back. Oh, because I have a thing abo
+ const std::string& property_name,
+ const std::string& property_value) const {
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ DictionaryValue* item = NULL;
+ CHECK(list->GetDictionary(i, &item))
+ << property_value << "/" << property_name;
+ std::string value;
+ if (item->GetString(property_name, &value) && value == property_value)
+ return item;
+ }
+
+ return NULL;
+}
+
const base::DictionaryValue* ExtensionAPI::GetSchema(
const std::string& api_name) const {
SchemaMap::const_iterator maybe_schema = schemas_.find(api_name);
return maybe_schema != schemas_.end() ? maybe_schema->second.get() : NULL;
}
-void ExtensionAPI::GetSchemasForExtension(const Extension& extension,
- GetSchemasFilter filter,
- SchemaMap* out) const {
- // Check both required_permissions and optional_permissions since we need
- // to return all schemas that might be needed.
- GetSchemasForPermissions(*extension.required_permission_set(), filter, out);
- GetSchemasForPermissions(*extension.optional_permission_set(), filter, out);
-
- // Note that dependency resolution might introduce APIs outside of the filter
- // (for example, "extensions" has unprivileged componenents but relies on
- // "tabs" which doesn't). It doesn't matter because schema_generated_bindings
- // does individual function/event based checking anyway, but it's a shame.
- ResolveDependencies(out);
+scoped_ptr<std::set<std::string> > ExtensionAPI::GetAPIsForContext(
+ Feature::Context context,
+ const Extension* extension,
+ const GURL& url) const {
+ scoped_ptr<std::set<std::string> > result(new std::set<std::string>());
+
+ switch (context) {
+ case Feature::UNSPECIFIED_CONTEXT:
+ break;
+
+ case Feature::PRIVILEGED_CONTEXT:
+ // Availability is determined by the permissions of the extension.
+ CHECK(extension);
+ InsertAllowedAPIs(extension, result.get());
+ ResolveDependencies(result.get());
+ break;
+
+ case Feature::UNPRIVILEGED_CONTEXT:
+ case Feature::CONTENT_SCRIPT_CONTEXT:
+ // Availability is determined by the permissions of the extension
+ // (but only those APIs that are unprivileged).
+ CHECK(extension);
+ InsertAllowedAPIs(extension, result.get());
+ // Resolving dependencies before removing unprivileged APIs means that
+ // some unprivilged APIs may have unrealised dependencies. Too bad!
+ ResolveDependencies(result.get());
+ RemovePrivilegedAPIs(result.get());
koz (OOO until 15th September) 2012/03/06 04:06:58 This logic is beautiful ;_;
not at google - send to devlin 2012/03/06 11:36:46 Cheers ;_;
+ break;
+
+ case Feature::WEB_PAGE_CONTEXT:
+ // Availablility is determined by the url.
+ CHECK(url.is_valid());
+ for (std::map<std::string, URLPatternSet>::const_iterator i =
koz (OOO until 15th September) 2012/03/06 04:06:58 tiny nit: I feel like this part should be lifted i
not at google - send to devlin 2012/03/06 11:36:46 Cool, looks better.
+ url_matching_apis_.begin(); i != url_matching_apis_.end(); ++i) {
+ if (i->second.MatchesURL(url))
+ result->insert(i->first);
+ }
+ break;
+ }
+
+ return result.Pass();
}
-void ExtensionAPI::ResolveDependencies(SchemaMap* out) const {
+void ExtensionAPI::InsertAllowedAPIs(
+ const Extension* extension, std::set<std::string>* out) const {
+ for (SchemaMap::const_iterator i = schemas_.begin(); i != schemas_.end();
+ ++i) {
+ if (extension->required_permission_set()->HasAnyAccessToAPI(i->first) ||
+ extension->optional_permission_set()->HasAnyAccessToAPI(i->first)) {
+ out->insert(i->first);
+ }
+ }
+}
+
+void ExtensionAPI::ResolveDependencies(std::set<std::string>* out) const {
std::set<std::string> missing_dependencies;
- for (SchemaMap::const_iterator i = out->begin(); i != out->end(); ++i)
- GetMissingDependencies(*i->second, *out, &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 api_name = *missing_dependencies.begin();
- missing_dependencies.erase(api_name);
- linked_ptr<const DictionaryValue> schema = schemas_.find(api_name)->second;
- (*out)[api_name] = schema;
- GetMissingDependencies(*schema, *out, &missing_dependencies);
+ std::string next = *missing_dependencies.begin();
+ missing_dependencies.erase(next);
+ out->insert(next);
+ GetMissingDependencies(next, *out, &missing_dependencies);
}
}
-void ExtensionAPI::GetDefaultSchemas(GetSchemasFilter filter,
- SchemaMap* out) const {
- scoped_refptr<ExtensionPermissionSet> default_permissions(
- new ExtensionPermissionSet());
- GetSchemasForPermissions(*default_permissions, filter, out);
- ResolveDependencies(out);
-}
+void ExtensionAPI::GetMissingDependencies(
+ const std::string& api_name,
+ const std::set<std::string>& reference,
+ std::set<std::string>* out) const {
+ const base::DictionaryValue* schema = GetSchema(api_name);
+ CHECK(schema) << "Schema for " << api_name << " not found";
-void ExtensionAPI::GetSchemasForPermissions(
- const ExtensionPermissionSet& permissions,
- GetSchemasFilter filter,
- SchemaMap* out) const {
- for (SchemaMap::const_iterator it = schemas_.begin(); it != schemas_.end();
- ++it) {
- if (filter == ONLY_UNPRIVILEGED && IsWholeAPIPrivileged(it->first))
- continue;
- if (permissions.HasAnyAccessToAPI(it->first))
- (*out)[it->first] = it->second;
+ ListValue* dependencies = NULL;
+ if (!schema->GetList("dependencies", &dependencies))
+ return;
+
+ for (size_t i = 0; i < dependencies->GetSize(); ++i) {
+ std::string api_name;
+ if (dependencies->GetString(i, &api_name) && !reference.count(api_name))
+ out->insert(api_name);
}
}
-bool ExtensionAPI::IsWholeAPIPrivileged(const std::string& api_name) const {
- return !completely_unprivileged_apis_.count(api_name) &&
- !partially_unprivileged_apis_.count(api_name);
+void ExtensionAPI::RemovePrivilegedAPIs(std::set<std::string>* apis) const {
+ std::set<std::string> privileged_apis;
+ for (std::set<std::string>::iterator i = apis->begin(); i != apis->end();
+ ++i) {
+ if (!completely_unprivileged_apis_.count(*i) &&
+ !partially_unprivileged_apis_.count(*i)) {
+ privileged_apis.insert(*i);
+ }
+ }
+ for (std::set<std::string>::iterator i = privileged_apis.begin();
+ i != privileged_apis.end(); ++i) {
+ apis->erase(*i);
+ }
}
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698