diff options
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 50 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 10 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 2 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 2 | ||||
-rw-r--r-- | chrome/chrome.gyp | 1 | ||||
-rw-r--r-- | chrome/common/ipc_channel_handle.h | 45 | ||||
-rw-r--r-- | chrome/common/ipc_channel_posix.cc | 87 | ||||
-rw-r--r-- | chrome/common/ipc_channel_posix.h | 18 | ||||
-rw-r--r-- | chrome/common/ipc_message_utils.h | 29 | ||||
-rw-r--r-- | chrome/common/plugin_messages_internal.h | 15 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 11 | ||||
-rw-r--r-- | chrome/plugin/plugin_channel.cc | 14 | ||||
-rw-r--r-- | chrome/plugin/plugin_channel.h | 8 | ||||
-rw-r--r-- | chrome/plugin/plugin_thread.cc | 13 | ||||
-rw-r--r-- | chrome/plugin/plugin_thread.h | 14 | ||||
-rw-r--r-- | chrome/plugin/webplugin_delegate_stub.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 18 |
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; |