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