summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/plugin_process_host.cc50
-rw-r--r--chrome/browser/plugin_process_host.h10
-rw-r--r--chrome/browser/plugin_service.cc2
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc2
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/common/ipc_channel_handle.h45
-rw-r--r--chrome/common/ipc_channel_posix.cc87
-rw-r--r--chrome/common/ipc_channel_posix.h18
-rw-r--r--chrome/common/ipc_message_utils.h29
-rw-r--r--chrome/common/plugin_messages_internal.h15
-rw-r--r--chrome/common/render_messages_internal.h11
-rw-r--r--chrome/plugin/plugin_channel.cc14
-rw-r--r--chrome/plugin/plugin_channel.h8
-rw-r--r--chrome/plugin/plugin_thread.cc13
-rw-r--r--chrome/plugin/plugin_thread.h14
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc6
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc18
17 files changed, 283 insertions, 60 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index 5216755..e704a5f 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -40,6 +40,7 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/render_messages.h"
+#include "chrome/common/ipc_channel_handle.h"
#include "net/base/cookie_monster.h"
#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
@@ -53,6 +54,10 @@
#include "sandbox/src/sandbox.h"
#endif
+#if defined(OS_POSIX)
+#include "chrome/common/ipc_channel_posix.h"
+#endif
+
static const char kDefaultPluginFinderURL[] =
"http://dl.google.com/chrome/plugins/plugins2.xml";
@@ -454,7 +459,7 @@ void PluginProcessHost::OnChannelConnected(int32 peer_pid) {
void PluginProcessHost::OnChannelError() {
for (size_t i = 0; i < pending_requests_.size(); ++i) {
ReplyToRenderer(pending_requests_[i].renderer_message_filter_.get(),
- std::string(),
+ IPC::ChannelHandle(),
FilePath(),
pending_requests_[i].reply_msg);
}
@@ -468,8 +473,17 @@ void PluginProcessHost::OpenChannelToPlugin(
IPC::Message* reply_msg) {
InstanceCreated();
if (opening_channel()) {
+ // The channel is already in the process of being opened. Put
+ // this "open channel" request into a queue of requests that will
+ // be run once the channel is open.
+ //
+ // On POSIX, we'll only create the pipe when we get around to actually
+ // making this request. So the socket fd is -1 for now. (On Windows,
+ // socket_fd is unused.)
+ int socket_fd = -1;
pending_requests_.push_back(
- ChannelRequest(renderer_message_filter, mime_type, reply_msg));
+ ChannelRequest(renderer_message_filter, mime_type, reply_msg,
+ socket_fd));
return;
}
@@ -506,7 +520,8 @@ void PluginProcessHost::OnResolveProxyCompleted(IPC::Message* reply_msg,
void PluginProcessHost::ReplyToRenderer(
ResourceMessageFilter* renderer_message_filter,
- const std::string& channel, const FilePath& plugin_path,
+ const IPC::ChannelHandle& channel,
+ const FilePath& plugin_path,
IPC::Message* reply_msg) {
ViewHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg, channel,
plugin_path);
@@ -522,29 +537,48 @@ URLRequestContext* PluginProcessHost::GetRequestContext(
void PluginProcessHost::RequestPluginChannel(
ResourceMessageFilter* renderer_message_filter,
const std::string& mime_type, IPC::Message* reply_msg) {
+ // We're about to send the request for a plugin channel.
+ // On POSIX, we create the channel endpoints here, so we can send the
+ // endpoints to the plugin and renderer.
+ int plugin_fd = -1, renderer_fd = -1;
+#if defined(OS_POSIX)
+ // On POSIX, we create the channel endpoints here.
+ IPC::SocketPair(&plugin_fd, &renderer_fd);
+#endif
+
// We can't send any sync messages from the browser because it might lead to
// a hang. However this async messages must be answered right away by the
// plugin process (i.e. unblocks a Send() call like a sync message) otherwise
// a deadlock can occur if the plugin creation request from the renderer is
// a result of a sync message by the plugin process.
PluginProcessMsg_CreateChannel* msg = new PluginProcessMsg_CreateChannel(
+#if defined(OS_POSIX)
+ // Takes ownership of plugin_fd.
+ base::FileDescriptor(plugin_fd, true),
+#endif
renderer_message_filter->GetProcessId(),
renderer_message_filter->off_the_record());
msg->set_unblock(true);
if (Send(msg)) {
sent_requests_.push(ChannelRequest(
- renderer_message_filter, mime_type, reply_msg));
+ renderer_message_filter, mime_type, reply_msg, renderer_fd));
} else {
- ReplyToRenderer(renderer_message_filter, std::string(), FilePath(),
+ ReplyToRenderer(renderer_message_filter, IPC::ChannelHandle(), FilePath(),
reply_msg);
}
}
void PluginProcessHost::OnChannelCreated(const std::string& channel_name) {
- ReplyToRenderer(sent_requests_.front().renderer_message_filter_.get(),
- channel_name,
+ const ChannelRequest& request = sent_requests_.front();
+ IPC::ChannelHandle channel_handle(channel_name
+#if defined(OS_POSIX)
+ , base::FileDescriptor(request.socket, true)
+#endif
+ );
+ ReplyToRenderer(request.renderer_message_filter_.get(),
+ channel_handle,
info_.path,
- sent_requests_.front().reply_msg);
+ request.reply_msg);
sent_requests_.pop();
}
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index 56004f6..9a74dff 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -18,6 +18,7 @@
#include "chrome/browser/net/resolve_proxy_msg_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/common/child_process_host.h"
+#include "chrome/common/ipc_channel_handle.h"
#include "webkit/glue/webplugininfo.h"
class URLRequestContext;
@@ -65,7 +66,7 @@ class PluginProcessHost : public ChildProcessHost,
// Sends the reply to an open channel request to the renderer with the given
// channel name.
static void ReplyToRenderer(ResourceMessageFilter* renderer_message_filter,
- const std::string& channel,
+ const IPC::ChannelHandle& channel,
const FilePath& plugin_path,
IPC::Message* reply_msg);
@@ -113,12 +114,15 @@ class PluginProcessHost : public ChildProcessHost,
struct ChannelRequest {
ChannelRequest(ResourceMessageFilter* renderer_message_filter,
- const std::string& m, IPC::Message* r) :
+ const std::string& m, IPC::Message* r,
+ int s) :
mime_type(m), reply_msg(r),
- renderer_message_filter_(renderer_message_filter) { }
+ renderer_message_filter_(renderer_message_filter),
+ socket(s) { }
std::string mime_type;
IPC::Message* reply_msg;
scoped_refptr<ResourceMessageFilter> renderer_message_filter_;
+ int socket;
};
// These are channel requests that we are waiting to send to the
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index 773698a..c49d56d 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -167,7 +167,7 @@ void PluginService::OpenChannelToPlugin(
plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg);
} else {
PluginProcessHost::ReplyToRenderer(renderer_msg_filter,
- std::string(),
+ IPC::ChannelHandle(),
FilePath(),
reply_msg);
}
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 2121378..4728b17 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -176,7 +176,7 @@ void ResourceMessageFilter::OnFilterAdded(IPC::Channel* channel) {
// Called on the IPC thread:
void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) {
- DCHECK(!handle());
+ DCHECK(!handle()) << " " << handle();
base::ProcessHandle peer_handle;
if (!base::OpenProcessHandle(peer_pid, &peer_handle)) {
NOTREACHED();
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index bace7a5f..346986f 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -347,6 +347,7 @@
'common/important_file_writer.cc',
'common/important_file_writer.h',
'common/ipc_channel.h',
+ 'common/ipc_channel_handle.h',
'common/ipc_channel_posix.cc',
'common/ipc_channel_posix.h',
'common/ipc_channel_proxy.cc',
diff --git a/chrome/common/ipc_channel_handle.h b/chrome/common/ipc_channel_handle.h
new file mode 100644
index 0000000..2bb6380
--- /dev/null
+++ b/chrome/common/ipc_channel_handle.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2009 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 CHROME_COMMON_IPC_CHANNEL_HANDLE_H_
+#define CHROME_COMMON_IPC_CHANNEL_HANDLE_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
+// On Windows, any process can create an IPC channel and others can fetch
+// it by name. We pass around the channel names over IPC.
+// On POSIX, we instead pass around handles to channel endpoints via IPC.
+// When it's time to IPC a new channel endpoint around, we send both the
+// channel name as well as a base::FileDescriptor, which is itself a special
+// type that knows how to copy a socket endpoint over IPC.
+//
+// In sum, when passing a handle to a channel over IPC, use this data structure
+// to work on both Windows and POSIX.
+
+namespace IPC {
+
+struct ChannelHandle {
+ // Note that serialization for this object is defined in the ParamTraits
+ // template specialization in ipc_message_utils.h.
+ std::string name;
+#if defined(OS_POSIX)
+ base::FileDescriptor socket;
+#endif
+
+ ChannelHandle() {}
+#if defined(OS_POSIX)
+ ChannelHandle(const std::string& n, const base::FileDescriptor& s)
+ : name(n), socket(s) {}
+#else
+ ChannelHandle(const std::string& n) : name(n) {}
+#endif
+};
+
+} // namespace IPC
+
+#endif // CHROME_COMMON_IPC_CHANNEL_HANDLE_H_
diff --git a/chrome/common/ipc_channel_posix.cc b/chrome/common/ipc_channel_posix.cc
index babc16c..63f2703 100644
--- a/chrome/common/ipc_channel_posix.cc
+++ b/chrome/common/ipc_channel_posix.cc
@@ -104,9 +104,9 @@ class PipeMap {
DCHECK(fd != -1);
ChannelToFDMap::const_iterator i = map_.find(channel_id);
- CHECK(i == map_.end()) << "Creating second IPC server for '"
- << channel_id
- << "' while first still exists";
+ CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") "
+ << "for '" << channel_id << "' while first "
+ << "(fd " << i->second << ") still exists";
map_[channel_id] = fd;
}
@@ -116,16 +116,20 @@ class PipeMap {
ChannelToFDMap map_;
};
-// Used to map a channel name to the equivalent FD # in the client process.
-int ChannelNameToClientFD(const std::string& channel_id) {
+// Used to map a channel name to the equivalent FD # in the current process.
+// Returns -1 if the channel is unknown.
+int ChannelNameToFD(const std::string& channel_id) {
// See the large block comment above PipeMap for the reasoning here.
const int fd = Singleton<PipeMap>()->Lookup(channel_id);
- if (fd != -1)
- return dup(fd);
- // If we don't find an entry, we assume that the correct value has been
- // inserted in the magic slot.
- return Singleton<base::GlobalDescriptors>()->Get(kPrimaryIPCChannel);
+ if (fd != -1) {
+ int dup_fd = dup(fd);
+ if (dup_fd < 0)
+ LOG(FATAL) << "dup(" << fd << "): " << strerror(errno);
+ return dup_fd;
+ }
+
+ return fd;
}
//------------------------------------------------------------------------------
@@ -261,6 +265,34 @@ Channel::ChannelImpl::ChannelImpl(const std::string& channel_id, Mode mode,
}
}
+// static
+void AddChannelSocket(const std::string& name, int socket) {
+ Singleton<PipeMap>()->Insert(name, socket);
+}
+
+// static
+bool SocketPair(int* fd1, int* fd2) {
+ int pipe_fds[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
+ LOG(ERROR) << "socketpair(): " << strerror(errno);
+ return false;
+ }
+
+ // Set both ends to be non-blocking.
+ if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
+ fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
+ LOG(ERROR) << "fcntl(O_NONBLOCK): " << strerror(errno);
+ HANDLE_EINTR(close(pipe_fds[0]));
+ HANDLE_EINTR(close(pipe_fds[1]));
+ return false;
+ }
+
+ *fd1 = pipe_fds[0];
+ *fd2 = pipe_fds[1];
+
+ return true;
+}
+
bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id,
Mode mode) {
DCHECK(server_listen_pipe_ == -1 && pipe_ == -1);
@@ -282,27 +314,24 @@ bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id,
waiting_connect_ = false;
}
} else {
- // socketpair()
+ // This is the normal (non-unit-test) case, where we're using sockets.
+ // Three possible cases:
+ // 1) It's for a channel we already have a pipe for; reuse it.
+ // 2) It's the initial IPC channel:
+ // 2a) Server side: create the pipe.
+ // 2b) Client side: Pull the pipe out of the GlobalDescriptors set.
pipe_name_ = channel_id;
- if (mode == MODE_SERVER) {
- int pipe_fds[2];
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
- return false;
- }
- // Set both ends to be non-blocking.
- if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
- fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
- HANDLE_EINTR(close(pipe_fds[0]));
- HANDLE_EINTR(close(pipe_fds[1]));
- return false;
+ pipe_ = ChannelNameToFD(pipe_name_);
+ if (pipe_ < 0) {
+ // Initial IPC channel.
+ if (mode == MODE_SERVER) {
+ if (!SocketPair(&pipe_, &client_pipe_))
+ return false;
+ AddChannelSocket(pipe_name_, client_pipe_);
+ } else {
+ pipe_ = Singleton<base::GlobalDescriptors>()->Get(kPrimaryIPCChannel);
}
- pipe_ = pipe_fds[0];
- client_pipe_ = pipe_fds[1];
-
- Singleton<PipeMap>()->Insert(pipe_name_, client_pipe_);
} else {
- pipe_ = ChannelNameToClientFD(pipe_name_);
- DCHECK(pipe_ > 0);
waiting_connect_ = false;
}
}
@@ -612,7 +641,7 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() {
return false;
}
#endif // OS_MACOSX
- LOG(ERROR) << "pipe error: " << strerror(errno);
+ LOG(ERROR) << "pipe error on " << pipe_ << ": " << strerror(errno);
return false;
}
diff --git a/chrome/common/ipc_channel_posix.h b/chrome/common/ipc_channel_posix.h
index ed3d727..5e8d977 100644
--- a/chrome/common/ipc_channel_posix.h
+++ b/chrome/common/ipc_channel_posix.h
@@ -18,6 +18,15 @@
namespace IPC {
+// Store that channel name |name| is available via socket |socket|.
+// Used when the channel has been precreated by another process on
+// our behalf and they've just shipped us the socket.
+void AddChannelSocket(const std::string& name, int socket);
+
+// Construct a socket pair appropriate for IPC: UNIX domain, nonblocking.
+// Returns false on error.
+bool SocketPair(int* fd1, int* fd2);
+
// An implementation of ChannelImpl for POSIX systems that works via
// socketpairs. See the .cc file for an overview of the implementation.
class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
@@ -60,9 +69,16 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
// a socketpair().
bool uses_fifo_;
+ // File descriptor we're listening on for new connections in the FIFO case;
+ // unused otherwise.
int server_listen_pipe_;
+
+ // The pipe used for communication.
int pipe_;
- int client_pipe_; // The client end of our socketpair().
+
+ // For a server, the client end of our socketpair() -- the other end of our
+ // pipe_ that is passed to the client.
+ int client_pipe_;
// The "name" of our pipe. On Windows this is the global identifier for
// the pipe. On POSIX it's used as a key in a local map of file descriptors.
diff --git a/chrome/common/ipc_message_utils.h b/chrome/common/ipc_message_utils.h
index 3f0f7b2..2ae2ab5 100644
--- a/chrome/common/ipc_message_utils.h
+++ b/chrome/common/ipc_message_utils.h
@@ -16,6 +16,7 @@
#if defined(OS_POSIX)
#include "chrome/common/file_descriptor_set_posix.h"
#endif
+#include "chrome/common/ipc_channel_handle.h"
#include "chrome/common/ipc_sync_message.h"
#include "chrome/common/thumbnail_score.h"
#include "chrome/common/transport_dib.h"
@@ -726,6 +727,34 @@ struct ParamTraits<base::FileDescriptor> {
};
#endif // defined(OS_POSIX)
+// A ChannelHandle is basically a platform-inspecific wrapper around the
+// fact that IPC endpoints are handled specially on POSIX. See above comments
+// on FileDescriptor for more background.
+template<>
+struct ParamTraits<IPC::ChannelHandle> {
+ typedef ChannelHandle param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.name);
+#if defined(OS_POSIX)
+ WriteParam(m, p.socket);
+#endif
+ }
+ static bool Read(const Message* m, void** iter, param_type* r) {
+ return ReadParam(m, iter, &r->name)
+#if defined(OS_POSIX)
+ && ReadParam(m, iter, &r->socket)
+#endif
+ ;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(StringPrintf(L"ChannelHandle(%s", p.name.c_str()));
+#if defined(OS_POSIX)
+ ParamTraits<base::FileDescriptor>::Log(p.socket, l);
+#endif
+ l->append(L")");
+ }
+};
+
template<>
struct ParamTraits<ThumbnailScore> {
typedef ThumbnailScore param_type;
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index b2805fc..500bd93 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -3,9 +3,14 @@
// found in the LICENSE file.
#include "base/shared_memory.h"
+#include "build/build_config.h"
#include "chrome/common/ipc_message_macros.h"
#include "webkit/glue/webcursor.h"
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
//-----------------------------------------------------------------------------
// PluginProcess messages
// These are messages sent from the browser to the plugin process.
@@ -15,9 +20,19 @@ IPC_BEGIN_MESSAGES(PluginProcess)
// PluginProcessHostMsg_ChannelCreated message. The renderer's process_id is
// passed so that the plugin process reuses an existing channel to that
// process if it exists.
+ // It would be nice to use #ifdefs inside the parameter list to not need to
+ // duplicate this across POSIX/Windows but the Visual Studio compiler doesn't
+ // like that.
+#if defined(OS_WIN)
IPC_MESSAGE_CONTROL2(PluginProcessMsg_CreateChannel,
int /* process_id */,
bool /* off_the_record */)
+#elif defined(OS_POSIX)
+ IPC_MESSAGE_CONTROL3(PluginProcessMsg_CreateChannel,
+ base::FileDescriptor /* socket for new channel */,
+ int /* process_id */,
+ bool /* off_the_record */)
+#endif
// Allows a chrome plugin loaded in the browser process to send arbitrary
// data to an instance of the same plugin loaded in a plugin process.
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index d96220d..5debd5f 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -17,6 +17,7 @@
#include "base/gfx/native_widget_types.h"
#include "base/shared_memory.h"
#include "base/values.h"
+#include "chrome/common/ipc_channel_handle.h"
#include "chrome/common/ipc_message_macros.h"
#include "chrome/common/transport_dib.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -924,16 +925,16 @@ IPC_BEGIN_MESSAGES(ViewHost)
std::string /* origin */,
std::string /* target */)
- // A renderer sends this to the browser process when it wants to create a
- // plugin. The browser will create the plugin process if necessary, and
- // will return the channel name on success. On error an empty string is
- // returned.
+ // A renderer sends this to the browser process when it wants to
+ // create a plugin. The browser will create the plugin process if
+ // necessary, and will return a handle to the channel on success.
+ // On error an empty string is returned.
IPC_SYNC_MESSAGE_CONTROL4_2(ViewHostMsg_OpenChannelToPlugin,
GURL /* url */,
std::string /* mime_type */,
std::string /* clsid */,
std::wstring /* locale */,
- std::string /* channel_name */,
+ IPC::ChannelHandle /* handle to channel */,
FilePath /* plugin_path */)
// Clipboard IPC messages
diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc
index 4ff7b2b..b9e7a52 100644
--- a/chrome/plugin/plugin_channel.cc
+++ b/chrome/plugin/plugin_channel.cc
@@ -7,17 +7,29 @@
#include "base/command_line.h"
#include "base/process_util.h"
#include "base/string_util.h"
+#include "build/build_config.h"
#include "chrome/common/child_process.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/plugin/plugin_thread.h"
+#if defined(OS_POSIX)
+#include "chrome/common/ipc_channel_posix.h"
+#endif
+
PluginChannel* PluginChannel::GetPluginChannel(
- int process_id, MessageLoop* ipc_message_loop) {
+ int process_id, MessageLoop* ipc_message_loop, int channel_fd) {
// map renderer's process id to a (single) channel to that process
std::string channel_name = StringPrintf(
"%d.r%d", base::GetCurrentProcId(), process_id);
+#if defined(OS_POSIX)
+ // If we were provided an already-open channel, associate it with
+ // the channel name in this process's name<->socket map.
+ if (channel_fd > 0)
+ IPC::AddChannelSocket(channel_name, channel_fd);
+#endif
+
return static_cast<PluginChannel*>(PluginChannelBase::GetChannel(
channel_name,
IPC::Channel::MODE_SERVER,
diff --git a/chrome/plugin/plugin_channel.h b/chrome/plugin/plugin_channel.h
index f0bba80..21373fb 100644
--- a/chrome/plugin/plugin_channel.h
+++ b/chrome/plugin/plugin_channel.h
@@ -15,8 +15,12 @@
// process. On the renderer side there's a corresponding PluginChannelHost.
class PluginChannel : public PluginChannelBase {
public:
- static PluginChannel* GetPluginChannel(
- int process_id, MessageLoop* ipc_message_loop);
+ // Get a new PluginChannel object for the current process.
+ // POSIX only: If |channel_fd| > 0, use that file descriptor for the
+ // channel socket.
+ static PluginChannel* GetPluginChannel(int process_id,
+ MessageLoop* ipc_message_loop,
+ int channel_fd);
~PluginChannel();
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index cb92de4..2f9c2ec 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -102,10 +102,19 @@ void PluginThread::CleanUp() {
lazy_tls.Pointer()->Set(NULL);
}
-void PluginThread::OnCreateChannel(int process_id, bool off_the_record) {
+void PluginThread::OnCreateChannel(
+#if defined(OS_POSIX)
+ base::FileDescriptor socket,
+#endif
+ int process_id,
+ bool off_the_record) {
+ int fd = -1;
+#if defined(OS_POSIX)
+ fd = socket.fd;
+#endif
std::string channel_name;
scoped_refptr<PluginChannel> channel =
- PluginChannel::GetPluginChannel(process_id, owner_loop());
+ PluginChannel::GetPluginChannel(process_id, owner_loop(), fd);
if (channel.get()) {
channel_name = channel->channel_name();
channel->set_off_the_record(off_the_record);
diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h
index 052be0a..911940a 100644
--- a/chrome/plugin/plugin_thread.h
+++ b/chrome/plugin/plugin_thread.h
@@ -7,10 +7,15 @@
#include "base/file_path.h"
#include "base/native_library.h"
+#include "build/build_config.h"
#include "chrome/common/child_thread.h"
#include "chrome/plugin/plugin_channel.h"
#include "webkit/glue/plugins/plugin_lib.h"
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
class NotificationService;
// The PluginThread class represents a background thread where plugin instances
@@ -31,7 +36,14 @@ class PluginThread : public ChildThread {
virtual void Init();
virtual void CleanUp();
- void OnCreateChannel(int process_id, bool off_the_record);
+ // Callback for when a channel has been created.
+ // On POSIX, |socket| is the channel endpoint socket.
+ void OnCreateChannel(
+#if defined(OS_POSIX)
+ base::FileDescriptor socket,
+#endif
+ int process_id,
+ bool off_the_record);
void OnPluginMessage(const std::vector<uint8> &data);
scoped_ptr<NotificationService> notification_service_;
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index 800db41..8cc3273 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -135,9 +135,9 @@ void WebPluginDelegateStub::OnInit(const PluginMsg_Init_Params& params,
delegate_ = WebPluginDelegate::Create(
path, mime_type_, gfx::NativeViewFromId(params.containing_window));
#else
- // We don't have gfx::NativeViewFromId on Linux
- NOTIMPLEMENTED();
- delegate_ = NULL;
+ NOTIMPLEMENTED() << " need to figure out nativeview id business";
+ delegate_ = WebPluginDelegate::Create(
+ path, mime_type_, NULL);
#endif
if (delegate_) {
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 87d3ec1..8117acf 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -41,6 +41,10 @@
#include "chrome/common/gfx/emf.h"
#endif
+#if defined(OS_POSIX)
+#include "chrome/common/ipc_channel_posix.h"
+#endif
+
using WebKit::WebInputEvent;
using WebKit::WebDragData;
using WebKit::WebVector;
@@ -207,16 +211,24 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn,
char** argv, int argc,
WebPlugin* plugin,
bool load_manually) {
- std::string channel_name;
+ IPC::ChannelHandle channel_handle;
FilePath plugin_path;
if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin(
url, mime_type_, clsid_, webkit_glue::GetWebKitLocale(),
- &channel_name, &plugin_path)))
+ &channel_handle, &plugin_path))) {
return false;
+ }
+
+#if defined(OS_POSIX)
+ // If we received a ChannelHandle, register it now.
+ if (channel_handle.socket.fd >= 0)
+ IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd);
+#endif
MessageLoop* ipc_message_loop = RenderThread::current()->owner_loop();
scoped_refptr<PluginChannelHost> channel_host =
- PluginChannelHost::GetPluginChannelHost(channel_name, ipc_message_loop);
+ PluginChannelHost::GetPluginChannelHost(channel_handle.name,
+ ipc_message_loop);
if (!channel_host.get())
return false;