Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: content/browser/plugin_service_browsertest.cc

Issue 9019004: Rename PluginService to PluginServiceImpl. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "content/browser/plugin_service.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/path_service.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/test/base/in_process_browser_test.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "content/browser/resource_context.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/test/test_browser_thread.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "webkit/plugins/npapi/plugin_list.h"
19
20 using content::BrowserThread;
21
22 namespace {
23
24 const char kNPAPITestPluginMimeType[] = "application/vnd.npapi-test";
25
26 void OpenChannel(PluginProcessHost::Client* client) {
27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
28 // Start opening the channel
29 PluginService::GetInstance()->OpenChannelToNpapiPlugin(
30 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, client);
31 }
32
33 // Mock up of the Client and the Listener classes that would supply the
34 // communication channel with the plugin.
35 class MockPluginProcessHostClient : public PluginProcessHost::Client,
36 public IPC::Channel::Listener {
37 public:
38 MockPluginProcessHostClient(const content::ResourceContext& context)
39 : context_(context),
40 channel_(NULL),
41 set_plugin_info_called_(false) {
42 }
43
44 virtual ~MockPluginProcessHostClient() {
45 if (channel_)
46 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_);
47 }
48
49 // Client implementation.
50 virtual int ID() OVERRIDE { return 42; }
51 virtual bool OffTheRecord() OVERRIDE { return false; }
52 virtual const content::ResourceContext& GetResourceContext() OVERRIDE {
53 return context_;
54 }
55 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {}
56 virtual void OnSentPluginChannelRequest() OVERRIDE {}
57
58 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
59 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
60 ASSERT_TRUE(set_plugin_info_called_);
61 ASSERT_TRUE(!channel_);
62 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this);
63 ASSERT_TRUE(channel_->Connect());
64 }
65
66 void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE {
67 ASSERT_TRUE(info.mime_types.size());
68 ASSERT_EQ(kNPAPITestPluginMimeType, info.mime_types[0].mime_type);
69 set_plugin_info_called_ = true;
70 }
71
72 MOCK_METHOD0(OnError, void());
73
74 // Listener implementation.
75 MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message& message));
76 void OnChannelConnected(int32 peer_pid) OVERRIDE {
77 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
78 MessageLoop::QuitClosure());
79 }
80 MOCK_METHOD0(OnChannelError, void());
81 MOCK_METHOD0(OnChannelDenied, void());
82 MOCK_METHOD0(OnChannelListenError, void());
83
84 private:
85 const content::ResourceContext& context_;
86 IPC::Channel* channel_;
87 bool set_plugin_info_called_;
88 DISALLOW_COPY_AND_ASSIGN(MockPluginProcessHostClient);
89 };
90
91 class PluginServiceTest : public InProcessBrowserTest {
92 public:
93 PluginServiceTest() : InProcessBrowserTest() { }
94
95 virtual void SetUpCommandLine(CommandLine* command_line) {
96 #ifdef OS_MACOSX
97 FilePath browser_directory;
98 PathService::Get(base::DIR_MODULE, &browser_directory);
99 command_line->AppendSwitchPath(switches::kExtraPluginDir,
100 browser_directory.AppendASCII("plugins"));
101 #endif
102 }
103 };
104
105 // Try to open a channel to the test plugin. Minimal plugin process spawning
106 // test for the PluginService interface.
107 IN_PROC_BROWSER_TEST_F(PluginServiceTest, OpenChannelToPlugin) {
108 ::testing::StrictMock<MockPluginProcessHostClient> mock_client(
109 browser()->profile()->GetResourceContext());
110 BrowserThread::PostTask(
111 BrowserThread::IO, FROM_HERE,
112 base::Bind(&OpenChannel, &mock_client));
113 ui_test_utils::RunMessageLoop();
114 }
115
116 // A strict mock that fails if any of the methods are called. They shouldn't be
117 // called since the request should get canceled before then.
118 class MockCanceledPluginServiceClient : public PluginProcessHost::Client {
119 public:
120 MockCanceledPluginServiceClient(const content::ResourceContext& context)
121 : context_(context),
122 get_resource_context_called_(false) {
123 }
124
125 virtual ~MockCanceledPluginServiceClient() {}
126
127 // Client implementation.
128 MOCK_METHOD0(ID, int());
129 virtual const content::ResourceContext& GetResourceContext() OVERRIDE {
130 get_resource_context_called_ = true;
131 return context_;
132 }
133 MOCK_METHOD0(OffTheRecord, bool());
134 MOCK_METHOD1(OnFoundPluginProcessHost, void(PluginProcessHost* host));
135 MOCK_METHOD0(OnSentPluginChannelRequest, void());
136 MOCK_METHOD1(OnChannelOpened, void(const IPC::ChannelHandle& handle));
137 MOCK_METHOD1(SetPluginInfo, void(const webkit::WebPluginInfo& info));
138 MOCK_METHOD0(OnError, void());
139
140 bool get_resource_context_called() const {
141 return get_resource_context_called_;
142 }
143
144 private:
145 const content::ResourceContext& context_;
146 bool get_resource_context_called_;
147
148 DISALLOW_COPY_AND_ASSIGN(MockCanceledPluginServiceClient);
149 };
150
151 void DoNothing() {}
152
153 void QuitUIMessageLoopFromIOThread() {
154 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
155 MessageLoop::QuitClosure());
156 }
157
158 void OpenChannelAndThenCancel(PluginProcessHost::Client* client) {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
160 // Start opening the channel
161 PluginService::GetInstance()->OpenChannelToNpapiPlugin(
162 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, client);
163 // Immediately cancel it. This is guaranteed to work since PluginService needs
164 // to consult its filter on the FILE thread.
165 PluginService::GetInstance()->CancelOpenChannelToNpapiPlugin(client);
166 // Before we terminate the test, add a roundtrip through the FILE thread to
167 // make sure that it's had a chance to post back to the IO thread. Then signal
168 // the UI thread to stop and exit the test.
169 BrowserThread::PostTaskAndReply(
170 BrowserThread::FILE, FROM_HERE,
171 base::Bind(&DoNothing),
172 base::Bind(&QuitUIMessageLoopFromIOThread));
173 }
174
175 // Should not attempt to open a channel, since it should be canceled early on.
176 IN_PROC_BROWSER_TEST_F(PluginServiceTest, CancelOpenChannelToPluginService) {
177 ::testing::StrictMock<MockCanceledPluginServiceClient> mock_client(
178 browser()->profile()->GetResourceContext());
179 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
180 base::Bind(OpenChannelAndThenCancel, &mock_client));
181 ui_test_utils::RunMessageLoop();
182 EXPECT_TRUE(mock_client.get_resource_context_called());
183 }
184
185 class MockCanceledBeforeSentPluginProcessHostClient
186 : public MockCanceledPluginServiceClient {
187 public:
188 MockCanceledBeforeSentPluginProcessHostClient(
189 const content::ResourceContext& context)
190 : MockCanceledPluginServiceClient(context),
191 set_plugin_info_called_(false),
192 on_found_plugin_process_host_called_(false),
193 host_(NULL) {}
194
195 virtual ~MockCanceledBeforeSentPluginProcessHostClient() {}
196
197 // Client implementation.
198 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
200 ASSERT_TRUE(info.mime_types.size());
201 ASSERT_EQ(kNPAPITestPluginMimeType, info.mime_types[0].mime_type);
202 set_plugin_info_called_ = true;
203 }
204 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
206 set_on_found_plugin_process_host_called();
207 set_host(host);
208 // This gets called right before we request the plugin<=>renderer channel,
209 // so we have to post a task to cancel it.
210 MessageLoop::current()->PostTask(
211 FROM_HERE,
212 base::Bind(&PluginProcessHost::CancelPendingRequest,
213 base::Unretained(host), this));
214 MessageLoop::current()->PostTask(
215 FROM_HERE,
216 base::Bind(&QuitUIMessageLoopFromIOThread));
217 }
218
219 bool set_plugin_info_called() const {
220 return set_plugin_info_called_;
221 }
222
223 bool on_found_plugin_process_host_called() const {
224 return on_found_plugin_process_host_called_;
225 }
226
227 protected:
228 void set_on_found_plugin_process_host_called() {
229 on_found_plugin_process_host_called_ = true;
230 }
231 void set_host(PluginProcessHost* host) {
232 host_ = host;
233 }
234
235 PluginProcessHost* host() const { return host_; }
236
237 private:
238 bool set_plugin_info_called_;
239 bool on_found_plugin_process_host_called_;
240 PluginProcessHost* host_;
241
242 DISALLOW_COPY_AND_ASSIGN(MockCanceledBeforeSentPluginProcessHostClient);
243 };
244
245 IN_PROC_BROWSER_TEST_F(
246 PluginServiceTest, CancelBeforeSentOpenChannelToPluginProcessHost) {
247 ::testing::StrictMock<MockCanceledBeforeSentPluginProcessHostClient>
248 mock_client(browser()->profile()->GetResourceContext());
249 BrowserThread::PostTask(
250 BrowserThread::IO, FROM_HERE,
251 base::Bind(&OpenChannel, &mock_client));
252 ui_test_utils::RunMessageLoop();
253 EXPECT_TRUE(mock_client.get_resource_context_called());
254 EXPECT_TRUE(mock_client.set_plugin_info_called());
255 EXPECT_TRUE(mock_client.on_found_plugin_process_host_called());
256 }
257
258 class MockCanceledAfterSentPluginProcessHostClient
259 : public MockCanceledBeforeSentPluginProcessHostClient {
260 public:
261 MockCanceledAfterSentPluginProcessHostClient(
262 const content::ResourceContext& context)
263 : MockCanceledBeforeSentPluginProcessHostClient(context),
264 on_sent_plugin_channel_request_called_(false) {}
265 virtual ~MockCanceledAfterSentPluginProcessHostClient() {}
266
267 // Client implementation.
268
269 virtual int ID() OVERRIDE { return 42; }
270 virtual bool OffTheRecord() OVERRIDE { return false; }
271
272 // We override this guy again since we don't want to cancel yet.
273 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
275 set_on_found_plugin_process_host_called();
276 set_host(host);
277 }
278
279 virtual void OnSentPluginChannelRequest() OVERRIDE {
280 on_sent_plugin_channel_request_called_ = true;
281 host()->CancelSentRequest(this);
282 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
283 MessageLoop::QuitClosure());
284 }
285
286 bool on_sent_plugin_channel_request_called() const {
287 return on_sent_plugin_channel_request_called_;
288 }
289
290 private:
291 bool on_sent_plugin_channel_request_called_;
292
293 DISALLOW_COPY_AND_ASSIGN(MockCanceledAfterSentPluginProcessHostClient);
294 };
295
296 // Should not attempt to open a channel, since it should be canceled early on.
297 IN_PROC_BROWSER_TEST_F(
298 PluginServiceTest, CancelAfterSentOpenChannelToPluginProcessHost) {
299 ::testing::StrictMock<MockCanceledAfterSentPluginProcessHostClient>
300 mock_client(browser()->profile()->GetResourceContext());
301 BrowserThread::PostTask(
302 BrowserThread::IO, FROM_HERE,
303 base::Bind(&OpenChannel, &mock_client));
304 ui_test_utils::RunMessageLoop();
305 EXPECT_TRUE(mock_client.get_resource_context_called());
306 EXPECT_TRUE(mock_client.set_plugin_info_called());
307 EXPECT_TRUE(mock_client.on_found_plugin_process_host_called());
308 EXPECT_TRUE(mock_client.on_sent_plugin_channel_request_called());
309 }
310
311 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698