Home | History | Annotate | Download | only in browser
      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/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"
     24 
     25 #if defined(OS_WIN)
     26 #include "base/win/registry.h"
     27 #endif
     28 
     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
     35 
     36 using base::ASCIIToUTF16;
     37 
     38 namespace content {
     39 namespace {
     40 
     41 void SetUrlRequestMock(const base::FilePath& path) {
     42   URLRequestMockHTTPJob::AddUrlHandler(path);
     43 }
     44 
     45 }
     46 
     47 class PluginTest : public ContentBrowserTest {
     48  protected:
     49   PluginTest() {}
     50 
     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");
     54 
     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);
     66       }
     67     }
     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
     76   }
     77 
     78   virtual void SetUpOnMainThread() OVERRIDE {
     79     base::FilePath path = GetTestFilePath("", "");
     80     BrowserThread::PostTask(
     81         BrowserThread::IO, FROM_HERE, base::Bind(&SetUrlRequestMock, path));
     82   }
     83 
     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);
     98     }
     99   }
    100 
    101   void LoadAndWait(const GURL& url) {
    102     LoadAndWaitInWindow(shell(), url);
    103   }
    104 
    105   GURL GetURL(const char* filename) {
    106     return GetTestUrl("npapi", filename);
    107   }
    108 
    109   void NavigateAway() {
    110     GURL url = GetTestUrl("", "simple_page.html");
    111     LoadAndWait(url);
    112   }
    113 
    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;
    122     }
    123 
    124     GURL url = GetTestUrl("plugin", filename);
    125     LoadAndWait(url);
    126   }
    127 };
    128 
    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();
    134 }
    135 
    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"));
    141 }
    142 
    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"));
    148 }
    149 
    150 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectReleasedOnDestruction)) {
    151   NavigateToURL(shell(), GetURL("npobject_released_on_destruction.html"));
    152   NavigateAway();
    153 }
    154 
    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"));
    161 }
    162 
    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"));
    171 
    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());
    178 }
    179 #endif
    180 
    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
    187 
    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);
    193 }
    194 
    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"));
    202 
    203   base::string16 expected_title(ASCIIToUTF16("OK"));
    204   TitleWatcher title_watcher(shell()->web_contents(), expected_title);
    205   title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
    206 
    207   WaitForAppModalDialog(shell());
    208 
    209   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    210 }
    211 
    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"));
    217 }
    218 #endif
    219 
    220 // Test invoking many plugins within a single page.
    221 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ManyPlugins)) {
    222   LoadAndWait(GetURL("many_plugins.html"));
    223 }
    224 
    225 // Test various calls to GetURL from a plugin.
    226 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURL)) {
    227   LoadAndWait(GetURL("geturl.html"));
    228 }
    229 
    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"));
    234 }
    235 
    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"));
    240 }
    241 
    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"));
    245 }
    246 
    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"));
    251 }
    252 
    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"));
    258 }
    259 
    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"));
    267 }
    268 #endif
    269 
    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"));
    275 }
    276 
    277 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNewStream)) {
    278   LoadAndWait(GetURL("self_delete_plugin_stream.html"));
    279 }
    280 
    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"));
    286 }
    287 #endif
    288 
    289 #if defined(OS_WIN)
    290 
    291 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyPluginWindowRect)) {
    292   LoadAndWait(GetURL("verify_plugin_window_rect.html"));
    293 }
    294 
    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"));
    299 }
    300 
    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"));
    304 
    305   WaitForAppModalDialog(shell());
    306   WaitForAppModalDialog(shell());
    307 }
    308 
    309 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyNPObjectLifetimeTest)) {
    310   LoadAndWait(GetURL("npobject_lifetime_test.html"));
    311 }
    312 
    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"));
    316 }
    317 
    318 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNPNEvaluate)) {
    319   LoadAndWait(GetURL("execute_script_delete_in_npn_evaluate.html"));
    320 }
    321 
    322 IN_PROC_BROWSER_TEST_F(PluginTest,
    323                        MAYBE(SelfDeleteCreatePluginInNPNEvaluate)) {
    324   LoadAndWait(GetURL("npn_plugin_delete_create_in_evaluate.html"));
    325 }
    326 
    327 #endif  // OS_WIN
    328 
    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"));
    337 }
    338 #endif
    339 
    340 // Test checking the privacy mode is off.
    341 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateDisabled)) {
    342   LoadAndWait(GetURL("private.html"));
    343 }
    344 
    345 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ScheduleTimer)) {
    346   LoadAndWait(GetURL("schedule_timer.html"));
    347 }
    348 
    349 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginThreadAsyncCall)) {
    350   LoadAndWait(GetURL("plugin_thread_async_call.html"));
    351 }
    352 
    353 IN_PROC_BROWSER_TEST_F(PluginTest, PluginSingleRangeRequest) {
    354   LoadAndWait(GetURL("plugin_single_range_request.html"));
    355 }
    356 
    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);
    363 }
    364 
    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"));
    370 }
    371 #endif
    372 
    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);
    378 }
    379 
    380 #if defined(OS_WIN)
    381 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(EnsureScriptingWorksInDestroy)) {
    382   LoadAndWait(GetURL("ensure_scripting_works_in_destroy.html"));
    383 }
    384 
    385 // This test uses a Windows Event to signal to the plugin that it should crash
    386 // on NP_Initialize.
    387 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NoHangIfInitCrashes)) {
    388   HANDLE crash_event = CreateEvent(NULL, TRUE, FALSE, L"TestPluginCrashOnInit");
    389   SetEvent(crash_event);
    390   LoadAndWait(GetURL("no_hang_if_init_crashes.html"));
    391   CloseHandle(crash_event);
    392 }
    393 #endif
    394 
    395 // If this flakes on Mac, use http://crbug.com/111508
    396 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginReferrerTest)) {
    397   GURL url(URLRequestMockHTTPJob::GetMockUrl(
    398       base::FilePath().AppendASCII("npapi").
    399                        AppendASCII("plugin_url_request_referrer_test.html")));
    400   LoadAndWait(url);
    401 }
    402 
    403 #if defined(OS_MACOSX)
    404 // Test is flaky, see http://crbug.com/134515.
    405 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_PluginConvertPointTest) {
    406   gfx::Rect bounds(50, 50, 400, 400);
    407   SetWindowBounds(shell()->window(), bounds);
    408 
    409   NavigateToURL(shell(), GetURL("convert_point.html"));
    410 
    411   base::string16 expected_title(ASCIIToUTF16("OK"));
    412   TitleWatcher title_watcher(shell()->web_contents(), expected_title);
    413   title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
    414   // TODO(stuartmorgan): When the automation system supports sending clicks,
    415   // change the test to trigger on mouse-down rather than window focus.
    416 
    417   // TODO: is this code still needed? It was here when it used to run in
    418   // browser_tests.
    419   //static_cast<WebContentsDelegate*>(shell())->
    420   //    ActivateContents(shell()->web_contents());
    421   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    422 }
    423 #endif
    424 
    425 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Flash)) {
    426   TestPlugin("flash.html");
    427 }
    428 
    429 #if defined(OS_WIN)
    430 // Windows only test
    431 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashSecurity) {
    432   TestPlugin("flash.html");
    433 }
    434 #endif  // defined(OS_WIN)
    435 
    436 #if defined(OS_WIN)
    437 // TODO(port) Port the following tests to platforms that have the required
    438 // plugins.
    439 // Flaky: http://crbug.com/55915
    440 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Quicktime)) {
    441   TestPlugin("quicktime.html");
    442 }
    443 
    444 // Disabled - http://crbug.com/44662
    445 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MediaPlayerNew)) {
    446   TestPlugin("wmp_new.html");
    447 }
    448 
    449 // Disabled - http://crbug.com/44673
    450 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Real)) {
    451   TestPlugin("real.html");
    452 }
    453 
    454 // http://crbug.com/320041
    455 #if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
    456     (defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN))
    457 #define MAYBE_FlashOctetStream DISABLED_FlashOctetStream
    458 #else
    459 #define MAYBE_FlashOctetStream FlashOctetStream
    460 #endif
    461 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_FlashOctetStream) {
    462   TestPlugin("flash-octet-stream.html");
    463 }
    464 
    465 #if defined(OS_WIN)
    466 // http://crbug.com/53926
    467 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashLayoutWhilePainting) {
    468 #else
    469 IN_PROC_BROWSER_TEST_F(PluginTest, FlashLayoutWhilePainting) {
    470 #endif
    471   TestPlugin("flash-layout-while-painting.html");
    472 }
    473 
    474 // http://crbug.com/8690
    475 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_Java) {
    476   TestPlugin("Java.html");
    477 }
    478 
    479 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Silverlight)) {
    480   TestPlugin("silverlight.html");
    481 }
    482 #endif  // defined(OS_WIN)
    483 
    484 class TestResourceDispatcherHostDelegate
    485     : public ResourceDispatcherHostDelegate {
    486  public:
    487   TestResourceDispatcherHostDelegate() : found_cookie_(false) {}
    488 
    489   bool found_cookie() { return found_cookie_; }
    490 
    491   void WaitForPluginRequest() {
    492     if (found_cookie_)
    493       return;
    494 
    495     runner_ = new MessageLoopRunner;
    496     runner_->Run();
    497   }
    498 
    499  private:
    500   // ResourceDispatcherHostDelegate implementation:
    501   virtual void OnResponseStarted(
    502       net::URLRequest* request,
    503       ResourceContext* resource_context,
    504       ResourceResponse* response,
    505       IPC::Sender* sender) OVERRIDE {
    506     // The URL below comes from plugin_geturl_test.cc.
    507     if (!EndsWith(request->url().spec(),
    508                  "npapi/plugin_ref_target_page.html",
    509                  true)) {
    510       return;
    511     }
    512     net::HttpRequestHeaders headers;
    513     bool found_cookie = false;
    514     if (request->GetFullRequestHeaders(&headers) &&
    515         headers.ToString().find("Cookie: blah") != std::string::npos) {
    516       found_cookie = true;
    517     }
    518     BrowserThread::PostTask(
    519         BrowserThread::UI,
    520         FROM_HERE,
    521         base::Bind(&TestResourceDispatcherHostDelegate::GotCookie,
    522                    base::Unretained(this), found_cookie));
    523   }
    524 
    525   void GotCookie(bool found_cookie) {
    526     found_cookie_ = found_cookie;
    527     if (runner_)
    528       runner_->QuitClosure().Run();
    529   }
    530 
    531   scoped_refptr<MessageLoopRunner> runner_;
    532   bool found_cookie_;
    533 
    534   DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
    535 };
    536 
    537 // Ensure that cookies get sent with plugin requests.
    538 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Cookies)) {
    539   // Create a new browser just to ensure that the plugin process' child_id is
    540   // not equal to its type (PROCESS_TYPE_PLUGIN), as that was the error which
    541   // caused this bug.
    542   NavigateToURL(CreateBrowser(), GURL("about:blank"));
    543 
    544   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    545   GURL url(embedded_test_server()->GetURL("/npapi/cookies.html"));
    546 
    547   TestResourceDispatcherHostDelegate test_delegate;
    548   ResourceDispatcherHostDelegate* old_delegate =
    549       ResourceDispatcherHostImpl::Get()->delegate();
    550   ResourceDispatcherHostImpl::Get()->SetDelegate(&test_delegate);
    551   LoadAndWait(url);
    552   test_delegate.WaitForPluginRequest();
    553   ASSERT_TRUE(test_delegate.found_cookie());
    554   ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate);
    555 }
    556 
    557 }  // namespace content
    558