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