summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-14 16:52:58 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-14 16:52:58 +0000
commit184808f27fbc5cf8dc4a9c637d644bda31c6cfe8 (patch)
tree0db99fde76ca2142910775f750596e458c5353fc /content
parent254004a393625cbcf09254e1ce127319f8a3addd (diff)
downloadchromium_src-184808f27fbc5cf8dc4a9c637d644bda31c6cfe8.zip
chromium_src-184808f27fbc5cf8dc4a9c637d644bda31c6cfe8.tar.gz
chromium_src-184808f27fbc5cf8dc4a9c637d644bda31c6cfe8.tar.bz2
Move ppapi_plugin to content.
TBR=brettw Review URL: http://codereview.chromium.org/6679041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/content.gyp1
-rw-r--r--content/content_ppapi_plugin.gypi28
-rw-r--r--content/ppapi_plugin/DEPS4
-rw-r--r--content/ppapi_plugin/plugin_process_dispatcher.cc38
-rw-r--r--content/ppapi_plugin/plugin_process_dispatcher.h24
-rw-r--r--content/ppapi_plugin/ppapi_plugin_main.cc28
-rw-r--r--content/ppapi_plugin/ppapi_process.cc11
-rw-r--r--content/ppapi_plugin/ppapi_process.h20
-rw-r--r--content/ppapi_plugin/ppapi_thread.cc129
-rw-r--r--content/ppapi_plugin/ppapi_thread.h74
10 files changed, 357 insertions, 0 deletions
diff --git a/content/content.gyp b/content/content.gyp
index cc3fe6a..62c12eb 100644
--- a/content/content.gyp
+++ b/content/content.gyp
@@ -10,6 +10,7 @@
'content_browser.gypi',
'content_common.gypi',
'content_gpu.gypi',
+ 'content_ppapi_plugin.gypi',
'content_worker.gypi',
],
}
diff --git a/content/content_ppapi_plugin.gypi b/content/content_ppapi_plugin.gypi
new file mode 100644
index 0000000..d504fd5
--- /dev/null
+++ b/content/content_ppapi_plugin.gypi
@@ -0,0 +1,28 @@
+# Copyright (c) 2011 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.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'content_ppapi_plugin',
+ 'type': '<(library)',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../ppapi/ppapi.gyp:ppapi_proxy',
+ ],
+ 'sources': [
+ 'ppapi_plugin/plugin_process_dispatcher.cc',
+ 'ppapi_plugin/plugin_process_dispatcher.h',
+ 'ppapi_plugin/ppapi_plugin_main.cc',
+ 'ppapi_plugin/ppapi_process.cc',
+ 'ppapi_plugin/ppapi_process.h',
+ 'ppapi_plugin/ppapi_thread.cc',
+ 'ppapi_plugin/ppapi_thread.h',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ },
+ ],
+}
diff --git a/content/ppapi_plugin/DEPS b/content/ppapi_plugin/DEPS
new file mode 100644
index 0000000..ba39a68
--- /dev/null
+++ b/content/ppapi_plugin/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+ppapi/c",
+ "+ppapi/proxy",
+]
diff --git a/content/ppapi_plugin/plugin_process_dispatcher.cc b/content/ppapi_plugin/plugin_process_dispatcher.cc
new file mode 100644
index 0000000..08528e7
--- /dev/null
+++ b/content/ppapi_plugin/plugin_process_dispatcher.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2011 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/ppapi_plugin/plugin_process_dispatcher.h"
+
+#include "content/common/child_process.h"
+
+namespace {
+
+class PluginReleaseTask : public Task {
+ public:
+ void Run() {
+ ChildProcess::current()->ReleaseProcess();
+ }
+};
+
+// How long we wait before releasing the plugin process.
+const int kPluginReleaseTimeMs = 30 * 1000; // 30 seconds.
+
+} // namespace
+
+PluginProcessDispatcher::PluginProcessDispatcher(
+ base::ProcessHandle remote_process_handle,
+ GetInterfaceFunc get_interface)
+ : pp::proxy::PluginDispatcher(remote_process_handle, get_interface) {
+ ChildProcess::current()->AddRefProcess();
+}
+
+PluginProcessDispatcher::~PluginProcessDispatcher() {
+ // Don't free the process right away. This timer allows the child process
+ // to be re-used if the user rapidly goes to a new page that requires this
+ // plugin. This is the case for common plugins where they may be used on a
+ // source and destination page of a navigation. We don't want to tear down
+ // and re-start processes each time in these cases.
+ MessageLoop::current()->PostDelayedTask(FROM_HERE, new PluginReleaseTask(),
+ kPluginReleaseTimeMs);
+}
diff --git a/content/ppapi_plugin/plugin_process_dispatcher.h b/content/ppapi_plugin/plugin_process_dispatcher.h
new file mode 100644
index 0000000..309fe1a
--- /dev/null
+++ b/content/ppapi_plugin/plugin_process_dispatcher.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2011 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_PPAPI_PLUGIN_PLUGIN_PROCESS_DISPATCHER_H_
+#define CONTENT_PPAPI_PLUGIN_PLUGIN_PROCESS_DISPATCHER_H_
+
+#include "base/basictypes.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+
+// Wrapper around a PluginDispatcher that provides the necessary integration
+// for plugin process management. This class is to avoid direct dependencies
+// from the PPAPI proxy on the Chrome multiprocess infrastructure.
+class PluginProcessDispatcher : public pp::proxy::PluginDispatcher {
+ public:
+ PluginProcessDispatcher(base::ProcessHandle remote_process_handle,
+ GetInterfaceFunc get_interface);
+ virtual ~PluginProcessDispatcher();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PluginProcessDispatcher);
+};
+
+#endif // CONTENT_PPAPI_PLUGIN_PLUGIN_PROCESS_DISPATCHER_H_
diff --git a/content/ppapi_plugin/ppapi_plugin_main.cc b/content/ppapi_plugin/ppapi_plugin_main.cc
new file mode 100644
index 0000000..e18051a
--- /dev/null
+++ b/content/ppapi_plugin/ppapi_plugin_main.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2011 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 "base/message_loop.h"
+#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/common/child_process.h"
+#include "content/common/main_function_params.h"
+#include "content/ppapi_plugin/ppapi_thread.h"
+
+// Main function for starting the PPAPI plugin process.
+int PpapiPluginMain(const MainFunctionParams& parameters) {
+ const CommandLine& command_line = parameters.command_line_;
+ if (command_line.HasSwitch(switches::kPpapiStartupDialog)) {
+ ChildProcess::WaitForDebugger("Ppapi");
+ }
+
+ MessageLoop main_message_loop(MessageLoop::TYPE_UI);
+ base::PlatformThread::SetName("CrPPAPIMain");
+
+ ChildProcess ppapi_process;
+ ppapi_process.set_main_thread(new PpapiThread());
+
+ main_message_loop.Run();
+ return 0;
+}
diff --git a/content/ppapi_plugin/ppapi_process.cc b/content/ppapi_plugin/ppapi_process.cc
new file mode 100644
index 0000000..fdf1a19
--- /dev/null
+++ b/content/ppapi_plugin/ppapi_process.cc
@@ -0,0 +1,11 @@
+// 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 "content/ppapi_plugin/ppapi_process.h"
+
+PpapiProcess::PpapiProcess() {
+}
+
+PpapiProcess::~PpapiProcess() {
+}
diff --git a/content/ppapi_plugin/ppapi_process.h b/content/ppapi_plugin/ppapi_process.h
new file mode 100644
index 0000000..ed0dec9
--- /dev/null
+++ b/content/ppapi_plugin/ppapi_process.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2011 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_PPAPI_PLUGIN_PPAPI_PROCESS_H_
+#define CONTENT_PPAPI_PLUGIN_PPAPI_PROCESS_H_
+#pragma once
+
+#include "content/common/child_process.h"
+
+class PpapiProcess : public ChildProcess {
+ public:
+ PpapiProcess();
+ ~PpapiProcess();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PpapiProcess);
+};
+
+#endif // CONTENT_PPAPI_PLUGIN_PPAPI_PROCESS_H_
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc
new file mode 100644
index 0000000..67d13a61
--- /dev/null
+++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2011 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/ppapi_plugin/ppapi_thread.h"
+
+#include <limits>
+
+#include "base/process_util.h"
+#include "base/rand_util.h"
+#include "content/common/child_process.h"
+#include "content/ppapi_plugin/plugin_process_dispatcher.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_sync_channel.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppp.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+PpapiThread::PpapiThread()
+ : get_plugin_interface_(NULL),
+ local_pp_module_(
+ base::RandInt(0, std::numeric_limits<PP_Module>::max())) {
+}
+
+PpapiThread::~PpapiThread() {
+ if (library_.is_valid()) {
+ // The ShutdownModule function is optional.
+ pp::proxy::Dispatcher::ShutdownModuleFunc shutdown_module =
+ reinterpret_cast<pp::proxy::Dispatcher::ShutdownModuleFunc>(
+ library_.GetFunctionPointer("PPP_ShutdownModule"));
+ if (shutdown_module)
+ shutdown_module();
+ }
+}
+
+// The "regular" ChildThread implements this function and does some standard
+// dispatching, then uses the message router. We don't actually need any of
+// this so this function just overrides that one.
+//
+// Note that this function is called only for messages from the channel to the
+// browser process. Messages from the renderer process are sent via a different
+// channel that ends up at Dispatcher::OnMessageReceived.
+bool PpapiThread::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
+ IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin)
+ IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnMsgCreateChannel)
+ IPC_END_MESSAGE_MAP()
+ return true;
+}
+
+MessageLoop* PpapiThread::GetIPCMessageLoop() {
+ return ChildProcess::current()->io_message_loop();
+}
+
+base::WaitableEvent* PpapiThread::GetShutdownEvent() {
+ return ChildProcess::current()->GetShutDownEvent();
+}
+
+std::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() {
+ return &globally_seen_instance_ids_;
+}
+
+void PpapiThread::OnMsgLoadPlugin(const FilePath& path) {
+ base::ScopedNativeLibrary library(base::LoadNativeLibrary(path));
+ if (!library.is_valid())
+ return;
+
+ // Get the GetInterface function (required).
+ get_plugin_interface_ =
+ reinterpret_cast<pp::proxy::Dispatcher::GetInterfaceFunc>(
+ library.GetFunctionPointer("PPP_GetInterface"));
+ if (!get_plugin_interface_) {
+ LOG(WARNING) << "No PPP_GetInterface in plugin library";
+ return;
+ }
+
+ // Get the InitializeModule function (required).
+ pp::proxy::Dispatcher::InitModuleFunc init_module =
+ reinterpret_cast<pp::proxy::Dispatcher::InitModuleFunc>(
+ library.GetFunctionPointer("PPP_InitializeModule"));
+ if (!init_module) {
+ LOG(WARNING) << "No PPP_InitializeModule in plugin library";
+ return;
+ }
+ int32_t init_error = init_module(
+ local_pp_module_,
+ &pp::proxy::PluginDispatcher::GetInterfaceFromDispatcher);
+ if (init_error != PP_OK) {
+ LOG(WARNING) << "InitModule failed with error " << init_error;
+ return;
+ }
+
+ library_.Reset(library.Release());
+}
+
+void PpapiThread::OnMsgCreateChannel(base::ProcessHandle host_process_handle,
+ int renderer_id) {
+ IPC::ChannelHandle channel_handle;
+ if (!library_.is_valid() || // Plugin couldn't be loaded.
+ !SetupRendererChannel(host_process_handle, renderer_id,
+ &channel_handle)) {
+ Send(new PpapiHostMsg_ChannelCreated(IPC::ChannelHandle()));
+ return;
+ }
+
+ Send(new PpapiHostMsg_ChannelCreated(channel_handle));
+}
+
+bool PpapiThread::SetupRendererChannel(base::ProcessHandle host_process_handle,
+ int renderer_id,
+ IPC::ChannelHandle* handle) {
+ PluginProcessDispatcher* dispatcher = new PluginProcessDispatcher(
+ host_process_handle, get_plugin_interface_);
+
+ IPC::ChannelHandle plugin_handle;
+ plugin_handle.name = StringPrintf("%d.r%d", base::GetCurrentProcId(),
+ renderer_id);
+ if (!dispatcher->InitWithChannel(this, plugin_handle, false))
+ return false;
+
+ handle->name = plugin_handle.name;
+#if defined(OS_POSIX)
+ // On POSIX, pass the renderer-side FD.
+ handle->socket = base::FileDescriptor(dispatcher->GetRendererFD(), false);
+#endif
+
+ return true;
+}
+
diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h
new file mode 100644
index 0000000..2ccc4be
--- /dev/null
+++ b/content/ppapi_plugin/ppapi_thread.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2011 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_PPAPI_PLUGIN_PPAPI_THREAD_H_
+#define CONTENT_PPAPI_PLUGIN_PPAPI_THREAD_H_
+#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"
+#include "content/common/child_thread.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/proxy/dispatcher.h"
+
+class FilePath;
+
+namespace IPC {
+struct ChannelHandle;
+}
+
+namespace pp {
+namespace proxy {
+class PluginDispatcher;
+}
+}
+
+class PpapiThread : public ChildThread,
+ public pp::proxy::Dispatcher::Delegate {
+ public:
+ PpapiThread();
+ ~PpapiThread();
+
+ private:
+ // ChildThread overrides.
+ virtual bool OnMessageReceived(const IPC::Message& msg);
+
+ // Dispatcher::Delegate implementation.
+ virtual MessageLoop* GetIPCMessageLoop();
+ virtual base::WaitableEvent* GetShutdownEvent();
+ virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet();
+
+ // Message handlers.
+ void OnMsgLoadPlugin(const FilePath& path);
+ void OnMsgCreateChannel(base::ProcessHandle host_process_handle,
+ int renderer_id);
+
+ // Sets up the channel to the given renderer. On success, returns true and
+ // fills the given ChannelHandle with the information from the new channel.
+ bool SetupRendererChannel(base::ProcessHandle host_process_handle,
+ int renderer_id,
+ IPC::ChannelHandle* handle);
+
+ base::ScopedNativeLibrary library_;
+
+ pp::proxy::Dispatcher::GetInterfaceFunc get_plugin_interface_;
+
+ // Local concept of the module ID. Some functions take this. It's necessary
+ // for the in-process PPAPI to handle this properly, but for proxied it's
+ // unnecessary. The proxy talking to multiple renderers means that each
+ // renderer has a different idea of what the module ID is for this plugin.
+ // To force people to "do the right thing" we generate a random module ID
+ // and pass it around as necessary.
+ PP_Module local_pp_module_;
+
+ // See Dispatcher::Delegate::GetGloballySeenInstanceIDSet.
+ std::set<PP_Instance> globally_seen_instance_ids_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpapiThread);
+};
+
+#endif // CONTENT_PPAPI_PLUGIN_PPAPI_THREAD_H_