blob: 8f907232121487b3a8ce48c923e8658cfd85546e [file] [log] [blame]
[email protected]7557d282012-02-01 20:50:161// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d4af1e72011-10-21 17:45:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/plugin_loader_posix.h"
6
[email protected]183d4b82011-11-11 18:50:267#include "base/at_exit.h"
[email protected]d4af1e72011-10-21 17:45:438#include "base/bind.h"
[email protected]57999812013-02-24 05:40:529#include "base/files/file_path.h"
[email protected]d4af1e72011-10-21 17:45:4310#include "base/memory/ref_counted.h"
[email protected]2fccd3f2013-07-18 00:10:5211#include "base/message_loop/message_loop.h"
[email protected]74ebfb12013-06-07 20:48:0012#include "base/strings/utf_string_conversions.h"
[email protected]92145552011-10-31 16:28:0313#include "content/browser/browser_thread_impl.h"
[email protected]d4af1e72011-10-21 17:45:4314#include "testing/gmock/include/gmock/gmock.h"
[email protected]c38831a12011-10-28 12:44:4915#include "testing/gtest/include/gtest/gtest.h"
[email protected]d4af1e72011-10-21 17:45:4316
[email protected]130757672012-10-24 00:26:1917namespace content {
[email protected]92145552011-10-31 16:28:0318
[email protected]d4af1e72011-10-21 17:45:4319class MockPluginLoaderPosix : public PluginLoaderPosix {
20 public:
21 MOCK_METHOD0(LoadPluginsInternal, void(void));
22
23 size_t number_of_pending_callbacks() {
24 return callbacks_.size();
25 }
26
[email protected]2dec8ec2013-02-07 19:20:3427 std::vector<base::FilePath>* canonical_list() {
[email protected]d4af1e72011-10-21 17:45:4328 return &canonical_list_;
29 }
30
31 size_t next_load_index() {
32 return next_load_index_;
33 }
34
[email protected]d7bd3e52013-07-21 04:29:2035 const std::vector<WebPluginInfo>& loaded_plugins() {
[email protected]d4af1e72011-10-21 17:45:4336 return loaded_plugins_;
37 }
38
[email protected]d7bd3e52013-07-21 04:29:2039 std::vector<WebPluginInfo>* internal_plugins() {
[email protected]d4af1e72011-10-21 17:45:4340 return &internal_plugins_;
41 }
42
[email protected]6a0dc7a2011-11-02 14:37:0743 void RealLoadPluginsInternal() {
44 PluginLoaderPosix::LoadPluginsInternal();
45 }
46
[email protected]d7bd3e52013-07-21 04:29:2047 void TestOnPluginLoaded(uint32 index, const WebPluginInfo& plugin) {
[email protected]893e2812011-11-02 16:40:1648 OnPluginLoaded(index, plugin);
[email protected]d4af1e72011-10-21 17:45:4349 }
50
[email protected]2dec8ec2013-02-07 19:20:3451 void TestOnPluginLoadFailed(uint32 index, const base::FilePath& path) {
[email protected]893e2812011-11-02 16:40:1652 OnPluginLoadFailed(index, path);
[email protected]d4af1e72011-10-21 17:45:4353 }
[email protected]fb90c942012-04-27 23:40:5054
55 protected:
56 virtual ~MockPluginLoaderPosix() {}
[email protected]d4af1e72011-10-21 17:45:4357};
58
[email protected]d7bd3e52013-07-21 04:29:2059void VerifyCallback(int* run_count, const std::vector<WebPluginInfo>&) {
[email protected]d4af1e72011-10-21 17:45:4360 ++(*run_count);
61}
62
63class PluginLoaderPosixTest : public testing::Test {
64 public:
65 PluginLoaderPosixTest()
[email protected]2dec8ec2013-02-07 19:20:3466 : plugin1_(ASCIIToUTF16("plugin1"), base::FilePath("/tmp/one.plugin"),
[email protected]d4af1e72011-10-21 17:45:4367 ASCIIToUTF16("1.0"), string16()),
[email protected]2dec8ec2013-02-07 19:20:3468 plugin2_(ASCIIToUTF16("plugin2"), base::FilePath("/tmp/two.plugin"),
[email protected]d4af1e72011-10-21 17:45:4369 ASCIIToUTF16("2.0"), string16()),
[email protected]2dec8ec2013-02-07 19:20:3470 plugin3_(ASCIIToUTF16("plugin3"), base::FilePath("/tmp/three.plugin"),
[email protected]d4af1e72011-10-21 17:45:4371 ASCIIToUTF16("3.0"), string16()),
72 file_thread_(BrowserThread::FILE, &message_loop_),
73 io_thread_(BrowserThread::IO, &message_loop_),
74 plugin_loader_(new MockPluginLoaderPosix) {
75 }
76
[email protected]183d4b82011-11-11 18:50:2677 virtual void SetUp() OVERRIDE {
[email protected]e67385f2011-12-21 06:00:5678 PluginServiceImpl::GetInstance()->Init();
[email protected]183d4b82011-11-11 18:50:2679 }
80
[email protected]dd32b1272013-05-04 14:17:1181 base::MessageLoop* message_loop() { return &message_loop_; }
[email protected]d4af1e72011-10-21 17:45:4382 MockPluginLoaderPosix* plugin_loader() { return plugin_loader_.get(); }
83
84 void AddThreePlugins() {
85 plugin_loader_->canonical_list()->clear();
86 plugin_loader_->canonical_list()->push_back(plugin1_.path);
87 plugin_loader_->canonical_list()->push_back(plugin2_.path);
88 plugin_loader_->canonical_list()->push_back(plugin3_.path);
89 }
90
91 // Data used for testing.
[email protected]d7bd3e52013-07-21 04:29:2092 WebPluginInfo plugin1_;
93 WebPluginInfo plugin2_;
94 WebPluginInfo plugin3_;
[email protected]d4af1e72011-10-21 17:45:4395
96 private:
[email protected]183d4b82011-11-11 18:50:2697 base::ShadowingAtExitManager at_exit_manager_; // Destroys PluginService.
98
[email protected]dd32b1272013-05-04 14:17:1199 base::MessageLoopForIO message_loop_;
[email protected]92145552011-10-31 16:28:03100 BrowserThreadImpl file_thread_;
101 BrowserThreadImpl io_thread_;
[email protected]d4af1e72011-10-21 17:45:43102
103 scoped_refptr<MockPluginLoaderPosix> plugin_loader_;
104};
105
106TEST_F(PluginLoaderPosixTest, QueueRequests) {
107 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19108 PluginService::GetPluginsCallback callback =
[email protected]d4af1e72011-10-21 17:45:43109 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
110
111 EXPECT_EQ(0u, plugin_loader()->number_of_pending_callbacks());
112 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
113 EXPECT_EQ(1u, plugin_loader()->number_of_pending_callbacks());
114
115 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
116 EXPECT_EQ(2u, plugin_loader()->number_of_pending_callbacks());
117
[email protected]9a9ab7d32012-03-12 22:51:11118 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(2);
[email protected]f319ace2012-11-10 19:07:29119 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43120
[email protected]d4af1e72011-10-21 17:45:43121 EXPECT_EQ(0, did_callback);
122
[email protected]9a9ab7d32012-03-12 22:51:11123 plugin_loader()->canonical_list()->clear();
124 plugin_loader()->canonical_list()->push_back(plugin1_.path);
125 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
[email protected]f319ace2012-11-10 19:07:29126 message_loop()->RunUntilIdle();
[email protected]9a9ab7d32012-03-12 22:51:11127
128 EXPECT_EQ(1, did_callback);
129 EXPECT_EQ(1u, plugin_loader()->number_of_pending_callbacks());
130
131 plugin_loader()->canonical_list()->clear();
132 plugin_loader()->canonical_list()->push_back(plugin1_.path);
[email protected]893e2812011-11-02 16:40:16133 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
[email protected]f319ace2012-11-10 19:07:29134 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43135
136 EXPECT_EQ(2, did_callback);
137 EXPECT_EQ(0u, plugin_loader()->number_of_pending_callbacks());
138}
139
140TEST_F(PluginLoaderPosixTest, ThreeSuccessfulLoads) {
141 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19142 PluginService::GetPluginsCallback callback =
[email protected]d4af1e72011-10-21 17:45:43143 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
144
145 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
146
147 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
[email protected]f319ace2012-11-10 19:07:29148 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43149
150 AddThreePlugins();
151
152 EXPECT_EQ(0u, plugin_loader()->next_load_index());
153
[email protected]d7bd3e52013-07-21 04:29:20154 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
[email protected]d4af1e72011-10-21 17:45:43155
[email protected]893e2812011-11-02 16:40:16156 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
[email protected]d4af1e72011-10-21 17:45:43157 EXPECT_EQ(1u, plugin_loader()->next_load_index());
158 EXPECT_EQ(1u, plugins.size());
159 EXPECT_EQ(plugin1_.name, plugins[0].name);
160
[email protected]f319ace2012-11-10 19:07:29161 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43162 EXPECT_EQ(0, did_callback);
163
[email protected]893e2812011-11-02 16:40:16164 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
[email protected]d4af1e72011-10-21 17:45:43165 EXPECT_EQ(2u, plugin_loader()->next_load_index());
166 EXPECT_EQ(2u, plugins.size());
167 EXPECT_EQ(plugin2_.name, plugins[1].name);
168
[email protected]f319ace2012-11-10 19:07:29169 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43170 EXPECT_EQ(0, did_callback);
171
[email protected]893e2812011-11-02 16:40:16172 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
[email protected]d4af1e72011-10-21 17:45:43173 EXPECT_EQ(3u, plugins.size());
174 EXPECT_EQ(plugin3_.name, plugins[2].name);
175
[email protected]f319ace2012-11-10 19:07:29176 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43177 EXPECT_EQ(1, did_callback);
178}
179
[email protected]7557d282012-02-01 20:50:16180TEST_F(PluginLoaderPosixTest, ThreeSuccessfulLoadsThenCrash) {
181 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19182 PluginService::GetPluginsCallback callback =
[email protected]7557d282012-02-01 20:50:16183 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
184
185 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
186
187 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(2);
[email protected]f319ace2012-11-10 19:07:29188 message_loop()->RunUntilIdle();
[email protected]7557d282012-02-01 20:50:16189
190 AddThreePlugins();
191
192 EXPECT_EQ(0u, plugin_loader()->next_load_index());
193
[email protected]d7bd3e52013-07-21 04:29:20194 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
[email protected]7557d282012-02-01 20:50:16195
196 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
197 EXPECT_EQ(1u, plugin_loader()->next_load_index());
198 EXPECT_EQ(1u, plugins.size());
199 EXPECT_EQ(plugin1_.name, plugins[0].name);
200
[email protected]f319ace2012-11-10 19:07:29201 message_loop()->RunUntilIdle();
[email protected]7557d282012-02-01 20:50:16202 EXPECT_EQ(0, did_callback);
203
204 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
205 EXPECT_EQ(2u, plugin_loader()->next_load_index());
206 EXPECT_EQ(2u, plugins.size());
207 EXPECT_EQ(plugin2_.name, plugins[1].name);
208
[email protected]f319ace2012-11-10 19:07:29209 message_loop()->RunUntilIdle();
[email protected]7557d282012-02-01 20:50:16210 EXPECT_EQ(0, did_callback);
211
212 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
213 EXPECT_EQ(3u, plugins.size());
214 EXPECT_EQ(plugin3_.name, plugins[2].name);
215
[email protected]f319ace2012-11-10 19:07:29216 message_loop()->RunUntilIdle();
[email protected]7557d282012-02-01 20:50:16217 EXPECT_EQ(1, did_callback);
218
219 plugin_loader()->OnProcessCrashed(42);
220}
221
[email protected]d4af1e72011-10-21 17:45:43222TEST_F(PluginLoaderPosixTest, TwoFailures) {
223 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19224 PluginService::GetPluginsCallback callback =
[email protected]d4af1e72011-10-21 17:45:43225 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
226
227 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
228
229 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
[email protected]f319ace2012-11-10 19:07:29230 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43231
232 AddThreePlugins();
233
234 EXPECT_EQ(0u, plugin_loader()->next_load_index());
235
[email protected]d7bd3e52013-07-21 04:29:20236 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
[email protected]d4af1e72011-10-21 17:45:43237
[email protected]893e2812011-11-02 16:40:16238 plugin_loader()->TestOnPluginLoadFailed(0, plugin1_.path);
[email protected]d4af1e72011-10-21 17:45:43239 EXPECT_EQ(1u, plugin_loader()->next_load_index());
240 EXPECT_EQ(0u, plugins.size());
241
[email protected]f319ace2012-11-10 19:07:29242 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43243 EXPECT_EQ(0, did_callback);
244
[email protected]893e2812011-11-02 16:40:16245 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
[email protected]d4af1e72011-10-21 17:45:43246 EXPECT_EQ(2u, plugin_loader()->next_load_index());
247 EXPECT_EQ(1u, plugins.size());
248 EXPECT_EQ(plugin2_.name, plugins[0].name);
249
[email protected]f319ace2012-11-10 19:07:29250 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43251 EXPECT_EQ(0, did_callback);
252
[email protected]893e2812011-11-02 16:40:16253 plugin_loader()->TestOnPluginLoadFailed(2, plugin3_.path);
[email protected]d4af1e72011-10-21 17:45:43254 EXPECT_EQ(1u, plugins.size());
255
[email protected]f319ace2012-11-10 19:07:29256 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43257 EXPECT_EQ(1, did_callback);
258}
259
260TEST_F(PluginLoaderPosixTest, CrashedProcess) {
261 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19262 PluginService::GetPluginsCallback callback =
[email protected]d4af1e72011-10-21 17:45:43263 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
264
265 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
266
267 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
[email protected]f319ace2012-11-10 19:07:29268 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43269
270 AddThreePlugins();
271
272 EXPECT_EQ(0u, plugin_loader()->next_load_index());
273
[email protected]d7bd3e52013-07-21 04:29:20274 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
[email protected]d4af1e72011-10-21 17:45:43275
[email protected]893e2812011-11-02 16:40:16276 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
[email protected]d4af1e72011-10-21 17:45:43277 EXPECT_EQ(1u, plugin_loader()->next_load_index());
278 EXPECT_EQ(1u, plugins.size());
279 EXPECT_EQ(plugin1_.name, plugins[0].name);
280
[email protected]f319ace2012-11-10 19:07:29281 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43282 EXPECT_EQ(0, did_callback);
283
284 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
285 plugin_loader()->OnProcessCrashed(42);
286 EXPECT_EQ(1u, plugin_loader()->canonical_list()->size());
287 EXPECT_EQ(0u, plugin_loader()->next_load_index());
288 EXPECT_EQ(plugin3_.path.value(),
289 plugin_loader()->canonical_list()->at(0).value());
290}
291
292TEST_F(PluginLoaderPosixTest, InternalPlugin) {
293 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19294 PluginService::GetPluginsCallback callback =
[email protected]d4af1e72011-10-21 17:45:43295 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
296
297 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
298
299 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
[email protected]f319ace2012-11-10 19:07:29300 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43301
[email protected]2dec8ec2013-02-07 19:20:34302 plugin2_.path = base::FilePath("/internal/plugin.plugin");
[email protected]d4af1e72011-10-21 17:45:43303
304 AddThreePlugins();
305
306 plugin_loader()->internal_plugins()->clear();
307 plugin_loader()->internal_plugins()->push_back(plugin2_);
308
309 EXPECT_EQ(0u, plugin_loader()->next_load_index());
310
[email protected]d7bd3e52013-07-21 04:29:20311 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
[email protected]d4af1e72011-10-21 17:45:43312
[email protected]893e2812011-11-02 16:40:16313 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
[email protected]d4af1e72011-10-21 17:45:43314 EXPECT_EQ(1u, plugin_loader()->next_load_index());
315 EXPECT_EQ(1u, plugins.size());
316 EXPECT_EQ(plugin1_.name, plugins[0].name);
317
[email protected]f319ace2012-11-10 19:07:29318 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43319 EXPECT_EQ(0, did_callback);
320
321 // Internal plugins can fail to load if they're built-in with manual
322 // entrypoint functions.
[email protected]893e2812011-11-02 16:40:16323 plugin_loader()->TestOnPluginLoadFailed(1, plugin2_.path);
[email protected]d4af1e72011-10-21 17:45:43324 EXPECT_EQ(2u, plugin_loader()->next_load_index());
325 EXPECT_EQ(2u, plugins.size());
326 EXPECT_EQ(plugin2_.name, plugins[1].name);
327 EXPECT_EQ(0u, plugin_loader()->internal_plugins()->size());
328
[email protected]f319ace2012-11-10 19:07:29329 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43330 EXPECT_EQ(0, did_callback);
331
[email protected]893e2812011-11-02 16:40:16332 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
[email protected]d4af1e72011-10-21 17:45:43333 EXPECT_EQ(3u, plugins.size());
334 EXPECT_EQ(plugin3_.name, plugins[2].name);
335
[email protected]f319ace2012-11-10 19:07:29336 message_loop()->RunUntilIdle();
[email protected]d4af1e72011-10-21 17:45:43337 EXPECT_EQ(1, did_callback);
338}
[email protected]6a0dc7a2011-11-02 14:37:07339
340TEST_F(PluginLoaderPosixTest, AllCrashed) {
341 int did_callback = 0;
[email protected]130757672012-10-24 00:26:19342 PluginService::GetPluginsCallback callback =
[email protected]6a0dc7a2011-11-02 14:37:07343 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
344
345 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
346
347 // Spin the loop so that the canonical list of plugins can be set.
348 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
[email protected]f319ace2012-11-10 19:07:29349 message_loop()->RunUntilIdle();
[email protected]6a0dc7a2011-11-02 14:37:07350 AddThreePlugins();
351
352 EXPECT_EQ(0u, plugin_loader()->next_load_index());
353
354 // Mock the first two calls like normal.
355 testing::Expectation first =
356 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(2);
357 // On the last call, go through the default impl.
358 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal())
359 .After(first)
360 .WillOnce(
361 testing::Invoke(plugin_loader(),
362 &MockPluginLoaderPosix::RealLoadPluginsInternal));
363 plugin_loader()->OnProcessCrashed(42);
364 plugin_loader()->OnProcessCrashed(42);
365 plugin_loader()->OnProcessCrashed(42);
366
[email protected]f319ace2012-11-10 19:07:29367 message_loop()->RunUntilIdle();
[email protected]6a0dc7a2011-11-02 14:37:07368 EXPECT_EQ(1, did_callback);
369
370 EXPECT_EQ(0u, plugin_loader()->loaded_plugins().size());
371}
[email protected]130757672012-10-24 00:26:19372
373} // namespace content