summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-21 23:07:04 +0000
committerbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-21 23:07:04 +0000
commite46177921cafffdf8d911d92388f6d3b66483817 (patch)
tree7857dafa96f2eb9b76e1a013a875abc9d1120ac0
parenta86c93c574d51e430b89b41a18f72924614ade6e (diff)
downloadchromium_src-e46177921cafffdf8d911d92388f6d3b66483817.zip
chromium_src-e46177921cafffdf8d911d92388f6d3b66483817.tar.gz
chromium_src-e46177921cafffdf8d911d92388f6d3b66483817.tar.bz2
Add an IPC channel between the NaCl loader process and the renderer.
BUG=116317 TEST=manual Review URL: https://chromiumcodereview.appspot.com/10214007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143483 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc23
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h7
-rw-r--r--chrome/common/nacl_messages.h8
-rw-r--r--chrome/common/nacl_types.h1
-rw-r--r--chrome/common/render_messages.h9
-rw-r--r--chrome/nacl/nacl_ipc_adapter.cc7
-rw-r--r--chrome/nacl/nacl_ipc_adapter.h4
-rw-r--r--chrome/nacl/nacl_listener.cc27
-rw-r--r--chrome/renderer/pepper/ppb_nacl_private_impl.cc184
-rw-r--r--ppapi/c/private/ppb_nacl_private.h12
-rw-r--r--ppapi/native_client/src/trusted/plugin/nacl_entry_points.h6
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.cc38
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.h3
-rw-r--r--ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc9
-rw-r--r--ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h4
-rw-r--r--ppapi/native_client/src/trusted/plugin/service_runtime.cc8
-rw-r--r--ppapi/native_client/src/trusted/plugin/service_runtime.h6
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc16
-rw-r--r--webkit/plugins/ppapi/plugin_module.h4
19 files changed, 339 insertions, 37 deletions
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index 1def1fe..161361e 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -145,6 +145,9 @@ NaClProcessHost::NaClProcessHost(const GURL& manifest_url, bool off_the_record)
getenv("NACL_UNTRUSTED_EXCEPTION_HANDLING") != NULL) {
enable_exception_handling_ = true;
}
+
+ enable_ipc_proxy_ = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableNaClIPCProxy);
}
NaClProcessHost::~NaClProcessHost() {
@@ -537,6 +540,8 @@ bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler,
OnAttachDebugExceptionHandler)
#endif
+ IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated,
+ OnPpapiChannelCreated)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -556,7 +561,8 @@ void NaClProcessHost::OnResourcesReady() {
}
}
-bool NaClProcessHost::ReplyToRenderer() {
+bool NaClProcessHost::ReplyToRenderer(
+ const IPC::ChannelHandle& channel_handle) {
std::vector<nacl::FileDescriptor> handles_for_renderer;
for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
#if defined(OS_WIN)
@@ -600,7 +606,7 @@ bool NaClProcessHost::ReplyToRenderer() {
#endif
ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
- reply_msg_, handles_for_renderer);
+ reply_msg_, handles_for_renderer, channel_handle);
chrome_render_message_filter_->Send(reply_msg_);
chrome_render_message_filter_ = NULL;
reply_msg_ = NULL;
@@ -618,6 +624,7 @@ bool NaClProcessHost::StartNaClExecution() {
params.enable_exception_handling = enable_exception_handling_;
params.enable_debug_stub =
CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug);
+ params.enable_ipc_proxy = enable_ipc_proxy_;
base::PlatformFile irt_file = nacl_browser->IrtFile();
CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
@@ -665,7 +672,17 @@ bool NaClProcessHost::StartNaClExecution() {
}
bool NaClProcessHost::SendStart() {
- return ReplyToRenderer() && StartNaClExecution();
+ if (!enable_ipc_proxy_) {
+ if (!ReplyToRenderer(IPC::ChannelHandle()))
+ return false;
+ }
+ return StartNaClExecution();
+}
+
+void NaClProcessHost::OnPpapiChannelCreated(
+ const IPC::ChannelHandle& channel_handle) {
+ DCHECK(enable_ipc_proxy_);
+ ReplyToRenderer(channel_handle);
}
bool NaClProcessHost::StartWithLaunchedProcess() {
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index 4ab9413a..3a2d5fb 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -17,6 +17,7 @@
#include "chrome/common/nacl_types.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "googleurl/src/gurl.h"
+#include "ipc/ipc_channel_handle.h"
class ChromeRenderMessageFilter;
class CommandLine;
@@ -86,7 +87,7 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate {
// Sends the reply message to the renderer who is waiting for the plugin
// to load. Returns true on success.
- bool ReplyToRenderer();
+ bool ReplyToRenderer(const IPC::ChannelHandle& channel_handle);
// Sends the message to the NaCl process to load the plugin. Returns true
// on success.
@@ -113,6 +114,8 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate {
IPC::Message* reply_msg);
#endif
+ void OnPpapiChannelCreated(const IPC::ChannelHandle& channel_handle);
+
GURL manifest_url_;
#if defined(OS_WIN)
@@ -152,6 +155,8 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate {
bool off_the_record_;
+ bool enable_ipc_proxy_;
+
DISALLOW_COPY_AND_ASSIGN(NaClProcessHost);
};
diff --git a/chrome/common/nacl_messages.h b/chrome/common/nacl_messages.h
index 7a6f012..57d5e10 100644
--- a/chrome/common/nacl_messages.h
+++ b/chrome/common/nacl_messages.h
@@ -7,6 +7,7 @@
// Multiply-included message file, no traditional include guard.
#include "base/process.h"
#include "chrome/common/nacl_types.h"
+#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
#define IPC_MESSAGE_START NaClMsgStart
@@ -18,6 +19,7 @@ IPC_STRUCT_TRAITS_BEGIN(nacl::NaClStartParams)
IPC_STRUCT_TRAITS_MEMBER(version)
IPC_STRUCT_TRAITS_MEMBER(enable_exception_handling)
IPC_STRUCT_TRAITS_MEMBER(enable_debug_stub)
+ IPC_STRUCT_TRAITS_MEMBER(enable_ipc_proxy)
IPC_STRUCT_TRAITS_END()
//-----------------------------------------------------------------------------
@@ -72,3 +74,9 @@ IPC_SYNC_MESSAGE_CONTROL1_1(NaClProcessMsg_QueryKnownToValidate,
// database in the browser.
IPC_MESSAGE_CONTROL1(NaClProcessMsg_SetKnownToValidate,
std::string /* A validation signature */)
+
+// Notify the browser process that the server side of the PPAPI channel was
+// created successfully.
+IPC_MESSAGE_CONTROL1(NaClProcessHostMsg_PpapiChannelCreated,
+ IPC::ChannelHandle /* channel_handle */)
+
diff --git a/chrome/common/nacl_types.h b/chrome/common/nacl_types.h
index 86ed0d0..649436d 100644
--- a/chrome/common/nacl_types.h
+++ b/chrome/common/nacl_types.h
@@ -55,6 +55,7 @@ struct NaClStartParams {
bool enable_exception_handling;
bool enable_debug_stub;
+ bool enable_ipc_proxy;
};
} // namespace nacl
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index ff023cf..c4191ca 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -26,6 +26,7 @@
#include "chrome/common/translate_errors.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/common/webkit_param_traits.h"
+#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -485,12 +486,14 @@ IPC_MESSAGE_ROUTED3(ChromeViewHostMsg_ForwardMessageToExternalHost,
// A renderer sends this to the browser process when it wants to start
// a new instance of the Native Client process. The browser will launch
-// the process and return a handle to an IMC channel.
-IPC_SYNC_MESSAGE_CONTROL2_1(ChromeViewHostMsg_LaunchNaCl,
+// the process and return an IPC channel handle. This handle will only
+// be valid if the NaCl IPC proxy is enabled.
+IPC_SYNC_MESSAGE_CONTROL2_2(ChromeViewHostMsg_LaunchNaCl,
GURL /* manifest_url */,
int /* socket count */,
std::vector<nacl::FileDescriptor>
- /* imc channel handles */)
+ /* imc channel handles */,
+ IPC::ChannelHandle /* ipc_channel_handle */)
// Notification that the page has an OpenSearch description document
// associated with it.
diff --git a/chrome/nacl/nacl_ipc_adapter.cc b/chrome/nacl/nacl_ipc_adapter.cc
index f76fa0d..f915a6a 100644
--- a/chrome/nacl/nacl_ipc_adapter.cc
+++ b/chrome/nacl/nacl_ipc_adapter.cc
@@ -74,6 +74,7 @@ ssize_t NaClDescCustomRecvMsg(void* handle, NaClImcTypedMsgHdr* msg,
int /* flags */) {
if (msg->iov_length != 1)
return -1;
+ msg->ndesc_length = 0; // Messages with descriptors aren't supported yet.
return static_cast<ssize_t>(
ToAdapter(handle)->BlockingReceive(static_cast<char*>(msg->iov[0].base),
msg->iov[0].length));
@@ -281,6 +282,12 @@ NaClDesc* NaClIPCAdapter::MakeNaClDesc() {
return MakeNaClDescCustom(this);
}
+#if defined(OS_POSIX)
+int NaClIPCAdapter::TakeClientFileDescriptor() {
+ return io_thread_data_.channel_->TakeClientFileDescriptor();
+}
+#endif
+
bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& message) {
{
base::AutoLock lock(lock_);
diff --git a/chrome/nacl/nacl_ipc_adapter.h b/chrome/nacl/nacl_ipc_adapter.h
index 12500cd..8c3c493 100644
--- a/chrome/nacl/nacl_ipc_adapter.h
+++ b/chrome/nacl/nacl_ipc_adapter.h
@@ -77,6 +77,10 @@ class NaClIPCAdapter : public base::RefCountedThreadSafe<NaClIPCAdapter>,
// NaClDesc is reference-counted, and a reference is returned.
NaClDesc* MakeNaClDesc();
+#if defined(OS_POSIX)
+ int TakeClientFileDescriptor();
+#endif
+
// Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
diff --git a/chrome/nacl/nacl_listener.cc b/chrome/nacl/nacl_listener.cc
index a5433dc..7159749 100644
--- a/chrome/nacl/nacl_listener.cc
+++ b/chrome/nacl/nacl_listener.cc
@@ -13,13 +13,19 @@
#include "base/message_loop.h"
#include "base/rand_util.h"
#include "chrome/common/nacl_messages.h"
+#include "chrome/nacl/nacl_ipc_adapter.h"
#include "chrome/nacl/nacl_validation_db.h"
#include "chrome/nacl/nacl_validation_query.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_switches.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_sync_message_filter.h"
-#include "ipc/ipc_switches.h"
#include "native_client/src/trusted/service_runtime/sel_main_chrome.h"
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
#if defined(OS_LINUX)
#include "content/public/common/child_process_sandbox_support_linux.h"
#endif
@@ -188,6 +194,25 @@ void NaClListener::OnMsgStart(const nacl::NaClStartParams& params) {
return;
}
+ if (params.enable_ipc_proxy) {
+ // Create the server side of the channel and notify the process host so it
+ // can reply to the renderer, which will connect as client.
+ IPC::ChannelHandle channel_handle =
+ IPC::Channel::GenerateVerifiedChannelID("nacl");
+
+ scoped_refptr<NaClIPCAdapter> ipc_adapter(new NaClIPCAdapter(
+ channel_handle, io_thread_.message_loop_proxy()));
+ args->initial_ipc_desc = ipc_adapter.get()->MakeNaClDesc();
+
+#if defined(OS_POSIX)
+ channel_handle.socket = base::FileDescriptor(
+ ipc_adapter.get()->TakeClientFileDescriptor(), true);
+#endif
+
+ if (!Send(new NaClProcessHostMsg_PpapiChannelCreated(channel_handle)))
+ LOG(ERROR) << "Failed to send IPC channel handle to renderer.";
+ }
+
std::vector<nacl::FileDescriptor> handles = params.handles;
#if defined(OS_LINUX) || defined(OS_MACOSX)
diff --git a/chrome/renderer/pepper/ppb_nacl_private_impl.cc b/chrome/renderer/pepper/ppb_nacl_private_impl.cc
index b646065..6589d56 100644
--- a/chrome/renderer/pepper/ppb_nacl_private_impl.cc
+++ b/chrome/renderer/pepper/ppb_nacl_private_impl.cc
@@ -9,17 +9,36 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/message_loop.h"
#include "base/rand_util.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/sandbox_init.h"
#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
#include "ipc/ipc_sync_message_filter.h"
#include "ppapi/c/private/ppb_nacl_private.h"
#include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h"
+#include "ppapi/proxy/host_dispatcher.h"
+#include "ppapi/proxy/proxy_channel.h"
+#include "ppapi/shared_impl/ppapi_preferences.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "webkit/plugins/ppapi/host_globals.h"
+#include "webkit/plugins/ppapi/plugin_module.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
-#if defined(OS_WIN)
-#include "content/public/common/sandbox_init.h"
-#endif
+using content::RenderThread;
+using content::RenderView;
+using webkit::ppapi::HostGlobals;
+using webkit::ppapi::PluginInstance;
+using webkit::ppapi::PluginDelegate;
+using WebKit::WebView;
namespace {
@@ -28,16 +47,24 @@ base::LazyInstance<scoped_refptr<IPC::SyncMessageFilter> >
// Launch NaCl's sel_ldr process.
PP_Bool LaunchSelLdr(PP_Instance instance,
- const char* alleged_url, int socket_count,
- void* imc_handles) {
+ const char* alleged_url,
+ int socket_count,
+ void* imc_handles,
+ void** ipc_channel_handle) {
std::vector<nacl::FileDescriptor> sockets;
IPC::Sender* sender = content::RenderThread::Get();
if (sender == NULL)
sender = g_background_thread_sender.Pointer()->get();
+ scoped_ptr<IPC::ChannelHandle> channel_handle(new IPC::ChannelHandle);
if (!sender->Send(new ChromeViewHostMsg_LaunchNaCl(
- GURL(alleged_url), socket_count, &sockets)))
+ GURL(alleged_url), socket_count, &sockets,
+ channel_handle.get()))) {
+ *ipc_channel_handle = NULL;
return PP_FALSE;
+ }
+
+ *ipc_channel_handle = channel_handle.release();
CHECK(static_cast<int>(sockets.size()) == socket_count);
for (int i = 0; i < socket_count; i++) {
@@ -48,7 +75,150 @@ PP_Bool LaunchSelLdr(PP_Instance instance,
return PP_TRUE;
}
-PP_Bool StartPpapiProxy(PP_Instance instance) {
+class ProxyChannelDelegate
+ : public ppapi::proxy::ProxyChannel::Delegate {
+ public:
+ ProxyChannelDelegate();
+ virtual ~ProxyChannelDelegate();
+
+ // ProxyChannel::Delegate implementation.
+ virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE;
+ virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE;
+ virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
+ base::PlatformFile handle,
+ const IPC::SyncChannel& channel,
+ bool should_close_source) OVERRIDE;
+ private:
+ // TODO(bbudge) Modify the content public API so we can get
+ // the renderer process's shutdown event.
+ base::WaitableEvent shutdown_event_;
+};
+
+ProxyChannelDelegate::ProxyChannelDelegate()
+ : shutdown_event_(true, false) {
+}
+
+ProxyChannelDelegate::~ProxyChannelDelegate() {
+}
+
+base::MessageLoopProxy* ProxyChannelDelegate::GetIPCMessageLoop() {
+ return RenderThread::Get()->GetIOMessageLoopProxy().get();
+}
+
+base::WaitableEvent* ProxyChannelDelegate::GetShutdownEvent() {
+ return &shutdown_event_;
+}
+
+IPC::PlatformFileForTransit ProxyChannelDelegate::ShareHandleWithRemote(
+ base::PlatformFile handle,
+ const IPC::SyncChannel& channel,
+ bool should_close_source) {
+ return content::BrokerGetFileHandleForProcess(handle, channel.peer_pid(),
+ should_close_source);
+}
+
+// Stubbed out SyncMessageStatusReceiver, required by HostDispatcher.
+// TODO(bbudge) Use a content::PepperHungPluginFilter instead.
+class SyncMessageStatusReceiver
+ : public ppapi::proxy::HostDispatcher::SyncMessageStatusReceiver {
+ public:
+ SyncMessageStatusReceiver() {}
+
+ // SyncMessageStatusReceiver implementation.
+ virtual void BeginBlockOnSyncMessage() OVERRIDE {}
+ virtual void EndBlockOnSyncMessage() OVERRIDE {}
+
+ private:
+ virtual ~SyncMessageStatusReceiver() {}
+};
+
+class OutOfProcessProxy : public PluginDelegate::OutOfProcessProxy {
+ public:
+ OutOfProcessProxy() {}
+ virtual ~OutOfProcessProxy() {}
+
+ bool Init(const IPC::ChannelHandle& channel_handle,
+ PP_Module pp_module,
+ PP_GetInterface_Func local_get_interface,
+ const ppapi::Preferences& preferences,
+ SyncMessageStatusReceiver* status_receiver) {
+ if (channel_handle.name.empty())
+ return false;
+
+#if defined(OS_POSIX)
+ DCHECK_NE(-1, channel_handle.socket.fd);
+ if (channel_handle.socket.fd == -1)
+ return false;
+#endif
+
+ dispatcher_delegate_.reset(new ProxyChannelDelegate);
+ dispatcher_.reset(new ppapi::proxy::HostDispatcher(
+ pp_module, local_get_interface, status_receiver));
+
+ if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(),
+ channel_handle,
+ true, // Client.
+ preferences)) {
+ dispatcher_.reset();
+ dispatcher_delegate_.reset();
+ return false;
+ }
+
+ return true;
+ }
+
+ // OutOfProcessProxy implementation.
+ virtual const void* GetProxiedInterface(const char* name) OVERRIDE {
+ return dispatcher_->GetProxiedInterface(name);
+ }
+ virtual void AddInstance(PP_Instance instance) OVERRIDE {
+ ppapi::proxy::HostDispatcher::SetForInstance(instance, dispatcher_.get());
+ }
+ virtual void RemoveInstance(PP_Instance instance) OVERRIDE {
+ ppapi::proxy::HostDispatcher::RemoveForInstance(instance);
+ }
+
+ private:
+ scoped_ptr<ppapi::proxy::HostDispatcher> dispatcher_;
+ scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_;
+};
+
+PP_Bool StartPpapiProxy(PP_Instance instance,
+ void* ipc_channel_handle) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableNaClIPCProxy)) {
+ scoped_ptr<IPC::ChannelHandle> channel_handle(
+ static_cast<IPC::ChannelHandle*>(ipc_channel_handle));
+ if (channel_handle->name.empty())
+ return PP_FALSE;
+
+ webkit::ppapi::PluginInstance* plugin_instance =
+ content::GetHostGlobals()->GetInstance(instance);
+ if (!plugin_instance)
+ return PP_FALSE;
+
+ WebView* web_view =
+ plugin_instance->container()->element().document().frame()->view();
+ RenderView* render_view = content::RenderView::FromWebView(web_view);
+
+ webkit::ppapi::PluginModule* plugin_module = plugin_instance->module();
+
+ scoped_refptr<SyncMessageStatusReceiver>
+ status_receiver(new SyncMessageStatusReceiver());
+ scoped_ptr<OutOfProcessProxy> out_of_process_proxy(new OutOfProcessProxy);
+ if (out_of_process_proxy->Init(
+ *channel_handle,
+ plugin_module->pp_module(),
+ webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc(),
+ ppapi::Preferences(render_view->GetWebkitPreferences()),
+ status_receiver.get())) {
+ plugin_module->InitAsProxiedNaCl(
+ out_of_process_proxy.PassAs<PluginDelegate::OutOfProcessProxy>(),
+ instance);
+ return PP_TRUE;
+ }
+ }
+
return PP_FALSE;
}
diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h
index dc7e7a2..06b900e 100644
--- a/ppapi/c/private/ppb_nacl_private.h
+++ b/ppapi/c/private/ppb_nacl_private.h
@@ -15,17 +15,21 @@
struct PPB_NaCl_Private {
// This function launches NaCl's sel_ldr process. On success, the function
// returns true, otherwise it returns false. When it returns true, it will
- // write |socket_count| nacl::Handles to imc_handles. Unless
+ // write |socket_count| nacl::Handles to imc_handles. |ipc_channel_handle|
+ // will point to information needed to start the IPC proxy. Unless
// EnableBackgroundSelLdrLaunch is called, this method must be invoked from
// the main thread.
PP_Bool (*LaunchSelLdr)(PP_Instance instance,
const char* alleged_url,
int socket_count,
- void* imc_handles);
+ void* imc_handles,
+ void** ipc_channel_handle);
// This function starts the PPAPI proxy so the nexe can communicate with the
- // browser's renderer process.
- PP_Bool (*StartPpapiProxy)(PP_Instance instance);
+ // browser's renderer process. |ipc_channel_handle| is the pointer returned
+ // by the call to LaunchSelLdr.
+ PP_Bool (*StartPpapiProxy)(PP_Instance instance,
+ void* ipc_channel_handle);
// On POSIX systems, this function returns the file descriptor of
// /dev/urandom. On non-POSIX systems, this function returns 0.
diff --git a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
index 3723394..eb66b8f 100644
--- a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
+++ b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
@@ -19,12 +19,10 @@
typedef bool (*LaunchNaClProcessFunc)(PP_Instance instance,
const char* url,
int socket_count,
- nacl::Handle* result_sockets);
-
-typedef bool (*StartPpapiProxyFunc)(PP_Instance instance);
+ nacl::Handle* result_sockets,
+ void** ipc_channel_handle);
extern LaunchNaClProcessFunc launch_nacl_process;
-extern StartPpapiProxyFunc start_ppapi_proxy;
#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_ENTRY_POINTS_H_
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc
index 891df69..2bfc50e 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.cc
+++ b/ppapi/native_client/src/trusted/plugin/plugin.cc
@@ -34,6 +34,7 @@
#include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
#include "native_client/src/trusted/plugin/json_manifest.h"
+#include "native_client/src/trusted/plugin/nacl_entry_points.h"
#include "native_client/src/trusted/plugin/nacl_subprocess.h"
#include "native_client/src/trusted/plugin/nexe_arch.h"
#include "native_client/src/trusted/plugin/plugin_error.h"
@@ -54,6 +55,7 @@
#include "ppapi/c/ppp_input_event.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/ppp_mouse_lock.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
#include "ppapi/cpp/dev/find_dev.h"
#include "ppapi/cpp/dev/printing_dev.h"
@@ -120,6 +122,13 @@ const int64_t kSizeKBMin = 1;
const int64_t kSizeKBMax = 512*1024; // very large .nexe
const uint32_t kSizeKBBuckets = 100;
+const PPB_NaCl_Private* GetNaclInterface() {
+ pp::Module *module = pp::Module::Get();
+ CHECK(module);
+ return static_cast<const PPB_NaCl_Private*>(
+ module->GetBrowserInterface(PPB_NACL_PRIVATE_INTERFACE));
+}
+
const PPB_UMA_Private* GetUMAInterface() {
pp::Module *module = pp::Module::Get();
CHECK(module);
@@ -602,13 +611,32 @@ bool Plugin::LoadNaClModuleCommon(nacl::DescWrapper* wrapper,
return false;
}
+ void* ipc_channel_handle = NULL;
bool service_runtime_started =
- new_service_runtime->Start(wrapper, error_info, manifest_base_url());
+ new_service_runtime->Start(wrapper,
+ error_info,
+ manifest_base_url(),
+ &ipc_channel_handle);
+ nacl::scoped_ptr<char> ipc_channel_handle_ptr(
+ reinterpret_cast<char*>(ipc_channel_handle));
PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime_started=%d)\n",
service_runtime_started));
if (!service_runtime_started) {
return false;
}
+
+ // Try to start the Chrome IPC-based proxy.
+ const PPB_NaCl_Private* ppb_nacl = GetNaclInterface();
+ if (ppb_nacl->StartPpapiProxy(
+ pp_instance(),
+ reinterpret_cast<void*>(ipc_channel_handle_ptr.release()))) {
+ using_ipc_proxy_ = true;
+ // We need to explicitly schedule this here. It is normally called in
+ // response to starting the SRPC proxy.
+ CHECK(init_done_cb.pp_completion_callback().func != NULL);
+ PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon, started ipc proxy.\n"));
+ pp::Module::Get()->core()->CallOnMainThread(0, init_done_cb, PP_OK);
+ }
return true;
}
@@ -631,6 +659,11 @@ bool Plugin::LoadNaClModule(nacl::DescWrapper* wrapper,
}
bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) {
+ // If we are using the IPC proxy, StartSrpcServices and StartJSObjectProxy
+ // don't makes sense. Return 'true' so that the plugin continues loading.
+ if (using_ipc_proxy_)
+ return true;
+
if (!main_subprocess_.StartSrpcServices()) {
error_info->SetReport(ERROR_SRPC_CONNECTION_FAIL,
"SRPC connection failure for " +
@@ -862,7 +895,8 @@ Plugin::Plugin(PP_Instance pp_instance)
init_time_(0),
ready_time_(0),
nexe_size_(0),
- time_of_last_progress_event_(0) {
+ time_of_last_progress_event_(0),
+ using_ipc_proxy_(false) {
PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%"
NACL_PRId32")\n", static_cast<void*>(this), pp_instance));
callback_factory_.Initialize(this);
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h
index cd79517..1a709d8 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.h
+++ b/ppapi/native_client/src/trusted/plugin/plugin.h
@@ -517,6 +517,9 @@ class Plugin : public pp::InstancePrivate {
const FileDownloader* FindFileDownloader(PP_Resource url_loader) const;
int64_t time_of_last_progress_event_;
+
+ // Whether we are using IPC-based PPAPI proxy.
+ bool using_ipc_proxy_;
};
} // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
index d301612..140e0d8 100644
--- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
+++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
@@ -11,10 +11,12 @@ LaunchNaClProcessFunc launch_nacl_process = NULL;
namespace plugin {
bool SelLdrLauncherChrome::Start(const char* url) {
- return Start(0, url);
+ return Start(0, url, NULL);
}
-bool SelLdrLauncherChrome::Start(PP_Instance instance, const char* url) {
+bool SelLdrLauncherChrome::Start(PP_Instance instance,
+ const char* url,
+ void** ipc_channel_handle) {
// send a synchronous message to the browser process
// TODO(sehr): This is asserted to be one. Remove this parameter.
static const int kNumberOfChannelsToBeCreated = 1;
@@ -22,7 +24,8 @@ bool SelLdrLauncherChrome::Start(PP_Instance instance, const char* url) {
!launch_nacl_process(instance,
url,
kNumberOfChannelsToBeCreated,
- &channel_)) {
+ &channel_,
+ ipc_channel_handle)) {
return false;
}
return true;
diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
index e479499..15ce771 100644
--- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
+++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
@@ -13,7 +13,9 @@ namespace plugin {
class SelLdrLauncherChrome : public nacl::SelLdrLauncherBase {
public:
virtual bool Start(const char* url);
- virtual bool Start(PP_Instance instance, const char* url);
+ bool Start(PP_Instance instance,
+ const char* url,
+ void** ipc_channel_handle);
};
} // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
index 5c3b4fd..4177cf1 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
@@ -623,7 +623,9 @@ bool ServiceRuntime::InitCommunication(nacl::DescWrapper* nacl_desc,
}
bool ServiceRuntime::Start(nacl::DescWrapper* nacl_desc,
- ErrorInfo* error_info, const nacl::string& url) {
+ ErrorInfo* error_info,
+ const nacl::string& url,
+ void** ipc_channel_handle) {
PLUGIN_PRINTF(("ServiceRuntime::Start (nacl_desc=%p)\n",
reinterpret_cast<void*>(nacl_desc)));
@@ -643,7 +645,9 @@ bool ServiceRuntime::Start(nacl::DescWrapper* nacl_desc,
#ifdef NACL_STANDALONE
bool started = tmp_subprocess->Start(url.c_str());
#else
- bool started = tmp_subprocess->Start(plugin_->pp_instance(), url.c_str());
+ bool started = tmp_subprocess->Start(plugin_->pp_instance(),
+ url.c_str(),
+ ipc_channel_handle);
#endif
if (!started) {
PLUGIN_PRINTF(("ServiceRuntime::Start (start failed)\n"));
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h
index 554942a..8c9b55c 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.h
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h
@@ -216,10 +216,12 @@ class ServiceRuntime {
// Spawn a sel_ldr instance and establish an SrpcClient to it. The nexe
// to be started is passed through |nacl_file_desc|. On success, returns
// true. On failure, returns false and |error_string| is set to something
- // describing the error.
+ // describing the error. |ipc_channel_handle| returns information for
+ // connecting the Chrome IPC-based proxy.
bool Start(nacl::DescWrapper* nacl_file_desc,
ErrorInfo* error_info,
- const nacl::string& url);
+ const nacl::string& url,
+ void** ipc_channel_handle);
// Starts the application channel to the nexe.
SrpcClient* SetupAppChannel();
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index a16f79a..423209f 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -419,7 +419,8 @@ PluginModule::PluginModule(const std::string& name,
library_(NULL),
name_(name),
path_(path),
- reserve_instance_id_(NULL) {
+ reserve_instance_id_(NULL),
+ nacl_ipc_proxy_(false) {
// Ensure the globals object is created.
if (!host_globals)
host_globals = new HostGlobals;
@@ -496,9 +497,13 @@ void PluginModule::InitAsProxied(
}
void PluginModule::InitAsProxiedNaCl(
- PluginDelegate::OutOfProcessProxy* out_of_process_proxy,
+ scoped_ptr<PluginDelegate::OutOfProcessProxy> out_of_process_proxy,
PP_Instance instance) {
- InitAsProxied(out_of_process_proxy);
+ // TODO(bbudge) We need to switch the mode of the PluginModule on a
+ // per-instance basis. Fix this so out_of_process_proxy and other
+ // state is stored in a map, indexed by instance.
+ nacl_ipc_proxy_ = true;
+ InitAsProxied(out_of_process_proxy.release());
// InitAsProxied (for the trusted/out-of-process case) initializes only the
// module, and one or more instances are added later. In this case, the
// PluginInstance was already created as in-process, so we missed the proxy
@@ -560,6 +565,11 @@ void PluginModule::InstanceDeleted(PluginInstance* instance) {
if (out_of_process_proxy_.get())
out_of_process_proxy_->RemoveInstance(instance->pp_instance());
instances_.erase(instance);
+
+ if (nacl_ipc_proxy_) {
+ out_of_process_proxy_.reset();
+ reserve_instance_id_ = NULL;
+ }
}
scoped_refptr< ::ppapi::CallbackTracker> PluginModule::GetCallbackTracker() {
diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h
index d9b0162..d9d78ba 100644
--- a/webkit/plugins/ppapi/plugin_module.h
+++ b/webkit/plugins/ppapi/plugin_module.h
@@ -90,7 +90,7 @@ class WEBKIT_PLUGINS_EXPORT PluginModule :
// Initializes this module for the given NaCl proxy. This takes
// ownership of the given pointer, even in the failure case.
void InitAsProxiedNaCl(
- PluginDelegate::OutOfProcessProxy* out_of_process_proxy,
+ scoped_ptr<PluginDelegate::OutOfProcessProxy> out_of_process_proxy,
PP_Instance instance);
static const PPB_Core* GetCore();
@@ -203,6 +203,8 @@ class WEBKIT_PLUGINS_EXPORT PluginModule :
PP_Bool (*reserve_instance_id_)(PP_Module, PP_Instance);
+ bool nacl_ipc_proxy_;
+
DISALLOW_COPY_AND_ASSIGN(PluginModule);
};