Index: components/nacl/loader/nacl_listener.cc |
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc |
index c0e3c5e717054788ea2170d79f466b3fe8da1681..cf941cac32a3ca0b735cf2593ada0f5d1b0329fa 100644 |
--- a/components/nacl/loader/nacl_listener.cc |
+++ b/components/nacl/loader/nacl_listener.cc |
@@ -131,15 +131,29 @@ void DebugStubPortSelectedHandler(uint16_t port) { |
#endif |
+// This function should be used be provided to the ManifestChannel |
+// NaClIPCAdapter instead of the one inside NaClListener; this one will always |
+// run the callback, even if the NaClListener has been destroyed. |
+void ResolveFileToken( |
+ uint64_t token_lo, |
+ uint64_t token_hi, |
+ base::Callback<void(IPC::PlatformFileForTransit, |
+ base::FilePath)> resolved_cb) { |
+ if (!g_listener) |
+ resolved_cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
+ g_listener->ResolveFileToken(token_lo, token_hi, resolved_cb); |
+} |
+ |
// Creates the PPAPI IPC channel between the NaCl IRT and the host |
// (browser/renderer) process, and starts to listen it on the thread where |
// the given message_loop_proxy runs. |
// Also, creates and sets the corresponding NaClDesc to the given nap with |
// the FD #. |
-void SetUpIPCAdapter(IPC::ChannelHandle* handle, |
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
- struct NaClApp* nap, |
- int nacl_fd) { |
+scoped_refptr<NaClIPCAdapter> SetUpIPCAdapter( |
+ IPC::ChannelHandle* handle, |
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
+ struct NaClApp* nap, |
+ int nacl_fd) { |
scoped_refptr<NaClIPCAdapter> ipc_adapter( |
new NaClIPCAdapter(*handle, message_loop_proxy.get())); |
ipc_adapter->ConnectChannel(); |
@@ -151,6 +165,7 @@ void SetUpIPCAdapter(IPC::ChannelHandle* handle, |
// Pass a NaClDesc to the untrusted side. This will hold a ref to the |
// NaClIPCAdapter. |
NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); |
+ return ipc_adapter; |
} |
} // namespace |
@@ -251,6 +266,30 @@ bool NaClListener::Send(IPC::Message* msg) { |
} |
} |
+class FileTokenMessageFilter : public IPC::MessageFilter { |
+ public: |
+ virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE { |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(FileTokenMessageFilter, msg) |
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsyncReply, |
+ OnResolveFileTokenAsyncReply) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+ } |
+ |
+ void OnResolveFileTokenAsyncReply( |
+ uint64_t token_lo, |
+ uint64_t token_hi, |
+ IPC::PlatformFileForTransit ipc_fd, |
+ base::FilePath file_path) { |
+ if (g_listener) |
+ g_listener->OnFileTokenResolved(token_lo, token_hi, ipc_fd, file_path); |
+ } |
+ private: |
+ virtual ~FileTokenMessageFilter() { } |
+}; |
+ |
void NaClListener::Listen() { |
std::string channel_name = |
CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
@@ -259,6 +298,7 @@ void NaClListener::Listen() { |
this, io_thread_.message_loop_proxy().get(), &shutdown_event_); |
filter_ = new IPC::SyncMessageFilter(&shutdown_event_); |
channel_->AddFilter(filter_.get()); |
+ channel_->AddFilter(new FileTokenMessageFilter()); |
channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); |
main_loop_ = base::MessageLoop::current(); |
main_loop_->Run(); |
@@ -298,10 +338,12 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) { |
IPC::ChannelHandle browser_handle; |
IPC::ChannelHandle ppapi_renderer_handle; |
+ IPC::ChannelHandle manifest_service_handle; |
if (params.enable_ipc_proxy) { |
browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
+ manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
// Create the PPAPI IPC channels between the NaCl IRT and the host |
// (browser/renderer) processes. The IRT uses these channels to |
@@ -310,6 +352,14 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) { |
nap, NACL_CHROME_DESC_BASE); |
SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), |
nap, NACL_CHROME_DESC_BASE + 1); |
+ |
+ scoped_refptr<NaClIPCAdapter> manifest_ipc_adapter = |
+ SetUpIPCAdapter(&manifest_service_handle, |
+ io_thread_.message_loop_proxy(), |
+ nap, |
+ NACL_CHROME_DESC_BASE + 2); |
+ manifest_ipc_adapter->set_resolve_file_token_callback( |
+ base::Bind(&::ResolveFileToken)); |
} |
trusted_listener_ = new NaClTrustedListener( |
@@ -320,7 +370,7 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) { |
browser_handle, |
ppapi_renderer_handle, |
trusted_listener_->TakeClientChannelHandle(), |
- IPC::ChannelHandle()))) |
+ manifest_service_handle))) |
LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost."; |
std::vector<nacl::FileDescriptor> handles = params.handles; |
@@ -427,3 +477,23 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) { |
trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); |
NaClExit(exit_status); |
} |
+ |
+void NaClListener::ResolveFileToken( |
+ uint64_t token_lo, |
+ uint64_t token_hi, |
+ base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { |
+ if (!Send(new NaClProcessMsg_ResolveFileTokenAsync(token_lo, token_hi))) { |
+ cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
+ return; |
+ } |
+ resolved_cb_ = cb; |
+} |
+ |
+void NaClListener::OnFileTokenResolved( |
+ uint64_t token_lo, |
+ uint64_t token_hi, |
+ IPC::PlatformFileForTransit ipc_fd, |
+ base::FilePath file_path) { |
+ resolved_cb_.Run(ipc_fd, file_path); |
+ resolved_cb_.Reset(); |
+} |