summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-23 23:32:55 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-23 23:32:55 +0000
commit19215f85f0e477936a13c77450d0b12e40d7839c (patch)
tree95e4791d7a1e9bb1bd9736b2f3ec4cd0d1e5608a
parent4dd33d2a1bf4bff8c1c637bf38dda3f6d7882af5 (diff)
downloadchromium_src-19215f85f0e477936a13c77450d0b12e40d7839c.zip
chromium_src-19215f85f0e477936a13c77450d0b12e40d7839c.tar.gz
chromium_src-19215f85f0e477936a13c77450d0b12e40d7839c.tar.bz2
Add in support for internal pepper plugins into the PepperPluginRegistry and pepper::PluginModule.
Used Chromoting's plugin as the first attempt at using this interface. BUG=none TEST=compiles Review URL: http://codereview.chromium.org/2843018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50667 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome_common.gypi5
-rw-r--r--chrome/common/DEPS1
-rw-r--r--chrome/common/pepper_plugin_registry.cc66
-rw-r--r--chrome/common/pepper_plugin_registry.h11
-rw-r--r--remoting/client/plugin/chromoting_plugin.cc27
-rw-r--r--remoting/client/plugin/chromoting_plugin.h16
-rw-r--r--remoting/client/plugin/pepper_entrypoints.cc233
-rw-r--r--remoting/client/plugin/pepper_entrypoints.h20
-rw-r--r--remoting/remoting.gyp85
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc109
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.h41
11 files changed, 510 insertions, 104 deletions
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index f4a8e6e..e178607 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -311,6 +311,11 @@
'common/sandbox_policy.cc',
],
}],
+ ['remoting==1', {
+ 'dependencies': [
+ '../remoting/remoting.gyp:chromoting_plugin',
+ ],
+ }],
],
'export_dependent_settings': [
'../app/app.gyp:app_base',
diff --git a/chrome/common/DEPS b/chrome/common/DEPS
index c3db484..75629ca 100644
--- a/chrome/common/DEPS
+++ b/chrome/common/DEPS
@@ -3,6 +3,7 @@ include_rules = [
"+grit", # For generated headers
"+libxml",
"+media/audio",
+ "+remoting/client/plugin",
"+sandbox/src",
"+skia/include",
"+webkit/default_plugin",
diff --git a/chrome/common/pepper_plugin_registry.cc b/chrome/common/pepper_plugin_registry.cc
index 0a23eca..e7771c4 100644
--- a/chrome/common/pepper_plugin_registry.cc
+++ b/chrome/common/pepper_plugin_registry.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/string_util.h"
#include "chrome/common/chrome_switches.h"
+#include "remoting/client/plugin/pepper_entrypoints.h"
// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
@@ -16,6 +17,21 @@ PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
// static
void PepperPluginRegistry::GetList(std::vector<PepperPluginInfo>* plugins) {
+ InternalPluginInfoList internal_plugin_info;
+ GetInternalPluginInfo(&internal_plugin_info);
+ for (InternalPluginInfoList::const_iterator it =
+ internal_plugin_info.begin();
+ it != internal_plugin_info.end();
+ ++it) {
+ plugins->push_back(*it);
+ }
+
+ GetPluginInfoFromSwitch(plugins);
+}
+
+// static
+void PepperPluginRegistry::GetPluginInfoFromSwitch(
+ std::vector<PepperPluginInfo>* plugins) {
const std::wstring& value = CommandLine::ForCurrentProcess()->GetSwitchValue(
switches::kRegisterPepperPlugins);
if (value.empty())
@@ -44,6 +60,35 @@ void PepperPluginRegistry::GetList(std::vector<PepperPluginInfo>* plugins) {
}
}
+// static
+void PepperPluginRegistry::GetInternalPluginInfo(
+ InternalPluginInfoList* plugin_info) {
+ // Currently, to centralize the internal plugin registration logic, we
+ // hardcode the list of plugins, mimetypes, and registration information
+ // in this function. This is gross, but because the GetList() function is
+ // called from both the renderer and browser the other option is to force a
+ // special register function for each plugin to be called by both
+ // RendererMain() and BrowserMain(). This seemed like the better tradeoff.
+ //
+ // TODO(ajwong): Think up a better way to maintain the plugin registration
+ // information. Pehraps by construction of a singly linked list of
+ // plugin initializers that is built with static initializers?
+
+#if defined(ENABLE_REMOTING)
+ InternalPluginInfo info;
+ // Add the chromoting plugin.
+ info.path =
+ FilePath(FILE_PATH_LITERAL("internal-chromoting"));
+ info.mime_types.push_back("pepper-application/x-chromoting");
+ info.entry_points.get_interface = remoting::PPP_GetInterface;
+ info.entry_points.initialize_module = remoting::PPP_InitializeModule;
+ info.entry_points.shutdown_module = remoting::PPP_ShutdownModule;
+
+ plugin_info->push_back(info);
+#endif
+
+}
+
pepper::PluginModule* PepperPluginRegistry::GetModule(
const FilePath& path) const {
ModuleMap::const_iterator it = modules_.find(path);
@@ -53,8 +98,27 @@ pepper::PluginModule* PepperPluginRegistry::GetModule(
}
PepperPluginRegistry::PepperPluginRegistry() {
+ InternalPluginInfoList internal_plugin_info;
+ GetInternalPluginInfo(&internal_plugin_info);
+ // Register modules for these suckers.
+ for (InternalPluginInfoList::const_iterator it =
+ internal_plugin_info.begin();
+ it != internal_plugin_info.end();
+ ++it) {
+ const FilePath& path = it->path;
+ ModuleHandle module =
+ pepper::PluginModule::CreateInternalModule(it->entry_points);
+ if (!module) {
+ DLOG(ERROR) << "Failed to load pepper module: " << path.value();
+ continue;
+ }
+ modules_[path] = module;
+ }
+
+ // Add the modules specified on the command line last so that they can
+ // override the internal plugins.
std::vector<PepperPluginInfo> plugins;
- GetList(&plugins);
+ GetPluginInfoFromSwitch(&plugins);
for (size_t i = 0; i < plugins.size(); ++i) {
const FilePath& path = plugins[i].path;
ModuleHandle module = pepper::PluginModule::CreateModule(path);
diff --git a/chrome/common/pepper_plugin_registry.h b/chrome/common/pepper_plugin_registry.h
index 940a1ba..9949ed4 100644
--- a/chrome/common/pepper_plugin_registry.h
+++ b/chrome/common/pepper_plugin_registry.h
@@ -7,11 +7,12 @@
#include <string>
#include <map>
+#include <vector>
#include "webkit/glue/plugins/pepper_plugin_module.h"
struct PepperPluginInfo {
- FilePath path;
+ FilePath path; // Internal plugins are of the form "internal-[name]".
std::vector<std::string> mime_types;
};
@@ -28,6 +29,14 @@ class PepperPluginRegistry {
pepper::PluginModule* GetModule(const FilePath& path) const;
private:
+ static void GetPluginInfoFromSwitch(std::vector<PepperPluginInfo>* plugins);
+
+ struct InternalPluginInfo : public PepperPluginInfo {
+ pepper::PluginModule::EntryPoints entry_points;
+ };
+ typedef std::vector<InternalPluginInfo> InternalPluginInfoList;
+ static void GetInternalPluginInfo(InternalPluginInfoList* plugin_info);
+
PepperPluginRegistry();
typedef scoped_refptr<pepper::PluginModule> ModuleHandle;
diff --git a/remoting/client/plugin/chromoting_plugin.cc b/remoting/client/plugin/chromoting_plugin.cc
index 1657e20..9bc6fc2 100644
--- a/remoting/client/plugin/chromoting_plugin.cc
+++ b/remoting/client/plugin/chromoting_plugin.cc
@@ -23,13 +23,15 @@ using std::vector;
namespace remoting {
-const char* ChromotingPlugin::kMimeType =
- "pepper-application/x-chromoting-plugin::Chromoting";
-
-ChromotingPlugin::ChromotingPlugin(PP_Instance instance)
- : pp::Instance(instance),
- width_(0),
- height_(0) {
+const char* ChromotingPlugin::kMimeType = "pepper-application/x-chromoting";
+
+ChromotingPlugin::ChromotingPlugin(PP_Instance pp_instance,
+ const PPB_Instance* ppb_instance_funcs)
+ : width_(0),
+ height_(0),
+ drawing_context_(NULL),
+ pp_instance_(pp_instance),
+ ppb_instance_funcs_(ppb_instance_funcs) {
}
ChromotingPlugin::~ChromotingPlugin() {
@@ -47,7 +49,8 @@ ChromotingPlugin::~ChromotingPlugin() {
main_thread_->Stop();
}
-bool ChromotingPlugin::Init(uint32_t argc, const char* argn[], const char* argv[]) {
+bool ChromotingPlugin::Init(uint32_t argc, const char* argn[],
+ const char* argv[]) {
LOG(INFO) << "Started ChromotingPlugin::Init";
// Extract the URL from the arguments.
@@ -112,8 +115,13 @@ void ChromotingPlugin::ViewChanged(const PP_Rect& position,
width_ = position.size.width;
height_ = position.size.height;
+ /*
+ * TODO(ajwong): Reenable this code once we fingure out how we want to
+ * abstract away the C-api for DeviceContext2D.
device_context_ = pp::DeviceContext2D(width_, height_, false);
- if (!BindGraphicsDeviceContext(device_context_)) {
+ if (!ppb_instance_funcs_->BindGraphicsDeviceContext(
+ pp_instance_,
+ device_context_.pp_resource())) {
LOG(ERROR) << "Couldn't bind the device context.";
return;
}
@@ -130,6 +138,7 @@ void ChromotingPlugin::ViewChanged(const PP_Rect& position,
} else {
LOG(ERROR) << "Unable to allocate image.";
}
+ */
//client_->SetViewport(0, 0, width_, height_);
//client_->Repaint();
diff --git a/remoting/client/plugin/chromoting_plugin.h b/remoting/client/plugin/chromoting_plugin.h
index d19b612..757e038 100644
--- a/remoting/client/plugin/chromoting_plugin.h
+++ b/remoting/client/plugin/chromoting_plugin.h
@@ -11,8 +11,11 @@
#include "base/scoped_ptr.h"
#include "remoting/client/host_connection.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
-#include "third_party/ppapi/cpp/device_context_2d.h"
-#include "third_party/ppapi/cpp/instance.h"
+#include "third_party/ppapi/c/pp_event.h"
+#include "third_party/ppapi/c/pp_instance.h"
+#include "third_party/ppapi/c/pp_rect.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "third_party/ppapi/c/ppb_instance.h"
namespace base {
class Thread;
@@ -27,7 +30,7 @@ class PepperView;
class ChromotingClient;
-class ChromotingPlugin : public pp::Instance {
+class ChromotingPlugin {
public:
// The mimetype for which this plugin is registered.
//
@@ -35,7 +38,7 @@ class ChromotingPlugin : public pp::Instance {
// point. I think we should handle a special protocol (eg., chromotocol://)
static const char *kMimeType;
- ChromotingPlugin(PP_Instance instance);
+ ChromotingPlugin(PP_Instance instance, const PPB_Instance* instance_funcs);
virtual ~ChromotingPlugin();
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
@@ -55,7 +58,10 @@ class ChromotingPlugin : public pp::Instance {
int width_;
int height_;
- pp::DeviceContext2D device_context_;
+ PP_Resource drawing_context_;
+
+ PP_Instance pp_instance_;
+ const PPB_Instance* ppb_instance_funcs_;
scoped_ptr<base::Thread> main_thread_;
scoped_ptr<JingleThread> network_thread_;
diff --git a/remoting/client/plugin/pepper_entrypoints.cc b/remoting/client/plugin/pepper_entrypoints.cc
new file mode 100644
index 0000000..0ca7a06
--- /dev/null
+++ b/remoting/client/plugin/pepper_entrypoints.cc
@@ -0,0 +1,233 @@
+// 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 "remoting/client/plugin/pepper_entrypoints.h"
+
+#include "remoting/client/plugin/chromoting_plugin.h"
+#include "third_party/ppapi/c/pp_instance.h"
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/ppp_instance.h"
+#include "third_party/ppapi/cpp/instance.h"
+#include "third_party/ppapi/cpp/module.h"
+
+static const int kModuleInitSuccess = 0;
+static const int kModuleInitFailure = 1;
+
+namespace remoting {
+
+// Fork of ppapi::Module
+//
+// TODO(ajwong): Generalize this into something that other internal plugins can
+// use. Either that, or attempt to refactor the external ppapi C++ wrapper to
+// make it friendly for multiple Modules in one process. I think we can do this
+// by:
+// 1) Moving the singleton Module instance + C-bindings into another class
+// (eg., ModuleExporter) under a different gyp targe.
+// 2) Extracting the idea of a "Browser" out of the module that returns
+// PPB_Core, etc. This can be a singleton per process regardless of
+// module.
+// 3) Migrate all PPB related objects to get data out of Browser interface
+// instead of Module::Get().
+class ChromotingModule {
+ public:
+ ChromotingModule() {}
+
+ // This function will be automatically called after the object is created.
+ // This is where you can put functions that rely on other parts of the API,
+ // now that the module has been created.
+ virtual bool Init() { return true; }
+
+ PP_Module pp_module() const { return pp_module_; }
+ const PPB_Core& core() const { return *core_; }
+
+ // Implements GetInterface for the browser to get plugin interfaces. Override
+ // if you need to implement your own interface types that this wrapper
+ // doesn't support.
+ virtual const void* GetInstanceInterface(const char* interface_name) {
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
+ return &instance_interface_;
+
+ return NULL;
+ }
+
+ // Returns an interface in the browser.
+ const void* GetBrowserInterface(const char* interface_name) {
+ return get_browser_interface_(interface_name);
+ }
+
+ // Returns the object associated with this PP_Instance, or NULL if one is
+ // not found.
+ ChromotingPlugin* InstanceForPPInstance(PP_Instance instance) {
+ InstanceMap::iterator found = current_instances_.find(instance);
+ if (found == current_instances_.end())
+ return NULL;
+ return found->second;
+ }
+
+ // Sets the browser interface and calls the regular init function that
+ // can be overridden by the base classes.
+ //
+ // TODO(brettw) make this private when I can figure out how to make the
+ // initialize function a friend.
+ bool InternalInit(PP_Module mod,
+ PPB_GetInterface get_browser_interface) {
+ pp_module_ = mod;
+ get_browser_interface_ = get_browser_interface;
+ core_ = reinterpret_cast<const PPB_Core*>(GetBrowserInterface(
+ PPB_CORE_INTERFACE));
+ if (!core_)
+ return false; // Can't run without the core interface.
+
+ return Init();
+ }
+
+ // Implementation of Global PPP functions ---------------------------------
+ static int PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ ChromotingModule* module = new ChromotingModule();
+ if (!module)
+ return kModuleInitFailure;
+
+ if (!module->InternalInit(module_id, get_browser_interface)) {
+ delete module;
+ return kModuleInitFailure;
+ }
+
+ module_singleton_ = module;
+ return kModuleInitSuccess;
+ }
+
+ static void PPP_ShutdownModule() {
+ delete module_singleton_;
+ module_singleton_ = NULL;
+ }
+
+ static const void* PPP_GetInterface(const char* interface_name) {
+ if (!module_singleton_)
+ return NULL;
+ return module_singleton_->GetInstanceInterface(interface_name);
+ }
+
+ protected:
+ virtual ChromotingPlugin* CreateInstance(PP_Instance instance) {
+ const PPB_Instance* ppb_instance_funcs =
+ reinterpret_cast<const PPB_Instance *>(
+ module_singleton_->GetBrowserInterface(PPB_INSTANCE_INTERFACE));
+ return new ChromotingPlugin(instance, ppb_instance_funcs);
+ }
+
+ private:
+ static bool Instance_New(PP_Instance instance) {
+ if (!module_singleton_)
+ return false;
+ ChromotingPlugin* obj = module_singleton_->CreateInstance(instance);
+ if (obj) {
+ module_singleton_->current_instances_[instance] = obj;
+ return true;
+ }
+ return false;
+ }
+
+ static void Instance_Delete(PP_Instance instance) {
+ if (!module_singleton_)
+ return;
+ ChromotingModule::InstanceMap::iterator found =
+ module_singleton_->current_instances_.find(instance);
+ if (found == module_singleton_->current_instances_.end())
+ return;
+
+ // Remove it from the map before deleting to try to catch reentrancy.
+ ChromotingPlugin* obj = found->second;
+ module_singleton_->current_instances_.erase(found);
+ delete obj;
+ }
+
+ static bool Instance_Initialize(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ if (!module_singleton_)
+ return false;
+ ChromotingPlugin* instance =
+ module_singleton_->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->Init(argc, argn, argv);
+ }
+
+ static bool Instance_HandleEvent(PP_Instance pp_instance,
+ const PP_Event* event) {
+ if (!module_singleton_)
+ return false;
+ ChromotingPlugin* instance =
+ module_singleton_->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->HandleEvent(*event);
+ }
+
+ static PP_Var Instance_GetInstanceObject(PP_Instance pp_instance) {
+ PP_Var var;
+ var.type = PP_VarType_Void;
+ return var;
+ }
+
+ static void Instance_ViewChanged(PP_Instance pp_instance,
+ const PP_Rect* position,
+ const PP_Rect* clip) {
+ if (!module_singleton_)
+ return;
+ ChromotingPlugin* instance =
+ module_singleton_->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->ViewChanged(*position, *clip);
+ }
+
+ // Bindings and identifiers to and from the browser.
+ PP_Module pp_module_;
+ PPB_GetInterface get_browser_interface_;
+ PPB_Core const* core_;
+
+ // Instance tracking.
+ typedef std::map<PP_Instance, ChromotingPlugin*> InstanceMap;
+ InstanceMap current_instances_;
+
+ // Static members for the ppapi C-bridge.
+ static PPP_Instance instance_interface_;
+ static ChromotingModule* module_singleton_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromotingModule);
+};
+
+ChromotingModule* ChromotingModule::module_singleton_ = NULL;
+
+PPP_Instance ChromotingModule::instance_interface_ = {
+ &ChromotingModule::Instance_New,
+ &ChromotingModule::Instance_Delete,
+ &ChromotingModule::Instance_Initialize,
+ &ChromotingModule::Instance_HandleEvent,
+ &ChromotingModule::Instance_GetInstanceObject,
+ &ChromotingModule::Instance_ViewChanged,
+};
+
+// Implementation of Global PPP functions ---------------------------------
+//
+// TODO(ajwong): This is to get around friending issues. Fix it after we decide
+// whether or not ChromotingModule should be generalized.
+int PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ return ChromotingModule::PPP_InitializeModule(module_id,
+ get_browser_interface);
+}
+
+void PPP_ShutdownModule() {
+ return ChromotingModule::PPP_ShutdownModule();
+}
+
+const void* PPP_GetInterface(const char* interface_name) {
+ return ChromotingModule::PPP_GetInterface(interface_name);
+}
+
+} // namespace remoting
diff --git a/remoting/client/plugin/pepper_entrypoints.h b/remoting/client/plugin/pepper_entrypoints.h
new file mode 100644
index 0000000..ab6de20
--- /dev/null
+++ b/remoting/client/plugin/pepper_entrypoints.h
@@ -0,0 +1,20 @@
+// 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 REMOTING_CLIENT_PLUGIN_PEPPER_ENTRYPOINTS_
+#define REMOTING_CLIENT_PLUGIN_PEPPER_ENTRYPOINTS_
+
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/ppb.h"
+
+namespace remoting {
+
+int PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface);
+void PPP_ShutdownModule();
+const void* PPP_GetInterface(const char* interface_name);
+
+} // namespace remoting
+
+#endif // REMOTING_CLIENT_PLUGIN_PEPPER_ENTRYPOINTS_
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 47dc6ea..818fbd3 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -16,46 +16,8 @@
},
'conditions': [
- # Chromoting Client targets
['OS=="linux" or OS=="mac"', {
'targets': [
- {
- 'target_name': 'chromoting_client_plugin',
- 'type': 'static_library',
- 'defines': [
- 'HAVE_STDINT_H', # Required by on2_integer.h
- ],
- 'dependencies': [
- 'chromoting_base',
- 'chromoting_client',
- 'chromoting_jingle_glue',
- '../third_party/ppapi/ppapi.gyp:ppapi_cpp',
- '../third_party/zlib/zlib.gyp:zlib',
- ],
- 'sources': [
- 'client/plugin/chromoting_plugin.cc',
- 'client/plugin/chromoting_plugin.h',
- 'client/plugin/pepper_view.cc',
- 'client/plugin/pepper_view.h',
- '../media/base/yuv_convert.cc',
- '../media/base/yuv_convert.h',
- '../media/base/yuv_row.h',
- '../media/base/yuv_row_posix.cc',
- '../media/base/yuv_row_table.cc',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'sources': [
- '../media/base/yuv_row_win.cc',
- ],
- }],
- ['OS=="linux" and target_arch=="x64" and linux_fpic!=1', {
- # Shared libraries need -fPIC on x86-64
- 'cflags': ['-fPIC'],
- }],
- ], # end of 'conditions'
- }, # end of target 'chromoting_client_plugin'
-
# Simple webserver for testing chromoting client plugin.
{
'target_name': 'chromoting_client_test_webserver',
@@ -63,13 +25,13 @@
'sources': [
'tools/client_webserver/main.c',
],
- }, # end of target 'chromoting_client_test_webserver'
-
- ], # end of Client targets
- }], # end of OS conditions for Client targets
+ }
+ ], # end of target 'chromoting_client_test_webserver'
+ }],
# TODO(hclam): Enable this target for mac.
['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
+
'targets': [
{
'target_name': 'chromoting_x11_client',
@@ -100,6 +62,45 @@
'targets': [
{
+ 'target_name': 'chromoting_plugin',
+ 'type': 'static_library',
+ 'defines': [
+ 'HAVE_STDINT_H', # Required by on2_integer.h
+ ],
+ 'dependencies': [
+ 'chromoting_base',
+ 'chromoting_client',
+ 'chromoting_jingle_glue',
+ '../third_party/ppapi/ppapi.gyp:ppapi_c',
+ '../third_party/zlib/zlib.gyp:zlib',
+ ],
+ 'sources': [
+ 'client/plugin/chromoting_plugin.cc',
+ 'client/plugin/chromoting_plugin.h',
+ 'client/plugin/pepper_entrypoints.cc',
+ 'client/plugin/pepper_entrypoints.h',
+ 'client/plugin/pepper_view.cc',
+ 'client/plugin/pepper_view.h',
+ '../media/base/yuv_convert.cc',
+ '../media/base/yuv_convert.h',
+ '../media/base/yuv_row.h',
+ '../media/base/yuv_row_table.cc',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'sources': [
+ '../media/base/yuv_row_win.cc',
+ ],
+ }],
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="mac"', {
+ 'sources': [
+ '../media/base/yuv_row_posix.cc',
+ ],
+ }],
+ ], # end of 'conditions'
+ }, # end of target 'chromoting_plugin'
+
+ {
'target_name': 'chromoting_base',
'type': '<(library)',
'dependencies': [
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
index 22a9eb2..26cef2c 100644
--- a/webkit/glue/plugins/pepper_plugin_module.cc
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -31,9 +31,6 @@
#include "webkit/glue/plugins/pepper_resource_tracker.h"
#include "webkit/glue/plugins/pepper_var.h"
-typedef bool (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface);
-typedef void (*PPP_ShutdownModuleFunc)();
-
namespace pepper {
namespace {
@@ -158,11 +155,9 @@ const void* GetInterface(const char* name) {
} // namespace
-PluginModule::PluginModule(const FilePath& filename)
- : filename_(filename),
- initialized_(false),
- library_(0),
- ppp_get_interface_(NULL) {
+PluginModule::PluginModule()
+ : initialized_(false),
+ library_(NULL) {
GetMainThreadMessageLoop(); // Initialize the main thread message loop.
GetLivePluginSet()->insert(this);
}
@@ -174,25 +169,31 @@ PluginModule::~PluginModule() {
GetLivePluginSet()->erase(this);
- if (library_) {
- PPP_ShutdownModuleFunc shutdown_module =
- reinterpret_cast<PPP_ShutdownModuleFunc>(
- base::GetFunctionPointerFromNativeLibrary(library_,
- "PPP_ShutdownModule"));
- if (shutdown_module)
- shutdown_module();
+ if (entry_points_.shutdown_module)
+ entry_points_.shutdown_module();
+
+ if (library_)
base::UnloadNativeLibrary(library_);
- }
}
// static
scoped_refptr<PluginModule> PluginModule::CreateModule(
- const FilePath& filename) {
+ const FilePath& path) {
// FIXME(brettw) do uniquifying of the plugin here like the NPAPI one.
- scoped_refptr<PluginModule> lib(new PluginModule(filename));
- if (!lib->Load())
- lib = NULL;
+ scoped_refptr<PluginModule> lib(new PluginModule());
+ if (!lib->InitFromFile(path))
+ return NULL;
+
+ return lib;
+}
+
+scoped_refptr<PluginModule> PluginModule::CreateInternalModule(
+ EntryPoints entry_points) {
+ scoped_refptr<PluginModule> lib(new PluginModule());
+ if (!lib->InitFromEntryPoints(entry_points))
+ return NULL;
+
return lib;
}
@@ -204,39 +205,71 @@ PluginModule* PluginModule::FromPPModule(PP_Module module) {
return lib;
}
-bool PluginModule::Load() {
+bool PluginModule::InitFromEntryPoints(const EntryPoints& entry_points) {
if (initialized_)
return true;
+
+ // Attempt to run the initialization funciton.
+ int retval = entry_points.initialize_module(GetPPModule(), &GetInterface);
+ if (retval != 0) {
+ LOG(WARNING) << "PPP_InitializeModule returned failure " << retval;
+ return false;
+ }
+
+ entry_points_ = entry_points;
initialized_ = true;
+ return true;
+}
- library_ = base::LoadNativeLibrary(filename_);
- if (!library_)
+bool PluginModule::InitFromFile(const FilePath& path) {
+ if (initialized_)
+ return true;
+
+ base::NativeLibrary library = base::LoadNativeLibrary(path);
+ if (!library)
return false;
- // Save the GetInterface function pointer for later.
- ppp_get_interface_ =
+ EntryPoints entry_points;
+ if (!LoadEntryPoints(library, &entry_points) ||
+ !InitFromEntryPoints(entry_points)) {
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ // We let InitFromEntryPoints() handle setting the all the internal state
+ // of the object other than the |library_| reference.
+ library_ = library;
+ return true;
+}
+
+// static
+bool PluginModule::LoadEntryPoints(const base::NativeLibrary& library,
+ EntryPoints* entry_points) {
+
+ entry_points->get_interface =
reinterpret_cast<PPP_GetInterfaceFunc>(
- base::GetFunctionPointerFromNativeLibrary(library_,
+ base::GetFunctionPointerFromNativeLibrary(library,
"PPP_GetInterface"));
- if (!ppp_get_interface_) {
+ if (!entry_points->get_interface) {
LOG(WARNING) << "No PPP_GetInterface in plugin library";
return false;
}
- // Call the plugin initialize function.
- PPP_InitializeModuleFunc initialize_module =
+ entry_points->initialize_module =
reinterpret_cast<PPP_InitializeModuleFunc>(
- base::GetFunctionPointerFromNativeLibrary(library_,
+ base::GetFunctionPointerFromNativeLibrary(library,
"PPP_InitializeModule"));
- if (!initialize_module) {
+ if (!entry_points->initialize_module) {
LOG(WARNING) << "No PPP_InitializeModule in plugin library";
return false;
}
- int retval = initialize_module(GetPPModule(), &GetInterface);
- if (retval != 0) {
- LOG(WARNING) << "PPP_InitializeModule returned failure " << retval;
- return false;
- }
+
+ // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to
+ // be NULL.
+ entry_points->shutdown_module =
+ reinterpret_cast<PPP_ShutdownModuleFunc>(
+ base::GetFunctionPointerFromNativeLibrary(library,
+ "PPP_ShutdownModule"));
return true;
}
@@ -264,9 +297,9 @@ PluginInstance* PluginModule::GetSomeInstance() const {
}
const void* PluginModule::GetPluginInterface(const char* name) const {
- if (!ppp_get_interface_)
+ if (!entry_points_.get_interface)
return NULL;
- return ppp_get_interface_(name);
+ return entry_points_.get_interface(name);
}
void PluginModule::InstanceCreated(PluginInstance* instance) {
diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h
index 0498c45..1b2d9fb 100644
--- a/webkit/glue/plugins/pepper_plugin_module.h
+++ b/webkit/glue/plugins/pepper_plugin_module.h
@@ -12,6 +12,7 @@
#include "base/native_library.h"
#include "base/ref_counted.h"
#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/ppb.h"
namespace pepper {
@@ -20,9 +21,27 @@ class PluginInstance;
class PluginModule : public base::RefCounted<PluginModule> {
public:
+ typedef const void* (*PPP_GetInterfaceFunc)(const char*);
+ typedef int (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface);
+ typedef void (*PPP_ShutdownModuleFunc)();
+
+ struct EntryPoints {
+ EntryPoints()
+ : get_interface(NULL),
+ initialize_module(NULL),
+ shutdown_module(NULL) {
+ }
+
+ PPP_GetInterfaceFunc get_interface;
+ PPP_InitializeModuleFunc initialize_module;
+ PPP_ShutdownModuleFunc shutdown_module;
+ };
+
~PluginModule();
- static scoped_refptr<PluginModule> CreateModule(const FilePath& filename);
+ static scoped_refptr<PluginModule> CreateModule(const FilePath& path);
+ static scoped_refptr<PluginModule> CreateInternalModule(
+ EntryPoints entry_points);
// Converts the given module ID to an actual module object. Will return NULL
// if the module is invalid.
@@ -47,18 +66,24 @@ class PluginModule : public base::RefCounted<PluginModule> {
void InstanceDeleted(PluginInstance* instance);
private:
- typedef const void* (*PPP_GetInterfaceFunc)(const char*);
-
- explicit PluginModule(const FilePath& filename);
+ PluginModule();
- bool Load();
-
- FilePath filename_;
+ bool InitFromEntryPoints(const EntryPoints& entry_points);
+ bool InitFromFile(const FilePath& path);
+ static bool LoadEntryPoints(const base::NativeLibrary& library,
+ EntryPoints* entry_points);
bool initialized_;
+
+ // Holds a reference to the base::NativeLibrary handle if this PluginModule
+ // instance wraps functions loaded from a library. Can be NULL. If
+ // |library_| is non-NULL, PluginModule will attempt to unload the library
+ // during destruction.
base::NativeLibrary library_;
- PPP_GetInterfaceFunc ppp_get_interface_;
+ // Contains pointers to the entry points of the actual plugin
+ // implementation.
+ EntryPoints entry_points_;
// Non-owning pointers to all instances associated with this module. When
// there are no more instances, this object should be deleted.