| Index: webkit/glue/plugins/pepper_plugin_module.cc
|
| ===================================================================
|
| --- webkit/glue/plugins/pepper_plugin_module.cc (revision 0)
|
| +++ webkit/glue/plugins/pepper_plugin_module.cc (revision 0)
|
| @@ -0,0 +1,206 @@
|
| +// 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 "webkit/glue/plugins/pepper_plugin_module.h"
|
| +
|
| +#include <set>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/scoped_ptr.h"
|
| +#include "third_party/ppapi/c/ppb_core.h"
|
| +#include "third_party/ppapi/c/ppb_device_context_2d.h"
|
| +#include "third_party/ppapi/c/ppb_image_data.h"
|
| +#include "third_party/ppapi/c/ppb_instance.h"
|
| +#include "third_party/ppapi/c/ppb_var.h"
|
| +#include "third_party/ppapi/c/ppp.h"
|
| +#include "third_party/ppapi/c/ppp_instance.h"
|
| +#include "third_party/ppapi/c/pp_module.h"
|
| +#include "third_party/ppapi/c/pp_resource.h"
|
| +#include "third_party/ppapi/c/pp_var.h"
|
| +#include "webkit/glue/plugins/pepper_device_context_2d.h"
|
| +#include "webkit/glue/plugins/pepper_image_data.h"
|
| +#include "webkit/glue/plugins/pepper_plugin_instance.h"
|
| +#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 {
|
| +
|
| +// Maintains all currently loaded plugin libs for validating PP_Module
|
| +// identifiers.
|
| +typedef std::set<PluginModule*> PluginModuleSet;
|
| +
|
| +PluginModuleSet* GetLivePluginSet() {
|
| + static PluginModuleSet live_plugin_libs;
|
| + return &live_plugin_libs;
|
| +}
|
| +
|
| +// PPB_Core --------------------------------------------------------------------
|
| +
|
| +void AddRefResource(PP_Resource resource) {
|
| + Resource* res = ResourceTracker::Get()->GetResource(resource);
|
| + if (!res) {
|
| + DLOG(WARNING) << "AddRef()ing a nonexistent resource";
|
| + return;
|
| + }
|
| + res->AddRef();
|
| +}
|
| +
|
| +void ReleaseResource(PP_Resource resource) {
|
| + Resource* res = ResourceTracker::Get()->GetResource(resource);
|
| + if (!res) {
|
| + DLOG(WARNING) << "Release()ing a nonexistent resource";
|
| + return;
|
| + }
|
| + res->Release();
|
| +}
|
| +
|
| +const PPB_Core core_interface = {
|
| + &AddRefResource,
|
| + &ReleaseResource,
|
| +};
|
| +
|
| +// GetInterface ----------------------------------------------------------------
|
| +
|
| +const void* GetInterface(const char* name) {
|
| + if (strcmp(name, PPB_CORE_INTERFACE) == 0)
|
| + return &core_interface;
|
| + if (strcmp(name, PPB_VAR_INTERFACE) == 0)
|
| + return GetVarInterface();
|
| + if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0)
|
| + return PluginInstance::GetInterface();
|
| + if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0)
|
| + return ImageData::GetInterface();
|
| + if (strcmp(name, PPB_DEVICECONTEXT2D_INTERFACE) == 0)
|
| + return DeviceContext2D::GetInterface();
|
| + return NULL;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +PluginModule::PluginModule(const FilePath& filename)
|
| + : filename_(filename),
|
| + initialized_(false),
|
| + library_(0),
|
| + ppp_get_interface_(NULL) {
|
| + GetLivePluginSet()->insert(this);
|
| +}
|
| +
|
| +PluginModule::~PluginModule() {
|
| + // When the module is being deleted, there should be no more instances still
|
| + // holding a reference to us.
|
| + DCHECK(instances_.empty());
|
| +
|
| + GetLivePluginSet()->erase(this);
|
| +
|
| + if (library_) {
|
| + PPP_ShutdownModuleFunc shutdown_module =
|
| + reinterpret_cast<PPP_ShutdownModuleFunc>(
|
| + base::GetFunctionPointerFromNativeLibrary(library_,
|
| + "PPP_ShutdownModule"));
|
| + if (shutdown_module)
|
| + shutdown_module();
|
| + base::UnloadNativeLibrary(library_);
|
| + }
|
| +}
|
| +
|
| +// static
|
| +scoped_refptr<PluginModule> PluginModule::CreateModule(
|
| + const FilePath& filename) {
|
| + // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one.
|
| +
|
| + scoped_refptr<PluginModule> lib(new PluginModule(filename));
|
| + if (!lib->Load())
|
| + lib = NULL;
|
| + return lib;
|
| +}
|
| +
|
| +// static
|
| +PluginModule* PluginModule::FromPPModule(PP_Module module) {
|
| + PluginModule* lib = reinterpret_cast<PluginModule*>(module.id);
|
| + if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end())
|
| + return NULL; // Invalid plugin.
|
| + return lib;
|
| +}
|
| +
|
| +bool PluginModule::Load() {
|
| + if (initialized_)
|
| + return true;
|
| + initialized_ = true;
|
| +
|
| + library_ = base::LoadNativeLibrary(filename_);
|
| + if (!library_)
|
| + return false;
|
| +
|
| + // Save the GetInterface function pointer for later.
|
| + ppp_get_interface_ =
|
| + reinterpret_cast<PPP_GetInterfaceFunc>(
|
| + base::GetFunctionPointerFromNativeLibrary(library_,
|
| + "PPP_GetInterface"));
|
| + if (!ppp_get_interface_) {
|
| + LOG(WARNING) << "No PPP_GetInterface in plugin library";
|
| + return false;
|
| + }
|
| +
|
| + // Call the plugin initialize function.
|
| + PPP_InitializeModuleFunc initialize_module =
|
| + reinterpret_cast<PPP_InitializeModuleFunc>(
|
| + base::GetFunctionPointerFromNativeLibrary(library_,
|
| + "PPP_InitializeModule"));
|
| + if (!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;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +PP_Module PluginModule::GetPPModule() const {
|
| + PP_Module ret;
|
| + ret.id = reinterpret_cast<intptr_t>(this);
|
| + return ret;
|
| +}
|
| +
|
| +PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) {
|
| + const PPP_Instance* plugin_instance_interface =
|
| + reinterpret_cast<const PPP_Instance*>(GetPluginInterface(
|
| + PPP_INSTANCE_INTERFACE));
|
| + if (!plugin_instance_interface) {
|
| + LOG(WARNING) << "Plugin doesn't support instance interface, failing.";
|
| + return NULL;
|
| + }
|
| + return new PluginInstance(delegate, this, plugin_instance_interface);
|
| +}
|
| +
|
| +PluginInstance* PluginModule::GetSomeInstance() const {
|
| + // This will generally crash later if there is not actually any instance to
|
| + // return, so we force a crash now to make bugs easier to track down.
|
| + CHECK(!instances_.empty());
|
| + return *instances_.begin();
|
| +}
|
| +
|
| +const void* PluginModule::GetPluginInterface(const char* name) const {
|
| + if (!ppp_get_interface_)
|
| + return NULL;
|
| + return ppp_get_interface_(name);
|
| +}
|
| +
|
| +void PluginModule::InstanceCreated(PluginInstance* instance) {
|
| + instances_.insert(instance);
|
| +}
|
| +
|
| +void PluginModule::InstanceDeleted(PluginInstance* instance) {
|
| + instances_.erase(instance);
|
| +}
|
| +
|
| +} // namespace pepper
|
|
|
| Property changes on: webkit/glue/plugins/pepper_plugin_module.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|