summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/ppapi_plugin_process_host.h2
-rw-r--r--content/browser/renderer_host/pepper/pepper_renderer_connection.cc79
-rw-r--r--content/browser/renderer_host/pepper/pepper_renderer_connection.h47
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc3
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/public/renderer/renderer_ppapi_host.h13
-rw-r--r--content/renderer/pepper/mock_renderer_ppapi_host.cc9
-rw-r--r--content/renderer/pepper/mock_renderer_ppapi_host.h4
-rw-r--r--content/renderer/pepper/pepper_browser_connection.cc78
-rw-r--r--content/renderer/pepper/pepper_browser_connection.h61
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.cc9
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.h9
-rw-r--r--content/renderer/pepper/renderer_ppapi_host_impl.cc25
-rw-r--r--content/renderer/pepper/renderer_ppapi_host_impl.h4
-rw-r--r--ppapi/host/ppapi_host.cc41
-rw-r--r--ppapi/host/ppapi_host.h6
-rw-r--r--ppapi/proxy/ppapi_messages.h22
-rw-r--r--webkit/plugins/ppapi/plugin_delegate.h1
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc6
-rw-r--r--webkit/plugins/ppapi/plugin_module.h7
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