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