summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-30 13:24:23 +0000
committerbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-30 13:24:23 +0000
commit68ca863f9323a1ab2d02545f893f34a1e58a1a3f (patch)
treed2c2a910fcdd242ca70815bba3be4f9420cd0df7 /ppapi
parent6ecc9adc9370980d134c5e3591a27712ed8f8932 (diff)
downloadchromium_src-68ca863f9323a1ab2d02545f893f34a1e58a1a3f.zip
chromium_src-68ca863f9323a1ab2d02545f893f34a1e58a1a3f.tar.gz
chromium_src-68ca863f9323a1ab2d02545f893f34a1e58a1a3f.tar.bz2
Change NaCl IPC PPAPI proxy startup to support a NaCl-Browser process
channel. NaClProcessHost now creates an initial NaCl-Browser channel, then uses it to send a message to create the NaCl-Renderer channel. The main() for the IPC-IRT creates a PpapiDispatcher object to manage this channel and manage the PluginDispatchers for each renderer. BUG=116317 TEST=manual Review URL: https://chromiumcodereview.appspot.com/10883047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154134 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/proxy/plugin_main_nacl.cc188
-rw-r--r--ppapi/proxy/ppapi_messages.h8
-rw-r--r--ppapi/proxy/ppapi_param_traits.cc9
-rw-r--r--ppapi/proxy/ppb_audio_proxy.cc9
-rw-r--r--ppapi/proxy/serialized_structs.cc10
-rw-r--r--ppapi/proxy/serialized_structs.h25
6 files changed, 183 insertions, 66 deletions
diff --git a/ppapi/proxy/plugin_main_nacl.cc b/ppapi/proxy/plugin_main_nacl.cc
index 96a6891..ac7cdcd 100644
--- a/ppapi/proxy/plugin_main_nacl.cc
+++ b/ppapi/proxy/plugin_main_nacl.cc
@@ -23,6 +23,7 @@
#include "ppapi/c/ppp_instance.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
+#include "ppapi/proxy/plugin_proxy_delegate.h"
#include "ppapi/shared_impl/ppb_audio_shared.h"
#if defined(IPC_MESSAGE_LOG_ENABLED)
@@ -36,60 +37,48 @@
using ppapi::proxy::PluginDispatcher;
using ppapi::proxy::PluginGlobals;
+using ppapi::proxy::PluginProxyDelegate;
+using ppapi::proxy::ProxyChannel;
+using ppapi::proxy::SerializedHandle;
namespace {
-// Copied from src/content/ppapi_plugin/ppapi_thread. This is a minimal
-// implementation to get us started.
-class PluginDispatcherDelegate : public PluginDispatcher::PluginDelegate {
+// This class manages communication between the plugin and the browser, and
+// manages the PluginDispatcher instances for communication between the plugin
+// and the renderer.
+class PpapiDispatcher : public ProxyChannel,
+ public PluginDispatcher::PluginDelegate,
+ public PluginProxyDelegate {
public:
- explicit PluginDispatcherDelegate(
- scoped_refptr<base::MessageLoopProxy> io_loop)
- : message_loop_(io_loop),
- shutdown_event_(true, false) {
- }
-
- virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE {
- return message_loop_.get();
- }
-
- virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE {
- return &shutdown_event_;
- }
+ explicit PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop);
+ // PluginDispatcher::PluginDelegate 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 {
- return IPC::InvalidPlatformFileForTransit();
- }
+ bool should_close_source) OVERRIDE;
+ virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE;
+ virtual uint32 Register(PluginDispatcher* plugin_dispatcher) OVERRIDE;
+ virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE;
- virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE {
- return &instances_;
- }
-
- virtual uint32 Register(PluginDispatcher* plugin_dispatcher) OVERRIDE {
- if (!plugin_dispatcher ||
- plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
- return 0;
- }
-
- uint32 id = 0;
- do {
- // Although it is unlikely, make sure that we won't cause any trouble when
- // the counter overflows.
- id = next_plugin_dispatcher_id_++;
- } while (id == 0 ||
- plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
- plugin_dispatchers_[id] = plugin_dispatcher;
- return id;
- }
+ // PluginProxyDelegate implementation.
+ virtual bool SendToBrowser(IPC::Message* msg) OVERRIDE;
+ virtual IPC::Sender* GetBrowserSender() OVERRIDE;
+ virtual std::string GetUILanguage() OVERRIDE;
+ virtual void PreCacheFont(const void* logfontw) OVERRIDE;
+ virtual void SetActiveURL(const std::string& url) OVERRIDE;
- virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE {
- plugin_dispatchers_.erase(plugin_dispatcher_id);
- }
+ // IPC::Listener implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
+ void OnMsgCreateNaClChannel(int renderer_id,
+ bool incognito,
+ SerializedHandle handle);
+ void OnPluginDispatcherMessageReceived(const IPC::Message& msg);
+
std::set<PP_Instance> instances_;
std::map<uint32, PluginDispatcher*> plugin_dispatchers_;
uint32 next_plugin_dispatcher_id_;
@@ -97,6 +86,113 @@ class PluginDispatcherDelegate : public PluginDispatcher::PluginDelegate {
base::WaitableEvent shutdown_event_;
};
+PpapiDispatcher::PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop)
+ : message_loop_(io_loop),
+ shutdown_event_(true, false) {
+ IPC::ChannelHandle channel_handle(
+ "NaCl IPC", base::FileDescriptor(NACL_IPC_FD, false));
+ InitWithChannel(this, channel_handle, false); // Channel is server.
+}
+
+base::MessageLoopProxy* PpapiDispatcher::GetIPCMessageLoop() {
+ return message_loop_.get();
+}
+
+base::WaitableEvent* PpapiDispatcher::GetShutdownEvent() {
+ return &shutdown_event_;
+}
+
+IPC::PlatformFileForTransit PpapiDispatcher::ShareHandleWithRemote(
+ base::PlatformFile handle,
+ const IPC::SyncChannel& channel,
+ bool should_close_source) OVERRIDE {
+ return IPC::InvalidPlatformFileForTransit();
+}
+
+std::set<PP_Instance>* PpapiDispatcher::GetGloballySeenInstanceIDSet() {
+ return &instances_;
+}
+
+uint32 PpapiDispatcher::Register(PluginDispatcher* plugin_dispatcher) {
+ if (!plugin_dispatcher ||
+ plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
+ return 0;
+ }
+
+ uint32 id = 0;
+ do {
+ // Although it is unlikely, make sure that we won't cause any trouble
+ // when the counter overflows.
+ id = next_plugin_dispatcher_id_++;
+ } while (id == 0 ||
+ plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
+ plugin_dispatchers_[id] = plugin_dispatcher;
+ return id;
+}
+
+void PpapiDispatcher::Unregister(uint32 plugin_dispatcher_id) {
+ plugin_dispatchers_.erase(plugin_dispatcher_id);
+}
+
+bool PpapiDispatcher::SendToBrowser(IPC::Message* msg) {
+ Send(msg);
+}
+
+IPC::Sender* PpapiDispatcher::GetBrowserSender() {
+ return this;
+}
+
+std::string PpapiDispatcher::GetUILanguage() {
+ NOTIMPLEMENTED();
+ return std::string();
+}
+
+void PpapiDispatcher::PreCacheFont(const void* logfontw) {
+ NOTIMPLEMENTED();
+}
+
+void PpapiDispatcher::SetActiveURL(const std::string& url) {
+ NOTIMPLEMENTED();
+}
+
+bool PpapiDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PpapiDispatcher, msg)
+ IPC_MESSAGE_HANDLER(PpapiMsg_CreateNaClChannel,
+ OnMsgCreateNaClChannel)
+ IPC_END_MESSAGE_MAP()
+ return true;
+}
+
+void PpapiDispatcher::OnMsgCreateNaClChannel(int renderer_id,
+ bool incognito,
+ SerializedHandle handle) {
+ PluginDispatcher* dispatcher =
+ new PluginDispatcher(::PPP_GetInterface, incognito);
+ // The channel handle's true name is not revealed here.
+ IPC::ChannelHandle channel_handle("nacl", handle.descriptor());
+ if (!dispatcher->InitPluginWithChannel(this, channel_handle, false)) {
+ delete dispatcher;
+ return;
+ }
+ // From here, the dispatcher will manage its own lifetime according to the
+ // lifetime of the attached channel.
+}
+
+void PpapiDispatcher::OnPluginDispatcherMessageReceived(
+ const IPC::Message& msg) {
+ // The first parameter should be a plugin dispatcher ID.
+ PickleIterator iter(msg);
+ uint32 id = 0;
+ if (!msg.ReadUInt32(&iter, &id)) {
+ NOTREACHED();
+ return;
+ }
+ std::map<uint32, ppapi::proxy::PluginDispatcher*>::iterator dispatcher =
+ plugin_dispatchers_.find(id);
+ if (dispatcher != plugin_dispatchers_.end())
+ dispatcher->second->OnMessageReceived(msg);
+}
+
} // namespace
void PpapiPluginRegisterThreadCreator(
@@ -127,13 +223,7 @@ int PpapiPluginMain() {
if (error)
return error;
- PluginDispatcherDelegate delegate(io_thread.message_loop_proxy());
-
- // TODO(dmichael) Figure out how to determine if we're in incognito
- PluginDispatcher dispatcher(::PPP_GetInterface, false /* incognito */);
- IPC::ChannelHandle channel_handle("NaCl IPC",
- base::FileDescriptor(NACL_IPC_FD, false));
- dispatcher.InitPluginWithChannel(&delegate, channel_handle, false);
+ PpapiDispatcher ppapi_dispatcher(io_thread.message_loop_proxy());
loop.Run();
return 0;
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 8ba5760..b1f460b 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -266,6 +266,14 @@ IPC_MESSAGE_CONTROL2(PpapiMsg_CreateChannel,
int /* renderer_id */,
bool /* incognito */)
+// Creates a channel to talk to a renderer. This message is only used by the
+// NaCl IPC proxy. It is intercepted by NaClIPCAdapter, which creates the
+// actual channel and rewrites the message for the untrusted side.
+IPC_MESSAGE_CONTROL3(PpapiMsg_CreateNaClChannel,
+ int /* renderer_id */,
+ bool /* incognito */,
+ ppapi::proxy::SerializedHandle /* channel_handle */)
+
// Each plugin may be referenced by multiple renderers. We need the instance
// IDs to be unique within a plugin, despite coming from different renderers,
// and unique within a renderer, despite going to different plugins. This means
diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc
index bcb2df0..a642da0 100644
--- a/ppapi/proxy/ppapi_param_traits.cc
+++ b/ppapi/proxy/ppapi_param_traits.cc
@@ -323,6 +323,7 @@ void ParamTraits<ppapi::proxy::SerializedHandle>::Write(Message* m,
ParamTraits<base::SharedMemoryHandle>::Write(m, p.shmem());
break;
case ppapi::proxy::SerializedHandle::SOCKET:
+ case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE:
ParamTraits<IPC::PlatformFileForTransit>::Write(m, p.descriptor());
break;
case ppapi::proxy::SerializedHandle::INVALID:
@@ -355,6 +356,14 @@ bool ParamTraits<ppapi::proxy::SerializedHandle>::Read(const Message* m,
}
break;
}
+ case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: {
+ IPC::PlatformFileForTransit desc;
+ if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) {
+ r->set_channel_handle(desc);
+ return true;
+ }
+ break;
+ }
case ppapi::proxy::SerializedHandle::INVALID:
return true;
// No default so the compiler will warn us if a new type is added.
diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc
index bc83be3..2bd5c89 100644
--- a/ppapi/proxy/ppb_audio_proxy.cc
+++ b/ppapi/proxy/ppb_audio_proxy.cc
@@ -26,6 +26,7 @@
#include "ppapi/thunk/thunk.h"
using ppapi::IntToPlatformFile;
+using ppapi::proxy::SerializedHandle;
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_Audio_API;
using ppapi::thunk::PPB_AudioConfig_API;
@@ -253,14 +254,14 @@ void PPB_Audio_Proxy::AudioChannelConnected(
// inconvenient to clean up. Our IPC code will automatically handle this for
// us, as long as the remote side always closes the handles it receives
// (in OnMsgNotifyAudioStreamCreated), even in the failure case.
- ppapi::proxy::SerializedHandle fd_wrapper(socket_handle);
+ SerializedHandle fd_wrapper(SerializedHandle::SOCKET, socket_handle);
// Note that we must call TotalSharedMemorySizeInBytes because
// Audio allocates extra space in shared memory for book-keeping, so the
// actual size of the shared memory buffer is larger than audio_buffer_length.
// When sending to NaCl, NaClIPCAdapter expects this size to match the size
// of the full shared memory buffer.
- ppapi::proxy::SerializedHandle handle_wrapper(
+ SerializedHandle handle_wrapper(
shared_memory,
media::TotalSharedMemorySizeInBytes(audio_buffer_length));
dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated(
@@ -309,8 +310,8 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated(
const HostResource& audio_id,
int32_t result_code,
- ppapi::proxy::SerializedHandle socket_handle,
- ppapi::proxy::SerializedHandle handle) {
+ SerializedHandle socket_handle,
+ SerializedHandle handle) {
CHECK(socket_handle.is_socket());
CHECK(handle.is_shmem());
EnterPluginFromHostResource<PPB_Audio_API> enter(audio_id);
diff --git a/ppapi/proxy/serialized_structs.cc b/ppapi/proxy/serialized_structs.cc
index 5e0989f..c647ed1 100644
--- a/ppapi/proxy/serialized_structs.cc
+++ b/ppapi/proxy/serialized_structs.cc
@@ -102,8 +102,9 @@ SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle,
}
SerializedHandle::SerializedHandle(
+ Type type,
const IPC::PlatformFileForTransit& socket_descriptor)
- : type_(SOCKET),
+ : type_(type),
shm_handle_(base::SharedMemory::NULLHandle()),
size_(0),
descriptor_(socket_descriptor) {
@@ -112,8 +113,8 @@ SerializedHandle::SerializedHandle(
bool SerializedHandle::IsHandleValid() const {
if (type_ == SHARED_MEMORY)
return base::SharedMemory::IsHandleValid(shm_handle_);
- else if (type_ == SOCKET)
- return (IPC::InvalidPlatformFileForTransit() == descriptor_);
+ else if (type_ == SOCKET || type_ == CHANNEL_HANDLE)
+ return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
return false;
}
@@ -145,8 +146,7 @@ bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) {
break;
}
case SOCKET:
- valid_type = true;
- break;
+ case CHANNEL_HANDLE:
case INVALID:
valid_type = true;
break;
diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h
index 7ad8456..ac9494d 100644
--- a/ppapi/proxy/serialized_structs.h
+++ b/ppapi/proxy/serialized_structs.h
@@ -107,7 +107,7 @@ struct PPPVideoCapture_Buffer {
// them in NaClIPCAdapter for use in NaCl.
class PPAPI_PROXY_EXPORT SerializedHandle {
public:
- enum Type { INVALID, SHARED_MEMORY, SOCKET };
+ enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE };
struct Header {
Header() : type(INVALID), size(0) {}
Header(Type type_arg, uint32_t size_arg)
@@ -124,15 +124,14 @@ class PPAPI_PROXY_EXPORT SerializedHandle {
// Create a shared memory handle.
SerializedHandle(const base::SharedMemoryHandle& handle, uint32_t size);
- // Create a socket handle.
- // TODO(dmichael): If we have other ways to use FDs later, this would be
- // ambiguous.
- explicit SerializedHandle(
- const IPC::PlatformFileForTransit& socket_descriptor);
+ // Create a socket or channel 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; }
const base::SharedMemoryHandle& shmem() const {
DCHECK(is_shmem());
return shm_handle_;
@@ -142,7 +141,7 @@ class PPAPI_PROXY_EXPORT SerializedHandle {
return size_;
}
const IPC::PlatformFileForTransit& descriptor() const {
- DCHECK(is_socket());
+ DCHECK(is_socket() || is_channel_handle());
return descriptor_;
}
void set_shmem(const base::SharedMemoryHandle& handle, uint32_t size) {
@@ -159,12 +158,22 @@ class PPAPI_PROXY_EXPORT SerializedHandle {
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_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());
+ }
bool IsHandleValid() const;
Header header() const {
@@ -189,7 +198,7 @@ class PPAPI_PROXY_EXPORT SerializedHandle {
base::SharedMemoryHandle shm_handle_;
uint32_t size_;
- // This is valid if type == SOCKET.
+ // This is valid if type == SOCKET || type == CHANNEL_HANDLE.
IPC::PlatformFileForTransit descriptor_;
};