| Index: chrome/browser/extensions/requirements_provider.cc
|
| diff --git a/chrome/browser/extensions/requirements_provider.cc b/chrome/browser/extensions/requirements_provider.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..510307721272dae61245ba012f26bc53e8c2e38e
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/requirements_provider.cc
|
| @@ -0,0 +1,173 @@
|
| +// 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/browser/extensions/requirements_provider.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/string16.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/gpu_feature_checker.h"
|
| +#include "chrome/common/extensions/extension_manifest_constants.h"
|
| +#include "chrome/common/extensions/extension.h"
|
| +#include "chrome/common/extensions/manifest.h"
|
| +#include "content/public/common/gpu_feature_type.h"
|
| +
|
| +namespace keys = extension_manifest_keys;
|
| +
|
| +namespace {
|
| +
|
| +const char* kWebGlError = "WebGL is not supported";
|
| +const char* kCSS3dError = "CSS3d is not supported";
|
| +#if defined(OS_CHROMEOS)
|
| +const char* kPluginsError = "Plugins are not supported";
|
| +#endif
|
| +
|
| +} // namespace
|
| +
|
| +namespace extensions {
|
| +
|
| +RequirementsProvider::RequirementsProvider()
|
| + : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
| +}
|
| +
|
| +RequirementsProvider::~RequirementsProvider() {
|
| + weak_factory_.InvalidateWeakPtrs();
|
| +}
|
| +
|
| +bool RequirementsProvider::Supports(const Extension* extension,
|
| + std::list<string16>* errors, bool* async,
|
| + ExtensionService* service) {
|
| + *async = false;
|
| + errors->clear();
|
| + DictionaryValue* requirements_value = NULL;
|
| + extension->manifest()->GetDictionary(keys::kRequirements,
|
| + &requirements_value);
|
| + if (!requirements_value)
|
| + return true;
|
| +
|
| + for (DictionaryValue::key_iterator it = requirements_value->begin_keys();
|
| + it != requirements_value->end_keys(); ++it) {
|
| + DictionaryValue* requirement_value;
|
| + requirements_value->GetDictionaryWithoutPathExpansion(
|
| + *it, &requirement_value);
|
| + if (!requirement_value)
|
| + continue;
|
| +
|
| + if (*it == "plugins") {
|
| +#if defined(OS_CHROMEOS)
|
| + errors->push_back(ASCIIToUTF16(kPluginsError));
|
| +#endif
|
| + } else if (*it == "3D") {
|
| + ListValue* features;
|
| + requirement_value->GetListWithoutPathExpansion("features", &features);
|
| + if (!features)
|
| + continue;
|
| + std::string feature;
|
| + base::ListValue::iterator it;
|
| + for (it = features->begin(); it != features->end(); ++it) {
|
| + if ((*it)->GetAsString(&feature)) {
|
| + if (feature == "webgl") {
|
| + if (checked_for_webgl_) {
|
| + if (!webgl_supported_)
|
| + errors->push_back(ASCIIToUTF16(kWebGlError));
|
| + } else {
|
| + *async = true;
|
| + // If the check is not ongoing, request one.
|
| + if (!webgl_checker_.get()) {
|
| + webgl_checker_ = new GPUFeatureChecker(
|
| + content::GPU_FEATURE_TYPE_WEBGL,
|
| + base::Bind(&RequirementsProvider::IsWebGLAvailable,
|
| + weak_factory_.GetWeakPtr()));
|
| + webgl_checker_->CheckGPUFeatureAvailability();
|
| + }
|
| + async_webgl_checks_.push_back(
|
| + GPUFeatureRequest(extension->id(), service->AsWeakPtr()));
|
| + }
|
| + } else if (feature == "css3d") {
|
| + if (checked_for_css3d_) {
|
| + if (!css3d_supported_) {
|
| + errors->push_back(ASCIIToUTF16(kCSS3dError));
|
| + }
|
| + } else {
|
| + *async = true;
|
| + // If the check is not ongoing, request one.
|
| + if (!css3d_checker_.get()) {
|
| + css3d_checker_ = new GPUFeatureChecker(
|
| + content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING,
|
| + base::Bind(&RequirementsProvider::IsCSS3dAvailable,
|
| + weak_factory_.GetWeakPtr()));
|
| + css3d_checker_->CheckGPUFeatureAvailability();
|
| + }
|
| + async_css3d_checks_.push_back(
|
| + GPUFeatureRequest(extension->id(), service->AsWeakPtr()));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return errors->empty();
|
| +}
|
| +
|
| +void RequirementsProvider::IsWebGLAvailable(bool available) {
|
| + webgl_supported_ = available;
|
| + checked_for_webgl_ = true;
|
| +
|
| + // The original assumption of true is valid.
|
| + if (webgl_supported_) {
|
| + async_webgl_checks_.clear();
|
| + return;
|
| + }
|
| +
|
| + // Answer all requests that are pending on the webgl check.
|
| + GPUFeatureRequest request;
|
| + while (!async_webgl_checks_.empty()) {
|
| + request = async_webgl_checks_.front();
|
| + async_webgl_checks_.pop_front();
|
| + if (request.weak_service.get()) {
|
| + request.weak_service->UnsupportedRequirements(
|
| + request.extension_id, ASCIIToUTF16(kWebGlError),
|
| + true /* disable the extension */);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void RequirementsProvider::IsCSS3dAvailable(bool available) {
|
| + css3d_supported_ = available;
|
| + checked_for_css3d_ = true;
|
| +
|
| + // The original assumption of true is valid.
|
| + if (css3d_supported_) {
|
| + async_css3d_checks_.clear();
|
| + return;
|
| + }
|
| +
|
| + // Answer all requests that are pending on the css3d check.
|
| + GPUFeatureRequest request;
|
| + while (!async_css3d_checks_.empty()) {
|
| + request = async_css3d_checks_.front();
|
| + async_css3d_checks_.pop_front();
|
| + if (request.weak_service.get()) {
|
| + request.weak_service->UnsupportedRequirements(
|
| + request.extension_id, ASCIIToUTF16(kCSS3dError),
|
| + true /* disable the extension */);
|
| + }
|
| + }
|
| +}
|
| +
|
| +RequirementsProvider::GPUFeatureRequest::GPUFeatureRequest()
|
| + : extension_id(""),
|
| + weak_service() {
|
| +}
|
| +
|
| +RequirementsProvider::GPUFeatureRequest::GPUFeatureRequest(
|
| + const std::string& id, base::WeakPtr<ExtensionService> service)
|
| + : extension_id(id),
|
| + weak_service(service) {
|
| +}
|
| +
|
| +RequirementsProvider::GPUFeatureRequest::~GPUFeatureRequest() {
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|