diff options
21 files changed, 420 insertions, 10 deletions
diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h index 4acf9a2..fe9c5b3 100644 --- a/content/browser/ppapi_plugin_process_host.h +++ b/content/browser/ppapi_plugin_process_host.h @@ -107,6 +107,8 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate, // channel is ready or if there's an error. void OpenChannelToPlugin(Client* client); + BrowserPpapiHostImpl* host_impl() { return host_impl_.get(); } + const BrowserChildProcessHostImpl* process() { return process_.get(); } const base::FilePath& plugin_path() const { return plugin_path_; } const base::FilePath& profile_data_directory() const { return profile_data_directory_; diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc new file mode 100644 index 0000000..ca6d61c --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc @@ -0,0 +1,79 @@ +// Copyright 2013 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. + +#include "content/browser/renderer_host/pepper/pepper_renderer_connection.h" + +#include "content/browser/browser_child_process_host_impl.h" +#include "content/browser/ppapi_plugin_process_host.h" +#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/common/content_client.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" + +namespace content { + +PepperRendererConnection::PepperRendererConnection() { +} + +PepperRendererConnection::~PepperRendererConnection() { +} + +bool PepperRendererConnection::OnMessageReceived(const IPC::Message& msg, + bool* message_was_ok) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(PepperRendererConnection, msg, *message_was_ok) + IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostFromHost, + OnMsgCreateResourceHostFromHost) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP_EX() + + return handled; +} + +void PepperRendererConnection::OnMsgCreateResourceHostFromHost( + int child_process_id, + const ppapi::proxy::ResourceMessageCallParams& params, + PP_Instance instance, + const IPC::Message& nested_msg) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + BrowserPpapiHostImpl* host = NULL; + + // Find the plugin which this message refers to. Check NaCl plugins first. + host = static_cast<BrowserPpapiHostImpl*>( + GetContentClient()->browser()->GetExternalBrowserPpapiHost( + child_process_id)); + + if (!host) { + // Check trusted pepper plugins. + for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter->process() && + iter->process()->GetData().id == child_process_id) { + // Found the plugin. + host = iter->host_impl(); + break; + } + } + } + + int pending_resource_host_id; + if (!host) { + DLOG(ERROR) << "Invalid plugin process ID."; + pending_resource_host_id = 0; + } else { + scoped_ptr<ppapi::host::ResourceHost> resource_host = + host->GetPpapiHost()->CreateResourceHost(params, + instance, + nested_msg); + pending_resource_host_id = + host->GetPpapiHost()->AddPendingResourceHost(resource_host.Pass()); + } + + Send(new PpapiHostMsg_CreateResourceHostFromHostReply( + params.sequence(), pending_resource_host_id)); +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.h b/content/browser/renderer_host/pepper/pepper_renderer_connection.h new file mode 100644 index 0000000..b4a751c --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.h @@ -0,0 +1,47 @@ +// Copyright 2013 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 CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_RENDERER_CONNECTION_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_RENDERER_CONNECTION_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "content/public/browser/browser_message_filter.h" +#include "ppapi/c/pp_instance.h" + +namespace ppapi { +namespace proxy { +class ResourceMessageCallParams; +} +} + +namespace content { + +// This class represents a connection from the browser to the renderer for +// sending/receiving pepper ResourceHost related messages. When the browser +// and renderer communicate about ResourceHosts, they should pass the plugin +// process ID to identify which plugin they are talking about. +class PepperRendererConnection : public BrowserMessageFilter { + public: + PepperRendererConnection(); + + // BrowserMessageFilter overrides. + virtual bool OnMessageReceived(const IPC::Message& msg, + bool* message_was_ok) OVERRIDE; + + private: + virtual ~PepperRendererConnection(); + + void OnMsgCreateResourceHostFromHost( + int child_process_id, + const ppapi::proxy::ResourceMessageCallParams& params, + PP_Instance instance, + const IPC::Message& nested_msg); + + DISALLOW_COPY_AND_ASSIGN(PepperRendererConnection); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_RENDERER_CONNECTION_H_ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 21c20c9..ecd4139 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -78,6 +78,7 @@ #include "content/browser/renderer_host/memory_benchmark_message_filter.h" #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h" #include "content/browser/renderer_host/pepper/pepper_message_filter.h" +#include "content/browser/renderer_host/pepper/pepper_renderer_connection.h" #include "content/browser/renderer_host/quota_dispatcher_host.h" #include "content/browser/renderer_host/render_message_filter.h" #include "content/browser/renderer_host/render_view_host_delegate.h" @@ -640,7 +641,9 @@ void RenderProcessHostImpl::CreateMessageFilters() { channel_->AddFilter(new MediaStreamDispatcherHost(GetID())); #endif #if defined(ENABLE_PLUGINS) + // TODO(raymes): PepperMessageFilter should be removed from here. channel_->AddFilter(new PepperMessageFilter(GetID(), browser_context)); + channel_->AddFilter(new PepperRendererConnection); #endif #if defined(ENABLE_INPUT_SPEECH) channel_->AddFilter(new InputTagSpeechDispatcherHost( diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 7f8c4c5..4e5944a 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -835,6 +835,8 @@ 'browser/renderer_host/pepper/pepper_print_settings_manager.h', 'browser/renderer_host/pepper/pepper_printing_host.cc', 'browser/renderer_host/pepper/pepper_printing_host.h', + 'browser/renderer_host/pepper/pepper_renderer_connection.cc', + 'browser/renderer_host/pepper/pepper_renderer_connection.h', 'browser/renderer_host/pepper/pepper_socket_utils.cc', 'browser/renderer_host/pepper/pepper_socket_utils.h', 'browser/renderer_host/pepper/pepper_tcp_server_socket.cc', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 07f946f..9008ba8 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -188,6 +188,8 @@ 'renderer/pepper/pepper_audio_input_host.h', 'renderer/pepper/pepper_broker_impl.cc', 'renderer/pepper/pepper_broker_impl.h', + 'renderer/pepper/pepper_browser_connection.cc', + 'renderer/pepper/pepper_browser_connection.h', 'renderer/pepper/pepper_device_enumeration_event_handler.cc', 'renderer/pepper/pepper_device_enumeration_event_handler.h', 'renderer/pepper/pepper_device_enumeration_host_helper.cc', diff --git a/content/public/renderer/renderer_ppapi_host.h b/content/public/renderer/renderer_ppapi_host.h index 0af9d7a..8d2e585 100644 --- a/content/public/renderer/renderer_ppapi_host.h +++ b/content/public/renderer/renderer_ppapi_host.h @@ -23,6 +23,7 @@ class Point; namespace IPC { struct ChannelHandle; +class Message; } namespace ppapi { @@ -131,6 +132,18 @@ class RendererPpapiHost { // Returns true if the plugin is running in process. virtual bool IsRunningInProcess() const = 0; + // There are times when the renderer needs to create a ResourceHost in the + // browser. This function does so asynchronously. |nested_msg| is the + // resource host creation message and |instance| is the PP_Instance which + // the resource will belong to. |callback| will be called with the pending + // host ID when the ResourceHost has been created. This can be passed back + // to the plugin to attach to the ResourceHost. A pending ID of 0 will be + // passed to the callback upon error. + virtual void CreateBrowserResourceHost( + PP_Instance instance, + const IPC::Message& nested_msg, + const base::Callback<void(int)>& callback) const = 0; + protected: virtual ~RendererPpapiHost() {} }; diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.cc b/content/renderer/pepper/mock_renderer_ppapi_host.cc index 155fb99..5a2da54 100644 --- a/content/renderer/pepper/mock_renderer_ppapi_host.cc +++ b/content/renderer/pepper/mock_renderer_ppapi_host.cc @@ -78,4 +78,13 @@ bool MockRendererPpapiHost::IsRunningInProcess() const { return false; } +void MockRendererPpapiHost::CreateBrowserResourceHost( + PP_Instance instance, + const IPC::Message& nested_msg, + const base::Callback<void(int)>& callback) const { + NOTIMPLEMENTED(); + callback.Run(0); + return; +} + } // namespace content diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.h b/content/renderer/pepper/mock_renderer_ppapi_host.h index c49bc9e..3194d3f 100644 --- a/content/renderer/pepper/mock_renderer_ppapi_host.h +++ b/content/renderer/pepper/mock_renderer_ppapi_host.h @@ -55,6 +55,10 @@ class MockRendererPpapiHost : public RendererPpapiHost { base::PlatformFile handle, bool should_close_source) OVERRIDE; virtual bool IsRunningInProcess() const OVERRIDE; + virtual void CreateBrowserResourceHost( + PP_Instance instance, + const IPC::Message& nested_msg, + const base::Callback<void(int)>& callback) const OVERRIDE; private: ppapi::proxy::ResourceMessageTestSink sink_; diff --git a/content/renderer/pepper/pepper_browser_connection.cc b/content/renderer/pepper/pepper_browser_connection.cc new file mode 100644 index 0000000..18f5c0e --- /dev/null +++ b/content/renderer/pepper/pepper_browser_connection.cc @@ -0,0 +1,78 @@ +// Copyright 2013 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. + +#include "content/renderer/pepper/pepper_browser_connection.h" + +#include <limits> + +#include "base/logging.h" +#include "content/renderer/pepper/pepper_plugin_delegate_impl.h" +#include "content/renderer/render_view_impl.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" + +namespace content { + +PepperBrowserConnection::PepperBrowserConnection( + PepperPluginDelegateImpl* plugin_delegate) + : plugin_delegate_(plugin_delegate), + next_sequence_number_(1) { +} + +PepperBrowserConnection::~PepperBrowserConnection() { +} + +bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PepperBrowserConnection, msg) + IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostFromHostReply, + OnMsgCreateResourceHostFromHostReply) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; +} + +void PepperBrowserConnection::SendBrowserCreate( + int child_process_id, + PP_Instance instance, + const IPC::Message& nested_msg, + const PendingResourceIDCallback& callback) { + int32_t sequence_number = GetNextSequence(); + pending_create_map_[sequence_number] = callback; + ppapi::proxy::ResourceMessageCallParams params(0, sequence_number); + plugin_delegate_->render_view()->Send( + new PpapiHostMsg_CreateResourceHostFromHost( + child_process_id, params, instance, nested_msg)); +} + +void PepperBrowserConnection::OnMsgCreateResourceHostFromHostReply( + int32_t sequence_number, + int pending_resource_host_id) { + // Check that the message is destined for the plugin this object is associated + // with. + std::map<int32_t, PendingResourceIDCallback>::iterator it = + pending_create_map_.find(sequence_number); + if (it != pending_create_map_.end()) { + it->second.Run(pending_resource_host_id); + pending_create_map_.erase(it); + } else { + NOTREACHED(); + } +} + +int32_t PepperBrowserConnection::GetNextSequence() { + // Return the value with wraparound, making sure we don't make a sequence + // number with a 0 ID. Note that signed wraparound is undefined in C++ so we + // manually check. + int32_t ret = next_sequence_number_; + if (next_sequence_number_ == std::numeric_limits<int32_t>::max()) + next_sequence_number_ = 1; // Skip 0 which is invalid. + else + next_sequence_number_++; + return ret; +} + +} // namespace content diff --git a/content/renderer/pepper/pepper_browser_connection.h b/content/renderer/pepper/pepper_browser_connection.h new file mode 100644 index 0000000..77db499 --- /dev/null +++ b/content/renderer/pepper/pepper_browser_connection.h @@ -0,0 +1,61 @@ +// Copyright 2013 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 CONTENT_RENDERER_PEPPER_PEPPER_BROWSER_CONNECTION_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_BROWSER_CONNECTION_H_ + +#include <map> + +#include "base/callback.h" +#include "content/public/renderer/render_view_observer.h" +#include "ppapi/c/pp_instance.h" + +namespace content { + +class PepperPluginDelegateImpl; + +// This class represents a connection from the renderer to the browser for +// sending/receiving pepper ResourceHost related messages. When the browser +// and renderer communicate about ResourceHosts, they should pass the plugin +// process ID to identify which plugin they are talking about. +class PepperBrowserConnection { + public: + typedef base::Callback<void(int)> PendingResourceIDCallback; + + explicit PepperBrowserConnection(PepperPluginDelegateImpl* plugin_delegate); + virtual ~PepperBrowserConnection(); + + bool OnMessageReceived(const IPC::Message& message); + + // Sends a request to the browser to create a ResourceHost for the given + // |instance| of a plugin identified by |child_process_id|. |callback| will be + // run when a reply is received with the pending resource ID. + void SendBrowserCreate(PP_Instance instance, + int child_process_id, + const IPC::Message& create_message, + const PendingResourceIDCallback& callback); + + private: + // Message handlers. + void OnMsgCreateResourceHostFromHostReply(int32_t sequence_number, + int pending_resource_host_id); + + // Return the next sequence number. + int32_t GetNextSequence(); + + // The plugin delegate that owns us. + PepperPluginDelegateImpl* plugin_delegate_; + + // Sequence number to track pending callbacks. + int32_t next_sequence_number_; + + // Maps a sequence number to the callback to be run. + std::map<int32_t, PendingResourceIDCallback> pending_create_map_; + + DISALLOW_COPY_AND_ASSIGN(PepperBrowserConnection); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_BROWSER_CONNECTION_H_ diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index dfcc090..4a0be19 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -42,6 +42,7 @@ #include "content/renderer/p2p/socket_dispatcher.h" #include "content/renderer/pepper/content_renderer_pepper_host_factory.h" #include "content/renderer/pepper/pepper_broker_impl.h" +#include "content/renderer/pepper/pepper_browser_connection.h" #include "content/renderer/pepper/pepper_device_enumeration_event_handler.h" #include "content/renderer/pepper/pepper_file_system_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" @@ -204,6 +205,10 @@ class HostDispatcherWrapper return peer_pid_; } + virtual int GetPluginChildId() OVERRIDE { + return plugin_child_id_; + } + ppapi::proxy::HostDispatcher* dispatcher() { return dispatcher_.get(); } private: @@ -328,6 +333,7 @@ ppapi::host::ResourceHost* GetRendererResourceHost( PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderViewImpl* render_view) : RenderViewObserver(render_view), render_view_(render_view), + pepper_browser_connection_(this), focused_plugin_(NULL), last_mouse_event_target_(NULL), device_enumeration_event_handler_( @@ -1469,6 +1475,9 @@ void PepperPluginDelegateImpl::StopEnumerateDevices(int request_id) { } bool PepperPluginDelegateImpl::OnMessageReceived(const IPC::Message& message) { + if (pepper_browser_connection_.OnMessageReceived(message)) + return true; + bool handled = true; IPC_BEGIN_MESSAGE_MAP(PepperPluginDelegateImpl, message) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ConnectACK, diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h index da546e1..5e611b0 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h @@ -18,6 +18,7 @@ #include "base/observer_list.h" #include "content/public/renderer/render_view_observer.h" #include "content/renderer/mouse_lock_dispatcher.h" +#include "content/renderer/pepper/pepper_browser_connection.h" #include "content/renderer/render_view_pepper_helper.h" #include "ppapi/c/pp_file_info.h" #include "ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h" @@ -70,6 +71,10 @@ class PepperPluginDelegateImpl RenderViewImpl* render_view() { return render_view_; } + PepperBrowserConnection* pepper_browser_connection() { + return &pepper_browser_connection_; + } + // Sets up the renderer host and out-of-process proxy for an external plugin // module. Returns the renderer host, or NULL if it couldn't be created. RendererPpapiHost* CreateExternalPluginModule( @@ -410,6 +415,10 @@ class PepperPluginDelegateImpl // Pointer to the RenderView that owns us. RenderViewImpl* render_view_; + // Connection for sending and receiving pepper host-related messages to/from + // the browser. + PepperBrowserConnection pepper_browser_connection_; + std::set<webkit::ppapi::PluginInstance*> active_instances_; typedef std::map<webkit::ppapi::PluginInstance*, MouseLockDispatcher::LockTarget*> LockTargetMap; diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.cc b/content/renderer/pepper/renderer_ppapi_host_impl.cc index fe915b8..aaa6242 100644 --- a/content/renderer/pepper/renderer_ppapi_host_impl.cc +++ b/content/renderer/pepper/renderer_ppapi_host_impl.cc @@ -8,12 +8,14 @@ #include "base/logging.h" #include "base/process_util.h" #include "content/common/sandbox_util.h" +#include "content/renderer/pepper/pepper_browser_connection.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "content/renderer/pepper/pepper_in_process_resource_creation.h" #include "content/renderer/pepper/pepper_in_process_router.h" #include "content/renderer/pepper/pepper_plugin_delegate_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" +#include "ipc/ipc_message.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/host_dispatcher.h" #include "third_party/WebKit/public/platform/WebRect.h" @@ -259,6 +261,29 @@ bool RendererPpapiHostImpl::IsRunningInProcess() const { return is_running_in_process_; } +void RendererPpapiHostImpl::CreateBrowserResourceHost( + PP_Instance instance, + const IPC::Message& nested_msg, + const base::Callback<void(int)>& callback) const { + PluginInstance* instance_object = GetAndValidateInstance(instance); + if (!instance_object) + callback.Run(0); + + // Since we're the embedder, we can make assumptions about the delegate on + // the instance. + PepperPluginDelegateImpl* delegate = + static_cast<PepperPluginDelegateImpl*>(instance_object->delegate()); + if (!delegate) + callback.Run(0); + + PepperBrowserConnection* browser_connection = + delegate->pepper_browser_connection(); + browser_connection->SendBrowserCreate(module_->GetPluginChildId(), + instance, + nested_msg, + callback); +} + PluginInstance* RendererPpapiHostImpl::GetAndValidateInstance( PP_Instance pp_instance) const { PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.h b/content/renderer/pepper/renderer_ppapi_host_impl.h index 9143342..ac9b9c9 100644 --- a/content/renderer/pepper/renderer_ppapi_host_impl.h +++ b/content/renderer/pepper/renderer_ppapi_host_impl.h @@ -101,6 +101,10 @@ class RendererPpapiHostImpl base::PlatformFile handle, bool should_close_source) OVERRIDE; virtual bool IsRunningInProcess() const OVERRIDE; + virtual void CreateBrowserResourceHost( + PP_Instance instance, + const IPC::Message& nested_msg, + const base::Callback<void(int)>& callback) const OVERRIDE; private: RendererPpapiHostImpl(webkit::ppapi::PluginModule* module, diff --git a/ppapi/host/ppapi_host.cc b/ppapi/host/ppapi_host.cc index 0b24e10..a200f3b6 100644 --- a/ppapi/host/ppapi_host.cc +++ b/ppapi/host/ppapi_host.cc @@ -99,9 +99,32 @@ void PpapiHost::SendUnsolicitedReply(PP_Resource resource, Send(new PpapiPluginMsg_ResourceReply(params, msg)); } +scoped_ptr<ResourceHost> PpapiHost::CreateResourceHost( + const proxy::ResourceMessageCallParams& params, + PP_Instance instance, + const IPC::Message& nested_msg) { + scoped_ptr<ResourceHost> resource_host; + DCHECK(!host_factory_filters_.empty()); // Caller forgot to add a factory. + for (size_t i = 0; i < host_factory_filters_.size(); i++) { + resource_host = host_factory_filters_[i]->CreateResourceHost( + this, params, instance, nested_msg).Pass(); + if (resource_host.get()) + break; + } + return resource_host.Pass(); +} + int PpapiHost::AddPendingResourceHost(scoped_ptr<ResourceHost> resource_host) { // The resource ID should not be assigned. - DCHECK(resource_host->pp_resource() == 0); + if (!resource_host.get() || resource_host->pp_resource() != 0) { + NOTREACHED(); + return 0; + } + + if (pending_resource_hosts_.size() + resources_.size() + >= kMaxResourcesPerPlugin) { + return 0; + } int pending_id = next_pending_resource_host_id_++; pending_resource_hosts_[pending_id] = @@ -168,18 +191,16 @@ void PpapiHost::OnHostMsgResourceCreated( TRACE_EVENT2("ppapi proxy", "PpapiHost::OnHostMsgResourceCreated", "Class", IPC_MESSAGE_ID_CLASS(nested_msg.type()), "Line", IPC_MESSAGE_ID_LINE(nested_msg.type())); - if (resources_.size() >= kMaxResourcesPerPlugin) + + if (pending_resource_hosts_.size() + resources_.size() + >= kMaxResourcesPerPlugin) { return; + } // Run through all filters until one grabs this message. - scoped_ptr<ResourceHost> resource_host; - DCHECK(!host_factory_filters_.empty()); // Caller forgot to add a factory. - for (size_t i = 0; i < host_factory_filters_.size(); i++) { - resource_host = host_factory_filters_[i]->CreateResourceHost( - this, params, instance, nested_msg).Pass(); - if (resource_host.get()) - break; - } + scoped_ptr<ResourceHost> resource_host = CreateResourceHost(params, instance, + nested_msg); + if (!resource_host.get()) { NOTREACHED(); return; diff --git a/ppapi/host/ppapi_host.h b/ppapi/host/ppapi_host.h index c661a9b..0b3d23d 100644 --- a/ppapi/host/ppapi_host.h +++ b/ppapi/host/ppapi_host.h @@ -61,6 +61,12 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener { // Sends the given unsolicited reply message to the plugin. void SendUnsolicitedReply(PP_Resource resource, const IPC::Message& msg); + // Create a ResourceHost with the given |nested_msg|. + scoped_ptr<ResourceHost> CreateResourceHost( + const proxy::ResourceMessageCallParams& params, + PP_Instance instance, + const IPC::Message& nested_msg); + // Adds the given host resource as a pending one (with no corresponding // PluginResource object and no PP_Resource ID yet). The pending resource ID // is returned. See PpapiHostMsg_AttachToPendingHost. diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 93df466..22e45d1 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1299,6 +1299,28 @@ IPC_SYNC_MESSAGE_CONTROL2_2(PpapiHostMsg_ResourceSyncCall, ppapi::proxy::ResourceMessageReplyParams /* reply_params */, IPC::Message /* reply_msg */) +// This message is sent from the renderer to the browser when it wants to create +// a ResourceHost in the browser. It contains the process ID of the plugin and +// the instance of the plugin for which to create the resource for. params +// contains the sequence number for the message to track the response. +// The nested message is a ResourceHost creation message. +IPC_MESSAGE_CONTROL4( + PpapiHostMsg_CreateResourceHostFromHost, + int /* child_process_id */, + ppapi::proxy::ResourceMessageCallParams /* params */, + PP_Instance /* instance */, + IPC::Message /* nested_msg */) + +// This message is sent from the browser to the renderer when it has created a +// ResourceHost for the renderer. It contains the sequence number that was sent +// in the request and the ID of the pending ResourceHost which was created in +// the browser. This ID is only useful for the plugin which can attach to the +// ResourceHost in the browser. +IPC_MESSAGE_CONTROL2( + PpapiHostMsg_CreateResourceHostFromHostReply, + int32_t /* sequence */, + int /* pending_host_id */) + //----------------------------------------------------------------------------- // Messages for resources using call/reply above. diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 6119c4c..9624e80 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -163,6 +163,7 @@ class PluginDelegate { virtual void RemoveInstance(PP_Instance instance) = 0; virtual base::ProcessId GetPeerProcessId() = 0; + virtual int GetPluginChildId() = 0; }; // Represents an image. This is to allow the browser layer to supply a correct diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index 3cc93fb..ce2a9a8 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -509,6 +509,12 @@ base::ProcessId PluginModule::GetPeerProcessId() { return base::kNullProcessId; } +int PluginModule::GetPluginChildId() { + if (out_of_process_proxy_) + return out_of_process_proxy_->GetPluginChildId(); + return 0; +} + // static const PPB_Core* PluginModule::GetCore() { return &core_interface; diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h index 7c11f7e..fdc03a2 100644 --- a/webkit/plugins/ppapi/plugin_module.h +++ b/webkit/plugins/ppapi/plugin_module.h @@ -129,6 +129,13 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : // returns |base::kNullProcessId| otherwise. base::ProcessId GetPeerProcessId(); + // Returns the plugin child process ID if the plugin is running out of + // process. Returns 0 otherwise. This is the ID that the browser process uses + // to idetify the child process for the plugin. This isn't directly useful + // from our process (the renderer) except in messages to the browser to + // disambiguate plugins. + int GetPluginChildId(); + static const PPB_Core* GetCore(); // Returns a pointer to the local GetInterface function for retrieving |