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_file_util.h" 19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/gpu_data_manager.h" 21 #include "extensions/common/extension.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 std::vector<std::string> expected_errors; 177 178 if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) { 179 expected_errors.push_back(l10n_util::GetStringUTF8( 180 IDS_EXTENSION_WEBGL_NOT_SUPPORTED)); 181 expected_errors.push_back(l10n_util::GetStringUTF8( 182 IDS_EXTENSION_CSS3D_NOT_SUPPORTED)); 183 } 184 185 checker_.Check(extension, base::Bind( 186 &RequirementsCheckerBrowserTest::ValidateRequirementErrors, 187 base::Unretained(this), expected_errors)); 188 content::BrowserThread::GetBlockingPool()->FlushForTesting(); 189 } 190 191 } // namespace extensions 192