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 |