summaryrefslogtreecommitdiffstats
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
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
-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
-rw-r--r--ppapi/c/trusted/ppp_broker.h10
-rw-r--r--ppapi/proxy/broker_dispatcher.cc55
-rw-r--r--ppapi/proxy/broker_dispatcher.h16
-rw-r--r--ppapi/proxy/ppapi_messages.h6
-rw-r--r--webkit/plugins/ppapi/ppb_broker_impl.cc8
-rw-r--r--webkit/plugins/ppapi/ppb_broker_impl.h2
12 files changed, 253 insertions, 49 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);
diff --git a/ppapi/c/trusted/ppp_broker.h b/ppapi/c/trusted/ppp_broker.h
index 09cd570..923c1828 100644
--- a/ppapi/c/trusted/ppp_broker.h
+++ b/ppapi/c/trusted/ppp_broker.h
@@ -37,14 +37,16 @@ extern "C" {
/**
* PP_ConnectInstance_Func defines the signature that you implement to
- * receive notifications when a new instance connects to the broker.
+ * receive notifications when a plugin instance connects to the broker.
+ * The broker should listen on the socket before returning.
*
* @param[in] instance The plugin instance connecting to the broker.
- * @param[in] socket Handle to a socket the broker can use to communicate with
- * the instance.
+ * @param[in] handle Handle to a socket the broker can use to communicate with
+ * the plugin.
* @return PP_OK on success. Any other value on failure.
*/
-typedef int32_t (*PP_ConnectInstance_Func)(PP_Instance instance, int socket);
+typedef int32_t (*PP_ConnectInstance_Func)(PP_Instance instance,
+ int32_t handle);
/**
* @}
*/
diff --git a/ppapi/proxy/broker_dispatcher.cc b/ppapi/proxy/broker_dispatcher.cc
index f72f37a..ff86212 100644
--- a/ppapi/proxy/broker_dispatcher.cc
+++ b/ppapi/proxy/broker_dispatcher.cc
@@ -4,15 +4,31 @@
#include "ppapi/proxy/broker_dispatcher.h"
+#include "base/sync_socket.h"
+#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/ppapi_messages.h"
namespace pp {
namespace proxy {
+namespace {
+
+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
+}
+
+} // namespace
+
BrokerDispatcher::BrokerDispatcher(base::ProcessHandle remote_process_handle,
PP_ConnectInstance_Func connect_instance)
- : ProxyChannel(remote_process_handle) {
- // TODO(ddorwin): Do something with connect_instance.
+ : ProxyChannel(remote_process_handle),
+ connect_instance_(connect_instance) {
}
BrokerDispatcher::~BrokerDispatcher() {
@@ -29,17 +45,44 @@ bool BrokerDispatcher::OnMessageReceived(const IPC::Message& msg) {
// Control messages.
if (msg.routing_id() == MSG_ROUTING_CONTROL) {
bool handled = true;
- // TODO(ddorwin): Implement. Don't build empty block - fails on Windows.
-#if 0
IPC_BEGIN_MESSAGE_MAP(BrokerDispatcher, msg)
- // IPC_MESSAGE_FORWARD(PpapiMsg_ConnectToInstance)
+ IPC_MESSAGE_HANDLER(PpapiMsg_ConnectToPlugin, OnMsgConnectToPlugin)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
-#endif
return handled;
}
return false;
}
+// Transfers ownership of the handle to the broker module.
+void BrokerDispatcher::OnMsgConnectToPlugin(
+ PP_Instance instance,
+ IPC::PlatformFileForTransit handle) {
+ int32_t result = PP_OK;
+ if (handle == IPC::InvalidPlatformFileForTransit()) {
+ result = PP_ERROR_FAILED;
+ } else {
+ base::SyncSocket::Handle socket_handle =
+ IPC::PlatformFileForTransitToPlatformFile(handle);
+
+ if (connect_instance_) {
+ result = connect_instance_(instance, PlatformFileToInt(socket_handle));
+ } else {
+ result = PP_ERROR_FAILED;
+ // Close the handle since there is no other owner.
+ // The easiest way to clean it up is to just put it in an object
+ // and then close them. This failure case is not performance critical.
+ base::SyncSocket temp_socket(socket_handle);
+ }
+ }
+
+ // TODO(ddorwin): Report result via IPC.
+}
+
+BrokerHostDispatcher::BrokerHostDispatcher(
+ base::ProcessHandle remote_process_handle)
+ : BrokerDispatcher(remote_process_handle, NULL) {
+}
+
} // namespace proxy
} // namespace pp
diff --git a/ppapi/proxy/broker_dispatcher.h b/ppapi/proxy/broker_dispatcher.h
index 6b0673b..e451218 100644
--- a/ppapi/proxy/broker_dispatcher.h
+++ b/ppapi/proxy/broker_dispatcher.h
@@ -22,11 +22,6 @@ class BrokerDispatcher : public ProxyChannel {
const IPC::ChannelHandle& channel_handle,
bool is_client);
- // Returns true if the dispatcher is on the broker side, or false if it's the
- // browser side.
- // TODO(ddorwin): Implement.
- // virtual bool IsBroker() const = 0;
-
// IPC::Channel::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& msg);
@@ -35,10 +30,21 @@ class BrokerDispatcher : public ProxyChannel {
BrokerDispatcher(base::ProcessHandle remote_process_handle,
PP_ConnectInstance_Func connect_instance);
+ void OnMsgConnectToPlugin(PP_Instance instance,
+ IPC::PlatformFileForTransit handle);
+
+ PP_ConnectInstance_Func connect_instance_;
+
private:
DISALLOW_COPY_AND_ASSIGN(BrokerDispatcher);
};
+// A simple class for broker hosts.
+class BrokerHostDispatcher : public BrokerDispatcher {
+ public:
+ BrokerHostDispatcher(base::ProcessHandle remote_process_handle);
+};
+
} // namespace proxy
} // namespace pp
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 3749961..2870a4a 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -67,6 +67,12 @@ IPC_MESSAGE_CONTROL2(PpapiMsg_ExecuteCallback,
uint32 /* serialized_callback */,
int32 /* param */)
+// Broker Process.
+
+IPC_SYNC_MESSAGE_CONTROL2_0(PpapiMsg_ConnectToPlugin,
+ PP_Instance /* instance */,
+ IPC::PlatformFileForTransit /* handle */)
+
// PPB_Audio.
// Notifies the result of the audio stream create call. This is called in
diff --git a/webkit/plugins/ppapi/ppb_broker_impl.cc b/webkit/plugins/ppapi/ppb_broker_impl.cc
index 959830a..16aa316 100644
--- a/webkit/plugins/ppapi/ppb_broker_impl.cc
+++ b/webkit/plugins/ppapi/ppb_broker_impl.cc
@@ -128,8 +128,10 @@ PPB_Broker_Impl* PPB_Broker_Impl::AsPPB_Broker_Impl() {
}
// Transfers ownership of the handle to the plugin.
-void PPB_Broker_Impl::BrokerConnected(int32_t handle) {
- DCHECK(handle);
+void PPB_Broker_Impl::BrokerConnected(int32_t handle, int32_t result) {
+ DCHECK(result == PP_OK ||
+ handle == PlatformFileToInt(base::kInvalidPlatformFileValue));
+
pipe_handle_ = handle;
// Synchronous calls are not supported.
@@ -137,7 +139,7 @@ void PPB_Broker_Impl::BrokerConnected(int32_t handle) {
scoped_refptr<TrackedCompletionCallback> callback;
callback.swap(connect_callback_);
- callback->Run(PP_OK); // Will complete abortively if necessary.
+ callback->Run(result); // Will complete abortively if necessary.
}
} // namespace ppapi
diff --git a/webkit/plugins/ppapi/ppb_broker_impl.h b/webkit/plugins/ppapi/ppb_broker_impl.h
index 2e7b0b6..5bba19a 100644
--- a/webkit/plugins/ppapi/ppb_broker_impl.h
+++ b/webkit/plugins/ppapi/ppb_broker_impl.h
@@ -33,7 +33,7 @@ class PPB_Broker_Impl : public Resource {
// Resource override.
virtual PPB_Broker_Impl* AsPPB_Broker_Impl();
- virtual void BrokerConnected(int32_t handle);
+ void BrokerConnected(int32_t handle, int32_t result);
private:
// PluginDelegate ppapi broker object.