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 |