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