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 <vector>
      6 
      7 #include "base/bind.h"
      8 #include "base/files/file_path.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/path_service.h"
     12 #include "base/strings/string_util.h"
     13 #include "chrome/browser/extensions/extension_browsertest.h"
     14 #include "chrome/browser/extensions/requirements_checker.h"
     15 #include "chrome/common/chrome_paths.h"
     16 #include "content/public/browser/browser_thread.h"
     17 #include "content/public/browser/gpu_data_manager.h"
     18 #include "extensions/common/extension.h"
     19 #include "extensions/common/file_util.h"
     20 #include "gpu/config/gpu_info.h"
     21 #include "grit/generated_resources.h"
     22 #include "ui/base/l10n/l10n_util.h"
     23 
     24 namespace extensions {
     25 
     26 class RequirementsCheckerBrowserTest : public ExtensionBrowserTest {
     27  public:
     28   scoped_refptr<const Extension> LoadExtensionFromDirName(
     29       const std::string& extension_dir_name) {
     30     base::FilePath extension_path;
     31     std::string load_error;
     32     PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
     33     extension_path = extension_path.AppendASCII("requirements_checker")
     34                                    .AppendASCII(extension_dir_name);
     35     scoped_refptr<const Extension> extension = file_util::LoadExtension(
     36         extension_path, Manifest::UNPACKED, 0, &load_error);
     37     CHECK_EQ(0U, load_error.length());
     38     return extension;
     39   }
     40 
     41   void ValidateRequirementErrors(std::vector<std::string> expected_errors,
     42                                  std::vector<std::string> actual_errors) {
     43     ASSERT_EQ(expected_errors, actual_errors);
     44     requirement_errors_.swap(actual_errors);
     45   }
     46 
     47   // This should only be called once per test instance. Calling more than once
     48   // will result in stale information in the GPUDataManager which will throw off
     49   // the RequirementsChecker.
     50   void BlackListGPUFeatures(const std::vector<std::string>& features) {
     51 #if !defined(NDEBUG)
     52     static bool called = false;
     53     DCHECK(!called);
     54     called = true;
     55 #endif
     56 
     57     static const std::string json_blacklist =
     58       "{\n"
     59       "  \"name\": \"gpu blacklist\",\n"
     60       "  \"version\": \"1.0\",\n"
     61       "  \"entries\": [\n"
     62       "    {\n"
     63       "      \"id\": 1,\n"
     64       "      \"features\": [\"" + JoinString(features, "\", \"") + "\"]\n"
     65       "    }\n"
     66       "  ]\n"
     67       "}";
     68     gpu::GPUInfo gpu_info;
     69     content::GpuDataManager::GetInstance()->InitializeForTesting(
     70         json_blacklist, gpu_info);
     71   }
     72 
     73  protected:
     74   std::vector<std::string> requirement_errors_;
     75   RequirementsChecker checker_;
     76 };
     77 
     78 IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, CheckEmptyExtension) {
     79   scoped_refptr<const Extension> extension(
     80       LoadExtensionFromDirName("no_requirements"));
     81   ASSERT_TRUE(extension.get());
     82   checker_.Check(extension, base::Bind(
     83       &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
     84       base::Unretained(this), std::vector<std::string>()));
     85   content::BrowserThread::GetBlockingPool()->FlushForTesting();
     86 }
     87 
     88 IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, CheckNpapiExtension) {
     89   scoped_refptr<const Extension> extension(
     90       LoadExtensionFromDirName("require_npapi"));
     91   ASSERT_TRUE(extension.get());
     92 
     93   std::vector<std::string> expected_errors;
     94 #if defined(OS_POSIX) && !defined(OS_MACOSX)
     95   expected_errors.push_back(l10n_util::GetStringUTF8(
     96       IDS_EXTENSION_NPAPI_NOT_SUPPORTED));
     97 #endif
     98 
     99   checker_.Check(extension, base::Bind(
    100       &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
    101       base::Unretained(this), expected_errors));
    102   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    103 }
    104 
    105 IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest,
    106                        CheckWindowShapeExtension) {
    107   scoped_refptr<const Extension> extension(
    108       LoadExtensionFromDirName("require_window_shape"));
    109   ASSERT_TRUE(extension.get());
    110 
    111   std::vector<std::string> expected_errors;
    112 #if !defined(USE_AURA)
    113   expected_errors.push_back(l10n_util::GetStringUTF8(
    114       IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED));
    115 #endif  // !defined(USE_AURA)
    116 
    117   checker_.Check(extension, base::Bind(
    118       &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
    119       base::Unretained(this), expected_errors));
    120   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    121 }
    122 
    123 IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, DisallowWebGL) {
    124   scoped_refptr<const Extension> extension(
    125       LoadExtensionFromDirName("require_3d"));
    126   ASSERT_TRUE(extension.get());
    127 
    128   // Backlist webgl
    129   std::vector<std::string> blacklisted_features;
    130   blacklisted_features.push_back("webgl");
    131   BlackListGPUFeatures(blacklisted_features);
    132   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    133 
    134   std::vector<std::string> expected_errors;
    135   expected_errors.push_back(l10n_util::GetStringUTF8(
    136       IDS_EXTENSION_WEBGL_NOT_SUPPORTED));
    137 
    138   checker_.Check(extension, base::Bind(
    139       &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
    140       base::Unretained(this), expected_errors));
    141   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    142 }
    143 
    144 IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, Check3DExtension) {
    145   scoped_refptr<const Extension> extension(
    146       LoadExtensionFromDirName("require_3d"));
    147   ASSERT_TRUE(extension.get());
    148 
    149   std::vector<std::string> expected_errors;
    150 
    151   if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) {
    152     expected_errors.push_back(l10n_util::GetStringUTF8(
    153         IDS_EXTENSION_WEBGL_NOT_SUPPORTED));
    154   }
    155 
    156   checker_.Check(extension, base::Bind(
    157       &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
    158       base::Unretained(this), expected_errors));
    159   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    160 }
    161 
    162 }  // namespace extensions
    163