summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-16 23:23:53 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-16 23:23:53 +0000
commiteb5960da1e59be98182120c3c489d92094f3c5c9 (patch)
tree0baeb22b52e5c9d54d15f4fdc5a36dc7a976733a /ppapi
parent97af43ea66f1a7a734cccbc0e4bf65b88c37c4a7 (diff)
downloadchromium_src-eb5960da1e59be98182120c3c489d92094f3c5c9.zip
chromium_src-eb5960da1e59be98182120c3c489d92094f3c5c9.tar.gz
chromium_src-eb5960da1e59be98182120c3c489d92094f3c5c9.tar.bz2
PPAPI/NaCl: Move handle extraction code to ppapi/proxy
BUG=165201 TEST= TBR=jln@chromium.org Review URL: https://chromiumcodereview.appspot.com/11894003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177257 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/ppapi_ipc.gypi4
-rw-r--r--ppapi/proxy/audio_input_resource.cc2
-rw-r--r--ppapi/proxy/audio_input_resource.h1
-rw-r--r--ppapi/proxy/handle_converter.cc258
-rw-r--r--ppapi/proxy/handle_converter.h62
-rw-r--r--ppapi/proxy/ppapi_messages.h1
-rw-r--r--ppapi/proxy/ppb_audio_proxy.h3
-rw-r--r--ppapi/proxy/ppb_buffer_proxy.h3
-rw-r--r--ppapi/proxy/ppb_graphics_3d_proxy.h3
-rw-r--r--ppapi/proxy/ppb_image_data_proxy.h2
-rw-r--r--ppapi/proxy/resource_message_params.h2
-rw-r--r--ppapi/proxy/serialized_handle.cc133
-rw-r--r--ppapi/proxy/serialized_handle.h141
-rw-r--r--ppapi/proxy/serialized_structs.cc119
-rw-r--r--ppapi/proxy/serialized_structs.h114
15 files changed, 609 insertions, 239 deletions
diff --git a/ppapi/ppapi_ipc.gypi b/ppapi/ppapi_ipc.gypi
index 8e374b2..616d8e5 100644
--- a/ppapi/ppapi_ipc.gypi
+++ b/ppapi/ppapi_ipc.gypi
@@ -12,6 +12,8 @@
# This part is shared between the targets defined below.
['ppapi_ipc_target==1', {
'sources': [
+ 'proxy/handle_converter.cc',
+ 'proxy/handle_converter.h',
'proxy/ppapi_messages.cc',
'proxy/ppapi_messages.h',
'proxy/ppapi_param_traits.cc',
@@ -20,6 +22,8 @@
'proxy/resource_message_params.h',
'proxy/serialized_flash_menu.cc',
'proxy/serialized_flash_menu.h',
+ 'proxy/serialized_handle.cc',
+ 'proxy/serialized_handle.h',
'proxy/serialized_structs.cc',
'proxy/serialized_structs.h',
'proxy/serialized_var.cc',
diff --git a/ppapi/proxy/audio_input_resource.cc b/ppapi/proxy/audio_input_resource.cc
index 2f17c6c..14dd236 100644
--- a/ppapi/proxy/audio_input_resource.cc
+++ b/ppapi/proxy/audio_input_resource.cc
@@ -12,7 +12,7 @@
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
-#include "ppapi/proxy/serialized_structs.h"
+#include "ppapi/proxy/serialized_handle.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/tracked_callback.h"
diff --git a/ppapi/proxy/audio_input_resource.h b/ppapi/proxy/audio_input_resource.h
index e8a1ffd..85f27e2 100644
--- a/ppapi/proxy/audio_input_resource.h
+++ b/ppapi/proxy/audio_input_resource.h
@@ -21,7 +21,6 @@ namespace ppapi {
namespace proxy {
class ResourceMessageReplyParams;
-class SerializedHandle;
class AudioInputResource : public PluginResource,
public thunk::PPB_AudioInput_API,
diff --git a/ppapi/proxy/handle_converter.cc b/ppapi/proxy/handle_converter.cc
new file mode 100644
index 0000000..a669062
--- /dev/null
+++ b/ppapi/proxy/handle_converter.cc
@@ -0,0 +1,258 @@
+// Copyright (c) 2013 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 "ppapi/proxy/handle_converter.h"
+
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_macros.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/proxy/serialized_handle.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace {
+
+void WriteHandle(int handle_index,
+ const ppapi::proxy::SerializedHandle& handle,
+ IPC::Message* message) {
+ ppapi::proxy::SerializedHandle::WriteHeader(handle.header(), message);
+
+ // Now write the handle itself in POSIX style.
+ message->WriteBool(true); // valid == true
+ message->WriteInt(handle_index);
+}
+
+typedef std::vector<ppapi::proxy::SerializedHandle> Handles;
+
+// We define overload for catching SerializedHandles, so that we can share
+// them correctly to the untrusted side, and another for handling all other
+// parameters. See ConvertHandlesImpl for how these get used.
+void ConvertHandlesInParam(const ppapi::proxy::SerializedHandle& handle,
+ Handles* handles,
+ IPC::Message* msg,
+ int* handle_index) {
+ handles->push_back(handle);
+ if (msg)
+ WriteHandle((*handle_index)++, handle, msg);
+}
+
+// For PpapiMsg_ResourceReply and the reply to PpapiHostMsg_ResourceSyncCall,
+// the handles are carried inside the ResourceMessageReplyParams.
+// NOTE: We only translate handles from host->NaCl. The only kind of
+// ResourceMessageParams that travels this direction is
+// ResourceMessageReplyParams, so that's the only one we need to handle.
+void ConvertHandlesInParam(
+ const ppapi::proxy::ResourceMessageReplyParams& params,
+ Handles* handles,
+ IPC::Message* msg,
+ int* handle_index) {
+ // First, if we need to rewrite the message parameters, write everything
+ // before the handles (there's nothing after the handles).
+ if (msg) {
+ params.WriteReplyHeader(msg);
+ // IPC writes the vector length as an int before the contents of the
+ // vector.
+ msg->WriteInt(static_cast<int>(params.handles().size()));
+ }
+ for (Handles::const_iterator iter = params.handles().begin();
+ iter != params.handles().end();
+ ++iter) {
+ // ConvertHandle will write each handle to |msg|, if necessary.
+ ConvertHandlesInParam(*iter, handles, msg, handle_index);
+ }
+ // Tell ResourceMessageReplyParams that we have taken the handles, so it
+ // shouldn't close them. The NaCl runtime will take ownership of them.
+ params.ConsumeHandles();
+}
+
+// This overload is to catch all types other than SerializedHandle or
+// ResourceMessageReplyParams. On Windows, |msg| will be a valid pointer, and we
+// must write |param| to it.
+template <class T>
+void ConvertHandlesInParam(const T& param,
+ Handles* /* handles */,
+ IPC::Message* msg,
+ int* /* handle_index */) {
+ // It's not a handle, so just write to the output message, if necessary.
+ if (msg)
+ IPC::WriteParam(msg, param);
+}
+
+// These just break apart the given tuple and run ConvertHandle 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 all of the message parameters, writing the handles in POSIX style
+// for NaCl.
+template <class A>
+void ConvertHandlesImpl(const Tuple1<A>& t1, Handles* handles,
+ IPC::Message* msg) {
+ int handle_index = 0;
+ ConvertHandlesInParam(t1.a, handles, msg, &handle_index);
+}
+template <class A, class B>
+void ConvertHandlesImpl(const Tuple2<A, B>& t1, Handles* handles,
+ IPC::Message* msg) {
+ int handle_index = 0;
+ ConvertHandlesInParam(t1.a, handles, msg, &handle_index);
+ ConvertHandlesInParam(t1.b, handles, msg, &handle_index);
+}
+template <class A, class B, class C>
+void ConvertHandlesImpl(const Tuple3<A, B, C>& t1, Handles* handles,
+ IPC::Message* msg) {
+ int handle_index = 0;
+ ConvertHandlesInParam(t1.a, handles, msg, &handle_index);
+ ConvertHandlesInParam(t1.b, handles, msg, &handle_index);
+ ConvertHandlesInParam(t1.c, handles, msg, &handle_index);
+}
+template <class A, class B, class C, class D>
+void ConvertHandlesImpl(const Tuple4<A, B, C, D>& t1, Handles* handles,
+ IPC::Message* msg) {
+ int handle_index = 0;
+ ConvertHandlesInParam(t1.a, handles, msg, &handle_index);
+ ConvertHandlesInParam(t1.b, handles, msg, &handle_index);
+ ConvertHandlesInParam(t1.c, handles, msg, &handle_index);
+ ConvertHandlesInParam(t1.d, handles, msg, &handle_index);
+}
+
+template <class MessageType>
+class HandleConverterImpl {
+ public:
+ explicit HandleConverterImpl(const IPC::Message* msg)
+ : msg_(static_cast<const MessageType*>(msg)) {
+ }
+ bool ConvertMessage(Handles* handles, IPC::Message* out_msg) {
+ typename TupleTypes<typename MessageType::Schema::Param>::ValueTuple params;
+ if (!MessageType::Read(msg_, &params))
+ return false;
+ ConvertHandlesImpl(params, handles, out_msg);
+ return true;
+ }
+
+ bool ConvertReply(Handles* handles, IPC::SyncMessage* out_msg) {
+ typename TupleTypes<typename MessageType::Schema::ReplyParam>::ValueTuple
+ params;
+ if (!MessageType::ReadReplyParam(msg_, &params))
+ return false;
+ // If we need to rewrite the message (i.e., on Windows), we need to make
+ // sure we write the message id first.
+ if (out_msg) {
+ out_msg->set_reply();
+ int id = IPC::SyncMessage::GetMessageId(*msg_);
+ out_msg->WriteInt(id);
+ }
+ ConvertHandlesImpl(params, handles, out_msg);
+ return true;
+ }
+ // TODO(dmichael): Add ConvertSyncMessage for outgoing sync messages, if we
+ // ever pass handles in one of those.
+
+ private:
+ const MessageType* msg_;
+};
+
+} // namespace
+
+#define CASE_FOR_MESSAGE(MESSAGE_TYPE) \
+ case MESSAGE_TYPE::ID: { \
+ HandleConverterImpl<MESSAGE_TYPE> extractor(&msg); \
+ if (!extractor.ConvertMessage(handles, new_msg_ptr->get())) \
+ return false; \
+ break; \
+ }
+#define CASE_FOR_REPLY(MESSAGE_TYPE) \
+ case MESSAGE_TYPE::ID: { \
+ HandleConverterImpl<MESSAGE_TYPE> extractor(&msg); \
+ if (!extractor.ConvertReply( \
+ handles, \
+ static_cast<IPC::SyncMessage*>(new_msg_ptr->get()))) \
+ return false; \
+ break; \
+ }
+
+namespace ppapi {
+namespace proxy {
+
+class SerializedHandle;
+
+HandleConverter::HandleConverter() {
+}
+
+bool HandleConverter::ConvertNativeHandlesToPosix(
+ const IPC::Message& msg,
+ std::vector<SerializedHandle>* handles,
+ scoped_ptr<IPC::Message>* new_msg_ptr) {
+ DCHECK(handles);
+ DCHECK(new_msg_ptr);
+ DCHECK(!new_msg_ptr->get());
+
+ // In Windows, we need to re-write the contents of the message. This is
+ // because in Windows IPC code, native HANDLE values are serialized in the
+ // body of the message.
+ //
+ // In POSIX, we only serialize an index in to a FileDescriptorSet, and the
+ // actual file descriptors are sent out-of-band. So on Windows, to make a
+ // message that's compatible with Windows, we need to write a new message that
+ // has simple indices in the message body instead of the HANDLEs.
+ //
+ // NOTE: This means on Windows, new_msg_ptr's serialized contents are not
+ // compatible with Windows IPC deserialization code; it is intended to be
+ // passed to NaCl.
+#if defined(OS_WIN)
+ new_msg_ptr->reset(
+ new IPC::Message(msg.routing_id(), msg.type(), msg.priority()));
+#else
+ // Even on POSIX, we have to rewrite messages to create channels, because
+ // these contain a handle with an invalid (place holder) descriptor. The
+ // message sending code sees this and doesn't pass the descriptor over
+ // correctly.
+ if (msg.type() == PpapiMsg_CreateNaClChannel::ID) {
+ new_msg_ptr->reset(
+ new IPC::Message(msg.routing_id(), msg.type(), msg.priority()));
+ }
+#endif
+
+ switch (msg.type()) {
+ CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel)
+ CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated)
+ CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply)
+ case IPC_REPLY_ID: {
+ int id = IPC::SyncMessage::GetMessageId(msg);
+ PendingSyncMsgMap::iterator iter(pending_sync_msgs_.find(id));
+ if (iter == pending_sync_msgs_.end()) {
+ NOTREACHED();
+ return false;
+ }
+ uint32_t type = iter->second;
+ pending_sync_msgs_.erase(iter);
+ switch (type) {
+ CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer)
+ CASE_FOR_REPLY(PpapiHostMsg_PPBImageData_CreateNaCl)
+ CASE_FOR_REPLY(PpapiHostMsg_ResourceSyncCall)
+ default:
+ // Do nothing for messages we don't know.
+ break;
+ }
+ break;
+ }
+ default:
+ // Do nothing for messages we don't know.
+ break;
+ }
+ return true;
+}
+
+void HandleConverter::RegisterSyncMessageForReply(const IPC::Message& msg) {
+ DCHECK(msg.is_sync());
+
+ int msg_id = IPC::SyncMessage::GetMessageId(msg);
+ DCHECK(pending_sync_msgs_.find(msg_id) == pending_sync_msgs_.end());
+
+ pending_sync_msgs_[msg_id] = msg.type();
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/handle_converter.h b/ppapi/proxy/handle_converter.h
new file mode 100644
index 0000000..456ee8d
--- /dev/null
+++ b/ppapi/proxy/handle_converter.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2013 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.
+
+#ifndef PPAPI_PROXY_HANDLE_CONVERTER_H_
+#define PPAPI_PROXY_HANDLE_CONVERTER_H_
+
+#include <map>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace ppapi {
+namespace proxy {
+
+class SerializedHandle;
+
+class PPAPI_PROXY_EXPORT HandleConverter {
+ public:
+ HandleConverter();
+
+ // Convert the native handles in |msg| to NaCl style.
+ // In some cases (e.g., Windows), we need to re-write the contents of the
+ // message; in those cases, |new_msg_ptr| will be set to the new message.
+ // If |msg| is already in a good form for NaCl, |new_msg_ptr| is left NULL.
+ // See the explanation in the body of the method.
+ //
+ // In either case, all the handles in |msg| are extracted into |handles| so
+ // that they can be converted to NaClDesc handles.
+ // See chrome/nacl/nacl_ipc_adapter.cc for where this gets used.
+ bool ConvertNativeHandlesToPosix(const IPC::Message& msg,
+ std::vector<SerializedHandle>* handles,
+ scoped_ptr<IPC::Message>* new_msg_ptr);
+
+ // This method informs HandleConverter that a sync message is being sent so
+ // that it can associate reply messages with their type.
+ //
+ // Users of HandleConverter must call this when they send a synchronous
+ // message, otherwise HandleConverter won't be able to convert handles in
+ // replies.
+ void RegisterSyncMessageForReply(const IPC::Message& msg);
+
+ private:
+ // When we send a synchronous message (from untrusted to trusted), we store
+ // its type here, so that later we can associate the reply with its type
+ // and potentially translate handles in the message.
+ typedef std::map<int, uint32> PendingSyncMsgMap;
+ PendingSyncMsgMap pending_sync_msgs_;
+
+ DISALLOW_COPY_AND_ASSIGN(HandleConverter);
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_HANDLE_CONVERTER_H_
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 54d6bfb..b4666e4 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -45,6 +45,7 @@
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/proxy/serialized_flash_menu.h"
+#include "ppapi/proxy/serialized_handle.h"
#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/proxy/serialized_var.h"
#include "ppapi/shared_impl/dir_contents.h"
diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h
index 2f85a83..757bdeb 100644
--- a/ppapi/proxy/ppb_audio_proxy.h
+++ b/ppapi/proxy/ppb_audio_proxy.h
@@ -17,7 +17,6 @@
#include "ppapi/c/ppb_audio_config.h"
#include "ppapi/proxy/interface_proxy.h"
#include "ppapi/proxy/proxy_completion_callback_factory.h"
-#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/utility/completion_callback_factory.h"
namespace ppapi {
@@ -26,6 +25,8 @@ class HostResource;
namespace proxy {
+class SerializedHandle;
+
class PPB_Audio_Proxy : public InterfaceProxy {
public:
PPB_Audio_Proxy(Dispatcher* dispatcher);
diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h
index 41f5e19..ff8e0ca 100644
--- a/ppapi/proxy/ppb_buffer_proxy.h
+++ b/ppapi/proxy/ppb_buffer_proxy.h
@@ -8,7 +8,6 @@
#include "base/shared_memory.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/interface_proxy.h"
-#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/ppb_buffer_api.h"
@@ -18,6 +17,8 @@ class HostResource;
namespace proxy {
+class SerializedHandle;
+
class Buffer : public thunk::PPB_Buffer_API, public Resource {
public:
Buffer(const HostResource& resource,
diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h
index 17529a1..493c489 100644
--- a/ppapi/proxy/ppb_graphics_3d_proxy.h
+++ b/ppapi/proxy/ppb_graphics_3d_proxy.h
@@ -13,7 +13,6 @@
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/interface_proxy.h"
#include "ppapi/proxy/proxy_completion_callback_factory.h"
-#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/utility/completion_callback_factory.h"
@@ -24,6 +23,8 @@ class HostResource;
namespace proxy {
+class SerializedHandle;
+
class Graphics3D : public PPB_Graphics3D_Shared {
public:
explicit Graphics3D(const HostResource& resource);
diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h
index c56217a5..ae24b35 100644
--- a/ppapi/proxy/ppb_image_data_proxy.h
+++ b/ppapi/proxy/ppb_image_data_proxy.h
@@ -27,6 +27,8 @@ class TransportDIB;
namespace ppapi {
namespace proxy {
+class SerializedHandle;
+
// The proxied image data resource. Unlike most resources, this needs to be
// public in the header since a number of other resources need to access it.
class ImageData : public ppapi::Resource,
diff --git a/ppapi/proxy/resource_message_params.h b/ppapi/proxy/resource_message_params.h
index 0e42ec9..21b0f73 100644
--- a/ppapi/proxy/resource_message_params.h
+++ b/ppapi/proxy/resource_message_params.h
@@ -11,7 +11,7 @@
#include "ipc/ipc_message_utils.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
-#include "ppapi/proxy/serialized_structs.h"
+#include "ppapi/proxy/serialized_handle.h"
namespace ppapi {
namespace proxy {
diff --git a/ppapi/proxy/serialized_handle.cc b/ppapi/proxy/serialized_handle.cc
new file mode 100644
index 0000000..0159e6f
--- /dev/null
+++ b/ppapi/proxy/serialized_handle.cc
@@ -0,0 +1,133 @@
+// Copyright (c) 2013 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 "ppapi/proxy/serialized_handle.h"
+
+#include "base/pickle.h"
+#include "base/platform_file.h"
+#include "base/shared_memory.h"
+#include "build/build_config.h"
+#include "ipc/ipc_platform_file.h"
+
+#if defined(OS_NACL)
+#include <unistd.h>
+#endif
+
+namespace ppapi {
+namespace proxy {
+
+SerializedHandle::SerializedHandle()
+ : type_(INVALID),
+ shm_handle_(base::SharedMemory::NULLHandle()),
+ size_(0),
+ descriptor_(IPC::InvalidPlatformFileForTransit()) {
+}
+
+SerializedHandle::SerializedHandle(Type type_param)
+ : type_(type_param),
+ shm_handle_(base::SharedMemory::NULLHandle()),
+ size_(0),
+ descriptor_(IPC::InvalidPlatformFileForTransit()) {
+}
+
+SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle,
+ uint32 size)
+ : type_(SHARED_MEMORY),
+ shm_handle_(handle),
+ size_(size),
+ descriptor_(IPC::InvalidPlatformFileForTransit()) {
+}
+
+SerializedHandle::SerializedHandle(
+ Type type,
+ const IPC::PlatformFileForTransit& socket_descriptor)
+ : type_(type),
+ shm_handle_(base::SharedMemory::NULLHandle()),
+ size_(0),
+ descriptor_(socket_descriptor) {
+}
+
+bool SerializedHandle::IsHandleValid() const {
+ switch (type_) {
+ case SHARED_MEMORY:
+ return base::SharedMemory::IsHandleValid(shm_handle_);
+ case SOCKET:
+ case CHANNEL_HANDLE:
+ case FILE:
+ return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
+ case INVALID:
+ return false;
+ // No default so the compiler will warn us if a new type is added.
+ }
+ return false;
+}
+
+void SerializedHandle::Close() {
+ if (IsHandleValid()) {
+ switch (type_) {
+ case INVALID:
+ NOTREACHED();
+ break;
+ case SHARED_MEMORY:
+ base::SharedMemory::CloseHandle(shm_handle_);
+ break;
+ case SOCKET:
+ case CHANNEL_HANDLE:
+ case FILE:
+ base::PlatformFile file =
+ IPC::PlatformFileForTransitToPlatformFile(descriptor_);
+#if !defined(OS_NACL)
+ base::ClosePlatformFile(file);
+#else
+ close(file);
+#endif
+ break;
+ // No default so the compiler will warn us if a new type is added.
+ }
+ }
+ *this = SerializedHandle();
+}
+
+// static
+bool SerializedHandle::WriteHeader(const Header& hdr, Pickle* pickle) {
+ if (!pickle->WriteInt(hdr.type))
+ return false;
+ if (hdr.type == SHARED_MEMORY) {
+ if (!pickle->WriteUInt32(hdr.size))
+ return false;
+ }
+ return true;
+}
+
+// static
+bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) {
+ *hdr = Header(INVALID, 0);
+ int type = 0;
+ if (!iter->ReadInt(&type))
+ return false;
+ bool valid_type = false;
+ switch (type) {
+ case SHARED_MEMORY: {
+ uint32 size = 0;
+ if (!iter->ReadUInt32(&size))
+ return false;
+ hdr->size = size;
+ valid_type = true;
+ break;
+ }
+ case SOCKET:
+ case CHANNEL_HANDLE:
+ case FILE:
+ case INVALID:
+ valid_type = true;
+ break;
+ // No default so the compiler will warn us if a new type is added.
+ }
+ if (valid_type)
+ hdr->type = Type(type);
+ return valid_type;
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/serialized_handle.h b/ppapi/proxy/serialized_handle.h
new file mode 100644
index 0000000..9e4136f
--- /dev/null
+++ b/ppapi/proxy/serialized_handle.h
@@ -0,0 +1,141 @@
+// Copyright (c) 2013 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.
+
+#ifndef PPAPI_PROXY_SERIALIZED_HANDLES_H_
+#define PPAPI_PROXY_SERIALIZED_HANDLES_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/shared_memory.h"
+#include "build/build_config.h"
+#include "ipc/ipc_platform_file.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+
+class Pickle;
+
+namespace ppapi {
+namespace proxy {
+
+// SerializedHandle is a unified structure for holding a handle (e.g., a shared
+// memory handle, socket descriptor, etc). This is useful for passing handles in
+// resource messages and also makes it easier to translate handles in
+// NaClIPCAdapter for use in NaCl.
+class PPAPI_PROXY_EXPORT SerializedHandle {
+ public:
+ enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE };
+ struct Header {
+ Header() : type(INVALID), size(0) {}
+ Header(Type type_arg, uint32 size_arg)
+ : type(type_arg), size(size_arg) {
+ }
+ Type type;
+ uint32 size;
+ };
+
+ SerializedHandle();
+ // Create an invalid handle of the given type.
+ explicit SerializedHandle(Type type);
+
+ // Create a shared memory handle.
+ SerializedHandle(const base::SharedMemoryHandle& handle, uint32 size);
+
+ // Create a socket, channel or file handle.
+ SerializedHandle(const Type type,
+ const IPC::PlatformFileForTransit& descriptor);
+
+ Type type() const { return type_; }
+ bool is_shmem() const { return type_ == SHARED_MEMORY; }
+ bool is_socket() const { return type_ == SOCKET; }
+ bool is_channel_handle() const { return type_ == CHANNEL_HANDLE; }
+ bool is_file() const { return type_ == FILE; }
+ const base::SharedMemoryHandle& shmem() const {
+ DCHECK(is_shmem());
+ return shm_handle_;
+ }
+ uint32 size() const {
+ DCHECK(is_shmem());
+ return size_;
+ }
+ const IPC::PlatformFileForTransit& descriptor() const {
+ DCHECK(is_socket() || is_channel_handle() || is_file());
+ return descriptor_;
+ }
+ void set_shmem(const base::SharedMemoryHandle& handle, uint32 size) {
+ type_ = SHARED_MEMORY;
+ shm_handle_ = handle;
+ size_ = size;
+
+ descriptor_ = IPC::InvalidPlatformFileForTransit();
+ }
+ void set_socket(const IPC::PlatformFileForTransit& socket) {
+ type_ = SOCKET;
+ descriptor_ = socket;
+
+ shm_handle_ = base::SharedMemory::NULLHandle();
+ size_ = 0;
+ }
+ void set_channel_handle(const IPC::PlatformFileForTransit& descriptor) {
+ type_ = CHANNEL_HANDLE;
+
+ descriptor_ = descriptor;
+ shm_handle_ = base::SharedMemory::NULLHandle();
+ size_ = 0;
+ }
+ void set_file_handle(const IPC::PlatformFileForTransit& descriptor) {
+ type_ = FILE;
+
+ descriptor_ = descriptor;
+ shm_handle_ = base::SharedMemory::NULLHandle();
+ size_ = 0;
+ }
+ void set_null_shmem() {
+ set_shmem(base::SharedMemory::NULLHandle(), 0);
+ }
+ void set_null_socket() {
+ set_socket(IPC::InvalidPlatformFileForTransit());
+ }
+ void set_null_channel_handle() {
+ set_channel_handle(IPC::InvalidPlatformFileForTransit());
+ }
+ void set_null_file_handle() {
+ set_file_handle(IPC::InvalidPlatformFileForTransit());
+ }
+ bool IsHandleValid() const;
+
+ Header header() const {
+ return Header(type_, size_);
+ }
+
+ // Closes the handle and sets it to invalid.
+ void Close();
+
+ // Write/Read a Header, which contains all the data except the handle. This
+ // allows us to write the handle in a platform-specific way, as is necessary
+ // in NaClIPCAdapter to share handles with NaCl from Windows.
+ static bool WriteHeader(const Header& hdr, Pickle* pickle);
+ static bool ReadHeader(PickleIterator* iter, Header* hdr);
+
+ private:
+ // The kind of handle we're holding.
+ Type type_;
+
+ // We hold more members than we really need; we can't easily use a union,
+ // because we hold non-POD types. But these types are pretty light-weight. If
+ // we add more complex things later, we should come up with a more memory-
+ // efficient strategy.
+ // These are valid if type == SHARED_MEMORY.
+ base::SharedMemoryHandle shm_handle_;
+ uint32 size_;
+
+ // This is valid if type == SOCKET || type == CHANNEL_HANDLE.
+ IPC::PlatformFileForTransit descriptor_;
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_SERIALIZED_HANDLES_H_
diff --git a/ppapi/proxy/serialized_structs.cc b/ppapi/proxy/serialized_structs.cc
index fcd41a7..ebd7ed0 100644
--- a/ppapi/proxy/serialized_structs.cc
+++ b/ppapi/proxy/serialized_structs.cc
@@ -5,20 +5,13 @@
#include "ppapi/proxy/serialized_structs.h"
#include "base/pickle.h"
-#include "base/platform_file.h"
-#include "base/shared_memory.h"
#include "build/build_config.h"
-#include "ipc/ipc_platform_file.h"
#include "ppapi/c/dev/ppb_font_dev.h"
#include "ppapi/c/pp_file_info.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
#include "ppapi/shared_impl/var.h"
-#if defined(OS_NACL)
-#include <unistd.h>
-#endif
-
namespace ppapi {
namespace proxy {
@@ -102,117 +95,5 @@ PPBFlash_DrawGlyphs_Params::PPBFlash_DrawGlyphs_Params()
PPBFlash_DrawGlyphs_Params::~PPBFlash_DrawGlyphs_Params() {}
-SerializedHandle::SerializedHandle()
- : type_(INVALID),
- shm_handle_(base::SharedMemory::NULLHandle()),
- size_(0),
- descriptor_(IPC::InvalidPlatformFileForTransit()) {
-}
-
-SerializedHandle::SerializedHandle(Type type_param)
- : type_(type_param),
- shm_handle_(base::SharedMemory::NULLHandle()),
- size_(0),
- descriptor_(IPC::InvalidPlatformFileForTransit()) {
-}
-
-SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle,
- uint32_t size)
- : type_(SHARED_MEMORY),
- shm_handle_(handle),
- size_(size),
- descriptor_(IPC::InvalidPlatformFileForTransit()) {
-}
-
-SerializedHandle::SerializedHandle(
- Type type,
- const IPC::PlatformFileForTransit& socket_descriptor)
- : type_(type),
- shm_handle_(base::SharedMemory::NULLHandle()),
- size_(0),
- descriptor_(socket_descriptor) {
-}
-
-bool SerializedHandle::IsHandleValid() const {
- switch (type_) {
- case SHARED_MEMORY:
- return base::SharedMemory::IsHandleValid(shm_handle_);
- case SOCKET:
- case CHANNEL_HANDLE:
- case FILE:
- return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
- case INVALID:
- return false;
- // No default so the compiler will warn us if a new type is added.
- }
- return false;
-}
-
-void SerializedHandle::Close() {
- if (IsHandleValid()) {
- switch (type_) {
- case INVALID:
- NOTREACHED();
- break;
- case SHARED_MEMORY:
- base::SharedMemory::CloseHandle(shm_handle_);
- break;
- case SOCKET:
- case CHANNEL_HANDLE:
- case FILE:
- base::PlatformFile file =
- IPC::PlatformFileForTransitToPlatformFile(descriptor_);
-#if !defined(OS_NACL)
- base::ClosePlatformFile(file);
-#else
- close(file);
-#endif
- break;
- // No default so the compiler will warn us if a new type is added.
- }
- }
- *this = SerializedHandle();
-}
-
-// static
-bool SerializedHandle::WriteHeader(const Header& hdr, Pickle* pickle) {
- if (!pickle->WriteInt(hdr.type))
- return false;
- if (hdr.type == SHARED_MEMORY) {
- if (!pickle->WriteUInt32(hdr.size))
- return false;
- }
- return true;
-}
-
-// static
-bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) {
- *hdr = Header(INVALID, 0);
- int type = 0;
- if (!iter->ReadInt(&type))
- return false;
- bool valid_type = false;
- switch (type) {
- case SHARED_MEMORY: {
- uint32_t size = 0;
- if (!iter->ReadUInt32(&size))
- return false;
- hdr->size = size;
- valid_type = true;
- break;
- }
- case SOCKET:
- case CHANNEL_HANDLE:
- case FILE:
- case INVALID:
- valid_type = true;
- break;
- // No default so the compiler will warn us if a new type is added.
- }
- if (valid_type)
- hdr->type = Type(type);
- return valid_type;
-}
-
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h
index 5c5dcab..dcb99817 100644
--- a/ppapi/proxy/serialized_structs.h
+++ b/ppapi/proxy/serialized_structs.h
@@ -11,7 +11,6 @@
#include "base/logging.h"
#include "base/shared_memory.h"
#include "build/build_config.h"
-#include "ipc/ipc_platform_file.h"
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_point.h"
@@ -87,119 +86,6 @@ struct PPBURLLoader_UpdateProgress_Params {
int64_t total_bytes_to_be_received;
};
-// We put all our handles in a unified structure to make it easy to translate
-// them in NaClIPCAdapter for use in NaCl.
-class PPAPI_PROXY_EXPORT SerializedHandle {
- public:
- enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE };
- struct Header {
- Header() : type(INVALID), size(0) {}
- Header(Type type_arg, uint32_t size_arg)
- : type(type_arg), size(size_arg) {
- }
- Type type;
- uint32_t size;
- };
-
- SerializedHandle();
- // Create an invalid handle of the given type.
- explicit SerializedHandle(Type type);
-
- // Create a shared memory handle.
- SerializedHandle(const base::SharedMemoryHandle& handle, uint32_t size);
-
- // Create a socket, channel or file handle.
- SerializedHandle(const Type type,
- const IPC::PlatformFileForTransit& descriptor);
-
- Type type() const { return type_; }
- bool is_shmem() const { return type_ == SHARED_MEMORY; }
- bool is_socket() const { return type_ == SOCKET; }
- bool is_channel_handle() const { return type_ == CHANNEL_HANDLE; }
- bool is_file() const { return type_ == FILE; }
- const base::SharedMemoryHandle& shmem() const {
- DCHECK(is_shmem());
- return shm_handle_;
- }
- uint32_t size() const {
- DCHECK(is_shmem());
- return size_;
- }
- const IPC::PlatformFileForTransit& descriptor() const {
- DCHECK(is_socket() || is_channel_handle() || is_file());
- return descriptor_;
- }
- void set_shmem(const base::SharedMemoryHandle& handle, uint32_t size) {
- type_ = SHARED_MEMORY;
- shm_handle_ = handle;
- size_ = size;
-
- descriptor_ = IPC::InvalidPlatformFileForTransit();
- }
- void set_socket(const IPC::PlatformFileForTransit& socket) {
- type_ = SOCKET;
- descriptor_ = socket;
-
- shm_handle_ = base::SharedMemory::NULLHandle();
- size_ = 0;
- }
- void set_channel_handle(const IPC::PlatformFileForTransit& descriptor) {
- type_ = CHANNEL_HANDLE;
-
- descriptor_ = descriptor;
- shm_handle_ = base::SharedMemory::NULLHandle();
- size_ = 0;
- }
- void set_file_handle(const IPC::PlatformFileForTransit& descriptor) {
- type_ = FILE;
-
- descriptor_ = descriptor;
- shm_handle_ = base::SharedMemory::NULLHandle();
- size_ = 0;
- }
- void set_null_shmem() {
- set_shmem(base::SharedMemory::NULLHandle(), 0);
- }
- void set_null_socket() {
- set_socket(IPC::InvalidPlatformFileForTransit());
- }
- void set_null_channel_handle() {
- set_channel_handle(IPC::InvalidPlatformFileForTransit());
- }
- void set_null_file_handle() {
- set_file_handle(IPC::InvalidPlatformFileForTransit());
- }
- bool IsHandleValid() const;
-
- Header header() const {
- return Header(type_, size_);
- }
-
- // Closes the handle and sets it to invalid.
- void Close();
-
- // Write/Read a Header, which contains all the data except the handle. This
- // allows us to write the handle in a platform-specific way, as is necessary
- // in NaClIPCAdapter to share handles with NaCl from Windows.
- static bool WriteHeader(const Header& hdr, Pickle* pickle);
- static bool ReadHeader(PickleIterator* iter, Header* hdr);
-
- private:
- // The kind of handle we're holding.
- Type type_;
-
- // We hold more members than we really need; we can't easily use a union,
- // because we hold non-POD types. But these types are pretty light-weight. If
- // we add more complex things later, we should come up with a more memory-
- // efficient strategy.
- // These are valid if type == SHARED_MEMORY.
- base::SharedMemoryHandle shm_handle_;
- uint32_t size_;
-
- // This is valid if type == SOCKET || type == CHANNEL_HANDLE.
- IPC::PlatformFileForTransit descriptor_;
-};
-
struct PPPDecryptor_Buffer {
ppapi::HostResource resource;
uint32_t size;