Android media: VideoFrame should not store so many sync points.
[chromium-blink-merge.git] / content / browser / plugin_browsertest.cc
blob223b7245fdaa4bf1949f1ed5dcf969e19654f1c4
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.
5 #include "base/command_line.h"
6 #include "base/file_util.h"
7 #include "base/path_service.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/loader/resource_dispatcher_host_impl.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/resource_dispatcher_host_delegate.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/public/test/browser_test_utils.h"
15 #include "content/public/test/content_browser_test.h"
16 #include "content/public/test/content_browser_test_utils.h"
17 #include "content/public/test/test_utils.h"
18 #include "content/shell/browser/shell.h"
19 #include "content/shell/common/shell_switches.h"
20 #include "content/test/net/url_request_mock_http_job.h"
21 #include "net/test/embedded_test_server/embedded_test_server.h"
22 #include "net/url_request/url_request.h"
23 #include "ui/gfx/rect.h"
25 #if defined(OS_WIN)
26 #include "base/win/registry.h"
27 #endif
29 // TODO(jschuh): Finish plugins on Win64. crbug.com/180861
30 #if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
31 #define MAYBE(x) DISABLED_##x
32 #else
33 #define MAYBE(x) x
34 #endif
36 using base::ASCIIToUTF16;
38 namespace content {
39 namespace {
41 void SetUrlRequestMock(const base::FilePath& path) {
42 URLRequestMockHTTPJob::AddUrlHandler(path);
47 class PluginTest : public ContentBrowserTest {
48 protected:
49 PluginTest() {}
51 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
52 // Some NPAPI tests schedule garbage collection to force object tear-down.
53 command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose_gc");
55 #if defined(OS_WIN)
56 const testing::TestInfo* const test_info =
57 testing::UnitTest::GetInstance()->current_test_info();
58 if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
59 // The installer adds our process names to the registry key below. Since
60 // the installer might not have run on this machine, add it manually.
61 base::win::RegKey regkey;
62 if (regkey.Open(HKEY_LOCAL_MACHINE,
63 L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
64 KEY_WRITE) == ERROR_SUCCESS) {
65 regkey.CreateKey(L"BROWSER_TESTS.EXE", KEY_READ);
68 #elif defined(OS_MACOSX)
69 base::FilePath plugin_dir;
70 PathService::Get(base::DIR_MODULE, &plugin_dir);
71 plugin_dir = plugin_dir.AppendASCII("plugins");
72 // The plugins directory isn't read by default on the Mac, so it needs to be
73 // explicitly registered.
74 command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);
75 #endif
78 virtual void SetUpOnMainThread() OVERRIDE {
79 base::FilePath path = GetTestFilePath("", "");
80 BrowserThread::PostTask(
81 BrowserThread::IO, FROM_HERE, base::Bind(&SetUrlRequestMock, path));
84 static void LoadAndWaitInWindow(Shell* window, const GURL& url) {
85 base::string16 expected_title(ASCIIToUTF16("OK"));
86 TitleWatcher title_watcher(window->web_contents(), expected_title);
87 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
88 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("plugin_not_found"));
89 NavigateToURL(window, url);
90 base::string16 title = title_watcher.WaitAndGetTitle();
91 if (title == ASCIIToUTF16("plugin_not_found")) {
92 const testing::TestInfo* const test_info =
93 testing::UnitTest::GetInstance()->current_test_info();
94 VLOG(0) << "PluginTest." << test_info->name()
95 << " not running because plugin not installed.";
96 } else {
97 EXPECT_EQ(expected_title, title);
101 void LoadAndWait(const GURL& url) {
102 LoadAndWaitInWindow(shell(), url);
105 GURL GetURL(const char* filename) {
106 return GetTestUrl("npapi", filename);
109 void NavigateAway() {
110 GURL url = GetTestUrl("", "simple_page.html");
111 LoadAndWait(url);
114 void TestPlugin(const char* filename) {
115 base::FilePath path = GetTestFilePath("plugin", filename);
116 if (!base::PathExists(path)) {
117 const testing::TestInfo* const test_info =
118 testing::UnitTest::GetInstance()->current_test_info();
119 VLOG(0) << "PluginTest." << test_info->name()
120 << " not running because test data wasn't found.";
121 return;
124 GURL url = GetTestUrl("plugin", filename);
125 LoadAndWait(url);
129 // Make sure that navigating away from a plugin referenced by JS doesn't
130 // crash.
131 IN_PROC_BROWSER_TEST_F(PluginTest, UnloadNoCrash) {
132 LoadAndWait(GetURL("layout_test_plugin.html"));
133 NavigateAway();
136 // Tests if a plugin executing a self deleting script using NPN_GetURL
137 // works without crashing or hanging
138 // Flaky: http://crbug.com/59327
139 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginGetUrl)) {
140 LoadAndWait(GetURL("self_delete_plugin_geturl.html"));
143 // Tests if a plugin executing a self deleting script using Invoke
144 // works without crashing or hanging
145 // Flaky. See http://crbug.com/30702
146 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvoke)) {
147 LoadAndWait(GetURL("self_delete_plugin_invoke.html"));
150 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectReleasedOnDestruction)) {
151 NavigateToURL(shell(), GetURL("npobject_released_on_destruction.html"));
152 NavigateAway();
155 // Test that a dialog is properly created when a plugin throws an
156 // exception. Should be run for in and out of process plugins, but
157 // the more interesting case is out of process, where we must route
158 // the exception to the correct renderer.
159 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectSetException)) {
160 LoadAndWait(GetURL("npobject_set_exception.html"));
163 #if defined(OS_WIN)
164 // Tests if a plugin executing a self deleting script in the context of
165 // a synchronous mouseup works correctly.
166 // This was never ported to Mac. The only thing remaining is to make
167 // SimulateMouseClick get to Mac plugins, currently it doesn't work.
168 IN_PROC_BROWSER_TEST_F(PluginTest,
169 MAYBE(SelfDeletePluginInvokeInSynchronousMouseUp)) {
170 NavigateToURL(shell(), GetURL("execute_script_delete_in_mouse_up.html"));
172 base::string16 expected_title(ASCIIToUTF16("OK"));
173 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
174 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
175 SimulateMouseClick(shell()->web_contents(), 0,
176 blink::WebMouseEvent::ButtonLeft);
177 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
179 #endif
181 // Flaky, http://crbug.com/302274.
182 #if defined(OS_MACOSX)
183 #define MAYBE_GetURLRequest404Response DISABLED_GetURLRequest404Response
184 #else
185 #define MAYBE_GetURLRequest404Response MAYBE(GetURLRequest404Response)
186 #endif
188 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_GetURLRequest404Response) {
189 GURL url(URLRequestMockHTTPJob::GetMockUrl(
190 base::FilePath().AppendASCII("npapi").
191 AppendASCII("plugin_url_request_404.html")));
192 LoadAndWait(url);
195 // Tests if a plugin executing a self deleting script using Invoke with
196 // a modal dialog showing works without crashing or hanging
197 // Disabled, flakily exceeds timeout, http://crbug.com/46257.
198 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvokeAlert)) {
199 // Navigate asynchronously because if we waitd until it completes, there's a
200 // race condition where the alert can come up before we start watching for it.
201 shell()->LoadURL(GetURL("self_delete_plugin_invoke_alert.html"));
203 base::string16 expected_title(ASCIIToUTF16("OK"));
204 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
205 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
207 WaitForAppModalDialog(shell());
209 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
212 // Test passing arguments to a plugin.
213 // crbug.com/306318
214 #if !defined(OS_LINUX)
215 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Arguments)) {
216 LoadAndWait(GetURL("arguments.html"));
218 #endif
220 // Test invoking many plugins within a single page.
221 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ManyPlugins)) {
222 LoadAndWait(GetURL("many_plugins.html"));
225 // Test various calls to GetURL from a plugin.
226 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURL)) {
227 LoadAndWait(GetURL("geturl.html"));
230 // Test various calls to GetURL for javascript URLs with
231 // non NULL targets from a plugin.
232 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL)) {
233 LoadAndWait(GetURL("get_javascript_url.html"));
236 // Test that calling GetURL with a javascript URL and target=_self
237 // works properly when the plugin is embedded in a subframe.
238 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL2)) {
239 LoadAndWait(GetURL("get_javascript_url2.html"));
242 // Test is flaky on linux/cros/win builders. http://crbug.com/71904
243 IN_PROC_BROWSER_TEST_F(PluginTest, GetURLRedirectNotification) {
244 LoadAndWait(GetURL("geturl_redirect_notify.html"));
247 // Tests that identity is preserved for NPObjects passed from a plugin
248 // into JavaScript.
249 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectIdentity)) {
250 LoadAndWait(GetURL("npobject_identity.html"));
253 // Tests that if an NPObject is proxies back to its original process, the
254 // original pointer is returned and not a proxy. If this fails the plugin
255 // will crash.
256 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectProxy)) {
257 LoadAndWait(GetURL("npobject_proxy.html"));
260 #if defined(OS_WIN) || defined(OS_MACOSX)
261 // Tests if a plugin executing a self deleting script in the context of
262 // a synchronous paint event works correctly
263 // http://crbug.com/44960
264 IN_PROC_BROWSER_TEST_F(PluginTest,
265 MAYBE(SelfDeletePluginInvokeInSynchronousPaint)) {
266 LoadAndWait(GetURL("execute_script_delete_in_paint.html"));
268 #endif
270 // Tests that if a plugin executes a self resizing script in the context of a
271 // synchronous paint, the plugin doesn't use deallocated memory.
272 // http://crbug.com/139462
273 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ResizeDuringPaint)) {
274 LoadAndWait(GetURL("resize_during_paint.html"));
277 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNewStream)) {
278 LoadAndWait(GetURL("self_delete_plugin_stream.html"));
281 // On Mac this test asserts in plugin_host: http://crbug.com/95558
282 // On all platforms it flakes in ~URLRequestContext: http://crbug.com/310336
283 #if !defined(NDEBUG)
284 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_DeletePluginInDeallocate) {
285 LoadAndWait(GetURL("plugin_delete_in_deallocate.html"));
287 #endif
289 #if defined(OS_WIN)
291 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyPluginWindowRect)) {
292 LoadAndWait(GetURL("verify_plugin_window_rect.html"));
295 // Tests that creating a new instance of a plugin while another one is handling
296 // a paint message doesn't cause deadlock.
297 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(CreateInstanceInPaint)) {
298 LoadAndWait(GetURL("create_instance_in_paint.html"));
301 // Tests that putting up an alert in response to a paint doesn't deadlock.
302 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_AlertInWindowMessage) {
303 NavigateToURL(shell(), GetURL("alert_in_window_message.html"));
305 WaitForAppModalDialog(shell());
306 WaitForAppModalDialog(shell());
309 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyNPObjectLifetimeTest)) {
310 LoadAndWait(GetURL("npobject_lifetime_test.html"));
313 // Tests that we don't crash or assert if NPP_New fails
314 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NewFails)) {
315 LoadAndWait(GetURL("new_fails.html"));
318 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNPNEvaluate)) {
319 LoadAndWait(GetURL("execute_script_delete_in_npn_evaluate.html"));
322 IN_PROC_BROWSER_TEST_F(PluginTest,
323 MAYBE(SelfDeleteCreatePluginInNPNEvaluate)) {
324 LoadAndWait(GetURL("npn_plugin_delete_create_in_evaluate.html"));
327 #endif // OS_WIN
329 // If this flakes, reopen http://crbug.com/17645
330 // As of 6 July 2011, this test is flaky on Windows (perhaps due to timing out).
331 #if !defined(OS_MACOSX) && !defined(OS_LINUX)
332 // Disabled on Mac because the plugin side isn't implemented yet, see
333 // "TODO(port)" in plugin_javascript_open_popup.cc.
334 // Disabled on Linux because we don't support NPAPI any more.
335 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(OpenPopupWindowWithPlugin)) {
336 LoadAndWait(GetURL("get_javascript_open_popup_with_plugin.html"));
338 #endif
340 // Test checking the privacy mode is off.
341 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateDisabled)) {
342 LoadAndWait(GetURL("private.html"));
345 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ScheduleTimer)) {
346 LoadAndWait(GetURL("schedule_timer.html"));
349 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginThreadAsyncCall)) {
350 LoadAndWait(GetURL("plugin_thread_async_call.html"));
353 IN_PROC_BROWSER_TEST_F(PluginTest, PluginSingleRangeRequest) {
354 LoadAndWait(GetURL("plugin_single_range_request.html"));
357 // Test checking the privacy mode is on.
358 // If this flakes on Linux, use http://crbug.com/104380
359 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateEnabled)) {
360 GURL url = GetURL("private.html");
361 url = GURL(url.spec() + "?private");
362 LoadAndWaitInWindow(CreateOffTheRecordBrowser(), url);
365 #if defined(OS_WIN) || defined(OS_MACOSX)
366 // Test a browser hang due to special case of multiple
367 // plugin instances indulged in sync calls across renderer.
368 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MultipleInstancesSyncCalls)) {
369 LoadAndWait(GetURL("multiple_instances_sync_calls.html"));
371 #endif
373 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURLRequestFailWrite)) {
374 GURL url(URLRequestMockHTTPJob::GetMockUrl(
375 base::FilePath().AppendASCII("npapi").
376 AppendASCII("plugin_url_request_fail_write.html")));
377 LoadAndWait(url);
380 #if defined(OS_WIN)
381 // Flaky on Windows x86. http://crbug.com/388245
382 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_EnsureScriptingWorksInDestroy) {
383 LoadAndWait(GetURL("ensure_scripting_works_in_destroy.html"));
386 // This test uses a Windows Event to signal to the plugin that it should crash
387 // on NP_Initialize.
388 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NoHangIfInitCrashes)) {
389 HANDLE crash_event = CreateEvent(NULL, TRUE, FALSE, L"TestPluginCrashOnInit");
390 SetEvent(crash_event);
391 LoadAndWait(GetURL("no_hang_if_init_crashes.html"));
392 CloseHandle(crash_event);
394 #endif
396 // If this flakes on Mac, use http://crbug.com/111508
397 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginReferrerTest)) {
398 GURL url(URLRequestMockHTTPJob::GetMockUrl(
399 base::FilePath().AppendASCII("npapi").
400 AppendASCII("plugin_url_request_referrer_test.html")));
401 LoadAndWait(url);
404 #if defined(OS_MACOSX)
405 // Test is flaky, see http://crbug.com/134515.
406 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_PluginConvertPointTest) {
407 gfx::Rect bounds(50, 50, 400, 400);
408 SetWindowBounds(shell()->window(), bounds);
410 NavigateToURL(shell(), GetURL("convert_point.html"));
412 base::string16 expected_title(ASCIIToUTF16("OK"));
413 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
414 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
415 // TODO(stuartmorgan): When the automation system supports sending clicks,
416 // change the test to trigger on mouse-down rather than window focus.
418 // TODO: is this code still needed? It was here when it used to run in
419 // browser_tests.
420 //static_cast<WebContentsDelegate*>(shell())->
421 // ActivateContents(shell()->web_contents());
422 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
424 #endif
426 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Flash)) {
427 TestPlugin("flash.html");
430 #if defined(OS_WIN)
431 // Windows only test
432 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashSecurity) {
433 TestPlugin("flash.html");
435 #endif // defined(OS_WIN)
437 #if defined(OS_WIN)
438 // TODO(port) Port the following tests to platforms that have the required
439 // plugins.
440 // Flaky: http://crbug.com/55915
441 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Quicktime)) {
442 TestPlugin("quicktime.html");
445 // Disabled - http://crbug.com/44662
446 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MediaPlayerNew)) {
447 TestPlugin("wmp_new.html");
450 // Disabled - http://crbug.com/44673
451 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Real)) {
452 TestPlugin("real.html");
455 // http://crbug.com/320041
456 #if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
457 (defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN))
458 #define MAYBE_FlashOctetStream DISABLED_FlashOctetStream
459 #else
460 #define MAYBE_FlashOctetStream FlashOctetStream
461 #endif
462 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_FlashOctetStream) {
463 TestPlugin("flash-octet-stream.html");
466 #if defined(OS_WIN)
467 // http://crbug.com/53926
468 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashLayoutWhilePainting) {
469 #else
470 IN_PROC_BROWSER_TEST_F(PluginTest, FlashLayoutWhilePainting) {
471 #endif
472 TestPlugin("flash-layout-while-painting.html");
475 // http://crbug.com/8690
476 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_Java) {
477 TestPlugin("Java.html");
480 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Silverlight)) {
481 TestPlugin("silverlight.html");
483 #endif // defined(OS_WIN)
485 class TestResourceDispatcherHostDelegate
486 : public ResourceDispatcherHostDelegate {
487 public:
488 TestResourceDispatcherHostDelegate() : found_cookie_(false) {}
490 bool found_cookie() { return found_cookie_; }
492 void WaitForPluginRequest() {
493 if (found_cookie_)
494 return;
496 runner_ = new MessageLoopRunner;
497 runner_->Run();
500 private:
501 // ResourceDispatcherHostDelegate implementation:
502 virtual void OnResponseStarted(
503 net::URLRequest* request,
504 ResourceContext* resource_context,
505 ResourceResponse* response,
506 IPC::Sender* sender) OVERRIDE {
507 // The URL below comes from plugin_geturl_test.cc.
508 if (!EndsWith(request->url().spec(),
509 "npapi/plugin_ref_target_page.html",
510 true)) {
511 return;
513 net::HttpRequestHeaders headers;
514 bool found_cookie = false;
515 if (request->GetFullRequestHeaders(&headers) &&
516 headers.ToString().find("Cookie: blah") != std::string::npos) {
517 found_cookie = true;
519 BrowserThread::PostTask(
520 BrowserThread::UI,
521 FROM_HERE,
522 base::Bind(&TestResourceDispatcherHostDelegate::GotCookie,
523 base::Unretained(this), found_cookie));
526 void GotCookie(bool found_cookie) {
527 found_cookie_ = found_cookie;
528 if (runner_)
529 runner_->QuitClosure().Run();
532 scoped_refptr<MessageLoopRunner> runner_;
533 bool found_cookie_;
535 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
538 // Ensure that cookies get sent with plugin requests.
539 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Cookies)) {
540 // Create a new browser just to ensure that the plugin process' child_id is
541 // not equal to its type (PROCESS_TYPE_PLUGIN), as that was the error which
542 // caused this bug.
543 NavigateToURL(CreateBrowser(), GURL("about:blank"));
545 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
546 GURL url(embedded_test_server()->GetURL("/npapi/cookies.html"));
548 TestResourceDispatcherHostDelegate test_delegate;
549 ResourceDispatcherHostDelegate* old_delegate =
550 ResourceDispatcherHostImpl::Get()->delegate();
551 ResourceDispatcherHostImpl::Get()->SetDelegate(&test_delegate);
552 LoadAndWait(url);
553 test_delegate.WaitForPluginRequest();
554 ASSERT_TRUE(test_delegate.found_cookie());
555 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate);
558 } // namespace content