#include "extensions/common/extensions_client.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
+#include "extensions/common/features/simple_feature.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "ui/base/resource/resource_bundle.h"
base::LazyInstance<Static> g_lazy_instance = LAZY_INSTANCE_INITIALIZER;
+// May override |g_lazy_instance| for a test.
+ExtensionAPI* g_shared_instance_for_test = NULL;
+
// 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]|.
// static
ExtensionAPI* ExtensionAPI::GetSharedInstance() {
- return g_lazy_instance.Get().api.get();
+ return g_shared_instance_for_test ? g_shared_instance_for_test
+ : g_lazy_instance.Get().api.get();
}
// static
*feature_name = full_name.substr(colon_index + 1);
}
+ExtensionAPI::OverrideSharedInstanceForTest::OverrideSharedInstanceForTest(
+ ExtensionAPI* testing_api)
+ : original_api_(g_shared_instance_for_test) {
+ g_shared_instance_for_test = testing_api;
+}
+
+ExtensionAPI::OverrideSharedInstanceForTest::~OverrideSharedInstanceForTest() {
+ g_shared_instance_for_test = original_api_;
+}
+
void ExtensionAPI::LoadSchema(const std::string& name,
const base::StringPiece& schema) {
scoped_ptr<base::ListValue> schema_list(LoadSchemaList(name, schema));
const GURL& url) {
FeatureProviderMap::iterator provider = dependency_providers_.find("api");
CHECK(provider != dependency_providers_.end());
- if (IsAvailable(api, extension, context, url).is_available())
+
+ if (api.IsAvailableToContext(extension, context, url).is_available())
return true;
// Check to see if there are any parts of this API that are allowed in this
// context.
const std::vector<Feature*> features = provider->second->GetChildren(api);
- for (std::vector<Feature*>::const_iterator feature = features.begin();
- feature != features.end();
- ++feature) {
- if (IsAvailable(**feature, extension, context, url).is_available())
+ for (std::vector<Feature*>::const_iterator it = features.begin();
+ it != features.end();
+ ++it) {
+ if ((*it)->IsAvailableToContext(extension, context, url).is_available())
return true;
}
return false;
return Feature::CreateAvailability(Feature::NOT_PRESENT,
std::string("Unknown feature: ") + full_name);
}
- return IsAvailable(*feature, extension, context, url);
+ return feature->IsAvailableToContext(extension, context, url);
}
-Feature::Availability ExtensionAPI::IsAvailable(const Feature& feature,
- const Extension* extension,
- Feature::Context context,
- const GURL& url) {
- 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::IsAvailableInUntrustedContext(const std::string& name,
+ const Extension* extension) {
+ return IsAvailable(name, extension, Feature::CONTENT_SCRIPT_CONTEXT, GURL())
+ .is_available() ||
+ IsAvailable(
+ name, extension, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL())
+ .is_available() ||
+ IsAvailable(name, extension, Feature::BLESSED_WEB_PAGE_CONTEXT, GURL())
+ .is_available() ||
+ IsAvailable(name, extension, Feature::WEB_PAGE_CONTEXT, GURL())
+ .is_available();
}
-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);
+bool ExtensionAPI::IsAvailableToWebUI(const std::string& name,
+ const GURL& url) {
+ return IsAvailable(name, NULL, Feature::WEBUI_CONTEXT, url).is_available();
}
const base::DictionaryValue* ExtensionAPI::GetSchema(