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:
LoadExtensionFromDirName(const std::string & extension_dir_name)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
ValidateRequirementErrors(std::vector<std::string> expected_errors,std::vector<std::string> actual_errors)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.
BlackListGPUFeatures(const std::vector<std::string> & features)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
IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest,CheckEmptyExtension)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
IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest,CheckNpapiExtension)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
IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest,CheckWindowShapeExtension)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
IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest,DisallowWebGL)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
IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest,Check3DExtension)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