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