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

Side by Side Diff: content/browser/browser_plugin/browser_plugin_host_browsertest.cc

Issue 10868012: Browser Plugin: New Implementation (Browser Side) (Closed) Base URL: http://git.chromium.org/chromium/src.git@master-trial-obrowser
Patch Set: integrate windows fix by Fady (original cl #10910228) Created 8 years, 3 months 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
OLDNEW
(Empty)
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 "base/memory/singleton.h"
6 #include "base/run_loop.h"
7 #include "base/utf_string_conversions.h"
8 #include "content/browser/browser_plugin/browser_plugin_guest.h"
9 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
10 #include "content/browser/browser_plugin/test_browser_plugin_embedder.h"
11 #include "content/browser/browser_plugin/test_browser_plugin_guest.h"
12 #include "content/browser/browser_plugin/test_timeout_tracker.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/common/view_messages.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/notification_types.h"
18 #include "content/public/test/browser_test_utils.h"
19 #include "content/public/test/test_utils.h"
20 #include "content/shell/shell.h"
21 #include "content/test/content_browser_test_utils.h"
22 #include "content/test/content_browser_test.h"
23 #include "ipc/ipc_message.h"
24 #include "net/base/net_util.h"
25 #include "net/test/test_server.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
27
28 using WebKit::WebInputEvent;
29 using WebKit::WebMouseEvent;
30 using content::BrowserPluginEmbedder;
31 using content::BrowserPluginGuest;
32 using content::BrowserPluginHostFactory;
33
34 namespace content {
35
36 const char* kHTMLForGuest =
37 "data:text/html,<html><body>hello world</body></html>";
38
39 // Test factory for creating test instances of BrowserPluginEmbedder and
40 // BrowserPluginGuest.
41 class TestBrowserPluginHostFactory : public BrowserPluginHostFactory {
42 public:
43 virtual BrowserPluginGuest* CreateBrowserPluginGuest(
44 int instance_id,
45 WebContentsImpl* web_contents,
46 RenderViewHost* render_view_host) OVERRIDE {
47 return new TestBrowserPluginGuest(instance_id,
48 web_contents,
49 render_view_host);
50 }
51
52 // Also keeps track of number of instances created.
53 virtual BrowserPluginEmbedder* CreateBrowserPluginEmbedder(
54 WebContentsImpl* web_contents,
55 RenderViewHost* render_view_host) OVERRIDE {
56 embedder_instance_count_++;
57 if (message_loop_runner_)
58 message_loop_runner_->Quit();
59
60 return new TestBrowserPluginEmbedder(web_contents, render_view_host);
61 }
62
63 // Singleton getter.
64 static TestBrowserPluginHostFactory* GetInstance() {
65 return Singleton<TestBrowserPluginHostFactory>::get();
66 }
67
68 // Waits for at least one embedder to be created in the test. Returns true if
69 // we have a guest, false if waiting times out.
70 bool WaitForEmbedderCreation() {
71 // Check if already have created instance.
72 if (embedder_instance_count_ > 0)
73 return true;
74 // Wait otherwise.
75 message_loop_runner_ = new MessageLoopRunner();
76 return TestTimeoutTracker::RunInActionTimeout(
77 message_loop_runner_.get());
78 }
79
80 protected:
81 TestBrowserPluginHostFactory() : embedder_instance_count_(0) {}
82 virtual ~TestBrowserPluginHostFactory() {}
83
84 private:
85 // For Singleton.
86 friend struct DefaultSingletonTraits<TestBrowserPluginHostFactory>;
87
88 scoped_refptr<MessageLoopRunner> message_loop_runner_;
89 int embedder_instance_count_;
90
91 DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginHostFactory);
92 };
93
94 // Test factory class for browser plugin that creates guests with short hang
95 // timeout.
96 class TestShortHangTimeoutGuestFactory : public TestBrowserPluginHostFactory {
97 public:
98 virtual BrowserPluginGuest* CreateBrowserPluginGuest(
99 int instance_id,
100 WebContentsImpl* web_contents,
101 RenderViewHost* render_view_host) OVERRIDE {
102 BrowserPluginGuest* ret = new TestBrowserPluginGuest(instance_id,
Charlie Reis 2012/09/13 00:51:44 nit: ret -> guest (ret is not a useful variable na
lazyboy 2012/09/13 15:56:24 Done.
103 web_contents,
104 render_view_host);
105 ret->SetGuestHangTimeoutForTesting(TestTimeouts::tiny_timeout());
106 return ret;
107 }
108
109 // Singleton getter.
110 static TestShortHangTimeoutGuestFactory* GetInstance() {
111 return Singleton<TestShortHangTimeoutGuestFactory>::get();
112 }
113
114 protected:
115 TestShortHangTimeoutGuestFactory() {}
116 virtual ~TestShortHangTimeoutGuestFactory() {}
117
118 private:
119 // For Singleton.
120 friend struct DefaultSingletonTraits<TestShortHangTimeoutGuestFactory>;
121
122 DISALLOW_COPY_AND_ASSIGN(TestShortHangTimeoutGuestFactory);
123 };
124
125 class BrowserPluginHostTest : public ContentBrowserTest {
126 public:
127 BrowserPluginHostTest() {}
128
129 virtual void SetUp() OVERRIDE {
130 // Override factory to create tests instances of BrowserPlugin*.
131 content::BrowserPluginEmbedder::set_factory_for_testing(
132 TestBrowserPluginHostFactory::GetInstance());
133 content::BrowserPluginGuest::set_factory_for_testing(
134 TestBrowserPluginHostFactory::GetInstance());
135
136 ContentBrowserTest::SetUp();
137 }
138 virtual void TearDown() OVERRIDE {
139 content::BrowserPluginEmbedder::set_factory_for_testing(NULL);
140 content::BrowserPluginGuest::set_factory_for_testing(NULL);
141
142 ContentBrowserTest::TearDown();
143 }
144
145 static void SimulateTabKeyPress(WebContents* web_contents) {
146 SimulateKeyPress(web_contents,
147 ui::VKEY_TAB,
148 false, // control.
149 false, // shift.
150 false, // alt.
151 false); // command.
152 }
153
154 private:
155 DISALLOW_COPY_AND_ASSIGN(BrowserPluginHostTest);
156 };
157
158 // This test loads a guest that has infinite loop, therefore it hangs the guest
159 // and eventually gets killed.
160 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, NavigateGuest) {
161 // Override the hang timeout for guest to be very small.
162 content::BrowserPluginGuest::set_factory_for_testing(
163 TestShortHangTimeoutGuestFactory::GetInstance());
164 ASSERT_TRUE(test_server()->Start());
165 GURL test_url(test_server()->GetURL("files/browser_plugin_embedder.html"));
166 NavigateToURL(shell(), test_url);
167
168 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
169 shell()->web_contents());
170 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
171 embedder_web_contents->GetRenderViewHost());
172
173 test_url = test_server()->GetURL(
174 "files/browser_plugin_infinite_loop_child.html");
175 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
176 StringPrintf("SetSrc('%s');", test_url.spec().c_str())));
177
178 // Wait to make sure embedder is created/attached to WebContents.
179 ASSERT_TRUE(
180 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation());
181
182 TestBrowserPluginEmbedder* test_embedder =
183 static_cast<TestBrowserPluginEmbedder*>(
184 embedder_web_contents->GetBrowserPluginEmbedder());
185 ASSERT_TRUE(test_embedder);
186 ASSERT_TRUE(test_embedder->WaitForGuestAdded());
187
188 // Verify that we have exactly one guest.
189 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
190 test_embedder->guest_web_contents_for_testing();
191 EXPECT_EQ(1u, instance_map.size());
192
193 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
194 instance_map.begin()->second);
195 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
196 test_guest_web_contents->GetBrowserPluginGuest());
197
198 // Wait for the guest to send an UpdateRectMsg, meaning it is ready.
199 ASSERT_TRUE(test_guest->WaitForUpdateRectMsg());
200
201 // Send a mouse event to the guest.
202 WebKit::WebMouseEvent mouse_event;
203 mouse_event.type = WebInputEvent::MouseDown;
204 mouse_event.button = WebMouseEvent::ButtonMiddle;
205 mouse_event.x = 35;
206 mouse_event.y = 35;
207 mouse_event.globalX = 35;
208 mouse_event.globalY = 35;
209
210 IPC::Message* input_message = new ViewMsg_HandleInputEvent(
211 embedder_web_contents->GetRenderViewHost()->GetRoutingID());
212 input_message->WriteData(reinterpret_cast<const char*>(&mouse_event),
213 sizeof(WebKit::WebMouseEvent));
214 embedder_web_contents->GetRenderViewHost()->Send(input_message);
215
216 // Expect the guest to crash.
217 ASSERT_TRUE(test_guest->WaitForCrashed());
218 }
219
220 // This test ensures that if guest isn't there and we resize the guest (from
221 // js), it remembers the size correctly.
222 //
223 // Initially we load an embedder with a guest without a src attribute (which has
224 // dimension 640x480), then resize it to 100x200, then we set the source to a
225 // sample guest. In the end we verify that the correct size has been set.
226 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, NavigateAfterResize) {
227 ASSERT_TRUE(test_server()->Start());
228 GURL test_url(test_server()->GetURL(
229 "files/browser_plugin_embedder.html"));
230 NavigateToURL(shell(), test_url);
231
232 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
233 shell()->web_contents());
234 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
235 embedder_web_contents->GetRenderViewHost());
236
237 int nxt_width = 100;
238 int nxt_height = 200;
239 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
240 StringPrintf("SetSize(%d, %d);", nxt_width, nxt_height)));
241
242 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
243 StringPrintf("SetSrc('%s');", kHTMLForGuest)));
244
245 // Wait to make sure embedder is created/attached to WebContents.
246 ASSERT_TRUE(
247 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation());
248
249 TestBrowserPluginEmbedder* test_embedder =
250 static_cast<TestBrowserPluginEmbedder*>(
251 embedder_web_contents->GetBrowserPluginEmbedder());
252 ASSERT_TRUE(test_embedder);
253 ASSERT_TRUE(test_embedder->WaitForGuestAdded());
254
255 // Verify that we have exactly one guest.
256 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
257 test_embedder->guest_web_contents_for_testing();
258 EXPECT_EQ(1u, instance_map.size());
259
260 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
261 instance_map.begin()->second);
262 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
263 test_guest_web_contents->GetBrowserPluginGuest());
264
265
266 // Wait for the guest to send an UpdateRectMsg, the dimensions should be
267 // 100 x 200.
268 ASSERT_TRUE(test_guest->WaitForUpdateRectMsgWithSize(nxt_width, nxt_height));
269 }
270
271 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AdvanceFocus) {
272 ASSERT_TRUE(test_server()->Start());
273 GURL test_url(test_server()->GetURL(
274 "files/browser_plugin_focus.html"));
275 NavigateToURL(shell(), test_url);
276
277 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
278 shell()->web_contents());
279 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
280 embedder_web_contents->GetRenderViewHost());
281
282 test_url = test_server()->GetURL(
283 "files/browser_plugin_focus_child.html");
284 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
285 StringPrintf("SetSrc('%s');", test_url.spec().c_str())));
286
287 // Wait to make sure embedder is created/attached to WebContents.
288 ASSERT_TRUE(
289 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation());
290
291 TestBrowserPluginEmbedder* test_embedder =
292 static_cast<TestBrowserPluginEmbedder*>(
293 embedder_web_contents->GetBrowserPluginEmbedder());
294 ASSERT_TRUE(test_embedder);
295 ASSERT_TRUE(test_embedder->WaitForGuestAdded());
296
297 // Verify that we have exactly one guest.
298 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
299 test_embedder->guest_web_contents_for_testing();
300 EXPECT_EQ(1u, instance_map.size());
301
302 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
303 instance_map.begin()->second);
304 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
305 test_guest_web_contents->GetBrowserPluginGuest());
306 ASSERT_TRUE(test_guest->WaitForUpdateRectMsg());
307
308 SimulateMouseClick(embedder_web_contents);
309 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
310 // Wait until we focus into the guest.
311 ASSERT_TRUE(test_guest->WaitForFocus());
312
313 // TODO(fsamuel): A third Tab key press should not be necessary.
314 // The browser plugin will take keyboard focus but it will not
315 // focus an initial element. The initial element is dependent
316 // upon tab direction which WebKit does not propagate to the plugin.
317 // See http://crbug.com/147644.
318 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
319 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
320 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
321 ASSERT_TRUE(test_guest->WaitForAdvanceFocus());
322 }
323
324 // This test opens a page in http and then opens another page in https, forcing
325 // a RenderViewHost swap in the web_contents. We verify if the embedder in the
Charlie Reis 2012/09/13 00:51:44 nit: verify if -> verify that
lazyboy 2012/09/13 15:56:24 Done.
326 // web_contents gets cleared properly.
327 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) {
328 ASSERT_TRUE(test_server()->Start());
329 net::TestServer https_server(
330 net::TestServer::TYPE_HTTPS,
331 net::TestServer::kLocalhost,
332 FilePath(FILE_PATH_LITERAL("content/test/data")));
333 ASSERT_TRUE(https_server.Start());
334
335 // 1. Load an embedder page with one guest in it.
336 GURL test_url(test_server()->GetURL("files/browser_plugin_embedder.html"));
337 NavigateToURL(shell(), test_url);
338
339 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
340 shell()->web_contents());
341 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
342 embedder_web_contents->GetRenderViewHost());
343 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
344 StringPrintf("SetSrc('%s');", kHTMLForGuest)));
345
346 // Wait to make sure embedder is created/attached to WebContents.
347 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
348
349 TestBrowserPluginEmbedder* test_embedder_before_swap =
350 static_cast<TestBrowserPluginEmbedder*>(
351 embedder_web_contents->GetBrowserPluginEmbedder());
352 ASSERT_TRUE(test_embedder_before_swap);
353 test_embedder_before_swap->WaitForGuestAdded();
354
355 // Verify that we have exactly one guest.
356 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
357 test_embedder_before_swap->guest_web_contents_for_testing();
358 EXPECT_EQ(1u, instance_map.size());
359
360 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
361 instance_map.begin()->second);
362 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
363 test_guest_web_contents->GetBrowserPluginGuest());
364
365 // Wait for the guest to send an UpdateRectMsg, which means the guest is
366 // ready.
367 test_guest->WaitForUpdateRectMsg();
368
369 // This URL is loaded in https, forcing a RenderViewHost swap.
370 GURL test_https_url(https_server.GetURL(
371 "files/browser_plugin_title_change.html"));
372
373 // 2. Navigate to a URL in https, so we trigger a RenderViewHost swap.
Charlie Reis 2012/09/13 00:51:44 nit: Move the test_https_url lines below this line
lazyboy 2012/09/13 15:56:24 Done.
374 content::WindowedNotificationObserver swap_observer(
375 content::NOTIFICATION_WEB_CONTENTS_SWAPPED,
376 content::Source<WebContents>(embedder_web_contents));
377 NavigateToURL(shell(), test_https_url);
378 swap_observer.Wait();
379
380 TestBrowserPluginEmbedder* test_embedder_after_swap =
381 static_cast<TestBrowserPluginEmbedder*>(
382 static_cast<WebContentsImpl*>(shell()->web_contents())->
383 GetBrowserPluginEmbedder());
384 // Verify we have a no embedder in web_contents (since the new page doesn't
385 // have any browser plugin).
386 ASSERT_TRUE(!test_embedder_after_swap);
387 ASSERT_NE(test_embedder_before_swap, test_embedder_after_swap);
388 }
389
390 // This test opens two pages in http and there is no RenderViewHost swap,
391 // therefore the embedder created on first page navigation stays the same in
392 // web_contents.
393 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) {
394 ASSERT_TRUE(test_server()->Start());
395
396 GURL test_url(test_server()->GetURL("files/browser_plugin_embedder.html"));
397 NavigateToURL(shell(), test_url);
398
399 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
400 shell()->web_contents());
401 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
402 embedder_web_contents->GetRenderViewHost());
403
404 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
405 StringPrintf("SetSrc('%s');", kHTMLForGuest)));
406
407 // Wait to make sure embedder is created/attached to WebContents.
408 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
409
410 TestBrowserPluginEmbedder* test_embedder_ =
411 static_cast<TestBrowserPluginEmbedder*>(
412 embedder_web_contents->GetBrowserPluginEmbedder());
413 ASSERT_TRUE(test_embedder_);
414 test_embedder_->WaitForGuestAdded();
415
416 // Verify that we have exactly one guest.
417 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
418 test_embedder_->guest_web_contents_for_testing();
419 EXPECT_EQ(1u, instance_map.size());
420
421 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
422 instance_map.begin()->second);
423 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
424 test_guest_web_contents->GetBrowserPluginGuest());
425
426 // Wait for the guest to send an UpdateRectMsg, which means the guest is
427 // ready.
428 test_guest->WaitForUpdateRectMsg();
429
430 // Navigate to another page in same host and port, so RenderViewHost swap
431 // does not happen and existing embedder doesn't change in web_contents.
432 GURL test_url_new(test_server()->GetURL(
433 "files/browser_plugin_title_change.html"));
434 const string16 expected_title = ASCIIToUTF16("done");
435 content::TitleWatcher title_watcher(shell()->web_contents(), expected_title);
436 NavigateToURL(shell(), test_url_new);
437 LOG(INFO) << "Start waiting for title";
438 string16 actual_title = title_watcher.WaitAndGetTitle();
439 EXPECT_EQ(expected_title, actual_title);
440 LOG(INFO) << "Done navigating to second page";
441
442 TestBrowserPluginEmbedder* test_embedder_after_nav =
443 static_cast<TestBrowserPluginEmbedder*>(
444 embedder_web_contents->GetBrowserPluginEmbedder());
445 // Embedder must not change in web_contents.
446 ASSERT_EQ(test_embedder_after_nav, test_embedder_);
447 }
448
449 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698