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

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: Disable BrowserPluginHostTest.NavigateGuest on win, flaking. 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/test/test_timeouts.h"
8 #include "base/utf_string_conversions.h"
9 #include "content/browser/browser_plugin/browser_plugin_guest.h"
10 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
11 #include "content/browser/browser_plugin/test_browser_plugin_embedder.h"
12 #include "content/browser/browser_plugin/test_browser_plugin_guest.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 "net/base/net_util.h"
24 #include "net/test/test_server.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
26
27 using WebKit::WebInputEvent;
28 using WebKit::WebMouseEvent;
29 using content::BrowserPluginEmbedder;
30 using content::BrowserPluginGuest;
31 using content::BrowserPluginHostFactory;
32
33 namespace content {
34
35 const char* kHTMLForGuest =
36 "data:text/html,<html><body>hello world</body></html>";
37 const char* kHTMLForGuestInfiniteLoop =
38 "data:text/html,<html><head><script type=\"text/javascript\">"
39 "function StartInfiniteLoop() {"
40 " setTimeout(function () {while (true) {} }, 0);"
41 "}"
42 "</script></head><body></body></html>";
43
44 // Test factory for creating test instances of BrowserPluginEmbedder and
45 // BrowserPluginGuest.
46 class TestBrowserPluginHostFactory : public BrowserPluginHostFactory {
47 public:
48 virtual BrowserPluginGuest* CreateBrowserPluginGuest(
49 int instance_id,
50 WebContentsImpl* web_contents,
51 RenderViewHost* render_view_host) OVERRIDE {
52 return new TestBrowserPluginGuest(instance_id,
53 web_contents,
54 render_view_host);
55 }
56
57 // Also keeps track of number of instances created.
58 virtual BrowserPluginEmbedder* CreateBrowserPluginEmbedder(
59 WebContentsImpl* web_contents,
60 RenderViewHost* render_view_host) OVERRIDE {
61 embedder_instance_count_++;
62 if (message_loop_runner_)
63 message_loop_runner_->Quit();
64
65 return new TestBrowserPluginEmbedder(web_contents, render_view_host);
66 }
67
68 // Singleton getter.
69 static TestBrowserPluginHostFactory* GetInstance() {
70 return Singleton<TestBrowserPluginHostFactory>::get();
71 }
72
73 // Waits for at least one embedder to be created in the test. Returns true if
74 // we have a guest, false if waiting times out.
75 void WaitForEmbedderCreation() {
76 // Check if already have created instance.
77 if (embedder_instance_count_ > 0)
78 return;
79 // Wait otherwise.
80 message_loop_runner_ = new MessageLoopRunner();
81 message_loop_runner_->Run();
82 }
83
84 protected:
85 TestBrowserPluginHostFactory() : embedder_instance_count_(0) {}
86 virtual ~TestBrowserPluginHostFactory() {}
87
88 private:
89 // For Singleton.
90 friend struct DefaultSingletonTraits<TestBrowserPluginHostFactory>;
91
92 scoped_refptr<MessageLoopRunner> message_loop_runner_;
93 int embedder_instance_count_;
94
95 DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginHostFactory);
96 };
97
98 // Test factory class for browser plugin that creates guests with short hang
99 // timeout.
100 class TestShortHangTimeoutGuestFactory : public TestBrowserPluginHostFactory {
101 public:
102 virtual BrowserPluginGuest* CreateBrowserPluginGuest(
103 int instance_id,
104 WebContentsImpl* web_contents,
105 RenderViewHost* render_view_host) OVERRIDE {
106 BrowserPluginGuest* guest = new TestBrowserPluginGuest(instance_id,
107 web_contents,
108 render_view_host);
109 guest->set_guest_hang_timeout_for_testing(TestTimeouts::tiny_timeout());
110 return guest;
111 }
112
113 // Singleton getter.
114 static TestShortHangTimeoutGuestFactory* GetInstance() {
115 return Singleton<TestShortHangTimeoutGuestFactory>::get();
116 }
117
118 protected:
119 TestShortHangTimeoutGuestFactory() {}
120 virtual ~TestShortHangTimeoutGuestFactory() {}
121
122 private:
123 // For Singleton.
124 friend struct DefaultSingletonTraits<TestShortHangTimeoutGuestFactory>;
125
126 DISALLOW_COPY_AND_ASSIGN(TestShortHangTimeoutGuestFactory);
127 };
128
129 class BrowserPluginHostTest : public ContentBrowserTest {
130 public:
131 BrowserPluginHostTest() {}
132
133 virtual void SetUp() OVERRIDE {
134 // Override factory to create tests instances of BrowserPlugin*.
135 content::BrowserPluginEmbedder::set_factory_for_testing(
136 TestBrowserPluginHostFactory::GetInstance());
137 content::BrowserPluginGuest::set_factory_for_testing(
138 TestBrowserPluginHostFactory::GetInstance());
139
140 ContentBrowserTest::SetUp();
141 }
142 virtual void TearDown() OVERRIDE {
143 content::BrowserPluginEmbedder::set_factory_for_testing(NULL);
144 content::BrowserPluginGuest::set_factory_for_testing(NULL);
145
146 ContentBrowserTest::TearDown();
147 }
148
149 static void SimulateTabKeyPress(WebContents* web_contents) {
150 SimulateKeyPress(web_contents,
151 ui::VKEY_TAB,
152 false, // control.
153 false, // shift.
154 false, // alt.
155 false); // command.
156 }
157
158 private:
159 DISALLOW_COPY_AND_ASSIGN(BrowserPluginHostTest);
160 };
161
162 // This test loads a guest that has infinite loop, therefore it hangs the guest
163 // and eventually gets killed.
164 // TODO(lazyboy): This test is flaky on Windows, since this relies on
165 // RenderViewGone to be called and times out. http://crbug.com/151190.
166 #if defined(OS_WIN)
167 #define MAYBE_NavigateGuest DISABLED_NavigateGuest
168 #else
169 #define MAYBE_NavigateGuest NavigateGuest
170 #endif
171 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_NavigateGuest) {
172 // Override the hang timeout for guest to be very small.
173 content::BrowserPluginGuest::set_factory_for_testing(
174 TestShortHangTimeoutGuestFactory::GetInstance());
175 ASSERT_TRUE(test_server()->Start());
176 GURL test_url(test_server()->GetURL(
177 "files/browser_plugin_embedder_crash.html"));
178 NavigateToURL(shell(), test_url);
179
180 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
181 shell()->web_contents());
182 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
183 embedder_web_contents->GetRenderViewHost());
184
185 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
186 StringPrintf("SetSrc('%s');", kHTMLForGuestInfiniteLoop)));
187
188 // Wait to make sure embedder is created/attached to WebContents.
189 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
190
191 TestBrowserPluginEmbedder* test_embedder =
192 static_cast<TestBrowserPluginEmbedder*>(
193 embedder_web_contents->GetBrowserPluginEmbedder());
194 ASSERT_TRUE(test_embedder);
195 test_embedder->WaitForGuestAdded();
196
197 // Verify that we have exactly one guest.
198 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
199 test_embedder->guest_web_contents_for_testing();
200 EXPECT_EQ(1u, instance_map.size());
201
202 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
203 instance_map.begin()->second);
204 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
205 test_guest_web_contents->GetBrowserPluginGuest());
206
207 // Wait for the guest to send an UpdateRectMsg, meaning it is ready.
208 test_guest->WaitForUpdateRectMsg();
209
210 test_guest_web_contents->GetRenderViewHost()->ExecuteJavascriptAndGetValue(
211 string16(), ASCIIToUTF16("StartInfiniteLoop();"));
212
213 // Send a mouse event to the guest.
214 SimulateMouseClick(embedder_web_contents);
215
216 // Expect the guest to crash.
217 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), resize it to 100x200, and 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 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
247
248 TestBrowserPluginEmbedder* test_embedder =
249 static_cast<TestBrowserPluginEmbedder*>(
250 embedder_web_contents->GetBrowserPluginEmbedder());
251 ASSERT_TRUE(test_embedder);
252 test_embedder->WaitForGuestAdded();
253
254 // Verify that we have exactly one guest.
255 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
256 test_embedder->guest_web_contents_for_testing();
257 EXPECT_EQ(1u, instance_map.size());
258
259 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
260 instance_map.begin()->second);
261 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
262 test_guest_web_contents->GetBrowserPluginGuest());
263
264
265 // Wait for the guest to send an UpdateRectMsg, the dimensions should be
266 // 100 x 200.
267 test_guest->WaitForUpdateRectMsgWithSize(nxt_width, nxt_height);
268 }
269
270 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AdvanceFocus) {
271 ASSERT_TRUE(test_server()->Start());
272 GURL test_url(test_server()->GetURL(
273 "files/browser_plugin_focus.html"));
274 NavigateToURL(shell(), test_url);
275
276 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
277 shell()->web_contents());
278 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
279 embedder_web_contents->GetRenderViewHost());
280
281 test_url = test_server()->GetURL(
282 "files/browser_plugin_focus_child.html");
283 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
284 StringPrintf("SetSrc('%s');", test_url.spec().c_str())));
285
286 // Wait to make sure embedder is created/attached to WebContents.
287 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
288
289 TestBrowserPluginEmbedder* test_embedder =
290 static_cast<TestBrowserPluginEmbedder*>(
291 embedder_web_contents->GetBrowserPluginEmbedder());
292 ASSERT_TRUE(test_embedder);
293 test_embedder->WaitForGuestAdded();
294
295 // Verify that we have exactly one guest.
296 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
297 test_embedder->guest_web_contents_for_testing();
298 EXPECT_EQ(1u, instance_map.size());
299
300 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
301 instance_map.begin()->second);
302 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
303 test_guest_web_contents->GetBrowserPluginGuest());
304 test_guest->WaitForUpdateRectMsg();
305
306 SimulateMouseClick(embedder_web_contents);
307 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
308 // Wait until we focus into the guest.
309 test_guest->WaitForFocus();
310
311 // TODO(fsamuel): A third Tab key press should not be necessary.
312 // The browser plugin will take keyboard focus but it will not
313 // focus an initial element. The initial element is dependent
314 // upon tab direction which WebKit does not propagate to the plugin.
315 // See http://crbug.com/147644.
316 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
317 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
318 BrowserPluginHostTest::SimulateTabKeyPress(embedder_web_contents);
319 test_guest->WaitForAdvanceFocus();
320 }
321
322 // This test opens a page in http and then opens another page in https, forcing
323 // a RenderViewHost swap in the web_contents. We verify that the embedder in the
324 // web_contents gets cleared properly.
325 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) {
326 ASSERT_TRUE(test_server()->Start());
327 net::TestServer https_server(
328 net::TestServer::TYPE_HTTPS,
329 net::TestServer::kLocalhost,
330 FilePath(FILE_PATH_LITERAL("content/test/data")));
331 ASSERT_TRUE(https_server.Start());
332
333 // 1. Load an embedder page with one guest in it.
334 GURL test_url(test_server()->GetURL("files/browser_plugin_embedder.html"));
335 NavigateToURL(shell(), test_url);
336
337 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
338 shell()->web_contents());
339 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
340 embedder_web_contents->GetRenderViewHost());
341 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
342 StringPrintf("SetSrc('%s');", kHTMLForGuest)));
343
344 // Wait to make sure embedder is created/attached to WebContents.
345 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
346
347 TestBrowserPluginEmbedder* test_embedder_before_swap =
348 static_cast<TestBrowserPluginEmbedder*>(
349 embedder_web_contents->GetBrowserPluginEmbedder());
350 ASSERT_TRUE(test_embedder_before_swap);
351 test_embedder_before_swap->WaitForGuestAdded();
352
353 // Verify that we have exactly one guest.
354 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
355 test_embedder_before_swap->guest_web_contents_for_testing();
356 EXPECT_EQ(1u, instance_map.size());
357
358 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
359 instance_map.begin()->second);
360 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
361 test_guest_web_contents->GetBrowserPluginGuest());
362
363 // Wait for the guest to send an UpdateRectMsg, which means the guest is
364 // ready.
365 test_guest->WaitForUpdateRectMsg();
366
367 // 2. Navigate to a URL in https, so we trigger a RenderViewHost swap.
368 GURL test_https_url(https_server.GetURL(
369 "files/browser_plugin_title_change.html"));
370 content::WindowedNotificationObserver swap_observer(
371 content::NOTIFICATION_WEB_CONTENTS_SWAPPED,
372 content::Source<WebContents>(embedder_web_contents));
373 NavigateToURL(shell(), test_https_url);
374 swap_observer.Wait();
375
376 TestBrowserPluginEmbedder* test_embedder_after_swap =
377 static_cast<TestBrowserPluginEmbedder*>(
378 static_cast<WebContentsImpl*>(shell()->web_contents())->
379 GetBrowserPluginEmbedder());
380 // Verify we have a no embedder in web_contents (since the new page doesn't
381 // have any browser plugin).
382 ASSERT_TRUE(!test_embedder_after_swap);
383 ASSERT_NE(test_embedder_before_swap, test_embedder_after_swap);
384 }
385
386 // This test opens two pages in http and there is no RenderViewHost swap,
387 // therefore the embedder created on first page navigation stays the same in
388 // web_contents.
389 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) {
390 ASSERT_TRUE(test_server()->Start());
391
392 GURL test_url(test_server()->GetURL("files/browser_plugin_embedder.html"));
393 NavigateToURL(shell(), test_url);
394
395 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
396 shell()->web_contents());
397 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
398 embedder_web_contents->GetRenderViewHost());
399
400 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
401 StringPrintf("SetSrc('%s');", kHTMLForGuest)));
402
403 // Wait to make sure embedder is created/attached to WebContents.
404 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
405
406 TestBrowserPluginEmbedder* test_embedder =
407 static_cast<TestBrowserPluginEmbedder*>(
408 embedder_web_contents->GetBrowserPluginEmbedder());
409 ASSERT_TRUE(test_embedder);
410 test_embedder->WaitForGuestAdded();
411
412 // Verify that we have exactly one guest.
413 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
414 test_embedder->guest_web_contents_for_testing();
415 EXPECT_EQ(1u, instance_map.size());
416
417 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
418 instance_map.begin()->second);
419 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
420 test_guest_web_contents->GetBrowserPluginGuest());
421
422 // Wait for the guest to send an UpdateRectMsg, which means the guest is
423 // ready.
424 test_guest->WaitForUpdateRectMsg();
425
426 // Navigate to another page in same host and port, so RenderViewHost swap
427 // does not happen and existing embedder doesn't change in web_contents.
428 GURL test_url_new(test_server()->GetURL(
429 "files/browser_plugin_title_change.html"));
430 const string16 expected_title = ASCIIToUTF16("done");
431 content::TitleWatcher title_watcher(shell()->web_contents(), expected_title);
432 NavigateToURL(shell(), test_url_new);
433 LOG(INFO) << "Start waiting for title";
434 string16 actual_title = title_watcher.WaitAndGetTitle();
435 EXPECT_EQ(expected_title, actual_title);
436 LOG(INFO) << "Done navigating to second page";
437
438 TestBrowserPluginEmbedder* test_embedder_after_nav =
439 static_cast<TestBrowserPluginEmbedder*>(
440 embedder_web_contents->GetBrowserPluginEmbedder());
441 // Embedder must not change in web_contents.
442 ASSERT_EQ(test_embedder_after_nav, test_embedder);
443 }
444
445 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, VisibilityChanged) {
446 ASSERT_TRUE(test_server()->Start());
447 GURL test_url(test_server()->GetURL(
448 "files/browser_plugin_focus.html"));
449 NavigateToURL(shell(), test_url);
450
451 WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
452 shell()->web_contents());
453 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
454 embedder_web_contents->GetRenderViewHost());
455
456 test_url = test_server()->GetURL(
457 "files/browser_plugin_focus_child.html");
458 rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
459 StringPrintf("SetSrc('%s');", test_url.spec().c_str())));
460
461 // Wait to make sure embedder is created/attached to WebContents.
462 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
463
464 TestBrowserPluginEmbedder* test_embedder =
465 static_cast<TestBrowserPluginEmbedder*>(
466 embedder_web_contents->GetBrowserPluginEmbedder());
467 ASSERT_TRUE(test_embedder);
468 test_embedder->WaitForGuestAdded();
469
470 // Verify that we have exactly one guest.
471 const BrowserPluginEmbedder::ContainerInstanceMap& instance_map =
472 test_embedder->guest_web_contents_for_testing();
473 EXPECT_EQ(1u, instance_map.size());
474
475 WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
476 instance_map.begin()->second);
477 TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
478 test_guest_web_contents->GetBrowserPluginGuest());
479
480 // Wait for the guest to send an UpdateRectMsg, meaning it is ready.
481 test_guest->WaitForUpdateRectMsg();
482
483 // Hide the embedder.
484 embedder_web_contents->WasHidden();
485
486 // Make sure that hiding the embedder also hides the guest.
487 test_guest->WaitUntilHidden();
488 }
489
490 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698