| // Copyright (c) 2010 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. |
| |
| #include "chrome/browser/ppapi_plugin_process_host.h" |
| |
| #include "base/command_line.h" |
| #include "base/file_path.h" |
| #include "base/process_util.h" |
| #include "chrome/browser/renderer_host/resource_message_filter.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/render_messages.h" |
| #include "ipc/ipc_channel_handle.h" |
| #include "ipc/ipc_switches.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| |
| PpapiPluginProcessHost::PpapiPluginProcessHost(ResourceMessageFilter* filter) |
| : BrowserChildProcessHost(ChildProcessInfo::PPAPI_PLUGIN_PROCESS, |
| filter->resource_dispatcher_host()), |
| filter_(filter) { |
| } |
| |
| PpapiPluginProcessHost::~PpapiPluginProcessHost() { |
| } |
| |
| void PpapiPluginProcessHost::Init(const FilePath& path, |
| IPC::Message* reply_msg) { |
| plugin_path_ = path; |
| reply_msg_.reset(reply_msg); |
| |
| if (!CreateChannel()) { |
| ReplyToRenderer(IPC::ChannelHandle()); |
| return; |
| } |
| |
| const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| CommandLine::StringType plugin_launcher = |
| browser_command_line.GetSwitchValueNative(switches::kPpapiPluginLauncher); |
| |
| FilePath exe_path = ChildProcessHost::GetChildPath(plugin_launcher.empty()); |
| if (exe_path.empty()) { |
| ReplyToRenderer(IPC::ChannelHandle()); |
| return; |
| } |
| |
| CommandLine* cmd_line = new CommandLine(exe_path); |
| cmd_line->AppendSwitchASCII(switches::kProcessType, |
| switches::kPpapiPluginProcess); |
| cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); |
| |
| if (!plugin_launcher.empty()) |
| cmd_line->PrependWrapper(plugin_launcher); |
| |
| // On posix, having a plugin launcher means we need to use another process |
| // instead of just forking the zygote. |
| Launch( |
| #if defined(OS_WIN) |
| FilePath(), |
| #elif defined(OS_POSIX) |
| plugin_launcher.empty(), |
| base::environment_vector(), |
| #endif |
| cmd_line); |
| } |
| |
| void PpapiPluginProcessHost::OnProcessLaunched() { |
| } |
| |
| URLRequestContext* PpapiPluginProcessHost::GetRequestContext( |
| uint32 request_id, |
| const ViewHostMsg_Resource_Request& request_data) { |
| return NULL; |
| } |
| |
| void PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| IPC_BEGIN_MESSAGE_MAP(PpapiPluginProcessHost, msg) |
| IPC_MESSAGE_HANDLER(PpapiHostMsg_PluginLoaded, OnPluginLoaded) |
| IPC_MESSAGE_UNHANDLED_ERROR(); |
| IPC_END_MESSAGE_MAP() |
| } |
| |
| void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) { |
| PpapiMsg_LoadPlugin* msg = new PpapiMsg_LoadPlugin(plugin_path_, |
| filter_->id()); |
| if (!Send(msg)) // Just send an empty handle on failure. |
| ReplyToRenderer(IPC::ChannelHandle()); |
| // This function will result in OnChannelCreated getting called to finish. |
| } |
| |
| void PpapiPluginProcessHost::OnChannelError() { |
| if (reply_msg_.get()) |
| ReplyToRenderer(IPC::ChannelHandle()); |
| } |
| |
| void PpapiPluginProcessHost::OnPluginLoaded(const IPC::ChannelHandle& handle) { |
| ReplyToRenderer(handle); |
| } |
| |
| void PpapiPluginProcessHost::ReplyToRenderer(const IPC::ChannelHandle& handle) { |
| DCHECK(reply_msg_.get()); |
| ViewHostMsg_OpenChannelToPepperPlugin::WriteReplyParams(reply_msg_.get(), |
| handle); |
| filter_->Send(reply_msg_.release()); |
| } |