1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/requirements_checker.h" 6 7 #include "base/bind.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/gpu/gpu_feature_checker.h" 10 #include "content/public/browser/browser_thread.h" 11 #include "extensions/common/extension.h" 12 #include "extensions/common/manifest.h" 13 #include "extensions/common/manifest_handlers/requirements_info.h" 14 #include "gpu/config/gpu_feature_type.h" 15 #include "grit/generated_resources.h" 16 #include "ui/base/l10n/l10n_util.h" 17 18 #if defined(OS_WIN) 19 #include "base/win/metro.h" 20 #endif // defined(OS_WIN) 21 22 namespace extensions { 23 24 RequirementsChecker::RequirementsChecker() 25 : pending_requirement_checks_(0) { 26 } 27 28 RequirementsChecker::~RequirementsChecker() { 29 } 30 31 void RequirementsChecker::Check(scoped_refptr<const Extension> extension, 32 base::Callback<void(std::vector<std::string> errors)> callback) { 33 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 34 35 callback_ = callback; 36 const RequirementsInfo& requirements = 37 RequirementsInfo::GetRequirements(extension.get()); 38 39 if (requirements.npapi) { 40 #if defined(OS_CHROMEOS) 41 errors_.push_back( 42 l10n_util::GetStringUTF8(IDS_EXTENSION_NPAPI_NOT_SUPPORTED)); 43 #endif // defined(OS_CHROMEOS) 44 #if defined(OS_WIN) 45 if (base::win::IsMetroProcess()) { 46 errors_.push_back( 47 l10n_util::GetStringUTF8(IDS_EXTENSION_NPAPI_NOT_SUPPORTED)); 48 } 49 #endif // defined(OS_WIN) 50 } 51 52 if (requirements.webgl) { 53 ++pending_requirement_checks_; 54 webgl_checker_ = new GPUFeatureChecker( 55 gpu::GPU_FEATURE_TYPE_WEBGL, 56 base::Bind(&RequirementsChecker::SetWebGLAvailability, 57 AsWeakPtr())); 58 } 59 60 if (requirements.css3d) { 61 ++pending_requirement_checks_; 62 css3d_checker_ = new GPUFeatureChecker( 63 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, 64 base::Bind(&RequirementsChecker::SetCSS3DAvailability, 65 AsWeakPtr())); 66 } 67 68 if (pending_requirement_checks_ == 0) { 69 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 70 base::Bind(callback_, errors_)); 71 // Reset the callback so any ref-counted bound parameters will get released. 72 callback_.Reset(); 73 return; 74 } 75 // Running the GPU checkers down here removes any race condition that arises 76 // from the use of pending_requirement_checks_. 77 if (webgl_checker_.get()) 78 webgl_checker_->CheckGPUFeatureAvailability(); 79 if (css3d_checker_.get()) 80 css3d_checker_->CheckGPUFeatureAvailability(); 81 } 82 83 void RequirementsChecker::SetWebGLAvailability(bool available) { 84 if (!available) { 85 errors_.push_back( 86 l10n_util::GetStringUTF8(IDS_EXTENSION_WEBGL_NOT_SUPPORTED)); 87 } 88 MaybeRunCallback(); 89 } 90 91 void RequirementsChecker::SetCSS3DAvailability(bool available) { 92 if (!available) { 93 errors_.push_back( 94 l10n_util::GetStringUTF8(IDS_EXTENSION_CSS3D_NOT_SUPPORTED)); 95 } 96 MaybeRunCallback(); 97 } 98 99 void RequirementsChecker::MaybeRunCallback() { 100 if (--pending_requirement_checks_ == 0) { 101 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 102 base::Bind(callback_, errors_)); 103 // Reset the callback so any ref-counted bound parameters will get released. 104 callback_.Reset(); 105 errors_.clear(); 106 } 107 } 108 109 } // namespace extensions 110