| Index: chrome/common/extensions/api/extension_api.cc
|
| ===================================================================
|
| --- chrome/common/extensions/api/extension_api.cc (revision 130700)
|
| +++ chrome/common/extensions/api/extension_api.cc (working copy)
|
| @@ -9,18 +9,13 @@
|
| #include <vector>
|
|
|
| #include "base/json/json_reader.h"
|
| -#include "base/json/json_writer.h"
|
| -#include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| -#include "base/string_number_conversions.h"
|
| #include "base/string_split.h"
|
| #include "base/string_util.h"
|
| #include "base/values.h"
|
| #include "chrome/common/extensions/api/generated_schemas.h"
|
| #include "chrome/common/extensions/extension.h"
|
| #include "chrome/common/extensions/extension_permission_set.h"
|
| -#include "chrome/common/extensions/simple_feature_provider.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| #include "googleurl/src/gurl.h"
|
| #include "grit/common_resources.h"
|
| #include "ui/base/resource/resource_bundle.h"
|
| @@ -28,7 +23,6 @@
|
| using base::DictionaryValue;
|
| using base::ListValue;
|
| using base::Value;
|
| -using content::BrowserThread;
|
|
|
| namespace extensions {
|
|
|
| @@ -36,11 +30,6 @@
|
|
|
| namespace {
|
|
|
| -const char* kChildKinds[] = {
|
| - "functions",
|
| - "events"
|
| -};
|
| -
|
| // 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,
|
| @@ -78,76 +67,13 @@
|
| return scoped_ptr<ListValue>(static_cast<ListValue*>(result.release()));
|
| }
|
|
|
| -DictionaryValue* FindListItem(const ListValue* list,
|
| - const std::string& property_name,
|
| - const std::string& property_value) {
|
| - 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 DictionaryValue* GetSchemaChild(const DictionaryValue* schema_node,
|
| - const std::string& child_name) {
|
| - DictionaryValue* child_node = NULL;
|
| - for (size_t i = 0; i < arraysize(kChildKinds); ++i) {
|
| - ListValue* list_node = NULL;
|
| - if (!schema_node->GetList(kChildKinds[i], &list_node))
|
| - continue;
|
| - child_node = FindListItem(list_node, "name", child_name);
|
| - if (child_node)
|
| - return child_node;
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -struct Static {
|
| - Static()
|
| - : api(ExtensionAPI::CreateWithDefaultConfiguration()) {
|
| - }
|
| - scoped_ptr<ExtensionAPI> api;
|
| -};
|
| -
|
| -base::LazyInstance<Static> g_lazy_instance = LAZY_INSTANCE_INITIALIZER;
|
| -
|
| } // namespace
|
|
|
| // static
|
| -ExtensionAPI* ExtensionAPI::GetSharedInstance() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - return g_lazy_instance.Get().api.get();
|
| +ExtensionAPI* ExtensionAPI::GetInstance() {
|
| + return Singleton<ExtensionAPI>::get();
|
| }
|
|
|
| -// static
|
| -ExtensionAPI* ExtensionAPI::CreateWithDefaultConfiguration() {
|
| - ExtensionAPI* api = new ExtensionAPI();
|
| - api->InitDefaultConfiguration();
|
| - return api;
|
| -}
|
| -
|
| -// static
|
| -void ExtensionAPI::SplitDependencyName(const std::string& full_name,
|
| - std::string* feature_type,
|
| - std::string* feature_name) {
|
| - size_t colon_index = full_name.find(':');
|
| - if (colon_index == std::string::npos) {
|
| - // TODO(aa): Remove this code when all API descriptions have been updated.
|
| - *feature_type = "api";
|
| - *feature_name = full_name;
|
| - return;
|
| - }
|
| -
|
| - *feature_type = full_name.substr(0, colon_index);
|
| - *feature_name = full_name.substr(colon_index + 1);
|
| -}
|
| -
|
| void ExtensionAPI::LoadSchema(const base::StringPiece& schema) {
|
| scoped_ptr<ListValue> schema_list(LoadSchemaList(schema));
|
| std::string schema_namespace;
|
| @@ -189,309 +115,238 @@
|
| }
|
| url_matching_apis_[schema_namespace] = pattern_set;
|
| }
|
| -
|
| - // Populate feature maps.
|
| - // TODO(aa): Consider not storing features that can never run on the current
|
| - // machine (e.g., because of platform restrictions).
|
| - bool uses_feature_system = false;
|
| - schema->GetBoolean("uses_feature_system", &uses_feature_system);
|
| - if (!uses_feature_system)
|
| - continue;
|
| -
|
| - Feature* feature = new Feature();
|
| - feature->set_name(schema_namespace);
|
| - feature->Parse(schema);
|
| -
|
| - FeatureMap* schema_features = new FeatureMap();
|
| - CHECK(features_.insert(
|
| - std::make_pair(schema_namespace,
|
| - make_linked_ptr(schema_features))).second);
|
| - CHECK(schema_features->insert(
|
| - std::make_pair("", make_linked_ptr(feature))).second);
|
| -
|
| - for (size_t i = 0; i < arraysize(kChildKinds); ++i) {
|
| - ListValue* child_list = NULL;
|
| - schema->GetList(kChildKinds[i], &child_list);
|
| - if (!child_list)
|
| - continue;
|
| -
|
| - for (size_t j = 0; j < child_list->GetSize(); ++j) {
|
| - DictionaryValue* child = NULL;
|
| - CHECK(child_list->GetDictionary(j, &child));
|
| -
|
| - scoped_ptr<Feature> child_feature(new Feature(*feature));
|
| - child_feature->Parse(child);
|
| - if (child_feature->Equals(*feature))
|
| - continue; // no need to store no-op features
|
| -
|
| - std::string child_name;
|
| - CHECK(child->GetString("name", &child_name));
|
| - child_feature->set_name(schema_namespace + "." + child_name);
|
| - CHECK(schema_features->insert(
|
| - std::make_pair(child_name,
|
| - make_linked_ptr(child_feature.release()))).second);
|
| - }
|
| - }
|
| }
|
| }
|
|
|
| ExtensionAPI::ExtensionAPI() {
|
| - RegisterDependencyProvider("api", this);
|
| -
|
| - // TODO(aa): Can remove this when all JSON files are converted.
|
| - RegisterDependencyProvider("", this);
|
| -}
|
| -
|
| -ExtensionAPI::~ExtensionAPI() {
|
| -}
|
| -
|
| -void ExtensionAPI::InitDefaultConfiguration() {
|
| - RegisterDependencyProvider(
|
| - "manifest", SimpleFeatureProvider::GetManifestFeatures());
|
| - RegisterDependencyProvider(
|
| - "permission", SimpleFeatureProvider::GetPermissionFeatures());
|
| -
|
| // Schemas to be loaded from resources.
|
| - CHECK(unloaded_schemas_.empty());
|
| - RegisterSchema("app", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_APP));
|
| - RegisterSchema("bookmarks", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_BOOKMARKS));
|
| - RegisterSchema("browserAction", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_BROWSERACTION));
|
| - RegisterSchema("browsingData", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_BROWSINGDATA));
|
| - RegisterSchema("chromeAuthPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_CHROMEAUTHPRIVATE));
|
| - RegisterSchema("chromeosInfoPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_CHROMEOSINFOPRIVATE));
|
| - RegisterSchema("contentSettings", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_CONTENTSETTINGS));
|
| - RegisterSchema("contextMenus", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_CONTEXTMENUS));
|
| - RegisterSchema("cookies", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_COOKIES));
|
| - RegisterSchema("debugger", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_DEBUGGER));
|
| - RegisterSchema("devtools", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_DEVTOOLS));
|
| - RegisterSchema("experimental.accessibility", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_ACCESSIBILITY));
|
| - RegisterSchema("experimental.alarms", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_ALARMS));
|
| - RegisterSchema("experimental.app", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP));
|
| - RegisterSchema("experimental.bookmarkManager", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER));
|
| - RegisterSchema("experimental.declarative", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_DECLARATIVE));
|
| - RegisterSchema("experimental.downloads", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_DOWNLOADS));
|
| - RegisterSchema("experimental.extension", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_EXTENSION));
|
| - RegisterSchema("experimental.fontSettings", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTSSETTINGS));
|
| - RegisterSchema("experimental.identity", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_IDENTITY));
|
| - RegisterSchema("experimental.infobars", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_INFOBARS));
|
| - RegisterSchema("experimental.input.ui", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_UI));
|
| - RegisterSchema("experimental.input.virtualKeyboard", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_VIRTUALKEYBOARD));
|
| - RegisterSchema("experimental.keybinding", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_KEYBINDING));
|
| - RegisterSchema("experimental.managedMode", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_MANAGEDMODE));
|
| - RegisterSchema("experimental.offscreenTabs", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_OFFSCREENTABS));
|
| - RegisterSchema("experimental.processes", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_PROCESSES));
|
| - RegisterSchema("experimental.rlz", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_RLZ));
|
| - RegisterSchema("experimental.serial", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_SERIAL));
|
| - RegisterSchema("experimental.socket", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_SOCKET));
|
| - RegisterSchema("experimental.speechInput", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_SPEECHINPUT));
|
| - RegisterSchema("experimental.webRequest", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXPERIMENTAL_WEBREQUEST));
|
| - RegisterSchema("extension", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_EXTENSION));
|
| - RegisterSchema("fileBrowserHandler", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER));
|
| - RegisterSchema("fileBrowserPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE));
|
| - RegisterSchema("history", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_HISTORY));
|
| - RegisterSchema("i18n", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_I18N));
|
| - RegisterSchema("idle", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_IDLE));
|
| - RegisterSchema("input.ime", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_INPUT_IME));
|
| - RegisterSchema("inputMethodPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE));
|
| - RegisterSchema("management", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_MANAGEMENT));
|
| - RegisterSchema("mediaPlayerPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_MEDIAPLAYERPRIVATE));
|
| - RegisterSchema("metricsPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_METRICSPRIVATE));
|
| - RegisterSchema("offersPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_OFFERSPRIVATE));
|
| - RegisterSchema("omnibox", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_OMNIBOX));
|
| - RegisterSchema("pageAction", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_PAGEACTION));
|
| - RegisterSchema("pageActions", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_PAGEACTIONS));
|
| - RegisterSchema("pageCapture", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_PAGECAPTURE));
|
| - RegisterSchema("permissions", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_PERMISSIONS));
|
| - RegisterSchema("privacy", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_PRIVACY));
|
| - RegisterSchema("proxy", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_PROXY));
|
| - RegisterSchema("storage", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_STORAGE));
|
| - RegisterSchema("systemPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_SYSTEMPRIVATE));
|
| - RegisterSchema("tabs", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TABS));
|
| - RegisterSchema("terminalPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TERMINALPRIVATE));
|
| - RegisterSchema("test", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TEST));
|
| - RegisterSchema("topSites", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TOPSITES));
|
| - RegisterSchema("ttsEngine", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TTSENGINE));
|
| - RegisterSchema("tts", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TTS));
|
| - RegisterSchema("types", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_TYPES));
|
| - RegisterSchema("webNavigation", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_WEBNAVIGATION));
|
| - RegisterSchema("webRequest", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_WEBREQUEST));
|
| - RegisterSchema("webSocketProxyPrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_WEBSOCKETPROXYPRIVATE));
|
| - RegisterSchema("webstore", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_WEBSTORE));
|
| - RegisterSchema("webstorePrivate", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_WEBSTOREPRIVATE));
|
| - RegisterSchema("windows", ReadFromResource(
|
| - IDR_EXTENSION_API_JSON_WINDOWS));
|
| + unloaded_schemas_["app"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_APP);
|
| + unloaded_schemas_["bookmarks"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_BOOKMARKS);
|
| + unloaded_schemas_["browserAction"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_BROWSERACTION);
|
| + unloaded_schemas_["browsingData"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_BROWSINGDATA);
|
| + unloaded_schemas_["chromeAuthPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_CHROMEAUTHPRIVATE);
|
| + unloaded_schemas_["chromeosInfoPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_CHROMEOSINFOPRIVATE);
|
| + unloaded_schemas_["contentSettings"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_CONTENTSETTINGS);
|
| + unloaded_schemas_["contextMenus"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_CONTEXTMENUS);
|
| + unloaded_schemas_["cookies"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_COOKIES);
|
| + unloaded_schemas_["debugger"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_DEBUGGER);
|
| + unloaded_schemas_["devtools"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_DEVTOOLS);
|
| + unloaded_schemas_["experimental.accessibility"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_ACCESSIBILITY);
|
| + unloaded_schemas_["experimental.alarms"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_ALARMS);
|
| + unloaded_schemas_["experimental.app"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP);
|
| + unloaded_schemas_["experimental.bookmarkManager"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER);
|
| + unloaded_schemas_["experimental.declarative"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_DECLARATIVE);
|
| + unloaded_schemas_["experimental.downloads"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_DOWNLOADS);
|
| + unloaded_schemas_["experimental.extension"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_EXTENSION);
|
| + unloaded_schemas_["experimental.fontSettings"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTSSETTINGS);
|
| + unloaded_schemas_["experimental.identity"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_IDENTITY);
|
| + unloaded_schemas_["experimental.infobars"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_INFOBARS);
|
| + unloaded_schemas_["experimental.input.ui"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_UI);
|
| + unloaded_schemas_["experimental.input.virtualKeyboard"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_VIRTUALKEYBOARD);
|
| + unloaded_schemas_["experimental.keybinding"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_KEYBINDING);
|
| + unloaded_schemas_["experimental.managedMode"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_MANAGEDMODE);
|
| + unloaded_schemas_["experimental.offscreenTabs"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_OFFSCREENTABS);
|
| + unloaded_schemas_["experimental.processes"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_PROCESSES);
|
| + unloaded_schemas_["experimental.rlz"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_RLZ);
|
| + unloaded_schemas_["experimental.serial"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_SERIAL);
|
| + unloaded_schemas_["experimental.socket"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_SOCKET);
|
| + unloaded_schemas_["experimental.speechInput"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_SPEECHINPUT);
|
| + unloaded_schemas_["experimental.webRequest"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXPERIMENTAL_WEBREQUEST);
|
| + unloaded_schemas_["extension"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_EXTENSION);
|
| + unloaded_schemas_["fileBrowserHandler"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER);
|
| + unloaded_schemas_["fileBrowserPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE);
|
| + unloaded_schemas_["history"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_HISTORY);
|
| + unloaded_schemas_["i18n"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_I18N);
|
| + unloaded_schemas_["idle"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_IDLE);
|
| + unloaded_schemas_["input.ime"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_INPUT_IME);
|
| + unloaded_schemas_["inputMethodPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE);
|
| + unloaded_schemas_["management"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_MANAGEMENT);
|
| + unloaded_schemas_["mediaPlayerPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_MEDIAPLAYERPRIVATE);
|
| + unloaded_schemas_["metricsPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_METRICSPRIVATE);
|
| + unloaded_schemas_["offersPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_OFFERSPRIVATE);
|
| + unloaded_schemas_["omnibox"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_OMNIBOX);
|
| + unloaded_schemas_["pageAction"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_PAGEACTION);
|
| + unloaded_schemas_["pageActions"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_PAGEACTIONS);
|
| + unloaded_schemas_["pageCapture"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_PAGECAPTURE);
|
| + unloaded_schemas_["permissions"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_PERMISSIONS);
|
| + unloaded_schemas_["privacy"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_PRIVACY);
|
| + unloaded_schemas_["proxy"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_PROXY);
|
| + unloaded_schemas_["storage"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_STORAGE);
|
| + unloaded_schemas_["systemPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_SYSTEMPRIVATE);
|
| + unloaded_schemas_["tabs"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TABS);
|
| + unloaded_schemas_["terminalPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TERMINALPRIVATE);
|
| + unloaded_schemas_["test"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TEST);
|
| + unloaded_schemas_["topSites"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TOPSITES);
|
| + unloaded_schemas_["ttsEngine"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TTSENGINE);
|
| + unloaded_schemas_["tts"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TTS);
|
| + unloaded_schemas_["types"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_TYPES);
|
| + unloaded_schemas_["webNavigation"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_WEBNAVIGATION);
|
| + unloaded_schemas_["webRequest"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_WEBREQUEST);
|
| + unloaded_schemas_["webSocketProxyPrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_WEBSOCKETPROXYPRIVATE);
|
| + unloaded_schemas_["webstore"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_WEBSTORE);
|
| + unloaded_schemas_["webstorePrivate"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_WEBSTOREPRIVATE);
|
| + unloaded_schemas_["windows"] = ReadFromResource(
|
| + IDR_EXTENSION_API_JSON_WINDOWS);
|
|
|
| // Schemas to be loaded via JSON generated from IDL files.
|
| GeneratedSchemas::Get(&unloaded_schemas_);
|
| }
|
|
|
| -void ExtensionAPI::RegisterSchema(const std::string& name,
|
| - const base::StringPiece& source) {
|
| - unloaded_schemas_[name] = source;
|
| +ExtensionAPI::~ExtensionAPI() {
|
| }
|
|
|
| -void ExtensionAPI::RegisterDependencyProvider(const std::string& name,
|
| - FeatureProvider* provider) {
|
| - dependency_providers_[name] = provider;
|
| -}
|
| -
|
| -bool ExtensionAPI::IsAvailable(const std::string& full_name,
|
| - const Extension* extension,
|
| - Feature::Context context) {
|
| - std::set<std::string> dependency_names;
|
| - dependency_names.insert(full_name);
|
| - ResolveDependencies(&dependency_names);
|
| -
|
| - for (std::set<std::string>::iterator iter = dependency_names.begin();
|
| - iter != dependency_names.end(); ++iter) {
|
| - scoped_ptr<Feature> feature(GetFeatureDependency(full_name));
|
| - CHECK(feature.get()) << *iter;
|
| -
|
| - Feature::Availability availability =
|
| - feature->IsAvailableToContext(extension, context);
|
| - if (availability != Feature::IS_AVAILABLE)
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| bool ExtensionAPI::IsPrivileged(const std::string& full_name) {
|
| + std::string api_name;
|
| std::string child_name;
|
| - std::string api_name = GetAPINameFromFullName(full_name, &child_name);
|
|
|
| - // First try to use the feature system.
|
| - scoped_ptr<Feature> feature(GetFeature(full_name));
|
| - if (feature.get()) {
|
| - // 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) {
|
| - scoped_ptr<Feature> dependency(GetFeatureDependency(*iter));
|
| - for (std::set<Feature::Context>::iterator context =
|
| - dependency->contexts()->begin();
|
| - context != dependency->contexts()->end(); ++context) {
|
| - if (*context != Feature::BLESSED_EXTENSION_CONTEXT)
|
| - return false;
|
| - }
|
| + {
|
| + std::vector<std::string> split;
|
| + base::SplitString(full_name, '.', &split);
|
| + std::reverse(split.begin(), split.end());
|
| + CHECK(!split.empty()); // |full_name| was empty or only whitespace.
|
| +
|
| + api_name = split.back();
|
| + split.pop_back();
|
| + if (api_name == "experimental") {
|
| + CHECK(!split.empty()); // |full_name| was "experimental" alone.
|
| + api_name += "." + split.back();
|
| + split.pop_back();
|
| }
|
| - return true;
|
| +
|
| + // This only really works properly if split.size() == 1, however:
|
| + // - if it's empty, it's ok to leave child_name empty; presumably there's
|
| + // no functions or events with empty names.
|
| + // - if it's > 1, we can just do our best.
|
| + if (split.size() > 0)
|
| + child_name = split[0];
|
| }
|
|
|
| - // If this API hasn't been converted yet, fall back to the old system.
|
| + // GetSchema to ensure that it gets loaded before any checks.
|
| + const DictionaryValue* schema = GetSchema(api_name);
|
| +
|
| 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);
|
| + if (partially_unprivileged_apis_.count(api_name)) {
|
| + return IsChildNamePrivileged(schema, "functions", child_name) &&
|
| + IsChildNamePrivileged(schema, "events", child_name);
|
| + }
|
|
|
| return true;
|
| }
|
|
|
| +DictionaryValue* ExtensionAPI::FindListItem(
|
| + const ListValue* list,
|
| + const std::string& property_name,
|
| + const std::string& property_value) {
|
| + 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) {
|
| + ListValue* child_list = NULL;
|
| + name_space_node->GetList(child_kind, &child_list);
|
| + if (!child_list)
|
| + return true;
|
| +
|
| bool unprivileged = false;
|
| - const DictionaryValue* child = GetSchemaChild(name_space_node, child_name);
|
| + DictionaryValue* child = FindListItem(child_list, "name", child_name);
|
| if (!child || !child->GetBoolean("unprivileged", &unprivileged))
|
| return true;
|
|
|
| return !unprivileged;
|
| }
|
|
|
| -const DictionaryValue* ExtensionAPI::GetSchema(const std::string& full_name) {
|
| - std::string child_name;
|
| - std::string api_name = GetAPINameFromFullName(full_name, &child_name);
|
| +const DictionaryValue* ExtensionAPI::GetSchema(const std::string& api_name) {
|
| + SchemaMap::const_iterator maybe_schema = schemas_.find(api_name);
|
| + if (maybe_schema != schemas_.end())
|
| + return maybe_schema->second.get();
|
|
|
| - const DictionaryValue* result = NULL;
|
| - SchemaMap::iterator maybe_schema = schemas_.find(api_name);
|
| - if (maybe_schema != schemas_.end()) {
|
| - result = maybe_schema->second.get();
|
| - } else {
|
| - // Might not have loaded yet; or might just not exist.
|
| - std::map<std::string, base::StringPiece>::iterator maybe_schema_resource =
|
| - unloaded_schemas_.find(api_name);
|
| - if (maybe_schema_resource == unloaded_schemas_.end())
|
| - return NULL;
|
| + // Might not have loaded yet; or might just not exist.
|
| + std::map<std::string, base::StringPiece>::iterator maybe_schema_resource =
|
| + unloaded_schemas_.find(api_name);
|
| + if (maybe_schema_resource == unloaded_schemas_.end())
|
| + return NULL;
|
|
|
| - LoadSchema(maybe_schema_resource->second);
|
| - maybe_schema = schemas_.find(api_name);
|
| - CHECK(schemas_.end() != maybe_schema);
|
| - result = maybe_schema->second.get();
|
| - }
|
| -
|
| - if (!child_name.empty())
|
| - result = GetSchemaChild(result, child_name);
|
| -
|
| - return result;
|
| + LoadSchema(maybe_schema_resource->second);
|
| + maybe_schema = schemas_.find(api_name);
|
| + CHECK(schemas_.end() != maybe_schema);
|
| + return maybe_schema->second.get();
|
| }
|
|
|
| scoped_ptr<std::set<std::string> > ExtensionAPI::GetAPIsForContext(
|
| @@ -503,19 +358,8 @@
|
| // schemas.
|
| LoadAllSchemas();
|
|
|
| - std::set<std::string> temp_result;
|
| + scoped_ptr<std::set<std::string> > result(new std::set<std::string>());
|
|
|
| - // First handle all the APIs that have been converted to the feature system.
|
| - if (extension) {
|
| - for (APIFeatureMap::iterator iter = features_.begin();
|
| - iter != features_.end(); ++iter) {
|
| - if (IsAvailable(iter->first, extension, context))
|
| - temp_result.insert(iter->first);
|
| - }
|
| - }
|
| -
|
| - // Second, fall back to the old way.
|
| - // TODO(aa): Remove this when all APIs have been converted.
|
| switch (context) {
|
| case Feature::UNSPECIFIED_CONTEXT:
|
| break;
|
| @@ -523,8 +367,8 @@
|
| case Feature::BLESSED_EXTENSION_CONTEXT:
|
| // Availability is determined by the permissions of the extension.
|
| CHECK(extension);
|
| - GetAllowedAPIs(extension, &temp_result);
|
| - ResolveDependencies(&temp_result);
|
| + GetAllowedAPIs(extension, result.get());
|
| + ResolveDependencies(result.get());
|
| break;
|
|
|
| case Feature::UNBLESSED_EXTENSION_CONTEXT:
|
| @@ -532,122 +376,27 @@
|
| // Same as BLESSED_EXTENSION_CONTEXT, but only those APIs that are
|
| // unprivileged.
|
| CHECK(extension);
|
| - GetAllowedAPIs(extension, &temp_result);
|
| + GetAllowedAPIs(extension, result.get());
|
| // Resolving dependencies before removing unprivileged APIs means that
|
| // some unprivileged APIs may have unrealised dependencies. Too bad!
|
| - ResolveDependencies(&temp_result);
|
| - RemovePrivilegedAPIs(&temp_result);
|
| + ResolveDependencies(result.get());
|
| + RemovePrivilegedAPIs(result.get());
|
| break;
|
|
|
| case Feature::WEB_PAGE_CONTEXT:
|
| // Availablility is determined by the url.
|
| CHECK(url.is_valid());
|
| - GetAPIsMatchingURL(url, &temp_result);
|
| + GetAPIsMatchingURL(url, result.get());
|
| break;
|
| }
|
|
|
| - // Filter out all non-API features and remove the feature type part of the
|
| - // name.
|
| - scoped_ptr<std::set<std::string> > result(new std::set<std::string>());
|
| - for (std::set<std::string>::iterator iter = temp_result.begin();
|
| - iter != temp_result.end(); ++iter) {
|
| - std::string feature_type;
|
| - std::string feature_name;
|
| - SplitDependencyName(*iter, &feature_type, &feature_name);
|
| - if (feature_type == "api")
|
| - result->insert(feature_name);
|
| - }
|
| -
|
| return result.Pass();
|
| }
|
|
|
| -scoped_ptr<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 api_features = features_.find(api_namespace);
|
| - if (api_features == features_.end())
|
| - return scoped_ptr<Feature>(NULL);
|
| -
|
| - scoped_ptr<Feature> result;
|
| - FeatureMap::iterator child_feature = api_features->second->find(child_name);
|
| - if (child_feature != api_features->second->end()) {
|
| - // TODO(aa): Argh, having FeatureProvider return a scoped pointer was a
|
| - // mistake. See: crbug.com/120068.
|
| - result.reset(new Feature(*child_feature->second));
|
| - } else {
|
| - FeatureMap::iterator parent_feature = api_features->second->find("");
|
| - CHECK(parent_feature != api_features->second->end());
|
| - result.reset(new Feature(*parent_feature->second));
|
| - }
|
| -
|
| - if (result->contexts()->empty()) {
|
| - result.reset();
|
| - LOG(ERROR) << "API feature '" << full_name
|
| - << "' must specify at least one context.";
|
| - }
|
| -
|
| - return result.Pass();
|
| -}
|
| -
|
| -scoped_ptr<Feature> ExtensionAPI::GetFeatureDependency(
|
| - const std::string& full_name) {
|
| - std::string feature_type;
|
| - std::string feature_name;
|
| - SplitDependencyName(full_name, &feature_type, &feature_name);
|
| -
|
| - FeatureProviderMap::iterator provider =
|
| - dependency_providers_.find(feature_type);
|
| - CHECK(provider != dependency_providers_.end()) << full_name;
|
| -
|
| - scoped_ptr<Feature> feature(provider->second->GetFeature(feature_name));
|
| - CHECK(feature.get()) << full_name;
|
| -
|
| - return feature.Pass();
|
| -}
|
| -
|
| -std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name,
|
| - std::string* child_name) {
|
| - std::string api_name_candidate = full_name;
|
| - while (true) {
|
| - if (features_.find(api_name_candidate) != features_.end() ||
|
| - schemas_.find(api_name_candidate) != schemas_.end() ||
|
| - unloaded_schemas_.find(api_name_candidate) != unloaded_schemas_.end()) {
|
| - std::string result = api_name_candidate;
|
| -
|
| - if (child_name) {
|
| - if (result.length() < full_name.length())
|
| - *child_name = full_name.substr(result.length() + 1);
|
| - else
|
| - *child_name = "";
|
| - }
|
| -
|
| - return result;
|
| - }
|
| -
|
| - size_t last_dot_index = api_name_candidate.rfind('.');
|
| - if (last_dot_index == std::string::npos)
|
| - break;
|
| -
|
| - api_name_candidate = api_name_candidate.substr(0, last_dot_index);
|
| - }
|
| -
|
| - *child_name = "";
|
| - return "";
|
| -}
|
| -
|
| void ExtensionAPI::GetAllowedAPIs(
|
| const Extension* extension, std::set<std::string>* out) {
|
| for (SchemaMap::const_iterator i = schemas_.begin(); i != schemas_.end();
|
| ++i) {
|
| - if (features_.find(i->first) != features_.end()) {
|
| - // This API is controlled by the feature system. Nothing to do here.
|
| - continue;
|
| - }
|
| -
|
| if (extension->required_permission_set()->HasAnyAccessToAPI(i->first) ||
|
| extension->optional_permission_set()->HasAnyAccessToAPI(i->first)) {
|
| out->insert(i->first);
|
| @@ -672,27 +421,17 @@
|
| 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);
|
| + const DictionaryValue* schema = GetSchema(api_name);
|
| + CHECK(schema) << "Schema for " << api_name << " not found";
|
|
|
| - // 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";
|
| -
|
| 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);
|
| - }
|
| + std::string api_name;
|
| + if (dependencies->GetString(i, &api_name) && !excluding.count(api_name))
|
| + out->insert(api_name);
|
| }
|
| }
|
|
|
| @@ -715,11 +454,6 @@
|
| std::set<std::string>* out) {
|
| for (std::map<std::string, URLPatternSet>::const_iterator i =
|
| url_matching_apis_.begin(); i != url_matching_apis_.end(); ++i) {
|
| - if (features_.find(i->first) != features_.end()) {
|
| - // This API is controlled by the feature system. Nothing to do.
|
| - continue;
|
| - }
|
| -
|
| if (i->second.MatchesURL(url))
|
| out->insert(i->first);
|
| }
|
|
|