Home | History | Annotate | Download | only in extensions
      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