diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-03 07:10:44 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-03 07:10:44 +0000 |
commit | 4734d0becafa5b77d708020eed24d97148ea208d (patch) | |
tree | db94ca97a1ac3f1831033ef07dbda98ccb53dfa6 /content | |
parent | 463ea5fc399e6275a2351df6b398b7d91b8f5a61 (diff) | |
download | chromium_src-4734d0becafa5b77d708020eed24d97148ea208d.zip chromium_src-4734d0becafa5b77d708020eed24d97148ea208d.tar.gz chromium_src-4734d0becafa5b77d708020eed24d97148ea208d.tar.bz2 |
Make ChildProcessHost be used through an interface in content/public, instead of by inheritence.
BUG=98716
Review URL: http://codereview.chromium.org/8787004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112878 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
19 files changed, 318 insertions, 234 deletions
diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc index 7744153..93c997b 100644 --- a/content/browser/browser_child_process_host.cc +++ b/content/browser/browser_child_process_host.cc @@ -17,7 +17,7 @@ #include "content/browser/profiler_message_filter.h" #include "content/browser/renderer_host/resource_message_filter.h" #include "content/browser/trace_message_filter.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" @@ -34,6 +34,8 @@ #endif using content::BrowserThread; +using content::ChildProcessHost; +using content::ChildProcessHostImpl; namespace { @@ -60,9 +62,9 @@ BrowserChildProcessHost::BrowserChildProcessHost( #endif disconnect_was_alive_(false) { data_.type = type; - data_.id = ChildProcessHost::GenerateChildProcessUniqueId(); + data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId(); - child_process_host_.reset(new ChildProcessHost(this)); + child_process_host_.reset(ChildProcessHost::Create(this)); child_process_host_->AddFilter(new TraceMessageFilter); child_process_host_->AddFilter(new ProfilerMessageFilter); @@ -98,7 +100,7 @@ void BrowserChildProcessHost::Launch( #elif defined(OS_POSIX) use_zygote, environ, - child_process_host()->channel()->TakeClientFileDescriptor(), + child_process_host()->TakeClientFileDescriptor(), #endif cmd_line, &client_)); diff --git a/content/browser/browser_child_process_host.h b/content/browser/browser_child_process_host.h index 2abb0bf..a4eca07 100644 --- a/content/browser/browser_child_process_host.h +++ b/content/browser/browser_child_process_host.h @@ -19,12 +19,14 @@ #include "content/public/common/child_process_host_delegate.h" #include "ipc/ipc_message.h" -class ChildProcessHost; - namespace base { class WaitableEvent; } +namespace content { +class ChildProcessHost; +} + // Plugins/workers and other child processes that live on the IO thread should // derive from this class. // @@ -122,7 +124,7 @@ class CONTENT_EXPORT BrowserChildProcessHost : // Sends the given notification on the UI thread. void Notify(int type); - ChildProcessHost* child_process_host() const { + content::ChildProcessHost* child_process_host() const { return child_process_host_.get(); } void set_name(const string16& name) { data_.name = name; } @@ -141,7 +143,7 @@ class CONTENT_EXPORT BrowserChildProcessHost : }; content::ChildProcessData data_; - scoped_ptr<ChildProcessHost> child_process_host_; + scoped_ptr<content::ChildProcessHost> child_process_host_; ClientHook client_; scoped_ptr<ChildProcessLauncher> child_process_; diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 3b18d38..9f0d735 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -17,7 +17,7 @@ #include "content/browser/gpu/gpu_process_host_ui_shim.h" #include "content/browser/renderer_host/render_widget_host.h" #include "content/browser/renderer_host/render_widget_host_view.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/gpu/gpu_messages.h" #include "content/gpu/gpu_child_thread.h" #include "content/gpu/gpu_process.h" @@ -35,6 +35,7 @@ #endif using content::BrowserThread; +using content::ChildProcessHost; bool GpuProcessHost::gpu_enabled_ = true; @@ -319,15 +320,15 @@ GpuProcessHost::~GpuProcessHost() { } bool GpuProcessHost::Init() { - if (!child_process_host()->CreateChannel()) + std::string channel_id = child_process_host()->CreateChannel(); + if (channel_id.empty()) return false; if (in_process_) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kDisableGpuWatchdog); - in_process_gpu_thread_.reset(new GpuMainThread( - child_process_host()->channel_id())); + in_process_gpu_thread_.reset(new GpuMainThread(channel_id)); base::Thread::Options options; #if defined(OS_WIN) @@ -343,7 +344,7 @@ bool GpuProcessHost::Init() { in_process_gpu_thread_->StartWithOptions(options); OnProcessLaunched(); // Fake a callback that the process is ready. - } else if (!LaunchGpuProcess()) + } else if (!LaunchGpuProcess(channel_id)) return false; return Send(new GpuMsg_Initialize()); @@ -358,7 +359,7 @@ void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { bool GpuProcessHost::Send(IPC::Message* msg) { DCHECK(CalledOnValidThread()); - if (child_process_host()->opening_channel()) { + if (child_process_host()->IsChannelOpening()) { queued_messages_.push(msg); return true; } @@ -543,7 +544,7 @@ bool GpuProcessHost::software_rendering() { return software_rendering_; } -bool GpuProcessHost::LaunchGpuProcess() { +bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { if (!gpu_enabled_ || g_gpu_crash_count >= kGpuMaxCrashCount) { SendOutstandingReplies(); gpu_enabled_ = false; @@ -568,8 +569,7 @@ bool GpuProcessHost::LaunchGpuProcess() { CommandLine* cmd_line = new CommandLine(exe_path); cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); - cmd_line->AppendSwitchASCII(switches::kProcessChannelID, - child_process_host()->channel_id()); + cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); // Propagate relevant command line switches. static const char* const kSwitchNames[] = { diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 073e8fd..479ebae 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -102,7 +102,7 @@ class GpuProcessHost : public BrowserChildProcessHost, gfx::PluginWindowHandle window, int32 renderer_id, int32 render_view_id); void OnGraphicsInfoCollected(const content::GPUInfo& gpu_info); - bool LaunchGpuProcess(); + bool LaunchGpuProcess(const std::string& channel_id); void SendOutstandingReplies(); void EstablishChannelError( diff --git a/content/browser/plugin_data_remover_impl.cc b/content/browser/plugin_data_remover_impl.cc index 38489d5..c41e913 100644 --- a/content/browser/plugin_data_remover_impl.cc +++ b/content/browser/plugin_data_remover_impl.cc @@ -10,12 +10,13 @@ #include "base/version.h" #include "content/browser/plugin_process_host.h" #include "content/browser/plugin_service.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_thread.h" #include "webkit/plugins/npapi/plugin_group.h" using content::BrowserThread; +using content::ChildProcessHostImpl; namespace { @@ -93,7 +94,7 @@ class PluginDataRemoverImpl::Context // PluginProcessHost::Client methods. virtual int ID() OVERRIDE { // Generate a unique identifier for this PluginProcessHostClient. - return ChildProcessHost::GenerateChildProcessUniqueId(); + return ChildProcessHostImpl::GenerateChildProcessUniqueId(); } virtual bool OffTheRecord() OVERRIDE { diff --git a/content/browser/plugin_loader_posix.cc b/content/browser/plugin_loader_posix.cc index bc96427..26fe95e 100644 --- a/content/browser/plugin_loader_posix.cc +++ b/content/browser/plugin_loader_posix.cc @@ -8,12 +8,13 @@ #include "base/message_loop.h" #include "base/message_loop_proxy.h" #include "base/metrics/histogram.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/utility_messages.h" #include "content/public/browser/browser_thread.h" #include "webkit/plugins/npapi/plugin_list.h" using content::BrowserThread; +using content::ChildProcessHost; PluginLoaderPosix::PluginLoaderPosix() : next_load_index_(0) { diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index 293072d..4989477 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -22,7 +22,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "content/browser/plugin_service.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/common/resource_messages.h" #include "content/public/browser/browser_thread.h" @@ -36,6 +36,7 @@ #include "ui/gfx/native_widget_types.h" using content::BrowserThread; +using content::ChildProcessHost; #if defined(USE_X11) #include "ui/gfx/gtk_native_view_id_manager.h" @@ -168,7 +169,8 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info, info_ = info; set_name(info_.name); - if (!child_process_host()->CreateChannel()) + std::string channel_id = child_process_host()->CreateChannel(); + if (channel_id.empty()) return false; // Build command line for plugin. When we have a plugin launcher, we can't @@ -235,8 +237,7 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info, cmd_line->AppendSwitchASCII(switches::kLang, locale); } - cmd_line->AppendSwitchASCII(switches::kProcessChannelID, - child_process_host()->channel_id()); + cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); #if defined(OS_POSIX) base::environment_vector env; @@ -366,7 +367,7 @@ void PluginProcessHost::CancelPendingRequestsForResourceContext( void PluginProcessHost::OpenChannelToPlugin(Client* client) { Notify(content::NOTIFICATION_CHILD_INSTANCE_CREATED); client->SetPluginInfo(info_); - if (child_process_host()->opening_channel()) { + if (child_process_host()->IsChannelOpening()) { // The channel is already in the process of being opened. Put // this "open channel" request into a queue of requests that will // be run once the channel is open. diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index f4ccd33..f633842 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc @@ -11,7 +11,7 @@ #include "base/utf_string_conversions.h" #include "content/browser/plugin_service.h" #include "content/browser/renderer_host/render_message_filter.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/child_process_messages.h" #include "content/public/common/content_switches.h" #include "content/public/common/pepper_plugin_info.h" @@ -20,6 +20,9 @@ #include "net/base/network_change_notifier.h" #include "ppapi/proxy/ppapi_messages.h" +using content::ChildProcessHost; +using content::ChildProcessHostImpl; + class PpapiPluginProcessHost::PluginNetworkObserver : public net::NetworkChangeNotifier::IPAddressObserver, public net::NetworkChangeNotifier::OnlineStateObserver { @@ -85,7 +88,7 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreateBrokerHost( } void PpapiPluginProcessHost::OpenChannelToPlugin(Client* client) { - if (child_process_host()->opening_channel()) { + if (child_process_host()->IsChannelOpening()) { // The channel is already in the process of being opened. Put // this "open channel" request into a queue of requests that will // be run once the channel is open. @@ -102,14 +105,14 @@ PpapiPluginProcessHost::PpapiPluginProcessHost(net::HostResolver* host_resolver) filter_(new PepperMessageFilter(host_resolver)), network_observer_(new PluginNetworkObserver(this)), is_broker_(false), - process_id_(ChildProcessHost::GenerateChildProcessUniqueId()) { + process_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()) { child_process_host()->AddFilter(filter_.get()); } PpapiPluginProcessHost::PpapiPluginProcessHost() : BrowserChildProcessHost(content::PROCESS_TYPE_PPAPI_BROKER), is_broker_(true), - process_id_(ChildProcessHost::GenerateChildProcessUniqueId()) { + process_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()) { } bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) { @@ -120,7 +123,8 @@ bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) { set_name(UTF8ToUTF16(info.name)); } - if (!child_process_host()->CreateChannel()) + std::string channel_id = child_process_host()->CreateChannel(); + if (channel_id.empty()) return false; const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); @@ -141,8 +145,7 @@ bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) { cmd_line->AppendSwitchASCII(switches::kProcessType, is_broker_ ? switches::kPpapiBrokerProcess : switches::kPpapiPluginProcess); - cmd_line->AppendSwitchASCII(switches::kProcessChannelID, - child_process_host()->channel_id()); + cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); // These switches are forwarded to both plugin and broker pocesses. static const char* kCommonForwardSwitches[] = { diff --git a/content/browser/renderer_host/mock_render_process_host.cc b/content/browser/renderer_host/mock_render_process_host.cc index bc0d9d8..9f3bca7 100644 --- a/content/browser/renderer_host/mock_render_process_host.cc +++ b/content/browser/renderer_host/mock_render_process_host.cc @@ -9,16 +9,18 @@ #include "base/time.h" #include "content/browser/child_process_security_policy.h" #include "content/browser/renderer_host/render_process_host_impl.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" +using content::ChildProcessHostImpl; + MockRenderProcessHost::MockRenderProcessHost( content::BrowserContext* browser_context) : transport_dib_(NULL), bad_msg_count_(0), factory_(NULL), - id_(ChildProcessHost::GenerateChildProcessUniqueId()), + id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), browser_context_(browser_context), max_page_id_(-1), fast_shutdown_started_(false) { diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index f84b968..fe937b2 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -29,7 +29,7 @@ #include "content/browser/renderer_host/render_widget_helper.h" #include "content/browser/resource_context.h" #include "content/browser/user_metrics.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/child_process_messages.h" #include "content/common/desktop_notification_messages.h" #include "content/common/view_messages.h" @@ -67,6 +67,7 @@ #endif using content::BrowserThread; +using content::ChildProcessHostImpl; using content::PluginServiceFilter; using net::CookieStore; @@ -686,7 +687,8 @@ void RenderMessageFilter::OnCheckNotificationPermission( void RenderMessageFilter::OnAllocateSharedMemory( uint32 buffer_size, base::SharedMemoryHandle* handle) { - ChildProcessHost::AllocateSharedMemory(buffer_size, peer_handle(), handle); + ChildProcessHostImpl::AllocateSharedMemory( + buffer_size, peer_handle(), handle); } net::URLRequestContext* RenderMessageFilter::GetRequestContextForURL( diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 4f05460..009b731 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -78,7 +78,7 @@ #include "content/browser/user_metrics.h" #include "content/browser/webui/web_ui_factory.h" #include "content/browser/worker_host/worker_message_filter.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/child_process_messages.h" #include "content/common/gpu/gpu_messages.h" #include "content/public/browser/notification_service.h" @@ -112,6 +112,8 @@ #include "third_party/skia/include/core/SkBitmap.h" using content::BrowserThread; +using content::ChildProcessHost; +using content::ChildProcessHostImpl; // This class creates the IO thread for the renderer when running in // single-process mode. It's not used in multi-process mode. @@ -283,7 +285,7 @@ RenderProcessHostImpl::RenderProcessHostImpl( this, &RenderProcessHostImpl::ClearTransportDIBCache)), accessibility_enabled_(false), is_initialized_(false), - id_(ChildProcessHost::GenerateChildProcessUniqueId()), + id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), browser_context_(browser_context), sudden_termination_allowed_(true), ignore_input_events_(false) { @@ -387,7 +389,7 @@ bool RenderProcessHostImpl::Init(bool is_accessibility_enabled) { // Setup the IPC channel. const std::string channel_id = - ChildProcessHost::GenerateRandomChannelID(this); + ChildProcessHostImpl::GenerateRandomChannelID(this); channel_.reset(new IPC::ChannelProxy( channel_id, IPC::Channel::MODE_SERVER, this, BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))); diff --git a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc index ae610be..5c216fa 100644 --- a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc @@ -21,7 +21,7 @@ #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" #include "content/browser/renderer_host/resource_handler.h" #include "content/browser/renderer_host/resource_message_filter.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/resource_messages.h" #include "content/common/view_messages.h" #include "content/public/common/resource_response.h" @@ -36,6 +36,7 @@ using content::BrowserThread; using content::BrowserThreadImpl; +using content::ChildProcessHostImpl; // TODO(eroman): Write unit tests for SafeBrowsing that exercise // SafeBrowsingResourceHandler. @@ -162,7 +163,7 @@ class ForwardingFilter : public ResourceMessageFilter { public: explicit ForwardingFilter(IPC::Message::Sender* dest) : ResourceMessageFilter( - ChildProcessHost::GenerateChildProcessUniqueId(), + ChildProcessHostImpl::GenerateChildProcessUniqueId(), content::PROCESS_TYPE_RENDERER, content::MockResourceContext::GetInstance(), new MockURLRequestContextSelector( diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index 8bc2234..998f8a5 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc @@ -9,7 +9,7 @@ #include "base/command_line.h" #include "base/message_loop.h" #include "base/utf_string_conversions.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/utility_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_switches.h" @@ -18,6 +18,7 @@ #include "webkit/plugins/plugin_switches.h" using content::BrowserThread; +using content::ChildProcessHost; UtilityProcessHost::Client::Client() { } @@ -87,7 +88,8 @@ bool UtilityProcessHost::StartProcess() { // launches a UtilityProcessHost. set_name(ASCIIToUTF16("utility process")); - if (!child_process_host()->CreateChannel()) + std::string channel_id = child_process_host()->CreateChannel(); + if (channel_id.empty()) return false; FilePath exe_path = GetUtilityProcessCmd(); @@ -99,8 +101,7 @@ bool UtilityProcessHost::StartProcess() { CommandLine* cmd_line = new CommandLine(exe_path); cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kUtilityProcess); - cmd_line->AppendSwitchASCII(switches::kProcessChannelID, - child_process_host()->channel_id()); + cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); std::string locale = content::GetContentClient()->browser()->GetApplicationLocale(); cmd_line->AppendSwitchASCII(switches::kLang, locale); diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc index 68d75c9..178de54 100644 --- a/content/browser/worker_host/worker_process_host.cc +++ b/content/browser/worker_host/worker_process_host.cc @@ -31,7 +31,7 @@ #include "content/browser/worker_host/message_port_service.h" #include "content/browser/worker_host/worker_message_filter.h" #include "content/browser/worker_host/worker_service.h" -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include "content/common/debug_flags.h" #include "content/common/view_messages.h" #include "content/common/worker_messages.h" @@ -49,6 +49,7 @@ #include "webkit/glue/resource_type.h" using content::BrowserThread; +using content::ChildProcessHost; namespace { @@ -112,7 +113,8 @@ WorkerProcessHost::~WorkerProcessHost() { } bool WorkerProcessHost::Init(int render_process_id) { - if (!child_process_host()->CreateChannel()) + std::string channel_id = child_process_host()->CreateChannel(); + if (channel_id.empty()) return false; #if defined(OS_LINUX) @@ -127,8 +129,7 @@ bool WorkerProcessHost::Init(int render_process_id) { CommandLine* cmd_line = new CommandLine(exe_path); cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess); - cmd_line->AppendSwitchASCII(switches::kProcessChannelID, - child_process_host()->channel_id()); + cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); std::string locale = content::GetContentClient()->browser()->GetApplicationLocale(); cmd_line->AppendSwitchASCII(switches::kLang, locale); diff --git a/content/common/child_process_host.h b/content/common/child_process_host.h deleted file mode 100644 index 7f044f4..0000000 --- a/content/common/child_process_host.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_CHILD_PROCESS_HOST_H_ -#define CONTENT_COMMON_CHILD_PROCESS_HOST_H_ -#pragma once - -#include <string> -#include <vector> - -#include "build/build_config.h" - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/singleton.h" -#include "base/shared_memory.h" -#include "base/string16.h" -#include "content/common/content_export.h" -#include "ipc/ipc_channel_proxy.h" - -class FilePath; - -namespace content { -class ChildProcessHostDelegate; -} - -// Provides common functionality for hosting a child process and processing IPC -// messages between the host and the child process. Users are responsible -// for the actual launching and terminating of the child processes. -class CONTENT_EXPORT ChildProcessHost : public IPC::Channel::Listener, - public IPC::Message::Sender { - public: - // These flags may be passed to GetChildPath in order to alter its behavior, - // causing it to return a child path more suited to a specific task. - enum { - // No special behavior requested. - CHILD_NORMAL = 0, - -#if defined(OS_LINUX) - // Indicates that the child execed after forking may be execced from - // /proc/self/exe rather than using the "real" app path. This prevents - // autoupdate from confusing us if it changes the file out from under us. - // You will generally want to set this on Linux, except when there is an - // override to the command line (for example, we're forking a renderer in - // gdb). In this case, you'd use GetChildPath to get the real executable - // file name, and then prepend the GDB command to the command line. - CHILD_ALLOW_SELF = 1 << 0, -#elif defined(OS_MACOSX) - - // Requests that the child run in a process that does not have the - // PIE (position-independent executable) bit set, effectively disabling - // ASLR. For process types that need to allocate a large contiguous - // region, ASLR may not leave a large enough "hole" for the purpose. This - // option should be used sparingly, and only when absolutely necessary. - // This option is currently incompatible with CHILD_ALLOW_HEAP_EXECUTION. - CHILD_NO_PIE = 1 << 1, - - // Requests that the child run in a process that does not protect the - // heap against execution. Normally, heap pages may be made executable - // with mprotect, so this mode should be used sparingly. It is intended - // for processes that may host plug-ins that expect an executable heap - // without having to call mprotect. This option is currently incompatible - // with CHILD_NO_PIE. - CHILD_ALLOW_HEAP_EXECUTION = 1 << 2, -#endif - }; - - virtual ~ChildProcessHost(); - - // Returns the pathname to be used for a child process. If a subprocess - // pathname was specified on the command line, that will be used. Otherwise, - // the default child process pathname will be returned. On most platforms, - // this will be the same as the currently-executing process. - // - // The |flags| argument accepts one or more flags such as CHILD_ALLOW_SELF - // and CHILD_ALLOW_HEAP_EXECUTION as defined above. Pass only CHILD_NORMAL - // if none of these special behaviors are required. - // - // On failure, returns an empty FilePath. - static FilePath GetChildPath(int flags); - - explicit ChildProcessHost(content::ChildProcessHostDelegate* delegate); - - // IPC::Message::Sender implementation. - virtual bool Send(IPC::Message* message) OVERRIDE; - - // Adds an IPC message filter. A reference will be kept to the filter. - void AddFilter(IPC::ChannelProxy::MessageFilter* filter); - - // Public and static for reuse by RenderMessageFilter. - static void AllocateSharedMemory( - uint32 buffer_size, base::ProcessHandle child_process, - base::SharedMemoryHandle* handle); - - // Generates a unique channel name for a child process. - // The "instance" pointer value is baked into the channel id. - static std::string GenerateRandomChannelID(void* instance); - - // Returns a unique ID to identify a child process. On construction, this - // function will be used to generate the id_, but it is also used to generate - // IDs for the RenderProcessHost, which doesn't inherit from us, and whose IDs - // must be unique for all child processes. - // - // This function is threadsafe since RenderProcessHost is on the UI thread, - // but normally this will be used on the IO thread. - static int GenerateChildProcessUniqueId(); - - // Send the shutdown message to the child process. - // Does not check if CanShutdown is true. - void ForceShutdown(); - - // Creates the IPC channel. Returns true iff it succeeded. - bool CreateChannel(); - - bool opening_channel() { return opening_channel_; } - const std::string& channel_id() { return channel_id_; } - IPC::Channel* channel() { return channel_.get(); } - - private: - // IPC::Channel::Listener methods: - virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - - // Message handlers: - void OnShutdownRequest(); - void OnAllocateSharedMemory(uint32 buffer_size, - base::SharedMemoryHandle* handle); - - content::ChildProcessHostDelegate* delegate_; - base::ProcessHandle peer_handle_; - bool opening_channel_; // True while we're waiting the channel to be opened. - scoped_ptr<IPC::Channel> channel_; - std::string channel_id_; - - // Holds all the IPC message filters. Since this object lives on the IO - // thread, we don't have a IPC::ChannelProxy and so we manage filters - // manually. - std::vector<scoped_refptr<IPC::ChannelProxy::MessageFilter> > filters_; - - DISALLOW_COPY_AND_ASSIGN(ChildProcessHost); -}; - -#endif // CONTENT_COMMON_CHILD_PROCESS_HOST_H_ diff --git a/content/common/child_process_host.cc b/content/common/child_process_host_impl.cc index 002e016..1e332ce 100644 --- a/content/common/child_process_host.cc +++ b/content/common/child_process_host_impl.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/child_process_host.h" +#include "content/common/child_process_host_impl.h" #include <limits> @@ -74,29 +74,11 @@ FilePath TransformPathForFeature(const FilePath& path, } // namespace #endif // OS_MACOSX -ChildProcessHost::ChildProcessHost(content::ChildProcessHostDelegate* delegate) - : delegate_(delegate), - peer_handle_(base::kNullProcessHandle), - opening_channel_(false) { -#if defined(OS_WIN) - AddFilter(new FontCacheDispatcher()); -#endif -} +namespace content { -ChildProcessHost::~ChildProcessHost() { - for (size_t i = 0; i < filters_.size(); ++i) { - filters_[i]->OnChannelClosing(); - filters_[i]->OnFilterRemoved(); - } - - base::CloseProcessHandle(peer_handle_); -} - -void ChildProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { - filters_.push_back(filter); - - if (channel_.get()) - filter->OnFilterAdded(channel_.get()); +// static +ChildProcessHost* ChildProcessHost::Create(ChildProcessHostDelegate* delegate) { + return new ChildProcessHostImpl(delegate); } // static @@ -143,16 +125,41 @@ FilePath ChildProcessHost::GetChildPath(int flags) { return child_path; } -void ChildProcessHost::ForceShutdown() { +ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate) + : delegate_(delegate), + peer_handle_(base::kNullProcessHandle), + opening_channel_(false) { +#if defined(OS_WIN) + AddFilter(new FontCacheDispatcher()); +#endif +} + +ChildProcessHostImpl::~ChildProcessHostImpl() { + for (size_t i = 0; i < filters_.size(); ++i) { + filters_[i]->OnChannelClosing(); + filters_[i]->OnFilterRemoved(); + } + + base::CloseProcessHandle(peer_handle_); +} + +void ChildProcessHostImpl::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { + filters_.push_back(filter); + + if (channel_.get()) + filter->OnFilterAdded(channel_.get()); +} + +void ChildProcessHostImpl::ForceShutdown() { Send(new ChildProcessMsg_Shutdown()); } -bool ChildProcessHost::CreateChannel() { +std::string ChildProcessHostImpl::CreateChannel() { channel_id_ = GenerateRandomChannelID(this); channel_.reset(new IPC::Channel( channel_id_, IPC::Channel::MODE_SERVER, this)); if (!channel_->Connect()) - return false; + return std::string(); for (size_t i = 0; i < filters_.size(); ++i) filters_[i]->OnFilterAdded(channel_.get()); @@ -167,10 +174,20 @@ bool ChildProcessHost::CreateChannel() { opening_channel_ = true; - return true; + return channel_id_; } -bool ChildProcessHost::Send(IPC::Message* message) { +bool ChildProcessHostImpl::IsChannelOpening() { + return opening_channel_; +} + +#if defined(OS_POSIX) +int ChildProcessHostImpl::TakeClientFileDescriptor() { + return channel_->TakeClientFileDescriptor(); +} +#endif + +bool ChildProcessHostImpl::Send(IPC::Message* message) { if (!channel_.get()) { delete message; return false; @@ -178,7 +195,7 @@ bool ChildProcessHost::Send(IPC::Message* message) { return channel_->Send(message); } -void ChildProcessHost::AllocateSharedMemory( +void ChildProcessHostImpl::AllocateSharedMemory( uint32 buffer_size, base::ProcessHandle child_process_handle, base::SharedMemoryHandle* shared_memory_handle) { base::SharedMemory shared_buf; @@ -190,7 +207,7 @@ void ChildProcessHost::AllocateSharedMemory( shared_buf.GiveToProcess(child_process_handle, shared_memory_handle); } -std::string ChildProcessHost::GenerateRandomChannelID(void* instance) { +std::string ChildProcessHostImpl::GenerateRandomChannelID(void* instance) { // Note: the string must start with the current process id, this is how // child processes determine the pid of the parent. // Build the channel ID. This is composed of a unique identifier for the @@ -202,13 +219,13 @@ std::string ChildProcessHost::GenerateRandomChannelID(void* instance) { base::RandInt(0, std::numeric_limits<int>::max())); } -int ChildProcessHost::GenerateChildProcessUniqueId() { +int ChildProcessHostImpl::GenerateChildProcessUniqueId() { // This function must be threadsafe. static base::subtle::Atomic32 last_unique_child_id = 0; return base::subtle::NoBarrier_AtomicIncrement(&last_unique_child_id, 1); } -bool ChildProcessHost::OnMessageReceived(const IPC::Message& msg) { +bool ChildProcessHostImpl::OnMessageReceived(const IPC::Message& msg) { #ifdef IPC_MESSAGE_LOG_ENABLED IPC::Logging* logger = IPC::Logging::GetInstance(); if (msg.type() == IPC_LOGGING_ID) { @@ -230,7 +247,7 @@ bool ChildProcessHost::OnMessageReceived(const IPC::Message& msg) { if (!handled) { handled = true; - IPC_BEGIN_MESSAGE_MAP(ChildProcessHost, msg) + IPC_BEGIN_MESSAGE_MAP(ChildProcessHostImpl, msg) IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest, OnShutdownRequest) IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory, @@ -249,7 +266,7 @@ bool ChildProcessHost::OnMessageReceived(const IPC::Message& msg) { return handled; } -void ChildProcessHost::OnChannelConnected(int32 peer_pid) { +void ChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) { NOTREACHED(); } @@ -259,7 +276,7 @@ void ChildProcessHost::OnChannelConnected(int32 peer_pid) { filters_[i]->OnChannelConnected(peer_pid); } -void ChildProcessHost::OnChannelError() { +void ChildProcessHostImpl::OnChannelError() { opening_channel_ = false; delegate_->OnChannelError(); @@ -270,13 +287,15 @@ void ChildProcessHost::OnChannelError() { delegate_->OnChildDisconnected(); } -void ChildProcessHost::OnAllocateSharedMemory( +void ChildProcessHostImpl::OnAllocateSharedMemory( uint32 buffer_size, base::SharedMemoryHandle* handle) { AllocateSharedMemory(buffer_size, peer_handle_, handle); } -void ChildProcessHost::OnShutdownRequest() { +void ChildProcessHostImpl::OnShutdownRequest() { if (delegate_->CanShutdown()) Send(new ChildProcessMsg_Shutdown()); } + +} // namespace content diff --git a/content/common/child_process_host_impl.h b/content/common/child_process_host_impl.h new file mode 100644 index 0000000..32736f3 --- /dev/null +++ b/content/common/child_process_host_impl.h @@ -0,0 +1,93 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_CHILD_PROCESS_HOST_IMPL_H_ +#define CONTENT_COMMON_CHILD_PROCESS_HOST_IMPL_H_ +#pragma once + +#include <string> +#include <vector> + +#include "build/build_config.h" + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/singleton.h" +#include "base/shared_memory.h" +#include "base/string16.h" +#include "content/public/common/child_process_host.h" + +class FilePath; + +namespace content { +class ChildProcessHostDelegate; + +// Provides common functionality for hosting a child process and processing IPC +// messages between the host and the child process. Users are responsible +// for the actual launching and terminating of the child processes. +class CONTENT_EXPORT ChildProcessHostImpl : public ChildProcessHost, + public IPC::Channel::Listener { + public: + virtual ~ChildProcessHostImpl(); + + // Public and static for reuse by RenderMessageFilter. + static void AllocateSharedMemory( + uint32 buffer_size, base::ProcessHandle child_process, + base::SharedMemoryHandle* handle); + + // Generates a unique channel name for a child process. + // The "instance" pointer value is baked into the channel id. + static std::string GenerateRandomChannelID(void* instance); + + // Returns a unique ID to identify a child process. On construction, this + // function will be used to generate the id_, but it is also used to generate + // IDs for the RenderProcessHost, which doesn't inherit from us, and whose IDs + // must be unique for all child processes. + // + // This function is threadsafe since RenderProcessHost is on the UI thread, + // but normally this will be used on the IO thread. + static int GenerateChildProcessUniqueId(); + + // ChildProcessHost implementation + virtual bool Send(IPC::Message* message) OVERRIDE; + virtual void ForceShutdown() OVERRIDE; + virtual std::string CreateChannel() OVERRIDE; + virtual bool IsChannelOpening() OVERRIDE; + virtual void AddFilter(IPC::ChannelProxy::MessageFilter* filter) OVERRIDE; +#if defined(OS_POSIX) + virtual int TakeClientFileDescriptor() OVERRIDE; +#endif + + private: + friend class ChildProcessHost; + + explicit ChildProcessHostImpl(ChildProcessHostDelegate* delegate); + + // IPC::Channel::Listener methods: + virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + virtual void OnChannelError() OVERRIDE; + + // Message handlers: + void OnShutdownRequest(); + void OnAllocateSharedMemory(uint32 buffer_size, + base::SharedMemoryHandle* handle); + + ChildProcessHostDelegate* delegate_; + base::ProcessHandle peer_handle_; + bool opening_channel_; // True while we're waiting the channel to be opened. + scoped_ptr<IPC::Channel> channel_; + std::string channel_id_; + + // Holds all the IPC message filters. Since this object lives on the IO + // thread, we don't have a IPC::ChannelProxy and so we manage filters + // manually. + std::vector<scoped_refptr<IPC::ChannelProxy::MessageFilter> > filters_; + + DISALLOW_COPY_AND_ASSIGN(ChildProcessHostImpl); +}; + +} // namespace content + +#endif // CONTENT_COMMON_CHILD_PROCESS_HOST_IMPL_H_ diff --git a/content/content_common.gypi b/content/content_common.gypi index a9bdb55..29f17a2 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -29,6 +29,7 @@ ], 'sources': [ 'public/common/bindings_policy.h', + 'public/common/child_process_host.h', 'public/common/child_process_host_delegate.h', 'public/common/child_process_sandbox_support_linux.h', 'public/common/content_constants.cc', @@ -82,8 +83,8 @@ 'common/appcache_messages.h', 'common/child_process.cc', 'common/child_process.h', - 'common/child_process_host.cc', - 'common/child_process_host.h', + 'common/child_process_host_impl.cc', + 'common/child_process_host_impl.h', 'common/child_process_messages.h', 'common/child_process_sandbox_support_impl_linux.cc', 'common/child_process_sandbox_support_impl_linux.h', diff --git a/content/public/common/child_process_host.h b/content/public/common/child_process_host.h new file mode 100644 index 0000000..31839fc --- /dev/null +++ b/content/public/common/child_process_host.h @@ -0,0 +1,97 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_H_ +#define CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_H_ +#pragma once + +#include "build/build_config.h" +#include "content/common/content_export.h" +#include "ipc/ipc_channel_proxy.h" + +class FilePath; + +namespace content { + +class ChildProcessHostDelegate; + +// Interface that all users of ChildProcessHost need to provide. +class ChildProcessHost : public IPC::Message::Sender { + public: + virtual ~ChildProcessHost() {} + + // Used to create a child process host. The delegate must outlive this object. + CONTENT_EXPORT static ChildProcessHost* Create( + ChildProcessHostDelegate* delegate); + + // These flags may be passed to GetChildPath in order to alter its behavior, + // causing it to return a child path more suited to a specific task. + enum { + // No special behavior requested. + CHILD_NORMAL = 0, + +#if defined(OS_LINUX) + // Indicates that the child execed after forking may be execced from + // /proc/self/exe rather than using the "real" app path. This prevents + // autoupdate from confusing us if it changes the file out from under us. + // You will generally want to set this on Linux, except when there is an + // override to the command line (for example, we're forking a renderer in + // gdb). In this case, you'd use GetChildPath to get the real executable + // file name, and then prepend the GDB command to the command line. + CHILD_ALLOW_SELF = 1 << 0, +#elif defined(OS_MACOSX) + + // Requests that the child run in a process that does not have the + // PIE (position-independent executable) bit set, effectively disabling + // ASLR. For process types that need to allocate a large contiguous + // region, ASLR may not leave a large enough "hole" for the purpose. This + // option should be used sparingly, and only when absolutely necessary. + // This option is currently incompatible with CHILD_ALLOW_HEAP_EXECUTION. + CHILD_NO_PIE = 1 << 1, + + // Requests that the child run in a process that does not protect the + // heap against execution. Normally, heap pages may be made executable + // with mprotect, so this mode should be used sparingly. It is intended + // for processes that may host plug-ins that expect an executable heap + // without having to call mprotect. This option is currently incompatible + // with CHILD_NO_PIE. + CHILD_ALLOW_HEAP_EXECUTION = 1 << 2, +#endif + }; + + // Returns the pathname to be used for a child process. If a subprocess + // pathname was specified on the command line, that will be used. Otherwise, + // the default child process pathname will be returned. On most platforms, + // this will be the same as the currently-executing process. + // + // The |flags| argument accepts one or more flags such as CHILD_ALLOW_SELF + // and CHILD_ALLOW_HEAP_EXECUTION as defined above. Pass only CHILD_NORMAL + // if none of these special behaviors are required. + // + // On failure, returns an empty FilePath. + CONTENT_EXPORT static FilePath GetChildPath(int flags); + + // Send the shutdown message to the child process. + // Does not check with the delegate's CanShutdown. + virtual void ForceShutdown() = 0; + + // Creates the IPC channel. Returns the channel id if it succeeded, an + // empty string otherwise + virtual std::string CreateChannel() = 0; + + // Returns true iff the IPC channel is currently being opened; + virtual bool IsChannelOpening() = 0; + + // Adds an IPC message filter. A reference will be kept to the filter. + virtual void AddFilter(IPC::ChannelProxy::MessageFilter* filter) = 0; + +#if defined(OS_POSIX) + // See IPC::Channel::TakeClientFileDescriptor. + virtual int TakeClientFileDescriptor() = 0; +#endif +}; + +}; // namespace content + +#endif // CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_H_ |