summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 16:00:47 +0000
committerddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 16:00:47 +0000
commit2b657fd950ea3e06ac489f37c5d320dde00d70ad (patch)
tree1dcd64a12edffbcb17bb9d33a04d7517a08d705a /content
parenteaca0ad17b151d28b1e5821f1fce27a6dadc0b29 (diff)
downloadchromium_src-2b657fd950ea3e06ac489f37c5d320dde00d70ad.zip
chromium_src-2b657fd950ea3e06ac489f37c5d320dde00d70ad.tar.gz
chromium_src-2b657fd950ea3e06ac489f37c5d320dde00d70ad.tar.bz2
Implemented broker dispatcher, pipe creation, and handle distribution.
BUG=none TEST=none Review URL: http://codereview.chromium.org/6865045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81951 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_message_filter.cc10
-rw-r--r--content/common/view_messages.h3
-rw-r--r--content/renderer/pepper_plugin_delegate_impl.cc143
-rw-r--r--content/renderer/pepper_plugin_delegate_impl.h36
-rw-r--r--content/renderer/render_view.cc10
-rw-r--r--content/renderer/render_view.h3
6 files changed, 175 insertions, 30 deletions
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 699e266..8f664d0 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -199,12 +199,12 @@ class OpenChannelToPpapiBrokerCallback : public PpapiBrokerProcessHost::Client {
*renderer_id = filter_->render_process_id();
}
- virtual void OnChannelOpened(base::ProcessHandle plugin_process_handle,
+ virtual void OnChannelOpened(base::ProcessHandle broker_process_handle,
const IPC::ChannelHandle& channel_handle) {
- filter_->Send(
- new ViewMsg_PpapiBrokerChannelCreated(routing_id_,
- request_id_,
- channel_handle));
+ filter_->Send(new ViewMsg_PpapiBrokerChannelCreated(routing_id_,
+ request_id_,
+ broker_process_handle,
+ channel_handle));
delete this;
}
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 7d0f024..86e2328 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1160,8 +1160,9 @@ IPC_MESSAGE_ROUTED0(ViewMsg_AccessibilityNotifications_ACK)
// Reply to ViewHostMsg_OpenChannelToPpapiBroker
// Tells the renderer that the channel to the broker has been created.
-IPC_MESSAGE_ROUTED2(ViewMsg_PpapiBrokerChannelCreated,
+IPC_MESSAGE_ROUTED3(ViewMsg_PpapiBrokerChannelCreated,
int /* request_id */,
+ base::ProcessHandle /* broker_process_handle */,
IPC::ChannelHandle /* handle */)
// Tells the renderer to empty its plugin list cache, optional reloading
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc
index 95d24db..f17a21f6 100644
--- a/content/renderer/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper_plugin_delegate_impl.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_split.h"
+#include "base/sync_socket.h"
#include "base/task.h"
#include "base/time.h"
#include "chrome/common/pepper_plugin_registry.h"
@@ -35,11 +36,13 @@
#include "content/renderer/render_widget_fullscreen_pepper.h"
#include "content/renderer/webgraphicscontext3d_command_buffer_impl.h"
#include "content/renderer/webplugin_delegate_proxy.h"
+#include "ipc/ipc_channel_handle.h"
#include "ppapi/c/dev/pp_video_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_flash.h"
#include "ppapi/c/private/ppb_flash_net_connector.h"
#include "ppapi/proxy/host_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserCompletion.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
@@ -64,6 +67,39 @@ namespace {
const int32 kDefaultCommandBufferSize = 1024 * 1024;
+int32_t PlatformFileToInt(base::PlatformFile handle) {
+#if defined(OS_WIN)
+ return static_cast<int32_t>(reinterpret_cast<intptr_t>(handle));
+#elif defined(OS_POSIX)
+ return handle;
+#else
+ #error Not implemented.
+#endif
+}
+
+base::SyncSocket::Handle DuplicateHandle(base::SyncSocket::Handle handle) {
+ base::SyncSocket::Handle out_handle = base::kInvalidPlatformFileValue;
+#if defined(OS_WIN)
+ DWORD options = DUPLICATE_SAME_ACCESS;
+ if (!::DuplicateHandle(::GetCurrentProcess(),
+ handle,
+ ::GetCurrentProcess(),
+ &out_handle,
+ 0,
+ FALSE,
+ options)) {
+ out_handle = base::kInvalidPlatformFileValue;
+ }
+#elif defined(OS_POSIX)
+ // If asked to close the source, we can simply re-use the source fd instead of
+ // dup()ing and close()ing.
+ out_handle = ::dup(handle);
+#else
+ #error Not implemented.
+#endif
+ return out_handle;
+}
+
// Implements the Image2D using a TransportDIB.
class PlatformImage2DImpl
: public webkit::ppapi::PluginDelegate::PlatformImage2D {
@@ -310,6 +346,8 @@ class DispatcherWrapper
scoped_ptr<pp::proxy::HostDispatcher> dispatcher_;
};
+} // namespace
+
bool DispatcherWrapper::Init(
base::ProcessHandle plugin_process_handle,
const IPC::ChannelHandle& channel_handle,
@@ -327,7 +365,50 @@ bool DispatcherWrapper::Init(
return true;
}
-} // namespace
+BrokerDispatcherWrapper::BrokerDispatcherWrapper() {
+}
+
+BrokerDispatcherWrapper::~BrokerDispatcherWrapper() {
+}
+
+bool BrokerDispatcherWrapper::Init(
+ base::ProcessHandle plugin_process_handle,
+ const IPC::ChannelHandle& channel_handle) {
+ dispatcher_.reset(
+ new pp::proxy::BrokerHostDispatcher(plugin_process_handle));
+
+ if (!dispatcher_->InitBrokerWithChannel(PepperPluginRegistry::GetInstance(),
+ channel_handle,
+ true)) {
+ dispatcher_.reset();
+ return false;
+ }
+ dispatcher_->channel()->SetRestrictDispatchToSameChannel(true);
+ return true;
+}
+
+// Does not take ownership of the local pipe.
+int32_t BrokerDispatcherWrapper::SendHandleToBroker(
+ PP_Instance instance,
+ base::SyncSocket::Handle handle) {
+ IPC::PlatformFileForTransit foreign_socket_handle =
+ dispatcher_->ShareHandleWithRemote(handle, false);
+ if (foreign_socket_handle == IPC::InvalidPlatformFileForTransit())
+ return PP_ERROR_FAILED;
+
+ if (!dispatcher_->Send(
+ new PpapiMsg_ConnectToPlugin(instance, foreign_socket_handle))) {
+ // The plugin did not receive the handle, so it must be closed.
+ // The easiest way to clean it up is to just put it in an object
+ // and then close it. This failure case is not performance critical.
+ // The handle could still leak if Send succeeded but the IPC later failed.
+ base::SyncSocket temp_socket(
+ IPC::PlatformFileForTransitToPlatformFile(foreign_socket_handle));
+ return PP_ERROR_FAILED;
+ }
+
+ return PP_OK;
+}
PpapiBrokerImpl::PpapiBrokerImpl() {
}
@@ -337,38 +418,69 @@ PpapiBrokerImpl::~PpapiBrokerImpl() {
// If the channel is not ready, queue the connection.
void PpapiBrokerImpl::Connect(webkit::ppapi::PPB_Broker_Impl* client) {
- if (channel_handle_.name.empty()) {
+ if (!dispatcher_.get()) {
pending_connects_.push_back(client);
return;
}
DCHECK(pending_connects_.empty());
- RequestPpapiBrokerPipe(client);
+ ConnectPluginToBroker(client);
}
void PpapiBrokerImpl::Disconnect(webkit::ppapi::PPB_Broker_Impl* client) {
- // TODO(ddorwin): Send message using channel_handle_ and clean up any pending
+ // TODO(ddorwin): Send message using dispatcher_ and clean up any pending
// connects or pipes.
}
void PpapiBrokerImpl::OnBrokerChannelConnected(
+ base::ProcessHandle broker_process_handle,
const IPC::ChannelHandle& channel_handle) {
- channel_handle_ = channel_handle;
+ scoped_ptr<BrokerDispatcherWrapper> dispatcher(new BrokerDispatcherWrapper);
+ if (dispatcher->Init(broker_process_handle, channel_handle)) {
+ dispatcher_.reset(dispatcher.release());
- // Process all pending channel requests from the renderers.
- for (size_t i = 0; i < pending_connects_.size(); i++)
- RequestPpapiBrokerPipe(pending_connects_[i]);
+ // Process all pending channel requests from the renderers.
+ for (size_t i = 0; i < pending_connects_.size(); i++)
+ ConnectPluginToBroker(pending_connects_[i]);
+ } else {
+ // Report failure to all clients.
+ for (size_t i = 0; i < pending_connects_.size(); i++) {
+ pending_connects_[i]->BrokerConnected(
+ PlatformFileToInt(base::kInvalidPlatformFileValue), PP_ERROR_FAILED);
+ }
+ }
pending_connects_.clear();
}
-void PpapiBrokerImpl::RequestPpapiBrokerPipe(
+void PpapiBrokerImpl::ConnectPluginToBroker(
webkit::ppapi::PPB_Broker_Impl* client) {
- // TOOD(ddorwin): Send an asynchronous message to the broker using
- // channel_handle_, queue the client with an ID, then return.
- // The broker will create the pipe, which will be provided in a message.
- // That message handler will call then client->BrokerConnected().
+ base::SyncSocket::Handle plugin_handle = base::kInvalidPlatformFileValue;
+ int32_t result = PP_OK;
+
+ base::SyncSocket* sockets[2] = {0};
+ if (base::SyncSocket::CreatePair(sockets)) {
+ // The socket objects will be deleted when this function exits, closing the
+ // handles. Any uses of the socket must duplicate them.
+ scoped_ptr<base::SyncSocket> broker_socket(sockets[0]);
+ scoped_ptr<base::SyncSocket> plugin_socket(sockets[1]);
+
+ result = dispatcher_->SendHandleToBroker(client->instance()->pp_instance(),
+ broker_socket->handle());
+
+ // If the broker has its pipe handle, duplicate the plugin's handle.
+ // Otherwise, the plugin's handle will be automatically closed.
+ if (result == PP_OK)
+ plugin_handle = DuplicateHandle(plugin_socket->handle());
+ } else {
+ result = PP_ERROR_FAILED;
+ }
+
+ // TOOD(ddorwin): Change the IPC to asynchronous: Queue an object containing
+ // client and plugin_socket.release(), then return.
+ // That message handler will then call client->BrokerConnected() with the
+ // saved pipe handle.
// Temporarily, just call back.
- client->BrokerConnected(1);
+ client->BrokerConnected(PlatformFileToInt(plugin_handle), result);
}
PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderView* render_view)
@@ -463,12 +575,13 @@ PepperPluginDelegateImpl::CreatePpapiBroker(
void PepperPluginDelegateImpl::OnPpapiBrokerChannelCreated(
int request_id,
+ base::ProcessHandle broker_process_handle,
const IPC::ChannelHandle& handle) {
scoped_refptr<PpapiBrokerImpl> broker =
*pending_connect_broker_.Lookup(request_id);
pending_connect_broker_.Remove(request_id);
- broker->OnBrokerChannelConnected(handle);
+ broker->OnBrokerChannelConnected(broker_process_handle, handle);
}
void PepperPluginDelegateImpl::ViewInitiatedPaint() {
diff --git a/content/renderer/pepper_plugin_delegate_impl.h b/content/renderer/pepper_plugin_delegate_impl.h
index f8cb567..dafafff 100644
--- a/content/renderer/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper_plugin_delegate_impl.h
@@ -14,7 +14,8 @@
#include "base/id_map.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "ipc/ipc_channel_handle.h"
+#include "ppapi/proxy/broker_dispatcher.h"
+#include "ppapi/proxy/proxy_channel.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/ppb_broker_impl.h"
#include "webkit/plugins/ppapi/ppb_flash_menu_impl.h"
@@ -27,6 +28,10 @@ class Point;
class Rect;
}
+namespace IPC {
+struct ChannelHandle;
+}
+
namespace webkit {
namespace ppapi {
class PepperFilePath;
@@ -46,6 +51,21 @@ struct CustomContextMenuContext;
class TransportDIB;
+class BrokerDispatcherWrapper {
+ public:
+ BrokerDispatcherWrapper();
+ ~BrokerDispatcherWrapper();
+
+ bool Init(base::ProcessHandle plugin_process_handle,
+ const IPC::ChannelHandle& channel_handle);
+
+ int32_t SendHandleToBroker(PP_Instance instance,
+ base::SyncSocket::Handle handle);
+
+ private:
+ scoped_ptr<pp::proxy::BrokerDispatcher> dispatcher_;
+};
+
class PpapiBrokerImpl : public webkit::ppapi::PluginDelegate::PpapiBroker {
public:
PpapiBrokerImpl();
@@ -55,14 +75,19 @@ class PpapiBrokerImpl : public webkit::ppapi::PluginDelegate::PpapiBroker {
virtual void Disconnect(webkit::ppapi::PPB_Broker_Impl* client);
// Called when the channel to the broker has been established.
- void OnBrokerChannelConnected(const IPC::ChannelHandle& channel_handle);
+ void OnBrokerChannelConnected(base::ProcessHandle broker_process_handle,
+ const IPC::ChannelHandle& channel_handle);
+
+ // Connects the plugin to the broker via a pipe.
+ void ConnectPluginToBroker(webkit::ppapi::PPB_Broker_Impl* client);
- // Asynchronously requests a pipe for this instance from the broker.
- void RequestPpapiBrokerPipe(webkit::ppapi::PPB_Broker_Impl* client);
+ // Asynchronously sends a pipe to the broker.
+ int32_t SendHandleToBroker(PP_Instance instance,
+ base::SyncSocket::Handle handle);
protected:
virtual ~PpapiBrokerImpl();
- IPC::ChannelHandle channel_handle_;
+ scoped_ptr<BrokerDispatcherWrapper> dispatcher_;
std::vector<scoped_refptr<webkit::ppapi::PPB_Broker_Impl> > pending_connects_;
std::vector<scoped_refptr<webkit::ppapi::PPB_Broker_Impl> > pending_pipes_;
@@ -111,6 +136,7 @@ class PepperPluginDelegateImpl
// Called by RenderView when ViewMsg_PpapiBrokerChannelCreated.
void OnPpapiBrokerChannelCreated(int request_id,
+ base::ProcessHandle broker_process_handle,
const IPC::ChannelHandle& handle);
// Notification that the render view has been focused or defocused. This
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 7a339f8..58f5cfc 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -4278,9 +4278,13 @@ void RenderView::OnAsyncFileOpened(base::PlatformFileError error_code,
message_id);
}
-void RenderView::OnPpapiBrokerChannelCreated(int request_id,
- const IPC::ChannelHandle& handle) {
- pepper_delegate_.OnPpapiBrokerChannelCreated(request_id, handle);
+void RenderView::OnPpapiBrokerChannelCreated(
+ int request_id,
+ base::ProcessHandle broker_process_handle,
+ IPC::ChannelHandle handle) {
+ pepper_delegate_.OnPpapiBrokerChannelCreated(request_id,
+ broker_process_handle,
+ handle);
}
#if defined(OS_MACOSX)
diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h
index 548117e1..8d846468 100644
--- a/content/renderer/render_view.h
+++ b/content/renderer/render_view.h
@@ -726,7 +726,8 @@ class RenderView : public RenderWidget,
IPC::PlatformFileForTransit file_for_transit,
int message_id);
void OnPpapiBrokerChannelCreated(int request_id,
- const IPC::ChannelHandle& handle);
+ base::ProcessHandle broker_process_handle,
+ IPC::ChannelHandle handle);
void OnCancelDownload(int32 download_id);
void OnClearFocusedNode();
void OnClosePage(const ViewMsg_ClosePage_Params& params);