diff options
author | ddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-18 16:00:47 +0000 |
---|---|---|
committer | ddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-18 16:00:47 +0000 |
commit | 2b657fd950ea3e06ac489f37c5d320dde00d70ad (patch) | |
tree | 1dcd64a12edffbcb17bb9d33a04d7517a08d705a /content | |
parent | eaca0ad17b151d28b1e5821f1fce27a6dadc0b29 (diff) | |
download | chromium_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.cc | 10 | ||||
-rw-r--r-- | content/common/view_messages.h | 3 | ||||
-rw-r--r-- | content/renderer/pepper_plugin_delegate_impl.cc | 143 | ||||
-rw-r--r-- | content/renderer/pepper_plugin_delegate_impl.h | 36 | ||||
-rw-r--r-- | content/renderer/render_view.cc | 10 | ||||
-rw-r--r-- | content/renderer/render_view.h | 3 |
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); |