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 |
deleted file mode 100644 |
index 2490d5dc45bf1e6e159da5ed777e9def16887e54..0000000000000000000000000000000000000000 |
--- a/chrome/common/extensions/api/extension_api.cc |
+++ /dev/null |
@@ -1,416 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/common/extensions/api/extension_api.h" |
- |
-#include <algorithm> |
-#include <string> |
-#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/strings/string_number_conversions.h" |
-#include "base/strings/string_split.h" |
-#include "base/strings/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/permissions/permissions_data.h" |
-#include "extensions/common/features/feature.h" |
-#include "extensions/common/features/feature_provider.h" |
-#include "extensions/common/permissions/permission_set.h" |
-#include "grit/common_resources.h" |
-#include "grit/extensions_api_resources.h" |
-#include "ui/base/resource/resource_bundle.h" |
-#include "url/gurl.h" |
- |
-namespace extensions { |
- |
-using api::GeneratedSchemas; |
- |
-namespace { |
- |
-const char* kChildKinds[] = { |
- "functions", |
- "events" |
-}; |
- |
-base::StringPiece ReadFromResource(int resource_id) { |
- return ResourceBundle::GetSharedInstance().GetRawDataResource( |
- resource_id); |
-} |
- |
-scoped_ptr<base::ListValue> LoadSchemaList(const std::string& name, |
- const base::StringPiece& schema) { |
- std::string error_message; |
- scoped_ptr<base::Value> result( |
- base::JSONReader::ReadAndReturnError( |
- schema, |
- base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN, // options |
- NULL, // error code |
- &error_message)); |
- |
- // Tracking down http://crbug.com/121424 |
- char buf[128]; |
- base::snprintf(buf, arraysize(buf), "%s: (%d) '%s'", |
- name.c_str(), |
- result.get() ? result->GetType() : -1, |
- error_message.c_str()); |
- |
- CHECK(result.get()) << error_message << " for schema " << schema; |
- CHECK(result->IsType(base::Value::TYPE_LIST)) << " for schema " << schema; |
- return scoped_ptr<base::ListValue>(static_cast<base::ListValue*>( |
- result.release())); |
-} |
- |
-const base::DictionaryValue* FindListItem(const base::ListValue* list, |
- const std::string& property_name, |
- const std::string& property_value) { |
- for (size_t i = 0; i < list->GetSize(); ++i) { |
- const base::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* GetSchemaChild( |
- const base::DictionaryValue* schema_node, |
- const std::string& child_name) { |
- const base::DictionaryValue* child_node = NULL; |
- for (size_t i = 0; i < arraysize(kChildKinds); ++i) { |
- const base::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; |
- |
-// If it exists and does not already specify a namespace, then the value stored |
-// with key |key| in |schema| will be updated to |schema_namespace| + "." + |
-// |schema[key]|. |
-void MaybePrefixFieldWithNamespace(const std::string& schema_namespace, |
- base::DictionaryValue* schema, |
- const std::string& key) { |
- if (!schema->HasKey(key)) |
- return; |
- |
- std::string old_id; |
- CHECK(schema->GetString(key, &old_id)); |
- if (old_id.find(".") == std::string::npos) |
- schema->SetString(key, schema_namespace + "." + old_id); |
-} |
- |
-// Modify all "$ref" keys anywhere in |schema| to be prefxied by |
-// |schema_namespace| if they do not already specify a namespace. |
-void PrefixRefsWithNamespace(const std::string& schema_namespace, |
- base::Value* value) { |
- base::ListValue* list = NULL; |
- base::DictionaryValue* dict = NULL; |
- if (value->GetAsList(&list)) { |
- for (base::ListValue::iterator i = list->begin(); i != list->end(); ++i) { |
- PrefixRefsWithNamespace(schema_namespace, *i); |
- } |
- } else if (value->GetAsDictionary(&dict)) { |
- MaybePrefixFieldWithNamespace(schema_namespace, dict, "$ref"); |
- for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) { |
- base::Value* value = NULL; |
- CHECK(dict->GetWithoutPathExpansion(i.key(), &value)); |
- PrefixRefsWithNamespace(schema_namespace, value); |
- } |
- } |
-} |
- |
-// Modify all objects in the "types" section of the schema to be prefixed by |
-// |schema_namespace| if they do not already specify a namespace. |
-void PrefixTypesWithNamespace(const std::string& schema_namespace, |
- base::DictionaryValue* schema) { |
- if (!schema->HasKey("types")) |
- return; |
- |
- // Add the namespace to all of the types defined in this schema |
- base::ListValue *types = NULL; |
- CHECK(schema->GetList("types", &types)); |
- for (size_t i = 0; i < types->GetSize(); ++i) { |
- base::DictionaryValue *type = NULL; |
- CHECK(types->GetDictionary(i, &type)); |
- MaybePrefixFieldWithNamespace(schema_namespace, type, "id"); |
- MaybePrefixFieldWithNamespace(schema_namespace, type, "customBindings"); |
- } |
-} |
- |
-// Modify the schema so that all types are fully qualified. |
-void PrefixWithNamespace(const std::string& schema_namespace, |
- base::DictionaryValue* schema) { |
- PrefixTypesWithNamespace(schema_namespace, schema); |
- PrefixRefsWithNamespace(schema_namespace, schema); |
-} |
- |
-} // namespace |
- |
-// static |
-ExtensionAPI* ExtensionAPI::GetSharedInstance() { |
- return g_lazy_instance.Get().api.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 std::string& name, |
- const base::StringPiece& schema) { |
- scoped_ptr<base::ListValue> schema_list(LoadSchemaList(name, schema)); |
- std::string schema_namespace; |
- |
- while (!schema_list->empty()) { |
- base::DictionaryValue* schema = NULL; |
- { |
- scoped_ptr<base::Value> value; |
- schema_list->Remove(schema_list->GetSize() - 1, &value); |
- CHECK(value.release()->GetAsDictionary(&schema)); |
- } |
- |
- CHECK(schema->GetString("namespace", &schema_namespace)); |
- PrefixWithNamespace(schema_namespace, schema); |
- schemas_[schema_namespace] = make_linked_ptr(schema); |
- if (!GeneratedSchemas::IsGenerated(schema_namespace)) |
- CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); |
- } |
-} |
- |
-ExtensionAPI::ExtensionAPI() : default_configuration_initialized_(false) { |
-} |
- |
-ExtensionAPI::~ExtensionAPI() { |
-} |
- |
-void ExtensionAPI::InitDefaultConfiguration() { |
- const char* names[] = {"api", "manifest", "permission"}; |
- for (size_t i = 0; i < arraysize(names); ++i) |
- RegisterDependencyProvider(names[i], FeatureProvider::GetByName(names[i])); |
- |
- // Schemas to be loaded from resources. |
- CHECK(unloaded_schemas_.empty()); |
- RegisterSchemaResource("app", IDR_EXTENSION_API_JSON_APP); |
- RegisterSchemaResource("browserAction", IDR_EXTENSION_API_JSON_BROWSERACTION); |
- RegisterSchemaResource("browsingData", IDR_EXTENSION_API_JSON_BROWSINGDATA); |
- RegisterSchemaResource("commands", IDR_EXTENSION_API_JSON_COMMANDS); |
- RegisterSchemaResource("declarativeContent", |
- IDR_EXTENSION_API_JSON_DECLARATIVE_CONTENT); |
- RegisterSchemaResource("declarativeWebRequest", |
- IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST); |
- RegisterSchemaResource("runtime", IDR_EXTENSION_API_JSON_RUNTIME); |
- RegisterSchemaResource("fileBrowserHandler", |
- IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER); |
- RegisterSchemaResource("fileBrowserPrivate", |
- IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE); |
- RegisterSchemaResource("inputMethodPrivate", |
- IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE); |
- RegisterSchemaResource("pageAction", IDR_EXTENSION_API_JSON_PAGEACTION); |
- RegisterSchemaResource("pageActions", IDR_EXTENSION_API_JSON_PAGEACTIONS); |
- RegisterSchemaResource("privacy", IDR_EXTENSION_API_JSON_PRIVACY); |
- RegisterSchemaResource("processes", IDR_EXTENSION_API_JSON_PROCESSES); |
- RegisterSchemaResource("proxy", IDR_EXTENSION_API_JSON_PROXY); |
- RegisterSchemaResource("scriptBadge", IDR_EXTENSION_API_JSON_SCRIPTBADGE); |
- RegisterSchemaResource("streamsPrivate", |
- IDR_EXTENSION_API_JSON_STREAMSPRIVATE); |
- RegisterSchemaResource("ttsEngine", IDR_EXTENSION_API_JSON_TTSENGINE); |
- RegisterSchemaResource("tts", IDR_EXTENSION_API_JSON_TTS); |
- RegisterSchemaResource("types", IDR_EXTENSION_API_JSON_TYPES); |
- RegisterSchemaResource("types.private", IDR_EXTENSION_API_JSON_TYPES_PRIVATE); |
- RegisterSchemaResource("webRequestInternal", |
- IDR_EXTENSION_API_JSON_WEBREQUESTINTERNAL); |
- RegisterSchemaResource("webstore", IDR_EXTENSION_API_JSON_WEBSTORE); |
- RegisterSchemaResource("webstorePrivate", |
- IDR_EXTENSION_API_JSON_WEBSTOREPRIVATE); |
- default_configuration_initialized_ = true; |
-} |
- |
-void ExtensionAPI::RegisterSchemaResource(const std::string& name, |
- int resource_id) { |
- unloaded_schemas_[name] = resource_id; |
-} |
- |
-void ExtensionAPI::RegisterDependencyProvider(const std::string& name, |
- FeatureProvider* provider) { |
- dependency_providers_[name] = provider; |
-} |
- |
-bool ExtensionAPI::IsAnyFeatureAvailableToContext(const std::string& api_name, |
- const Extension* extension, |
- Feature::Context context, |
- const GURL& url) { |
- FeatureProviderMap::iterator provider = dependency_providers_.find("api"); |
- CHECK(provider != dependency_providers_.end()); |
- const std::vector<std::string>& features = |
- provider->second->GetAllFeatureNames(); |
- |
- // Check to see if there are any parts of this API that are allowed in this |
- // context. |
- for (std::vector<std::string>::const_iterator i = features.begin(); |
- i != features.end(); ++i) { |
- const std::string& feature_name = *i; |
- if (feature_name != api_name && feature_name.find(api_name + ".") == 0) { |
- if (IsAvailable(feature_name, extension, context, url).is_available()) |
- return true; |
- } |
- } |
- return IsAvailable(api_name, extension, context, url).is_available(); |
-} |
- |
-Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, |
- const Extension* extension, |
- Feature::Context context, |
- const GURL& url) { |
- Feature* feature = GetFeatureDependency(full_name); |
- CHECK(feature) << full_name; |
- |
- 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, std::string()); |
-} |
- |
-bool ExtensionAPI::IsPrivileged(const std::string& full_name) { |
- Feature* feature = GetFeatureDependency(full_name); |
- CHECK(feature); |
- DCHECK(!feature->GetContexts()->empty()); |
- // 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); |
-} |
- |
-const base::DictionaryValue* ExtensionAPI::GetSchema( |
- const std::string& full_name) { |
- std::string child_name; |
- std::string api_name = GetAPINameFromFullName(full_name, &child_name); |
- |
- const base::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. |
- UnloadedSchemaMap::iterator maybe_schema_resource = |
- unloaded_schemas_.find(api_name); |
- if (maybe_schema_resource != unloaded_schemas_.end()) { |
- LoadSchema(maybe_schema_resource->first, |
- ReadFromResource(maybe_schema_resource->second)); |
- } else if (default_configuration_initialized_ && |
- GeneratedSchemas::IsGenerated(api_name)) { |
- LoadSchema(api_name, GeneratedSchemas::Get(api_name)); |
- } else { |
- return NULL; |
- } |
- |
- 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; |
-} |
- |
-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); |
- if (provider == dependency_providers_.end()) |
- return NULL; |
- |
- Feature* feature = provider->second->GetFeature(feature_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; |
-} |
- |
-std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name, |
- std::string* child_name) { |
- std::string api_name_candidate = full_name; |
- while (true) { |
- if (schemas_.find(api_name_candidate) != schemas_.end() || |
- GeneratedSchemas::IsGenerated(api_name_candidate) || |
- 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 std::string(); |
-} |
- |
-} // namespace extensions |