requirements_checker_browsertest.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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.h"
19#include "chrome/common/extensions/extension_file_util.h"
20#include "chrome/test/base/test_launcher_utils.h"
21#include "content/public/browser/browser_thread.h"
22#include "content/public/browser/gpu_data_manager.h"
23#include "gpu/config/gpu_info.h"
24#include "grit/generated_resources.h"
25#include "ui/base/l10n/l10n_util.h"
26#include "ui/gl/gl_switches.h"
27
28namespace extensions {
29
30class RequirementsCheckerBrowserTest : public ExtensionBrowserTest {
31 public:
32  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
33    // We need to launch GPU process to decide if WebGL is allowed.
34    // Run it on top of osmesa to avoid bot driver issues.
35#if !defined(OS_MACOSX)
36    CHECK(test_launcher_utils::OverrideGLImplementation(
37        command_line, gfx::kGLImplementationOSMesaName)) <<
38        "kUseGL must not be set multiple times!";
39#endif
40  }
41
42  scoped_refptr<const Extension> LoadExtensionFromDirName(
43      const std::string& extension_dir_name) {
44    base::FilePath extension_path;
45    std::string load_error;
46    PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
47    extension_path = extension_path.AppendASCII("requirements_checker")
48                                   .AppendASCII(extension_dir_name);
49    scoped_refptr<const Extension> extension =
50        extension_file_util::LoadExtension(extension_path, Manifest::UNPACKED,
51                                           0, &load_error);
52    CHECK(load_error.length() == 0u);
53    return extension;
54  }
55
56  void ValidateRequirementErrors(std::vector<std::string> expected_errors,
57                                 std::vector<std::string> actual_errors) {
58    ASSERT_EQ(expected_errors, actual_errors);
59    requirement_errors_.swap(actual_errors);
60  }
61
62  // This should only be called once per test instance. Calling more than once
63  // will result in stale information in the GPUDataManager which will throw off
64  // the RequirementsChecker.
65  void BlackListGPUFeatures(const std::vector<std::string>& features) {
66    static const std::string json_blacklist =
67      "{\n"
68      "  \"name\": \"gpu blacklist\",\n"
69      "  \"version\": \"1.0\",\n"
70      "  \"entries\": [\n"
71      "    {\n"
72      "      \"id\": 1,\n"
73      "      \"features\": [\"" + JoinString(features, "\", \"") + "\"]\n"
74      "    }\n"
75      "  ]\n"
76      "}";
77    gpu::GPUInfo gpu_info;
78    content::GpuDataManager::GetInstance()->InitializeForTesting(
79        json_blacklist, gpu_info);
80  }
81
82 protected:
83  std::vector<std::string> requirement_errors_;
84  RequirementsChecker checker_;
85};
86
87IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, CheckEmptyExtension) {
88  scoped_refptr<const Extension> extension(
89      LoadExtensionFromDirName("no_requirements"));
90  ASSERT_TRUE(extension.get());
91  checker_.Check(extension, base::Bind(
92      &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
93      base::Unretained(this), std::vector<std::string>()));
94  content::BrowserThread::GetBlockingPool()->FlushForTesting();
95}
96
97IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, CheckNpapiExtension) {
98  scoped_refptr<const Extension> extension(
99      LoadExtensionFromDirName("require_npapi"));
100  ASSERT_TRUE(extension.get());
101
102  std::vector<std::string> expected_errors;
103  // npapi plugins are dissalowd on CROMEOS.
104#if defined(OS_CHROMEOS)
105  expected_errors.push_back(l10n_util::GetStringUTF8(
106      IDS_EXTENSION_NPAPI_NOT_SUPPORTED));
107#endif  // defined(OS_CHROMEOS)
108
109  checker_.Check(extension, base::Bind(
110      &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
111      base::Unretained(this), expected_errors));
112  content::BrowserThread::GetBlockingPool()->FlushForTesting();
113}
114
115IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, DisallowCSS3D) {
116  scoped_refptr<const Extension> extension(
117      LoadExtensionFromDirName("require_3d"));
118  ASSERT_TRUE(extension.get());
119
120
121  // Blacklist css3d
122  std::vector<std::string> blacklisted_features;
123  blacklisted_features.push_back("accelerated_compositing");
124  BlackListGPUFeatures(blacklisted_features);
125  content::BrowserThread::GetBlockingPool()->FlushForTesting();
126
127  std::vector<std::string> expected_errors;
128  expected_errors.push_back(l10n_util::GetStringUTF8(
129      IDS_EXTENSION_CSS3D_NOT_SUPPORTED));
130
131  checker_.Check(extension, base::Bind(
132      &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
133      base::Unretained(this), expected_errors));
134  content::BrowserThread::GetBlockingPool()->FlushForTesting();
135}
136
137IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, DisallowWebGL) {
138  scoped_refptr<const Extension> extension(
139      LoadExtensionFromDirName("require_3d"));
140  ASSERT_TRUE(extension.get());
141
142  // Backlist webgl
143  std::vector<std::string> blacklisted_features;
144  blacklisted_features.push_back("webgl");
145  BlackListGPUFeatures(blacklisted_features);
146  content::BrowserThread::GetBlockingPool()->FlushForTesting();
147
148  std::vector<std::string> expected_errors;
149  expected_errors.push_back(l10n_util::GetStringUTF8(
150      IDS_EXTENSION_WEBGL_NOT_SUPPORTED));
151
152  checker_.Check(extension, base::Bind(
153      &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
154      base::Unretained(this), expected_errors));
155  content::BrowserThread::GetBlockingPool()->FlushForTesting();
156}
157
158IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, DisallowGPUFeatures) {
159  scoped_refptr<const Extension> extension(
160      LoadExtensionFromDirName("require_3d"));
161  ASSERT_TRUE(extension.get());
162
163  // Backlist both webgl and css3d
164  std::vector<std::string> blacklisted_features;
165  blacklisted_features.push_back("webgl");
166  blacklisted_features.push_back("accelerated_compositing");
167  BlackListGPUFeatures(blacklisted_features);
168  content::BrowserThread::GetBlockingPool()->FlushForTesting();
169
170  std::vector<std::string> expected_errors;
171  expected_errors.push_back(l10n_util::GetStringUTF8(
172      IDS_EXTENSION_WEBGL_NOT_SUPPORTED));
173  expected_errors.push_back(l10n_util::GetStringUTF8(
174      IDS_EXTENSION_CSS3D_NOT_SUPPORTED));
175
176  checker_.Check(extension, base::Bind(
177      &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
178      base::Unretained(this), expected_errors));
179  content::BrowserThread::GetBlockingPool()->FlushForTesting();
180}
181
182IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, Check3DExtension) {
183  scoped_refptr<const Extension> extension(
184      LoadExtensionFromDirName("require_3d"));
185  ASSERT_TRUE(extension.get());
186
187  checker_.Check(extension, base::Bind(
188      &RequirementsCheckerBrowserTest::ValidateRequirementErrors,
189      base::Unretained(this), std::vector<std::string>()));
190  content::BrowserThread::GetBlockingPool()->FlushForTesting();
191}
192
193}  // extensions
194