summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 17:17:21 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 17:17:21 +0000
commit5d84d01d904a2e5fa3e17b8d9165e63a20351160 (patch)
treedd87a4d94ed6276dc1551cbc5d3c744eb268cebd
parent9a80065bad1506ac11163d597ace3295ddbfa8cb (diff)
downloadchromium_src-5d84d01d904a2e5fa3e17b8d9165e63a20351160.zip
chromium_src-5d84d01d904a2e5fa3e17b8d9165e63a20351160.tar.gz
chromium_src-5d84d01d904a2e5fa3e17b8d9165e63a20351160.tar.bz2
Implement audio proxy for Pepper.
In addition to the basic proxying, this required some changes to the dispatcher and process infrastructure to get the handles of the processes available when I need them so I can duplicate the shared memory handles properly into the different processes. TEST=none BUG=none Review URL: http://codereview.chromium.org/4985001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68026 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser_child_process_host.cc8
-rw-r--r--chrome/browser/browser_child_process_host.h4
-rw-r--r--chrome/browser/ppapi_plugin_process_host.cc42
-rw-r--r--chrome/browser/ppapi_plugin_process_host.h3
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/ppapi_plugin/ppapi_thread.cc13
-rw-r--r--chrome/ppapi_plugin/ppapi_thread.h8
-rw-r--r--chrome/renderer/pepper_plugin_delegate_impl.cc4
-rw-r--r--ppapi/ppapi.gyp25
-rw-r--r--ppapi/proxy/DEPS3
-rw-r--r--ppapi/proxy/dispatcher.cc12
-rw-r--r--ppapi/proxy/dispatcher.h13
-rw-r--r--ppapi/proxy/host_dispatcher.cc5
-rw-r--r--ppapi/proxy/host_dispatcher.h4
-rw-r--r--ppapi/proxy/interface_id.h4
-rw-r--r--ppapi/proxy/plugin_dispatcher.cc5
-rw-r--r--ppapi/proxy/plugin_dispatcher.h5
-rw-r--r--ppapi/proxy/plugin_resource.h2
-rw-r--r--ppapi/proxy/ppapi_messages.h4
-rw-r--r--ppapi/proxy/ppapi_messages_internal.h49
-rw-r--r--ppapi/proxy/ppb_audio_config_proxy.cc135
-rw-r--r--ppapi/proxy/ppb_audio_config_proxy.h46
-rw-r--r--ppapi/proxy/ppb_audio_proxy.cc285
-rw-r--r--ppapi/proxy/ppb_audio_proxy.h78
-rw-r--r--ppapi/shared_impl/DEPS4
-rw-r--r--ppapi/shared_impl/README.txt2
-rw-r--r--ppapi/shared_impl/audio_impl.cc96
-rw-r--r--ppapi/shared_impl/audio_impl.h85
-rw-r--r--webkit/glue/plugins/pepper_audio.cc133
-rw-r--r--webkit/glue/plugins/pepper_audio.h71
-rw-r--r--webkit/glue/plugins/pepper_font.cc12
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc10
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.h3
-rw-r--r--webkit/glue/webkit_glue.gypi1
34 files changed, 999 insertions, 180 deletions
diff --git a/chrome/browser/browser_child_process_host.cc b/chrome/browser/browser_child_process_host.cc
index a317f26..5cfd536 100644
--- a/chrome/browser/browser_child_process_host.cc
+++ b/chrome/browser/browser_child_process_host.cc
@@ -117,6 +117,14 @@ void BrowserChildProcessHost::Launch(
&client_));
}
+base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const {
+ DCHECK(child_process_.get())
+ << "Requesting a child process handle before launching.";
+ DCHECK(child_process_->GetHandle())
+ << "Requesting a child process handle before launch has completed OK.";
+ return child_process_->GetHandle();
+}
+
bool BrowserChildProcessHost::Send(IPC::Message* msg) {
return SendOnChannel(msg);
}
diff --git a/chrome/browser/browser_child_process_host.h b/chrome/browser/browser_child_process_host.h
index cf30973..f70c035 100644
--- a/chrome/browser/browser_child_process_host.h
+++ b/chrome/browser/browser_child_process_host.h
@@ -73,6 +73,10 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver,
#endif
CommandLine* cmd_line);
+ // Returns the handle of the child process. This must be called only after
+ // OnProcessLaunched is called or it will be invalid and may crash.
+ base::ProcessHandle GetChildProcessHandle() const;
+
// ChildProcessLauncher::Client implementation.
virtual void OnProcessLaunched() { }
diff --git a/chrome/browser/ppapi_plugin_process_host.cc b/chrome/browser/ppapi_plugin_process_host.cc
index ba47b86..ded8964 100644
--- a/chrome/browser/ppapi_plugin_process_host.cc
+++ b/chrome/browser/ppapi_plugin_process_host.cc
@@ -29,7 +29,7 @@ void PpapiPluginProcessHost::Init(const FilePath& path,
reply_msg_.reset(reply_msg);
if (!CreateChannel()) {
- ReplyToRenderer(IPC::ChannelHandle());
+ ReplyToRenderer(NULL, IPC::ChannelHandle());
return;
}
@@ -39,7 +39,7 @@ void PpapiPluginProcessHost::Init(const FilePath& path,
FilePath exe_path = ChildProcessHost::GetChildPath(plugin_launcher.empty());
if (exe_path.empty()) {
- ReplyToRenderer(IPC::ChannelHandle());
+ ReplyToRenderer(NULL, IPC::ChannelHandle());
return;
}
@@ -80,25 +80,49 @@ void PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
}
void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) {
- PpapiMsg_LoadPlugin* msg = new PpapiMsg_LoadPlugin(plugin_path_,
+#if defined(OS_WIN)
+ base::ProcessHandle plugins_renderer_handle = NULL;
+ ::DuplicateHandle(::GetCurrentProcess(), filter_->handle(),
+ GetChildProcessHandle(), &plugins_renderer_handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+#elif defined(OS_POSIX)
+ base::ProcessHandle plugins_renderer_handle = filter_->handle();
+#endif
+
+ PpapiMsg_LoadPlugin* msg = new PpapiMsg_LoadPlugin(plugins_renderer_handle,
+ plugin_path_,
filter_->id());
if (!Send(msg)) // Just send an empty handle on failure.
- ReplyToRenderer(IPC::ChannelHandle());
+ ReplyToRenderer(NULL, IPC::ChannelHandle());
// This function will result in OnChannelCreated getting called to finish.
}
void PpapiPluginProcessHost::OnChannelError() {
if (reply_msg_.get())
- ReplyToRenderer(IPC::ChannelHandle());
+ ReplyToRenderer(NULL, IPC::ChannelHandle());
}
-void PpapiPluginProcessHost::OnPluginLoaded(const IPC::ChannelHandle& handle) {
- ReplyToRenderer(handle);
+void PpapiPluginProcessHost::OnPluginLoaded(
+ const IPC::ChannelHandle& channel_handle) {
+ base::ProcessHandle plugin_process = GetChildProcessHandle();
+#if defined(OS_WIN)
+ base::ProcessHandle renderers_plugin_handle = NULL;
+ ::DuplicateHandle(::GetCurrentProcess(), plugin_process,
+ filter_->handle(), &renderers_plugin_handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+#elif defined(OS_POSIX)
+ // Don't need to duplicate anything on POSIX since it's just a PID.
+ base::ProcessHandle renderers_plugin_handle = plugin_process;
+#endif
+ ReplyToRenderer(renderers_plugin_handle, channel_handle);
}
-void PpapiPluginProcessHost::ReplyToRenderer(const IPC::ChannelHandle& handle) {
+void PpapiPluginProcessHost::ReplyToRenderer(
+ base::ProcessHandle plugin_handle,
+ const IPC::ChannelHandle& channel_handle) {
DCHECK(reply_msg_.get());
ViewHostMsg_OpenChannelToPepperPlugin::WriteReplyParams(reply_msg_.get(),
- handle);
+ plugin_handle,
+ channel_handle);
filter_->Send(reply_msg_.release());
}
diff --git a/chrome/browser/ppapi_plugin_process_host.h b/chrome/browser/ppapi_plugin_process_host.h
index 956148c..dd71b14 100644
--- a/chrome/browser/ppapi_plugin_process_host.h
+++ b/chrome/browser/ppapi_plugin_process_host.h
@@ -39,7 +39,8 @@ class PpapiPluginProcessHost : public BrowserChildProcessHost {
void OnPluginLoaded(const IPC::ChannelHandle& handle);
// Sends the reply_msg_ to the renderer with the given channel info.
- void ReplyToRenderer(const IPC::ChannelHandle& handle);
+ void ReplyToRenderer(base::ProcessHandle plugin_handle,
+ const IPC::ChannelHandle& channel_handle);
ResourceMessageFilter* filter_;
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 34b5bf0..cf9e44f 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1579,15 +1579,16 @@ IPC_BEGIN_MESSAGES(ViewHost)
IPC_SYNC_MESSAGE_CONTROL2_2(ViewHostMsg_OpenChannelToPlugin,
GURL /* url */,
std::string /* mime_type */,
- IPC::ChannelHandle /* handle to channel */,
+ IPC::ChannelHandle /* channel_handle */,
WebPluginInfo /* info */)
// A renderer sends this to the browser process when it wants to
// create a pepper plugin. The browser will create the plugin process if
// necessary, and will return a handle to the channel on success.
// On error an empty string is returned.
- IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_OpenChannelToPepperPlugin,
+ IPC_SYNC_MESSAGE_CONTROL1_2(ViewHostMsg_OpenChannelToPepperPlugin,
FilePath /* path */,
+ base::ProcessHandle /* plugin_process_handle */,
IPC::ChannelHandle /* handle to channel */)
// A renderer sends this to the browser process when it wants to
diff --git a/chrome/ppapi_plugin/ppapi_thread.cc b/chrome/ppapi_plugin/ppapi_thread.cc
index 36ea9f6..8c4da88 100644
--- a/chrome/ppapi_plugin/ppapi_thread.cc
+++ b/chrome/ppapi_plugin/ppapi_thread.cc
@@ -47,9 +47,11 @@ void PpapiThread::OnMessageReceived(const IPC::Message& msg) {
IPC_END_MESSAGE_MAP()
}
-void PpapiThread::OnLoadPlugin(const FilePath& path, int renderer_id) {
+void PpapiThread::OnLoadPlugin(base::ProcessHandle host_process_handle,
+ const FilePath& path,
+ int renderer_id) {
IPC::ChannelHandle channel_handle;
- if (!LoadPluginLib(path) ||
+ if (!LoadPluginLib(host_process_handle, path) ||
!SetupRendererChannel(renderer_id, &channel_handle)) {
// An empty channel handle indicates error.
Send(new PpapiHostMsg_PluginLoaded(IPC::ChannelHandle()));
@@ -59,7 +61,8 @@ void PpapiThread::OnLoadPlugin(const FilePath& path, int renderer_id) {
Send(new PpapiHostMsg_PluginLoaded(channel_handle));
}
-bool PpapiThread::LoadPluginLib(const FilePath& path) {
+bool PpapiThread::LoadPluginLib(base::ProcessHandle host_process_handle,
+ const FilePath& path) {
base::ScopedNativeLibrary library(base::LoadNativeLibrary(path));
if (!library.is_valid())
return false;
@@ -88,8 +91,8 @@ bool PpapiThread::LoadPluginLib(const FilePath& path) {
library.GetFunctionPointer("PPP_ShutdownModule"));
library_.Reset(library.Release());
- dispatcher_.reset(new pp::proxy::PluginDispatcher(get_interface, init_module,
- shutdown_module));
+ dispatcher_.reset(new pp::proxy::PluginDispatcher(
+ host_process_handle, get_interface, init_module, shutdown_module));
pp::proxy::PluginDispatcher::SetGlobal(dispatcher_.get());
return true;
}
diff --git a/chrome/ppapi_plugin/ppapi_thread.h b/chrome/ppapi_plugin/ppapi_thread.h
index ed7b024..cf49c8b 100644
--- a/chrome/ppapi_plugin/ppapi_thread.h
+++ b/chrome/ppapi_plugin/ppapi_thread.h
@@ -7,6 +7,7 @@
#pragma once
#include "base/basictypes.h"
+#include "base/process.h"
#include "base/scoped_native_library.h"
#include "base/scoped_ptr.h"
#include "build/build_config.h"
@@ -34,9 +35,12 @@ class PpapiThread : public ChildThread {
virtual void OnMessageReceived(const IPC::Message& msg);
// Message handlers.
- void OnLoadPlugin(const FilePath& path, int renderer_id);
+ void OnLoadPlugin(base::ProcessHandle renderer_handle,
+ const FilePath& path,
+ int renderer_id);
- bool LoadPluginLib(const FilePath& path);
+ bool LoadPluginLib(base::ProcessHandle host_process_handle,
+ const FilePath& path);
// Sets up the channel to the given renderer. On success, returns true and
// fills the given ChannelHandle with the information from the new channel.
diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc
index 3cf9183..c3a85d9 100644
--- a/chrome/renderer/pepper_plugin_delegate_impl.cc
+++ b/chrome/renderer/pepper_plugin_delegate_impl.cc
@@ -426,13 +426,15 @@ PepperPluginDelegateImpl::~PepperPluginDelegateImpl() {
scoped_refptr<pepper::PluginModule>
PepperPluginDelegateImpl::CreateOutOfProcessPepperPlugin(
const FilePath& path) {
+ base::ProcessHandle plugin_process_handle = NULL;
IPC::ChannelHandle channel_handle;
render_view_->Send(new ViewHostMsg_OpenChannelToPepperPlugin(
- path, &channel_handle));
+ path, &plugin_process_handle, &channel_handle));
if (channel_handle.name.empty())
return scoped_refptr<pepper::PluginModule>(); // Couldn't be initialized.
return pepper::PluginModule::CreateOutOfProcessModule(
ChildProcess::current()->io_message_loop(),
+ plugin_process_handle,
channel_handle,
ChildProcess::current()->GetShutDownEvent());
}
diff --git a/ppapi/ppapi.gyp b/ppapi/ppapi.gyp
index b9fb347..b321dc6 100644
--- a/ppapi/ppapi.gyp
+++ b/ppapi/ppapi.gyp
@@ -495,11 +495,32 @@
# ],
},
{
+ 'target_name': 'ppapi_shared_impl',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'ppapi_c',
+ '../base/base.gyp:base',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'shared_impl/audio_impl.cc',
+ 'shared_impl/audio_impl.h',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'msvs_guid': 'E7420D65-A885-41EB-B4BE-04DE0C97033B',
+ }],
+ ],
+ },
+ {
'target_name': 'ppapi_proxy',
'type': 'static_library',
'dependencies': [
'../ipc/ipc.gyp:ipc',
'ppapi_c',
+ 'ppapi_shared_impl',
],
'all_dependent_settings': {
'include_dirs': [
@@ -536,6 +557,10 @@
'proxy/ppapi_messages_internal.h',
'proxy/ppapi_param_traits.cc',
'proxy/ppapi_param_traits.h',
+ 'proxy/ppb_audio_config_proxy.cc',
+ 'proxy/ppb_audio_config_proxy.h',
+ 'proxy/ppb_audio_proxy.cc',
+ 'proxy/ppb_audio_proxy.h',
'proxy/ppb_buffer_proxy.cc',
'proxy/ppb_buffer_proxy.h',
'proxy/ppb_char_set_proxy.cc',
diff --git a/ppapi/proxy/DEPS b/ppapi/proxy/DEPS
index d5d2f9c..7ef8f98 100644
--- a/ppapi/proxy/DEPS
+++ b/ppapi/proxy/DEPS
@@ -1,4 +1,7 @@
include_rules = [
+ "+base",
+ "+ipc",
+
# These files are really Chrome-only and we don't want to expose them, but
# we need to use them for the proxy. Allow the code here to pull these
# headers (which don't depend on anything else).
diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc
index b1ce1c4..df7383f 100644
--- a/ppapi/proxy/dispatcher.cc
+++ b/ppapi/proxy/dispatcher.cc
@@ -12,6 +12,8 @@
#include "base/logging.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_sync_channel.h"
+#include "ppapi/c/dev/ppb_audio_config_dev.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
#include "ppapi/c/dev/ppb_buffer_dev.h"
#include "ppapi/c/dev/ppb_char_set_dev.h"
#include "ppapi/c/dev/ppb_cursor_control_dev.h"
@@ -31,6 +33,8 @@
#include "ppapi/c/ppb_url_response_info.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppb_audio_config_proxy.h"
+#include "ppapi/proxy/ppb_audio_proxy.h"
#include "ppapi/proxy/ppb_buffer_proxy.h"
#include "ppapi/proxy/ppb_char_set_proxy.h"
#include "ppapi/proxy/ppb_core_proxy.h"
@@ -54,8 +58,10 @@
namespace pp {
namespace proxy {
-Dispatcher::Dispatcher(GetInterfaceFunc local_get_interface)
+Dispatcher::Dispatcher(base::ProcessHandle remote_process_handle,
+ GetInterfaceFunc local_get_interface)
: pp_module_(0),
+ remote_process_handle_(remote_process_handle),
disallow_trusted_interfaces_(true),
local_get_interface_(local_get_interface),
declared_supported_remote_interfaces_(false),
@@ -216,6 +222,10 @@ void Dispatcher::OnMsgDeclareInterfaces(
InterfaceProxy* Dispatcher::CreateProxyForInterface(
const std::string& interface_name,
const void* interface_functions) {
+ if (interface_name == PPB_AUDIO_CONFIG_DEV_INTERFACE)
+ return new PPB_AudioConfig_Proxy(this, interface_functions);
+ if (interface_name == PPB_AUDIO_DEV_INTERFACE)
+ return new PPB_Audio_Proxy(this, interface_functions);
if (interface_name == PPB_BUFFER_DEV_INTERFACE)
return new PPB_Buffer_Proxy(this, interface_functions);
if (interface_name == PPB_CHAR_SET_DEV_INTERFACE)
diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h
index 356dbcf..deee5fc 100644
--- a/ppapi/proxy/dispatcher.h
+++ b/ppapi/proxy/dispatcher.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/linked_ptr.h"
+#include "base/process.h"
#include "base/scoped_ptr.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_handle.h"
@@ -86,6 +87,14 @@ class Dispatcher : public IPC::Channel::Listener,
// or not supported by the remote side, returns NULL.
const void* GetProxiedInterface(const std::string& interface);
+ // Returns the remote process' handle. For the host dispatcher, this will be
+ // the plugin process, and for the plugin dispatcher, this will be the
+ // renderer process. This is used for sharing memory and such and is
+ // guaranteed valid (unless the remote process has suddenly died).
+ base::ProcessHandle remote_process_handle() const {
+ return remote_process_handle_;
+ }
+
// Called if the remote side is declaring to us which interfaces it supports
// so we don't have to query for each one. We'll pre-create proxies for
// each of the given interfaces.
@@ -105,7 +114,8 @@ class Dispatcher : public IPC::Channel::Listener,
}
protected:
- Dispatcher(GetInterfaceFunc local_get_interface);
+ Dispatcher(base::ProcessHandle remote_process_handle,
+ GetInterfaceFunc local_get_interface);
// Setter for the derived classes to set the appropriate var serialization.
// Takes ownership of the given pointer, which must be on the heap.
@@ -154,6 +164,7 @@ class Dispatcher : public IPC::Channel::Listener,
// this dispatcher.
PP_Module pp_module_;
+ base::ProcessHandle remote_process_handle_; // See getter above.
scoped_ptr<IPC::SyncChannel> channel_;
bool disallow_trusted_interfaces_;
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc
index bb70796..a717af8 100644
--- a/ppapi/proxy/host_dispatcher.cc
+++ b/ppapi/proxy/host_dispatcher.cc
@@ -19,10 +19,11 @@ InstanceToDispatcherMap* g_instance_to_dispatcher = NULL;
} // namespace
-HostDispatcher::HostDispatcher(const PPB_Var_Deprecated* var_interface,
+HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle,
+ const PPB_Var_Deprecated* var_interface,
PP_Module module,
GetInterfaceFunc local_get_interface)
- : Dispatcher(local_get_interface) {
+ : Dispatcher(remote_process_handle, local_get_interface) {
SetSerializationRules(new HostVarSerializationRules(var_interface, module));
}
diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h
index 94d45d2..f968652 100644
--- a/ppapi/proxy/host_dispatcher.h
+++ b/ppapi/proxy/host_dispatcher.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/process.h"
#include "base/scoped_ptr.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/dispatcher.h"
@@ -36,7 +37,8 @@ class HostDispatcher : public Dispatcher {
// Constructor for the renderer side.
//
// You must call Dispatcher::InitWithChannel after the constructor.
- HostDispatcher(const PPB_Var_Deprecated* var_interface,
+ HostDispatcher(base::ProcessHandle host_process_handle,
+ const PPB_Var_Deprecated* var_interface,
PP_Module module,
GetInterfaceFunc local_get_interface);
~HostDispatcher();
diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h
index f0ae597..8d85f03 100644
--- a/ppapi/proxy/interface_id.h
+++ b/ppapi/proxy/interface_id.h
@@ -12,7 +12,9 @@ namespace proxy {
// to route messages to the appropriate message handler.
enum InterfaceID {
// Zero is reserved for control messages.
- INTERFACE_ID_PPB_BUFFER = 1,
+ INTERFACE_ID_PPB_AUDIO = 1,
+ INTERFACE_ID_PPB_AUDIO_CONFIG,
+ INTERFACE_ID_PPB_BUFFER,
INTERFACE_ID_PPB_CHAR_SET,
INTERFACE_ID_PPB_CORE,
INTERFACE_ID_PPB_CURSORCONTROL,
diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc
index 085c15c..4c9adca 100644
--- a/ppapi/proxy/plugin_dispatcher.cc
+++ b/ppapi/proxy/plugin_dispatcher.cc
@@ -30,10 +30,11 @@ const void* GetInterfaceFromDispatcher(const char* interface) {
} // namespace
-PluginDispatcher::PluginDispatcher(GetInterfaceFunc get_interface,
+PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle,
+ GetInterfaceFunc get_interface,
InitModuleFunc init_module,
ShutdownModuleFunc shutdown_module)
- : Dispatcher(get_interface),
+ : Dispatcher(remote_process_handle, get_interface),
init_module_(init_module),
shutdown_module_(shutdown_module),
plugin_resource_tracker_(new PluginResourceTracker(
diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h
index 0a97965..79eafb1 100644
--- a/ppapi/proxy/plugin_dispatcher.h
+++ b/ppapi/proxy/plugin_dispatcher.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/process.h"
#include "base/scoped_ptr.h"
#include "ppapi/proxy/callback_tracker.h"
#include "ppapi/proxy/dispatcher.h"
@@ -29,7 +30,8 @@ class PluginDispatcher : public Dispatcher {
// module ID will be set upon receipt of the InitializeModule message.
//
// You must call Dispatcher::InitWithChannel after the constructor.
- PluginDispatcher(GetInterfaceFunc get_interface,
+ PluginDispatcher(base::ProcessHandle remote_process_handle,
+ GetInterfaceFunc get_interface,
InitModuleFunc init_module,
ShutdownModuleFunc shutdown_module);
~PluginDispatcher();
@@ -59,6 +61,7 @@ class PluginDispatcher : public Dispatcher {
}
private:
+ // IPC message handler.
void OnInitializeModule(PP_Module pp_module, bool* result);
InitModuleFunc init_module_;
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h
index 09ed59f..52a8609 100644
--- a/ppapi/proxy/plugin_resource.h
+++ b/ppapi/proxy/plugin_resource.h
@@ -11,6 +11,8 @@
// If you inherit from resource, make sure you add the class name here.
#define FOR_ALL_RESOURCES(F) \
+ F(Audio) \
+ F(AudioConfig) \
F(Buffer) \
F(Font) \
F(Graphics2D) \
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index d0f5bed..dd2b246 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -10,8 +10,12 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/process.h"
+#include "base/shared_memory.h"
#include "base/string16.h"
+#include "base/sync_socket.h"
#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_platform_file.h"
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
diff --git a/ppapi/proxy/ppapi_messages_internal.h b/ppapi/proxy/ppapi_messages_internal.h
index 22d8a52..d7f317e 100644
--- a/ppapi/proxy/ppapi_messages_internal.h
+++ b/ppapi/proxy/ppapi_messages_internal.h
@@ -13,7 +13,8 @@
// These are from the plugin to the renderer
IPC_BEGIN_MESSAGES(Ppapi)
// Loads the given plugin.
- IPC_MESSAGE_CONTROL2(PpapiMsg_LoadPlugin,
+ IPC_MESSAGE_CONTROL3(PpapiMsg_LoadPlugin,
+ base::ProcessHandle /* host_process_handle */,
FilePath /* path */,
int /* renderer_id */)
@@ -36,6 +37,27 @@ IPC_BEGIN_MESSAGES(Ppapi)
uint32 /* serialized_callback */,
int32 /* param */)
+ // PPB_Audio.
+
+ // Notifies the result of the audio stream create call. This is called in
+ // both error cases and in the normal success case. These cases are
+ // differentiated by the result code, which is one of the standard PPAPI
+ // result codes.
+ //
+ // The handler of this message should always close all of the handles passed
+ // in, since some could be valid even in the error case.
+ IPC_MESSAGE_ROUTED5(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
+ PP_Resource /* audio_id */,
+ int32_t /* result_code (will be != PP_OK on failure) */,
+ IPC::PlatformFileForTransit /* socket_handle */,
+ base::SharedMemoryHandle /* handle */,
+ int32_t /* length */)
+
+ // PPB_Graphics2D.
+ IPC_MESSAGE_ROUTED2(PpapiMsg_PPBGraphics2D_FlushACK,
+ PP_Resource /* graphics_2d */,
+ int32_t /* pp_error */)
+
// PPP_Class.
IPC_SYNC_MESSAGE_ROUTED3_2(PpapiMsg_PPPClass_HasProperty,
int64 /* ppp_class */,
@@ -88,11 +110,6 @@ IPC_BEGIN_MESSAGES(Ppapi)
int64 /* ppp_class */,
int64 /* object */)
- // PPB_Graphics2D.
- IPC_MESSAGE_ROUTED2(PpapiMsg_PPBGraphics2D_FlushACK,
- PP_Resource /* graphics_2d */,
- int32_t /* pp_error */)
-
// PPP_Instance.
IPC_SYNC_MESSAGE_ROUTED3_1(PpapiMsg_PPPInstance_DidCreate,
PP_Instance /* instance */,
@@ -142,6 +159,26 @@ IPC_BEGIN_MESSAGES(PpapiHost)
IPC_MESSAGE_CONTROL1(PpapiHostMsg_PluginLoaded,
IPC::ChannelHandle /* handle */)
+ // PPB_Audio.
+ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBAudio_Create,
+ PP_Instance /* instance_id */,
+ PP_Resource /* config_id */,
+ PP_Resource /* result */)
+ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBAudio_StartOrStop,
+ PP_Resource /* audio_id */,
+ bool /* play */)
+
+ // PPB_AudioConfig.
+ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBAudioConfig_Create,
+ PP_Module /* module */,
+ int32_t /* sample_rate */,
+ uint32_t /* sample_frame_count */,
+ PP_Resource /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(
+ PpapiHostMsg_PPBAudioConfig_RecommendSampleFrameCount,
+ uint32_t /* requested */,
+ uint32_t /* result */)
+
// PPB_Buffer.
IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBBuffer_Create,
PP_Module /* module */,
diff --git a/ppapi/proxy/ppb_audio_config_proxy.cc b/ppapi/proxy/ppb_audio_config_proxy.cc
new file mode 100644
index 0000000..7ec3e8f
--- /dev/null
+++ b/ppapi/proxy/ppb_audio_config_proxy.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2010 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 "ppapi/proxy/ppb_audio_config_proxy.h"
+
+#include "ppapi/c/dev/ppb_audio_config_dev.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+class AudioConfig : public PluginResource {
+ public:
+ AudioConfig(PP_AudioSampleRate_Dev sample_rate, uint32_t sample_frame_count)
+ : sample_rate_(sample_rate),
+ sample_frame_count_(sample_frame_count) {
+ }
+ virtual ~AudioConfig() {}
+
+ // Resource overrides.
+ virtual AudioConfig* AsAudioConfig() { return this; }
+
+ PP_AudioSampleRate_Dev sample_rate() const { return sample_rate_; }
+ uint32_t sample_frame_count() const { return sample_frame_count_; }
+
+ private:
+ PP_AudioSampleRate_Dev sample_rate_;
+ uint32_t sample_frame_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioConfig);
+};
+
+namespace {
+
+PP_Resource CreateStereo16bit(PP_Module module_id,
+ PP_AudioSampleRate_Dev sample_rate,
+ uint32_t sample_frame_count) {
+ PP_Resource result = 0;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudioConfig_Create(
+ INTERFACE_ID_PPB_AUDIO_CONFIG, module_id,
+ static_cast<int32_t>(sample_rate), sample_frame_count,
+ &result));
+ if (!result)
+ return 0;
+
+ linked_ptr<AudioConfig> object(
+ new AudioConfig(sample_rate, sample_frame_count));
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddResource(
+ result, object);
+ return result;
+}
+
+uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count) {
+ uint32_t result = 0;
+ PluginDispatcher::Get()->Send(
+ new PpapiHostMsg_PPBAudioConfig_RecommendSampleFrameCount(
+ INTERFACE_ID_PPB_AUDIO_CONFIG, requested_sample_frame_count,
+ &result));
+ return result;
+}
+
+PP_Bool IsAudioConfig(PP_Resource resource) {
+ AudioConfig* object = PluginResource::GetAs<AudioConfig>(resource);
+ return BoolToPPBool(!!object);
+}
+
+PP_AudioSampleRate_Dev GetSampleRate(PP_Resource config_id) {
+ AudioConfig* object = PluginResource::GetAs<AudioConfig>(config_id);
+ if (!object)
+ return PP_AUDIOSAMPLERATE_NONE;
+ return object->sample_rate();
+}
+
+uint32_t GetSampleFrameCount(PP_Resource config_id) {
+ AudioConfig* object = PluginResource::GetAs<AudioConfig>(config_id);
+ if (!object)
+ return 0;
+ return object->sample_frame_count();
+}
+
+const PPB_AudioConfig_Dev audio_config_interface = {
+ &CreateStereo16bit,
+ &RecommendSampleFrameCount,
+ &IsAudioConfig,
+ &GetSampleRate,
+ &GetSampleFrameCount
+};
+
+} // namespace
+
+PPB_AudioConfig_Proxy::PPB_AudioConfig_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_AudioConfig_Proxy::~PPB_AudioConfig_Proxy() {
+}
+
+const void* PPB_AudioConfig_Proxy::GetSourceInterface() const {
+ return &audio_config_interface;
+}
+
+InterfaceID PPB_AudioConfig_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_AUDIO_CONFIG;
+}
+
+void PPB_AudioConfig_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_AudioConfig_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudioConfig_Create,
+ OnMsgCreateStereo16Bit)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudioConfig_RecommendSampleFrameCount,
+ OnMsgRecommendSampleFrameCount)
+ IPC_END_MESSAGE_MAP()
+}
+
+void PPB_AudioConfig_Proxy::OnMsgCreateStereo16Bit(PP_Module module,
+ int32_t sample_rate,
+ uint32_t sample_frame_count,
+ PP_Resource* result) {
+ *result = ppb_audio_config_target()->CreateStereo16Bit(
+ module, static_cast<PP_AudioSampleRate_Dev>(sample_rate),
+ sample_frame_count);
+}
+
+void PPB_AudioConfig_Proxy::OnMsgRecommendSampleFrameCount(
+ uint32_t requested,
+ uint32_t* result) {
+ *result = ppb_audio_config_target()->RecommendSampleFrameCount(requested);
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_audio_config_proxy.h b/ppapi/proxy/ppb_audio_config_proxy.h
new file mode 100644
index 0000000..b80ea31
--- /dev/null
+++ b/ppapi/proxy/ppb_audio_config_proxy.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 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 PPAPI_PROXY_PPB_AUDIO_CONFIG_PROXY_H_
+#define PPAPI_PROXY_PPB_AUDIO_CONFIG_PROXY_H_
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_AudioConfig_Dev;
+
+namespace pp {
+namespace proxy {
+
+class PPB_AudioConfig_Proxy : public InterfaceProxy {
+ public:
+ PPB_AudioConfig_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_AudioConfig_Proxy();
+
+ const PPB_AudioConfig_Dev* ppb_audio_config_target() const {
+ return static_cast<const PPB_AudioConfig_Dev*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgCreateStereo16Bit(PP_Module module,
+ int32_t sample_rate,
+ uint32_t sample_frame_count,
+ PP_Resource* result);
+ void OnMsgRecommendSampleFrameCount(uint32_t requested, uint32_t* result);
+
+ DISALLOW_COPY_AND_ASSIGN(PPB_AudioConfig_Proxy);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PPB_AUDIO_CONFIG_PROXY_H_
diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc
new file mode 100644
index 0000000..bb40693
--- /dev/null
+++ b/ppapi/proxy/ppb_audio_proxy.cc
@@ -0,0 +1,285 @@
+// Copyright (c) 2010 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 "ppapi/proxy/ppb_audio_proxy.h"
+
+#include "base/simple_thread.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
+#include "ppapi/c/dev/ppb_audio_trusted_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/interface_id.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/audio_impl.h"
+
+namespace pp {
+namespace proxy {
+
+class Audio : public PluginResource, public pp::shared_impl::AudioImpl {
+ public:
+ Audio(PP_Resource config_id, PPB_Audio_Callback callback, void* user_data)
+ : config_(config_id) {
+ SetCallback(callback, user_data);
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddRefResource(
+ config_);
+ }
+ virtual ~Audio() {
+ PluginDispatcher::Get()->plugin_resource_tracker()->ReleaseResource(
+ config_);
+ }
+
+ // Resource overrides.
+ virtual Audio* AsAudio() { return this; }
+
+ PP_Resource config() const { return config_; }
+
+ void StartPlayback(PP_Resource resource) {
+ if (playing())
+ return;
+ SetStartPlaybackState();
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_StartOrStop(
+ INTERFACE_ID_PPB_AUDIO, resource, true));
+ }
+
+ void StopPlayback(PP_Resource resource) {
+ if (!playing())
+ return;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_StartOrStop(
+ INTERFACE_ID_PPB_AUDIO, resource, false));
+ SetStopPlaybackState();
+ }
+
+ private:
+ PP_Resource config_;
+
+ DISALLOW_COPY_AND_ASSIGN(Audio);
+};
+
+namespace {
+
+PP_Resource Create(PP_Instance instance_id,
+ PP_Resource config_id,
+ PPB_Audio_Callback callback,
+ void* user_data) {
+ PP_Resource result;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create(
+ INTERFACE_ID_PPB_AUDIO, instance_id, config_id, &result));
+ if (!result)
+ return 0;
+
+ linked_ptr<Audio> object(new Audio(config_id, callback, user_data));
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddResource(
+ result, object);
+ return result;
+}
+
+PP_Bool IsAudio(PP_Resource resource) {
+ Audio* object = PluginResource::GetAs<Audio>(resource);
+ return BoolToPPBool(!!object);
+}
+
+PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object)
+ return 0;
+ PP_Resource result = object->config();
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddRefResource(result);
+ return result;
+}
+
+PP_Bool StartPlayback(PP_Resource audio_id) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object)
+ return PP_FALSE;
+ object->StartPlayback(audio_id);
+ return PP_TRUE;
+}
+
+PP_Bool StopPlayback(PP_Resource audio_id) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object)
+ return PP_FALSE;
+ object->StopPlayback(audio_id);
+ return PP_TRUE;
+}
+
+const PPB_Audio_Dev audio_interface = {
+ &Create,
+ &IsAudio,
+ &GetCurrentConfiguration,
+ &StartPlayback,
+ &StopPlayback
+};
+
+} // namespace
+
+PPB_Audio_Proxy::PPB_Audio_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+}
+
+PPB_Audio_Proxy::~PPB_Audio_Proxy() {
+}
+
+const void* PPB_Audio_Proxy::GetSourceInterface() const {
+ return &audio_interface;
+}
+
+InterfaceID PPB_Audio_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_AUDIO;
+}
+
+void PPB_Audio_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Audio_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_Create, OnMsgCreate)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop,
+ OnMsgStartOrStop)
+
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
+ OnMsgNotifyAudioStreamCreated)
+ IPC_END_MESSAGE_MAP()
+}
+
+void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
+ PP_Resource config_id,
+ PP_Resource* result) {
+ const PPB_AudioTrusted_Dev* audio_trusted =
+ reinterpret_cast<const PPB_AudioTrusted_Dev*>(
+ dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_DEV_INTERFACE));
+ if (!audio_trusted) {
+ *result = 0;
+ return;
+ }
+
+ *result = audio_trusted->CreateTrusted(instance_id);
+ if (!result)
+ return;
+
+ CompletionCallback callback = callback_factory_.NewCallback(
+ &PPB_Audio_Proxy::AudioChannelConnected, *result);
+ int32_t open_error = audio_trusted->Open(*result, config_id,
+ callback.pp_completion_callback());
+ if (open_error != PP_ERROR_WOULDBLOCK)
+ callback.Run(open_error);
+}
+
+void PPB_Audio_Proxy::OnMsgStartOrStop(PP_Resource audio_id, bool play) {
+ if (play)
+ ppb_audio_target()->StartPlayback(audio_id);
+ else
+ ppb_audio_target()->StopPlayback(audio_id);
+}
+
+void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated(
+ PP_Resource audio_id,
+ int32_t result_code,
+ IPC::PlatformFileForTransit socket_handle,
+ base::SharedMemoryHandle handle,
+ uint32_t length) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object || result_code != PP_OK) {
+ // The caller may still have given us these handles in the failure case.
+ // The easiest way to clean these up is to just put them in the objects
+ // and then close them. This failure case is not performance critical.
+ base::SyncSocket temp_socket(
+ IPC::PlatformFileForTransitToPlatformFile(socket_handle));
+ base::SharedMemory temp_mem(handle, false);
+ return;
+ }
+ object->SetStreamInfo(
+ handle, length, IPC::PlatformFileForTransitToPlatformFile(socket_handle));
+}
+
+void PPB_Audio_Proxy::AudioChannelConnected(int32_t result,
+ PP_Resource resource) {
+ IPC::PlatformFileForTransit socket_handle =
+ IPC::InvalidPlatformFileForTransit();
+#if defined(OS_WIN)
+ base::SharedMemoryHandle shared_memory = NULL;
+#elif defined(OS_POSIX)
+ base::SharedMemoryHandle shared_memory(-1, false);
+#else
+ #error Not implemented.
+#endif
+ uint32_t shared_memory_length = 0;
+
+ int32_t result_code = result;
+ if (result_code == PP_OK) {
+ result_code = GetAudioConnectedHandles(resource, &socket_handle,
+ &shared_memory,
+ &shared_memory_length);
+ }
+
+ // Send all the values, even on error. This simplifies some of our cleanup
+ // code since the handles will be in the other process and could be
+ // inconvenient to clean up. Our IPC code will automatically handle this for
+ // us, as long as the remote side always closes the handles it receives
+ // (in OnMsgNotifyAudioStreamCreated), even in the failure case.
+ dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated(
+ INTERFACE_ID_PPB_AUDIO, resource, result_code, shared_memory,
+ socket_handle, shared_memory_length));
+}
+
+int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
+ PP_Resource resource,
+ IPC::PlatformFileForTransit* foreign_socket_handle,
+ base::SharedMemoryHandle* foreign_shared_memory_handle,
+ uint32_t* shared_memory_length) {
+ // Get the trusted audio interface which will give us the handles.
+ const PPB_AudioTrusted_Dev* audio_trusted =
+ reinterpret_cast<const PPB_AudioTrusted_Dev*>(
+ dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_DEV_INTERFACE));
+ if (!audio_trusted)
+ return PP_ERROR_NOINTERFACE;
+
+ // Get the socket handle for signaling.
+ int32_t socket_handle;
+ int32_t result = audio_trusted->GetSyncSocket(resource, &socket_handle);
+ if (result != PP_OK)
+ return result;
+
+#if defined(OS_WIN)
+ // On Windows, duplicate the socket into the plugin process, this will
+ // automatically close the source handle.
+ ::DuplicateHandle(
+ GetCurrentProcess(),
+ reinterpret_cast<HANDLE>(static_cast<intptr_t>(socket_handle)),
+ dispatcher()->remote_process_handle(), foreign_socket_handle,
+ STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
+ FALSE, DUPLICATE_CLOSE_SOURCE);
+#else
+ // On Posix, the socket handle will be auto-duplicated when we send the
+ // FileDescriptor. Set AutoClose since we don't need the handle any more.
+ *foreign_socket_handle = base::FileDescriptor(socket_handle, true);
+#endif
+
+ // Get the shared memory for the buffer.
+ // TODO(brettw) remove the reinterpret cast when the interface is updated.
+ int shared_memory_handle;
+ result = audio_trusted->GetSharedMemory(resource, &shared_memory_handle,
+ shared_memory_length);
+ if (result != PP_OK)
+ return result;
+
+ base::SharedMemory shared_memory(
+#if defined(OS_WIN)
+ reinterpret_cast<HANDLE>(static_cast<intptr_t>(shared_memory_handle)),
+#else
+ base::FileDescriptor(shared_memory_handle, false),
+#endif
+ false);
+
+ // Duplicate the shared memory to the plugin process. This will automatically
+ // close the source handle.
+ if (!shared_memory.GiveToProcess(dispatcher()->remote_process_handle(),
+ foreign_shared_memory_handle))
+ return PP_ERROR_FAILED;
+
+ return PP_OK;
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h
new file mode 100644
index 0000000..a6d2738
--- /dev/null
+++ b/ppapi/proxy/ppb_audio_proxy.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2010 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 PPAPI_PROXY_PPB_AUDIO_PROXY_H_
+#define PPAPI_PROXY_PPB_AUDIO_PROXY_H_
+
+#include "base/basictypes.h"
+#include "base/shared_memory.h"
+#include "base/sync_socket.h"
+#include "ipc/ipc_platform_file.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/proxy/interface_proxy.h"
+#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h"
+
+struct PPB_Audio_Dev;
+
+namespace pp {
+namespace proxy {
+
+class PPB_Audio_Proxy : public InterfaceProxy {
+ public:
+ PPB_Audio_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_Audio_Proxy();
+
+ const PPB_Audio_Dev* ppb_audio_target() const {
+ return static_cast<const PPB_Audio_Dev*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Plugin->renderer message handlers.
+ void OnMsgCreate(PP_Instance instance_id,
+ PP_Resource config_id,
+ PP_Resource* result);
+ void OnMsgStartOrStop(PP_Resource audio_id, bool play);
+
+ // Renderer->plugin message handlers.
+ void OnMsgNotifyAudioStreamCreated(
+ PP_Resource audio_id,
+ int32_t result_code,
+ IPC::PlatformFileForTransit socket_handle,
+ base::SharedMemoryHandle shared_memory_handle,
+ uint32_t shared_memory_length);
+
+ void AudioChannelConnected(int32_t result, PP_Resource resource);
+
+ // In the renderer, this is called in response to a stream created message.
+ // It will retrieve the shared memory and socket handles and place them into
+ // the given out params. The return value is a PPAPI error code.
+ //
+ // The input arguments should be initialized to 0 or -1, depending on the
+ // platform's default invalid handle values. On error, some of these
+ // arguments may be written to, and others may be untouched, depending on
+ // where the error occurred.
+ int32_t GetAudioConnectedHandles(
+ PP_Resource resource,
+ IPC::PlatformFileForTransit* foreign_socket_handle,
+ base::SharedMemoryHandle* foreign_shared_memory_handle,
+ uint32_t* shared_memory_length);
+
+ CompletionCallbackFactory<PPB_Audio_Proxy,
+ ProxyNonThreadSafeRefCount> callback_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PPB_Audio_Proxy);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PPB_AUDIO_PROXY_H_
diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS
new file mode 100644
index 0000000..84fea55
--- /dev/null
+++ b/ppapi/shared_impl/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+base",
+ "-ppapi/cpp",
+]
diff --git a/ppapi/shared_impl/README.txt b/ppapi/shared_impl/README.txt
new file mode 100644
index 0000000..71ff8d6
--- /dev/null
+++ b/ppapi/shared_impl/README.txt
@@ -0,0 +1,2 @@
+This directory contains implementation code for PPAPI that needs to be shared
+between the backend implemntation in the renderer and in the proxy.
diff --git a/ppapi/shared_impl/audio_impl.cc b/ppapi/shared_impl/audio_impl.cc
new file mode 100644
index 0000000..83b73f6
--- /dev/null
+++ b/ppapi/shared_impl/audio_impl.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2010 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 "ppapi/shared_impl/audio_impl.h"
+
+#include "base/logging.h"
+
+namespace pp {
+namespace shared_impl {
+
+AudioImpl::AudioImpl()
+ : playing_(false),
+ shared_memory_size_(0),
+ callback_(NULL),
+ user_data_(NULL) {
+}
+
+AudioImpl::~AudioImpl() {
+ // Closing the socket causes the thread to exit - wait for it.
+ socket_->Close();
+ if (audio_thread_.get()) {
+ audio_thread_->Join();
+ audio_thread_.reset();
+ }
+}
+
+void AudioImpl::SetCallback(PPB_Audio_Callback callback, void* user_data) {
+ callback_ = callback;
+ user_data_ = user_data;
+}
+
+void AudioImpl::SetStartPlaybackState() {
+ DCHECK(!playing_);
+ DCHECK(!audio_thread_.get());
+
+ // If the socket doesn't exist, that means that the plugin has started before
+ // the browser has had a chance to create all the shared memory info and
+ // notify us. This is a common case. In this case, we just set the playing_
+ // flag and the playback will automatically start when that data is available
+ // in SetStreamInfo.
+ if (callback_ && socket_.get())
+ StartThread();
+ playing_ = true;
+}
+
+void AudioImpl::SetStopPlaybackState() {
+ DCHECK(playing_);
+
+ if (audio_thread_.get()) {
+ audio_thread_->Join();
+ audio_thread_.reset();
+ }
+ playing_ = false;
+}
+
+void AudioImpl::SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket_handle) {
+ socket_.reset(new base::SyncSocket(socket_handle));
+ shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
+ shared_memory_size_ = shared_memory_size;
+
+ if (callback_) {
+ shared_memory_->Map(shared_memory_size_);
+
+ // In common case StartPlayback() was called before StreamCreated().
+ if (playing_)
+ StartThread();
+ }
+}
+
+void AudioImpl::StartThread() {
+ DCHECK(callback_);
+ DCHECK(!audio_thread_.get());
+ audio_thread_.reset(new base::DelegateSimpleThread(
+ this, "plugin_audio_thread"));
+ audio_thread_->Start();
+}
+
+void AudioImpl::Run() {
+ int pending_data;
+ void* buffer = shared_memory_->memory();
+
+ while (sizeof(pending_data) ==
+ socket_->Receive(&pending_data, sizeof(pending_data)) &&
+ pending_data >= 0) {
+ // Exit the thread on pause.
+ if (pending_data < 0)
+ return;
+ callback_(buffer, shared_memory_size_, user_data_);
+ }
+}
+
+} // namespace shared_impl
+} // namespace pp
diff --git a/ppapi/shared_impl/audio_impl.h b/ppapi/shared_impl/audio_impl.h
new file mode 100644
index 0000000..b4cb077
--- /dev/null
+++ b/ppapi/shared_impl/audio_impl.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 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 PPAPI_SHARED_IMPL_AUDIO_IMPL_H_
+#define PPAPI_SHARED_IMPL_AUDIO_IMPL_H_
+
+#include "base/scoped_ptr.h"
+#include "base/simple_thread.h"
+#include "base/shared_memory.h"
+#include "base/sync_socket.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
+
+namespace pp {
+namespace shared_impl {
+
+// Implements the logic to map shared memory and run the audio thread signaled
+// from the sync socket. Both the proxy and the renderer implementation use
+// this code.
+class AudioImpl : public base::DelegateSimpleThread::Delegate {
+ public:
+ AudioImpl();
+ virtual ~AudioImpl();
+
+ bool playing() const { return playing_; }
+
+ // Sets the callback information that the background thread will use. This
+ // is optional. Without a callback, the thread will not be run. This
+ // non-callback mode is used in the renderer with the proxy, since the proxy
+ // handles the callback entirely within the plugin process.
+ void SetCallback(PPB_Audio_Callback callback, void* user_data);
+
+ // Configures the current state to be playing or not. The caller is
+ // responsible for ensuring the new state is the opposite of the current one.
+ //
+ // This is the implementation for PPB_Audio.Start/StopPlayback, except that
+ // it does not actually notify the audio system to stop playback, it just
+ // configures our object to stop generating callbacks. The actual stop
+ // playback request will be done in the derived classes and will be different
+ // from the proxy and the renderer.
+ void SetStartPlaybackState();
+ void SetStopPlaybackState();
+
+ // Sets the shared memory and socket handles. This will automatically start
+ // playback if we're currently set to play.
+ void SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket_handle);
+
+ private:
+ // Starts execution of the audio thread.
+ void StartThread();
+
+ // DelegateSimpleThread::Delegate implementation. Run on the audio thread.
+ void Run();
+
+ // True if playing the stream.
+ bool playing_;
+
+ // Socket used to notify us when audio is ready to accept new samples. This
+ // pointer is created in StreamCreated().
+ scoped_ptr<base::SyncSocket> socket_;
+
+ // Sample buffer in shared memory. This pointer is created in
+ // StreamCreated(). The memory is only mapped when the audio thread is
+ // created.
+ scoped_ptr<base::SharedMemory> shared_memory_;
+
+ // The size of the sample buffer in bytes.
+ size_t shared_memory_size_;
+
+ // When the callback is set, this thread is spawned for calling it.
+ scoped_ptr<base::DelegateSimpleThread> audio_thread_;
+
+ // Callback to call when audio is ready to accept new samples.
+ PPB_Audio_Callback callback_;
+
+ // User data pointer passed verbatim to the callback function.
+ void* user_data_;
+};
+
+} // namespace shared_impl
+} // namespace pp
+
+#endif // PPAPI_SHARED_IMPL_AUDIO_IMPL_H_
diff --git a/webkit/glue/plugins/pepper_audio.cc b/webkit/glue/plugins/pepper_audio.cc
index 0b0999a..d18dbae 100644
--- a/webkit/glue/plugins/pepper_audio.cc
+++ b/webkit/glue/plugins/pepper_audio.cc
@@ -96,9 +96,9 @@ PP_Bool IsAudio(PP_Resource resource) {
return BoolToPPBool(!!audio);
}
-PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
+PP_Resource GetCurrentConfig(PP_Resource audio_id) {
scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id);
- return audio ? audio->GetCurrentConfiguration() : 0;
+ return audio ? audio->GetCurrentConfig() : 0;
}
PP_Bool StartPlayback(PP_Resource audio_id) {
@@ -114,7 +114,7 @@ PP_Bool StopPlayback(PP_Resource audio_id) {
const PPB_Audio_Dev ppb_audio = {
&Create,
&IsAudio,
- &GetCurrentConfiguration,
+ &GetCurrentConfig,
&StartPlayback,
&StopPlayback,
};
@@ -201,14 +201,8 @@ AudioConfig* AudioConfig::AsAudioConfig() {
Audio::Audio(PluginModule* module, PP_Instance instance_id)
: Resource(module),
- playing_(false),
pp_instance_(instance_id),
audio_(NULL),
- socket_(NULL),
- shared_memory_(NULL),
- shared_memory_size_(0),
- callback_(NULL),
- user_data_(NULL),
create_callback_pending_(false) {
create_callback_ = PP_MakeCompletionCallback(NULL, NULL);
}
@@ -218,20 +212,12 @@ Audio::~Audio() {
audio_->ShutDown();
audio_ = NULL;
- // Closing the socket causes the thread to exit - wait for it.
- socket_->Close();
- if (audio_thread_.get()) {
- audio_thread_->Join();
- audio_thread_.reset();
- }
-
// If the completion callback hasn't fired yet, do so here
// with an error condition.
if (create_callback_pending_) {
PP_RunCompletionCallback(&create_callback_, PP_ERROR_ABORTED);
create_callback_pending_ = false;
}
- // Shared memory destructor will unmap the memory automatically.
}
const PPB_Audio_Dev* Audio::GetInterface() {
@@ -253,8 +239,7 @@ bool Audio::Init(PluginDelegate* plugin_delegate,
config_ = Resource::GetAs<AudioConfig>(config_id);
if (!config_)
return false;
- callback_ = callback;
- user_data_ = user_data;
+ SetCallback(callback, user_data);
// When the stream is created, we'll get called back on StreamCreated().
audio_ = plugin_delegate->CreateAudio(config_->sample_rate(),
@@ -263,6 +248,26 @@ bool Audio::Init(PluginDelegate* plugin_delegate,
return audio_ != NULL;
}
+PP_Resource Audio::GetCurrentConfig() {
+ return config_->GetReference();
+}
+
+bool Audio::StartPlayback() {
+ if (playing())
+ return true;
+ SetStartPlaybackState();
+ return audio_->StartPlayback();
+}
+
+bool Audio::StopPlayback() {
+ if (!playing())
+ return true;
+ if (!audio_->StopPlayback())
+ return false;
+ SetStopPlaybackState();
+ return true;
+}
+
int32_t Audio::Open(PluginDelegate* plugin_delegate,
PP_Resource config_id,
PP_CompletionCallback create_callback) {
@@ -287,11 +292,11 @@ int32_t Audio::Open(PluginDelegate* plugin_delegate,
}
int32_t Audio::GetSyncSocket(int* sync_socket) {
- if (socket_ != NULL) {
+ if (socket_for_create_callback_.get()) {
#if defined(OS_POSIX)
- *sync_socket = socket_->handle();
+ *sync_socket = socket_for_create_callback_->handle();
#elif defined(OS_WIN)
- *sync_socket = reinterpret_cast<int>(socket_->handle());
+ *sync_socket = reinterpret_cast<int>(socket_for_create_callback_->handle());
#else
#error "Platform not supported."
#endif
@@ -301,88 +306,42 @@ int32_t Audio::GetSyncSocket(int* sync_socket) {
}
int32_t Audio::GetSharedMemory(int* shm_handle, uint32_t* shm_size) {
- if (shared_memory_ != NULL) {
+ if (shared_memory_for_create_callback_.get()) {
#if defined(OS_POSIX)
- *shm_handle = shared_memory_->handle().fd;
+ *shm_handle = shared_memory_for_create_callback_->handle().fd;
#elif defined(OS_WIN)
- *shm_handle = reinterpret_cast<int>(shared_memory_->handle());
+ *shm_handle = reinterpret_cast<int>(
+ shared_memory_for_create_callback_->handle());
#else
#error "Platform not supported."
#endif
- *shm_size = shared_memory_size_;
+ *shm_size = shared_memory_size_for_create_callback_;
return PP_OK;
}
return PP_ERROR_FAILED;
}
-bool Audio::StartPlayback() {
- if (playing_)
- return true;
-
- CHECK(!audio_thread_.get());
- if (callback_ && socket_.get()) {
- audio_thread_.reset(new base::DelegateSimpleThread(this,
- "plugin_audio_thread"));
- audio_thread_->Start();
- }
- playing_ = true;
- return audio_->StartPlayback();
-}
-
-bool Audio::StopPlayback() {
- if (!playing_)
- return true;
-
- if (!audio_->StopPlayback())
- return false;
-
- if (audio_thread_.get()) {
- audio_thread_->Join();
- audio_thread_.reset();
- }
- playing_ = false;
- return true;
-}
-
void Audio::StreamCreated(base::SharedMemoryHandle shared_memory_handle,
size_t shared_memory_size,
base::SyncSocket::Handle socket_handle) {
- socket_.reset(new base::SyncSocket(socket_handle));
- shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
- shared_memory_size_ = shared_memory_size;
-
- // Trusted side of proxy can specify a callback to recieve handles.
if (create_callback_pending_) {
+ // Trusted side of proxy can specify a callback to recieve handles. In
+ // this case we don't need to map any data or start the thread since it
+ // will be handled by the proxy.
+ shared_memory_for_create_callback_.reset(
+ new base::SharedMemory(shared_memory_handle, false));
+ shared_memory_size_for_create_callback_ = shared_memory_size;
+ socket_for_create_callback_.reset(new base::SyncSocket(socket_handle));
+
PP_RunCompletionCallback(&create_callback_, 0);
create_callback_pending_ = false;
- }
-
- // Trusted, non-proxy audio will invoke buffer filling callback on a
- // dedicated thread, see Audio::Run() below.
- if (callback_) {
- shared_memory_->Map(shared_memory_size_);
-
- // In common case StartPlayback() was called before StreamCreated().
- if (playing_) {
- audio_thread_.reset(new base::DelegateSimpleThread(this,
- "plugin_audio_thread"));
- audio_thread_->Start();
- }
- }
-}
-void Audio::Run() {
- int pending_data;
- void* buffer = shared_memory_->memory();
- size_t buffer_size_in_bytes = config_->BufferSize();
-
- while (sizeof(pending_data) ==
- socket_->Receive(&pending_data, sizeof(pending_data)) &&
- pending_data >= 0) {
- // Exit the thread on pause.
- if (pending_data < 0)
- return;
- callback_(buffer, buffer_size_in_bytes, user_data_);
+ // Close the handles now that this process is done with them.
+ shared_memory_for_create_callback_.reset();
+ shared_memory_size_for_create_callback_ = 0;
+ socket_for_create_callback_.reset();
+ } else {
+ SetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle);
}
}
diff --git a/webkit/glue/plugins/pepper_audio.h b/webkit/glue/plugins/pepper_audio.h
index 3b4a8cc..7417544 100644
--- a/webkit/glue/plugins/pepper_audio.h
+++ b/webkit/glue/plugins/pepper_audio.h
@@ -6,14 +6,13 @@
#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_
#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
#include "base/shared_memory.h"
-#include "base/simple_thread.h"
#include "base/sync_socket.h"
#include "ppapi/c/dev/ppb_audio_dev.h"
#include "ppapi/c/dev/ppb_audio_config_dev.h"
#include "ppapi/c/dev/ppb_audio_trusted_dev.h"
#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/shared_impl/audio_impl.h"
#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
@@ -43,9 +42,11 @@ class AudioConfig : public Resource {
uint32_t sample_frame_count_;
};
+// Some of the backend functionality of this class is implemented by the
+// AudioImpl so it can be shared with the proxy.
class Audio : public Resource,
- public PluginDelegate::PlatformAudio::Client,
- public base::DelegateSimpleThread::Delegate {
+ public pp::shared_impl::AudioImpl,
+ public PluginDelegate::PlatformAudio::Client {
public:
explicit Audio(PluginModule* module, PP_Instance instance_id);
virtual ~Audio();
@@ -53,30 +54,25 @@ class Audio : public Resource,
static const PPB_Audio_Dev* GetInterface();
static const PPB_AudioTrusted_Dev* GetTrustedInterface();
+ PP_Instance pp_instance() {
+ return pp_instance_;
+ }
+
+ // PPB_Audio implementation.
bool Init(PluginDelegate* plugin_delegate,
PP_Resource config_id,
PPB_Audio_Callback user_callback, void* user_data);
+ PP_Resource GetCurrentConfig();
+ bool StartPlayback();
+ bool StopPlayback();
+ // PPB_Audio_Trusted implementation.
int32_t Open(PluginDelegate* plugin_delegate,
PP_Resource config_id,
PP_CompletionCallback create_callback);
-
- PP_Resource GetCurrentConfiguration() {
- return config_->GetReference();
- }
-
- PP_Instance pp_instance() {
- return pp_instance_;
- }
-
int32_t GetSyncSocket(int* sync_socket);
-
int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size);
- bool StartPlayback();
-
- bool StopPlayback();
-
// Resource override.
virtual Audio* AsAudio();
@@ -85,50 +81,29 @@ class Audio : public Resource,
virtual void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
size_t shared_memory_size_,
base::SyncSocket::Handle socket);
- // End of pepper::PluginDelegate::PlatformAudio::Client implementation.
-
- // Audio thread. DelegateSimpleThread::Delegate implementation.
- virtual void Run();
- // End of DelegateSimpleThread::Delegate implementation.
-
- // True if playing the stream.
- bool playing_;
// AudioConfig used for creating this Audio object.
scoped_refptr<AudioConfig> config_;
- // Instance id
+ // Plugin instance that owns this audio object.
PP_Instance pp_instance_;
// PluginDelegate audio object that we delegate audio IPC through.
PluginDelegate::PlatformAudio* audio_;
- // Socket used to notify us when audio is ready to accept new samples. This
- // pointer is created in StreamCreated().
- scoped_ptr<base::SyncSocket> socket_;
-
- // Sample buffer in shared memory. This pointer is created in
- // StreamCreated(). The memory is only mapped when the audio thread is
- // created.
- scoped_ptr<base::SharedMemory> shared_memory_;
-
- // The size of the sample buffer in bytes.
- size_t shared_memory_size_;
-
- // When the callback is set, this thread is spawned for calling it.
- scoped_ptr<base::DelegateSimpleThread> audio_thread_;
-
- // Callback to call when audio is ready to accept new samples.
- volatile PPB_Audio_Callback callback_;
-
- // User data pointer passed verbatim to the callback function.
- void* user_data_;
-
// Is a create callback pending to fire?
bool create_callback_pending_;
// Trusted callback invoked from StreamCreated.
PP_CompletionCallback create_callback_;
+
+ // When a create callback is being issued, these will save the info for
+ // querying from the callback. The proxy uses this to get the handles to the
+ // other process instead of mapping them in the renderer. These will be
+ // invalid all other times.
+ scoped_ptr<base::SharedMemory> shared_memory_for_create_callback_;
+ size_t shared_memory_size_for_create_callback_;
+ scoped_ptr<base::SyncSocket> socket_for_create_callback_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_font.cc b/webkit/glue/plugins/pepper_font.cc
index 553c8ed..f871e69 100644
--- a/webkit/glue/plugins/pepper_font.cc
+++ b/webkit/glue/plugins/pepper_font.cc
@@ -135,12 +135,12 @@ PP_Bool Describe(PP_Resource font_id,
}
PP_Bool DrawTextAt(PP_Resource font_id,
- PP_Resource image_data,
- const PP_TextRun_Dev* text,
- const PP_Point* position,
- uint32_t color,
- const PP_Rect* clip,
- PP_Bool image_data_is_opaque) {
+ PP_Resource image_data,
+ const PP_TextRun_Dev* text,
+ const PP_Point* position,
+ uint32_t color,
+ const PP_Rect* clip,
+ PP_Bool image_data_is_opaque) {
scoped_refptr<Font> font(Resource::GetAs<Font>(font_id));
if (!font.get())
return PP_FALSE;
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
index b7bad9f..0da663a 100644
--- a/webkit/glue/plugins/pepper_plugin_module.cc
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -354,10 +354,12 @@ scoped_refptr<PluginModule> PluginModule::CreateInternalModule(
// static
scoped_refptr<PluginModule> PluginModule::CreateOutOfProcessModule(
MessageLoop* ipc_message_loop,
+ base::ProcessHandle plugin_process_handle,
const IPC::ChannelHandle& handle,
base::WaitableEvent* shutdown_event) {
scoped_refptr<PluginModule> lib(new PluginModule);
- if (!lib->InitForOutOfProcess(ipc_message_loop, handle, shutdown_event))
+ if (!lib->InitForOutOfProcess(ipc_message_loop, plugin_process_handle,
+ handle, shutdown_event))
return NULL;
return lib;
}
@@ -405,13 +407,14 @@ bool PluginModule::InitFromFile(const FilePath& path) {
}
bool PluginModule::InitForOutOfProcess(MessageLoop* ipc_message_loop,
+ base::ProcessHandle remote_process,
const IPC::ChannelHandle& handle,
base::WaitableEvent* shutdown_event) {
const PPB_Var_Deprecated* var_interface =
reinterpret_cast<const PPB_Var_Deprecated*>(
GetInterface(PPB_VAR_DEPRECATED_INTERFACE));
- dispatcher_.reset(new pp::proxy::HostDispatcher(var_interface,
- pp_module(), &GetInterface));
+ dispatcher_.reset(new pp::proxy::HostDispatcher(
+ remote_process, var_interface, pp_module(), &GetInterface));
#if defined(OS_POSIX)
// If we received a ChannelHandle, register it now.
@@ -427,7 +430,6 @@ bool PluginModule::InitForOutOfProcess(MessageLoop* ipc_message_loop,
bool init_result = false;
dispatcher_->Send(new PpapiMsg_InitializeModule(pp_module(), &init_result));
-
if (!init_result) {
// TODO(brettw) does the module get unloaded in this case?
dispatcher_.reset();
diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h
index 80eccda..19e1027 100644
--- a/webkit/glue/plugins/pepper_plugin_module.h
+++ b/webkit/glue/plugins/pepper_plugin_module.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/native_library.h"
+#include "base/process.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/weak_ptr.h"
@@ -74,6 +75,7 @@ class PluginModule : public base::RefCounted<PluginModule>,
EntryPoints entry_points);
static scoped_refptr<PluginModule> CreateOutOfProcessModule(
MessageLoop* ipc_message_loop,
+ base::ProcessHandle plugin_process_handle,
const IPC::ChannelHandle& handle,
base::WaitableEvent* shutdown_event);
@@ -122,6 +124,7 @@ class PluginModule : public base::RefCounted<PluginModule>,
bool InitFromEntryPoints(const EntryPoints& entry_points);
bool InitFromFile(const FilePath& path);
bool InitForOutOfProcess(MessageLoop* ipc_message_loop,
+ base::ProcessHandle remote_process,
const IPC::ChannelHandle& handle,
base::WaitableEvent* shutdown_event);
static bool LoadEntryPoints(const base::NativeLibrary& library,
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 8ed3e8b..0f9816d 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -148,6 +148,7 @@
'<(DEPTH)/gpu/gpu.gyp:gles2_implementation',
'<(DEPTH)/net/net.gyp:net',
'<(DEPTH)/ppapi/ppapi.gyp:ppapi_proxy',
+ '<(DEPTH)/ppapi/ppapi.gyp:ppapi_shared_impl',
'<(DEPTH)/printing/printing.gyp:printing',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',