Chromium Code Reviews| Index: chrome/renderer/pepper/ppb_nacl_private_impl.cc |
| =================================================================== |
| --- chrome/renderer/pepper/ppb_nacl_private_impl.cc (revision 137272) |
| +++ chrome/renderer/pepper/ppb_nacl_private_impl.cc (working copy) |
| @@ -7,25 +7,50 @@ |
| #ifndef DISABLE_NACL |
| #include "base/command_line.h" |
| +#include "base/compiler_specific.h" |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| +#include "base/message_loop.h" |
| +#include "base/path_service.h" |
| #include "base/rand_util_c.h" |
| +#include "chrome/common/chrome_paths.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::WebView; |
| namespace { |
| base::LazyInstance<scoped_refptr<IPC::SyncMessageFilter> > |
| g_background_thread_sender = LAZY_INSTANCE_INITIALIZER; |
| +base::LazyInstance<IPC::ChannelHandle> g_ipc_channel_handle = |
| + LAZY_INSTANCE_INITIALIZER; |
| +base::ProcessId g_plugin_process_id; |
| + |
| // Launch NaCl's sel_ldr process. |
| PP_Bool LaunchSelLdr(PP_Instance instance, |
| const char* alleged_url, int socket_count, |
| @@ -36,7 +61,9 @@ |
| sender = g_background_thread_sender.Pointer()->get(); |
| if (!sender->Send(new ChromeViewHostMsg_LaunchNaCl( |
| - GURL(alleged_url), socket_count, &sockets))) |
| + GURL(alleged_url), socket_count, &sockets, |
| + g_ipc_channel_handle.Pointer(), |
| + &g_plugin_process_id))) |
| return PP_FALSE; |
| CHECK(static_cast<int>(sockets.size()) == socket_count); |
| @@ -48,7 +75,141 @@ |
| return PP_TRUE; |
| } |
| +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: |
| + 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. |
| +class SyncMessageStatusReceiver |
| + : public ppapi::proxy::HostDispatcher::SyncMessageStatusReceiver { |
| + public: |
| + SyncMessageStatusReceiver() {} |
| + virtual ~SyncMessageStatusReceiver() {} |
| + |
| + // SyncMessageStatusReceiver implementation. |
| + virtual void BeginBlockOnSyncMessage() {} |
| + virtual void EndBlockOnSyncMessage() {} |
| +}; |
| + |
| +class OutOfProcessProxy |
| + : public webkit::ppapi::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) { |
|
dmichael (off chromium)
2012/05/23 00:41:04
OVERRIDE for these?
bbudge
2012/05/23 21:42:20
Done.
|
| + return dispatcher_->GetProxiedInterface(name); |
| + } |
| + virtual void AddInstance(PP_Instance instance) { |
| + ppapi::proxy::HostDispatcher::SetForInstance(instance, dispatcher_.get()); |
| + } |
| + virtual void RemoveInstance(PP_Instance instance) { |
| + 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) { |
| + if (CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kEnableNaClIPCProxy)) { |
| + IPC::ChannelHandle& channel_handle = g_ipc_channel_handle.Get(); |
| + 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->InitAsProxied(out_of_process_proxy.release()); |
|
dmichael (off chromium)
2012/05/23 00:41:04
I think this might cause trouble... this module h
|
| + return PP_TRUE; |
| + } |
| + } |
| + |
| return PP_FALSE; |
| } |