Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2447)

Unified Diff: chrome/nacl/nacl_ipc_adapter.cc

Issue 10796064: PPAPI/NaCl: Make nacl_ipc_adapter handle ImageData creation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sketch of idea for extracting handles generally Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/nacl/nacl_ipc_adapter.h ('k') | chrome/renderer/pepper/ppb_pdf_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/nacl/nacl_ipc_adapter.cc
diff --git a/chrome/nacl/nacl_ipc_adapter.cc b/chrome/nacl/nacl_ipc_adapter.cc
index 187eb8b602f85c4ffe4b4df23d48c3c84a2a8728..4d46a2d15d01192f2553fa76640160272ceeb754 100644
--- a/chrome/nacl/nacl_ipc_adapter.cc
+++ b/chrome/nacl/nacl_ipc_adapter.cc
@@ -129,6 +129,106 @@ void WriteFileDescriptor(IPC::Message* message, int index) {
message->WriteInt(index);
}
+typedef std::vector<ppapi::proxy::SerializedSharedMemoryHandle> ShmHandles;
+typedef std::vector<ppapi::proxy::SerializedFileDescriptor> FDs;
+
+void ExtractHandle(const ppapi::proxy::SerializedSharedMemoryHandle& handle,
+ ShmHandles* handles, FDs* /* fds */, IPC::Message* msg,
+ int* index) {
+ handles->push_back(handle);
+ if (msg)
+ WriteFileDescriptor(msg, (*index)++);
+}
+void ExtractHandle(const ppapi::proxy::SerializedFileDescriptor& fd,
+ ShmHandles* /* handles */, FDs* fds, IPC::Message* msg,
+ int* index) {
+ fds->push_back(fd);
+ if (msg)
+ WriteFileDescriptor(msg, (*index)++);
+}
+template <class T>
+ExtractHandle(cont T& param, ShmHandles* /* handles */, FDs* /* fds */,
+ IPC::Message* msg, int* index) {
+ // It's not a handle, so just write to the output message, if necessary.
+ if (msg)
+ IPC::WriteParam(m, param);
+}
+
+// These just break apart the given tuple and run ExtractHandle over each param.
+// The idea is to extract any handles in the tuple, while writing all data to
+// msg (if msg is valid). The msg will only be valid on Windows, where we need
+// to re-write the message to include the handles in POSIX style for NaCl.
+template <class A>
+void ExtractHandlesImpl(const Tuple1<A>& t1, ShmHandles* handles, FDs* fds,
+ IPC::Message* msg) {
+ int fd_index = 0;
+ ExtractHandle(t1.a, handles, fds, msg, &fd_index);
+}
+template <class A, class B>
+void ExtractHandlesImpl(const Tuple2<A, B>& t1, ShmHandles* handles, FDs* fds,
+ IPC::Message* msg) {
+ int fd_index = 0;
+ ExtractHandle(t1.a, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.b, handles, fds, msg, &fd_index);
+}
+template <class A, class B, class C>
+void ExtractHandlesImpl(const Tuple3<A, B, C>& t1, ShmHandles* handles,
+ FDs* fds, IPC::Message* msg) {
+ int fd_index = 0;
+ ExtractHandle(t1.a, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.b, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.c, handles, fds, msg, &fd_index);
+}
+template <class A, class B, class C, class D>
+void ExtractHandlesImpl(const Tuple4<A, B, C, D>& t1, ShmHandles* handles,
+ FDs* fds, IPC::Message* msg) {
+ int fd_index = 0;
+ ExtractHandle(t1.a, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.b, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.c, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.d, handles, fds, msg, &fd_index);
+}
+template <class A, class B, class C, class D, class E>
+void ExtractHandlesImpl(const Tuple5<A, B, C, D, E>& t1, ShmHandles* handles,
+ FDs* fds, IPC::Message* msg) {
+ int fd_index = 0;
+ ExtractHandle(t1.a, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.b, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.c, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.d, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.e, handles, fds, msg, &fd_index);
+}
+template <class A, class B, class C, class D, class E, class F>
+void ExtractHandlesImpl(const Tuple6<A, B, C, D, E, F>& t1, ShmHandles* handles,
+ FDs* fds, IPC::Message* msg) {
+ int fd_index = 0;
+ ExtractHandle(t1.a, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.b, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.c, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.d, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.e, handles, fds, msg, &fd_index);
+ ExtractHandle(t1.f, handles, fds, msg, &fd_index);
+}
+
+template <class MessageType>
+class HandleExtractor {
+ public:
+ explicit HandleExtractor(const IPC::Message* msg)
+ : msg_(static_cast<MessageType>(msg)) {
+ }
+ bool TranslateMessage(std::vector<base::SharedMemoryHandle>* shm_handles,
+ std::vector<IPC::PlatformFileForTransit>* fds,
+ IPC::Message* msg) {
+ typename MessageType::Schema::Param params;
+ if (!Read(msg, &params))
+ return false;
+ ExtractHandlesImpl(params, shm_handles, fds, msg);
+ return true;
+ }
+ private:
+ const MessageType* msg_;
+};
+
} // namespace
class NaClIPCAdapter::RewrittenMessage
@@ -346,54 +446,67 @@ bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& message) {
// Clear any descriptors left from the prior message.
locked_data_.nacl_descs_.clear();
- PickleIterator it(message);
+ // Pointer to the "new" message we will rewrite on Windows. On posix, this
+ // isn't necessary, so it will stay NULL.
+ IPC::Message new_message_ptr = NULL;
+#if defined(OS_WIN)
+ IPC::Message new_msg(message.routing_id(),
+ PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID,
+ message.priority());
+ new_message_ptr = &new_msg;
+#endif
+ ShmHandles handles;
+ FDs fds;
switch (message.type()) {
+ // Note that the case for each message is now pretty much boilerplate...
+ // We can condense it to a macro if we want to save lines of code. So you
+ // might get:
+ // CASE_FOR_MESSAGE(PpapiMsg_PPB_Audio_NotifyAudioStreamCreated);
+ // CASE_FOR_MESSAGE(PpapiMsg_PPB_AudioInput_NotifyAudioStreamCreated);
+ // etc.
case PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID: {
- int instance_id;
- int resource_id;
- int result_code;
- NaClHandle sock_handle;
- NaClHandle shm_handle;
- uint32_t shm_length;
- if (ReadHostResource(&it, &instance_id, &resource_id) &&
- it.ReadInt(&result_code) &&
- ReadFileDescriptor(message, &it, &sock_handle) &&
- ReadFileDescriptor(message, &it, &shm_handle) &&
- it.ReadUInt32(&shm_length)) {
- // Our caller, OnMessageReceived, holds the lock for locked_data_.
- // Import the sync socket. Use DescWrappers to simplify clean up.
- nacl::DescWrapperFactory factory;
- scoped_ptr<nacl::DescWrapper> socket_wrapper(
- factory.ImportSyncSocketHandle(sock_handle));
- // Import the shared memory handle and increase its size by 4 bytes to
- // accommodate the length data we write to signal the host.
- scoped_ptr<nacl::DescWrapper> shm_wrapper(
- factory.ImportShmHandle(shm_handle, shm_length + sizeof(uint32)));
- if (shm_wrapper.get() && socket_wrapper.get()) {
- locked_data_.nacl_descs_.push_back(socket_wrapper.release());
- locked_data_.nacl_descs_.push_back(shm_wrapper.release());
- }
-#if defined(OS_POSIX)
- SaveMessage(message);
-#else // defined(OS_POSIX)
- // On Windows we must rewrite the message to the POSIX representation.
- IPC::Message new_msg(message.routing_id(),
- PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID,
- message.priority());
- WriteHostResource(&new_msg, instance_id, resource_id);
- new_msg.WriteInt(result_code);
- WriteFileDescriptor(&new_msg, 0); // socket handle, index = 0
- WriteFileDescriptor(&new_msg, 1); // shm handle, index = 1
- new_msg.WriteUInt32(shm_length);
- SaveMessage(new_msg);
-#endif
- }
+ HandleExtractor<PpapiMsg_PPBAudio_NotifyAudioStreamCreated>
+ extractor(message);
+ if (!extractor.TranslateMessage(msg, &handles, &fds, new_message_ptr))
+ return false;
+ break;
+ case IPC_REPLY_ID: {
+ /* TODO(dmichael): Look up the type of the originating message, do
+ another switch here to deal with any reply messages with handles.*/
break;
}
- default: {
- SaveMessage(message);
+ default:
+#if defined(OS_WIN)
+ // There are no handles, and we didn't have to rewrite the new message.
+ // Just make sure that SaveMessage below saves the valid message, since
+ // new_msg doesn't have any data.
+ new_message_ptr = &message;
+#endif
+ // default case has nothing to do in posix; we'll save the message
+ // below.
+ }
+ // Now add any descriptors we found to nacl_descs_. These are usually both
+ // empty, unless we read a message containing a FD or handle.
+ nacl::DescWrapperFactory factory;
+ for (ShmHandles::const_iterator iter = handles.begin();
+ iter != handles.end();
+ ++iter) {
+ scoped_ptr<nacl::DescWrapper> shm_wrapper(
+ factory.ImportShmHandle(iter->handle, iter->length));
+ if (shm_wrapper.get())
+ locked_data_.nacl_descs_.push_back(shm_wrapper.release());
+ }
+ for (FDs::const_iterator iter = fds.begin(); iter != fds.end(); ++iter) {
+ scoped_ptr<nacl::DescWrapper> socket_wrapper(
+ factory.ImportSyncSocketHandle(sock_handle));
+ if (socket_wrapper.get())
+ locked_data_.nacl_descs_.push_back(socket_wrapper.release());
}
}
+ if (new_message_ptr)
+ SaveMessage(*new_message_ptr); // For Windows
+ else
+ SaveMessage(message);
}
cond_var_.Signal();
return true;
@@ -467,6 +580,21 @@ bool NaClIPCAdapter::SendCompleteMessage(const char* buffer,
if (locked_data_.channel_closed_)
return false; // TODO(brettw) clean up handles here when we add support!
+ // Deal with sync messages with handles in the reply.
+ if (msg->is_sync()) {
+ if (msg->type() == PpapiHostMsg_PPBImageData_CreateNaCl::ID) {
+ int id = IPC::SyncMessage::GetMessageId(*msg);
+ PickleIterator iter(IPC::SyncMessage::GetDataIterator(msg.get()));
+ int dummy, height, width;
+ if (iter.ReadInt(&dummy) && // instance
+ iter.ReadInt(&dummy) && // format
+ iter.ReadInt(&height) &&
+ iter.ReadInt(&width)) {
+ uint32_t size = height * width * 4;
+ locked_data_.pending_image_data_msgs_[id] = size;
+ }
+ }
+ }
// Actual send must be done on the I/O thread.
task_runner_->PostTask(FROM_HERE,
base::Bind(&NaClIPCAdapter::SendMessageOnIOThread, this,
@@ -496,6 +624,7 @@ void NaClIPCAdapter::SendMessageOnIOThread(scoped_ptr<IPC::Message> message) {
}
void NaClIPCAdapter::SaveMessage(const IPC::Message& message) {
+ lock_.AssertAcquired();
// There is some padding in this structure (the "padding" member is 16
// bits but this then gets padded to 32 bits). We want to be sure not to
// leak data to the untrusted plugin, so zero everything out first.
« no previous file with comments | « chrome/nacl/nacl_ipc_adapter.h ('k') | chrome/renderer/pepper/ppb_pdf_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698