browser_test_base.cc revision c2db58bd994c04d98e4ee2cd7565b71548655fe3
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/browser_test_base.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/stack_trace.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/main_function_params.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/test_utils.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h" 16c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "ui/compositor/compositor_switches.h" 17c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "ui/gl/gl_implementation.h" 18c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "ui/gl/gl_switches.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#if defined(OS_POSIX) 2158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process_handle.h" 2258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#endif 2358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h" 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/power_monitor/power_monitor_device_source.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_restrictions.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_main_runner.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(OS_CHROMEOS) 36c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "base/chromeos/chromeos_version.h" 37c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif 38c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On SIGTERM (sent by the runner on timeouts), dump a stack trace (to make 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// debugging easier) and also exit with a known error code (so that the test 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// framework considers this a failure -- http://crbug.com/57578). 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: We only want to do this in the browser process, and not forked 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// processes. That might lead to hangs because of locks inside tcmalloc or the 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OS. See http://crbug.com/141302. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int g_browser_process_pid; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void DumpStackTraceSignalHandler(int signal) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (g_browser_process_pid == base::GetCurrentProcId()) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) logging::RawLog(logging::LOG_ERROR, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "BrowserTestBase signal handler received SIGTERM. " 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Backtrace:\n"); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::StackTrace().PrintBacktrace(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _exit(128 + signal); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_POSIX) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RunTaskOnRendererThread(const base::Closure& task, 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& quit_task) { 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.Run(); 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern int BrowserMain(const MainFunctionParams&); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserTestBase::BrowserTestBase() 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : embedded_test_server_( 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new net::test_server::EmbeddedTestServer( 74c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))), 75c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_test_contexts_(true), 76c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_osmesa_(true) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::SetOverrideAmIBundled(true); 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::PowerMonitorDeviceSource::AllocateSystemIOPorts(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_sigterm_ = true; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserTestBase::~BrowserTestBase() { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // RemoteTestServer can cause wait on the UI thread. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_server_.reset(NULL); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserTestBase::SetUp() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The tests assume that file:// URIs can freely access other file:// URIs. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->AppendSwitch(switches::kDomAutomationController); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->AppendSwitch(switches::kSkipGpuDataLoading); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MainFunctionParams params(*command_line); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.ui_task = 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::Closure( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BrowserTestBase::ProxyRunTestOnMainThreadLoop, this)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(USE_AURA) 111c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Use test contexts for browser tests unless they override and force us to 112c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // use a real context. 113c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (allow_test_contexts_) 114c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch command_line->AppendSwitch(switches::kTestCompositor); 115c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif 116c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 117c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // When using real GL contexts, we usually use OSMesa as this works on all 118c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // bots. The command line can override this behaviour to use a real GPU. 119c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (command_line->HasSwitch(switches::kUseGpuInTests)) 120c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_osmesa_ = false; 121c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 122c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Some bots pass this flag when they want to use a real GPU. 123c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (command_line->HasSwitch("enable-gpu")) 124c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_osmesa_ = false; 125c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 126c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(OS_MACOSX) 127c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // On Mac we always use a real GPU. 128c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_osmesa_ = false; 129c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif 130c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 131c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(OS_ANDROID) 132c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // On Android we always use a real GPU. 133c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_osmesa_ = false; 134c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif 135c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 136c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(OS_CHROMEOS) 137c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // If the test is running on the chromeos envrionment (such as 138c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // device or vm bots), the compositor will use real GL contexts, and 139c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // we should use real GL bindings with it. 140c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (base::chromeos::IsRunningOnChromeOS()) 141c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch allow_osmesa_ = false; 142c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif 143c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 144c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (command_line->HasSwitch(switches::kUseGL)) { 145c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch NOTREACHED() << 146c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch "kUseGL should not be used with tests. Try kUseGpuInTests instead."; 147c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 148c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 149c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (allow_osmesa_) { 150c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch command_line->AppendSwitchASCII( 151c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch switches::kUseGL, gfx::kGLImplementationOSMesaName); 152c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 153c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetUpInProcessBrowserTestFixture(); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserMainRunner::Create()->Initialize(params); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We are done running the test by now. During teardown we 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // need to be able to perform IO. 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ThreadRestrictions::SetIOAllowed(true); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::IO, FROM_HERE, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserMain(params); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TearDownInProcessBrowserTestFixture(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserTestBase::TearDown() { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserTestBase::ProxyRunTestOnMainThreadLoop() { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle_sigterm_) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process_pid = base::GetCurrentProcId(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGTERM, DumpStackTraceSignalHandler); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_POSIX) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTestOnMainThreadLoop(); 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) embedded_test_server_.reset(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!test_server_.get()); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) test_server_.reset(new net::SpawnedTestServer( 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::SpawnedTestServer::TYPE_HTTP, 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::SpawnedTestServer::kLocalhost, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_server_base)); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserTestBase::PostTaskToInProcessRendererAndWait( 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& task) { 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop* renderer_loop = 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderProcessHostImpl::GetInProcessRendererThreadForTesting(); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(renderer_loop); 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) renderer_loop->PostTask( 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&RunTaskOnRendererThread, task, runner->QuitClosure())); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) runner->Run(); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 209