diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-08 06:38:45 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-08 06:38:45 +0000 |
commit | 1a78d9f39f364608a1a54b4274322e1ed4c2be9b (patch) | |
tree | 71ca778a5498c3e9e8c95e66013c74c80af13d33 /webkit/glue/plugins | |
parent | 13930f6c2d604b78faadd458ffcad121d434c421 (diff) | |
download | chromium_src-1a78d9f39f364608a1a54b4274322e1ed4c2be9b.zip chromium_src-1a78d9f39f364608a1a54b4274322e1ed4c2be9b.tar.gz chromium_src-1a78d9f39f364608a1a54b4274322e1ed4c2be9b.tar.bz2 |
Make webkit/glue/plugins no longer depend on ppapi/proxy directly. This causes
things that use webkit but otherwise don't need IPC to include the IPC
directory.
This patch moves the set-up of the proxy into the renderer. I also did a lot
of clean-up of the initialization and it seems much nicer now.
BUG=63684
TEST=manual PPAPI proxy testing
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68567 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r-- | webkit/glue/plugins/DEPS | 5 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_delegate.h | 31 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_module.cc | 207 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_module.h | 74 |
4 files changed, 149 insertions, 168 deletions
diff --git a/webkit/glue/plugins/DEPS b/webkit/glue/plugins/DEPS index cfee702..024a4ef 100644 --- a/webkit/glue/plugins/DEPS +++ b/webkit/glue/plugins/DEPS @@ -1,4 +1,9 @@ include_rules = [ "+ppapi", + + # Files in this directory must not depend on the proxy, because the proxy + # depends on IPC which we don't want to have in /webkit. + "-ppapi/proxy", + "+printing", ] diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index 7032c2c..57b66ba 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -16,6 +16,7 @@ #include "googleurl/src/gurl.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_stdint.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/glue/plugins/pepper_dir_contents.h" @@ -67,6 +68,36 @@ class FullscreenContainer; // Pepper plugins. class PluginDelegate { public: + // This class is implemented by the PluginDelegate implementation and is + // designed to manage the lifetime and communicatin with the proxy's + // HostDispatcher for out-of-process pepper plugins. + // + // The point of this is to avoid having a relationship from the pepper plugin + // implementation to the ppapi proxy code. Otherwise, things like the IPC + // system will be dependencies of the webkit directory, which we don't want. + // + // The PluginModule will scope the lifetime of this object to its own + // lifetime, so the implementation can use this to manage the HostDispatcher + // lifetime without introducing the dependency. + class OutOfProcessProxy { + public: + virtual ~OutOfProcessProxy() {} + + // Implements GetInterface for the proxied plugin. + virtual const void* GetProxiedInterface(const char* name) = 0; + + // Notification to the out-of-process layer that the given plugin instance + // has been created. This will happen before the normal PPB_Instance method + // calls so the out-of-process code can set up the tracking information for + // the new instance. + virtual void AddInstance(PP_Instance instance) = 0; + + // Like AddInstance but removes the given instance. This is called after + // regular instance shutdown so the out-of-process code can clean up its + // tracking information. + virtual void RemoveInstance(PP_Instance instance) = 0; + }; + // Represents an image. This is to allow the browser layer to supply a correct // image representation. In Chrome, this will be a TransportDIB. class PlatformImage2D { diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index 0da663a..24dd4e2 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -48,8 +48,6 @@ #include "ppapi/c/ppp_instance.h" #include "ppapi/c/trusted/ppb_image_data_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" -#include "ppapi/proxy/host_dispatcher.h" -#include "ppapi/proxy/ppapi_messages.h" #include "webkit/glue/plugins/pepper_audio.h" #include "webkit/glue/plugins/pepper_buffer.h" #include "webkit/glue/plugins/pepper_common.h" @@ -85,10 +83,6 @@ #include "webkit/glue/plugins/pepper_graphics_3d.h" #endif // ENABLE_GPU -#if defined(OS_POSIX) -#include "ipc/ipc_channel_posix.h" -#endif - namespace pepper { namespace { @@ -292,11 +286,49 @@ const void* GetInterface(const char* name) { return NULL; } +// Gets the PPAPI entry points from the given library and places them into the +// given structure. Returns true on success. +bool LoadEntryPointsFromLibrary(const base::NativeLibrary& library, + PluginModule::EntryPoints* entry_points) { + entry_points->get_interface = + reinterpret_cast<PluginModule::GetInterfaceFunc>( + base::GetFunctionPointerFromNativeLibrary(library, + "PPP_GetInterface")); + if (!entry_points->get_interface) { + LOG(WARNING) << "No PPP_GetInterface in plugin library"; + return false; + } + + entry_points->initialize_module = + reinterpret_cast<PluginModule::PPP_InitializeModuleFunc>( + base::GetFunctionPointerFromNativeLibrary(library, + "PPP_InitializeModule")); + if (!entry_points->initialize_module) { + LOG(WARNING) << "No PPP_InitializeModule in plugin library"; + return false; + } + + // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to + // be NULL. + entry_points->shutdown_module = + reinterpret_cast<PluginModule::PPP_ShutdownModuleFunc>( + base::GetFunctionPointerFromNativeLibrary(library, + "PPP_ShutdownModule")); + + return true; +} + } // namespace -PluginModule::PluginModule() - : initialized_(false), - library_(NULL) { +PluginModule::EntryPoints::EntryPoints() + : get_interface(NULL), + initialize_module(NULL), + shutdown_module(NULL) { +} + +// PluginModule ---------------------------------------------------------------- + +PluginModule::PluginModule() : library_(NULL) { pp_module_ = ResourceTracker::Get()->AddModule(this); GetMainThreadMessageLoop(); // Initialize the main thread message loop. GetLivePluginSet()->insert(this); @@ -329,144 +361,40 @@ PluginModule::~PluginModule() { ResourceTracker::Get()->ModuleDeleted(pp_module_); } -// static -scoped_refptr<PluginModule> PluginModule::CreateModule( - const FilePath& path) { - // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one. - - scoped_refptr<PluginModule> lib(new PluginModule()); - if (!lib->InitFromFile(path)) - return NULL; - - return lib; -} - -// static -scoped_refptr<PluginModule> PluginModule::CreateInternalModule( - EntryPoints entry_points) { - scoped_refptr<PluginModule> lib(new PluginModule()); - if (!lib->InitFromEntryPoints(entry_points)) - return NULL; - - return lib; -} - -// 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, plugin_process_handle, - handle, shutdown_event)) - return NULL; - return lib; -} - -// static -const PPB_Core* PluginModule::GetCore() { - return &core_interface; -} - -bool PluginModule::InitFromEntryPoints(const EntryPoints& entry_points) { - if (initialized_) - return true; - - // Attempt to run the initialization funciton. - int retval = entry_points.initialize_module(pp_module(), &GetInterface); - if (retval != 0) { - LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; - return false; - } - +bool PluginModule::InitAsInternalPlugin(const EntryPoints& entry_points) { entry_points_ = entry_points; - initialized_ = true; - return true; + return InitializeModule(); } -bool PluginModule::InitFromFile(const FilePath& path) { - if (initialized_) - return true; - +bool PluginModule::InitAsLibrary(const FilePath& path) { base::NativeLibrary library = base::LoadNativeLibrary(path); if (!library) return false; - EntryPoints entry_points; - if (!LoadEntryPoints(library, &entry_points) || - !InitFromEntryPoints(entry_points)) { + if (!LoadEntryPointsFromLibrary(library, &entry_points_) || + !InitializeModule()) { 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; } -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( - remote_process, var_interface, pp_module(), &GetInterface)); - -#if defined(OS_POSIX) - // If we received a ChannelHandle, register it now. - if (handle.socket.fd >= 0) - IPC::AddChannelSocket(handle.name, handle.socket.fd); -#endif - - if (!dispatcher_->InitWithChannel(ipc_message_loop, handle.name, true, - shutdown_event)) { - dispatcher_.reset(); - return false; - } - - 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(); - return false; - } - return true; +void PluginModule::InitAsProxied( + PluginDelegate::OutOfProcessProxy* out_of_process_proxy) { + DCHECK(!out_of_process_proxy_.get()); + out_of_process_proxy_.reset(out_of_process_proxy); } // static -bool PluginModule::LoadEntryPoints(const base::NativeLibrary& library, - EntryPoints* entry_points) { - entry_points->get_interface = - reinterpret_cast<PPP_GetInterfaceFunc>( - base::GetFunctionPointerFromNativeLibrary(library, - "PPP_GetInterface")); - if (!entry_points->get_interface) { - LOG(WARNING) << "No PPP_GetInterface in plugin library"; - return false; - } - - entry_points->initialize_module = - reinterpret_cast<PPP_InitializeModuleFunc>( - base::GetFunctionPointerFromNativeLibrary(library, - "PPP_InitializeModule")); - if (!entry_points->initialize_module) { - LOG(WARNING) << "No PPP_InitializeModule in plugin library"; - 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")); +const PPB_Core* PluginModule::GetCore() { + return &core_interface; +} - return true; +// static +PluginModule::GetInterfaceFunc PluginModule::GetLocalGetInterfaceFunc() { + return &GetInterface; } PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { @@ -479,10 +407,8 @@ PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { } PluginInstance* instance = new PluginInstance(delegate, this, plugin_instance_interface); - if (dispatcher_.get()) { - pp::proxy::HostDispatcher::SetForInstance(instance->pp_instance(), - dispatcher_.get()); - } + if (out_of_process_proxy_.get()) + out_of_process_proxy_->AddInstance(instance->pp_instance()); return instance; } @@ -494,8 +420,8 @@ PluginInstance* PluginModule::GetSomeInstance() const { } const void* PluginModule::GetPluginInterface(const char* name) const { - if (dispatcher_.get()) - return dispatcher_->GetProxiedInterface(name); + if (out_of_process_proxy_.get()) + return out_of_process_proxy_->GetProxiedInterface(name); // In-process plugins. if (!entry_points_.get_interface) @@ -508,7 +434,8 @@ void PluginModule::InstanceCreated(PluginInstance* instance) { } void PluginModule::InstanceDeleted(PluginInstance* instance) { - pp::proxy::HostDispatcher::RemoveForInstance(instance->pp_instance()); + if (out_of_process_proxy_.get()) + out_of_process_proxy_->RemoveInstance(instance->pp_instance()); instances_.erase(instance); } @@ -552,4 +479,14 @@ void PluginModule::RemovePluginObject(PluginObject* plugin_object) { live_plugin_objects_.erase(plugin_object); } +bool PluginModule::InitializeModule() { + DCHECK(!out_of_process_proxy_.get()) << "Don't call for proxied modules."; + int retval = entry_points_.initialize_module(pp_module(), &GetInterface); + if (retval != 0) { + LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; + return false; + } + return true; +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h index 19e1027..5ccd528 100644 --- a/webkit/glue/plugins/pepper_plugin_module.h +++ b/webkit/glue/plugins/pepper_plugin_module.h @@ -16,6 +16,7 @@ #include "base/weak_ptr.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/ppb.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" class FilePath; class MessageLoop; @@ -52,35 +53,46 @@ class PluginObject; class PluginModule : public base::RefCounted<PluginModule>, public base::SupportsWeakPtr<PluginModule> { public: - typedef const void* (*PPP_GetInterfaceFunc)(const char*); + typedef const void* (*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) { - } + // This structure is POD, with the constructor initializing to NULL. + EntryPoints(); - PPP_GetInterfaceFunc get_interface; + GetInterfaceFunc get_interface; PPP_InitializeModuleFunc initialize_module; - PPP_ShutdownModuleFunc shutdown_module; + PPP_ShutdownModuleFunc shutdown_module; // Optional, may be NULL. }; + // You must call one of the Init functions to create a module of the type + // you desire. + PluginModule(); + ~PluginModule(); - static scoped_refptr<PluginModule> CreateModule(const FilePath& path); - static scoped_refptr<PluginModule> CreateInternalModule( - 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); + // Initializes this module as an internal plugin with the given entrypoints. + // This is used for "plugins" compiled into Chrome. Returns true on success. + // False means that the plugin can not be used. + bool InitAsInternalPlugin(const EntryPoints& entry_points); + + // Initializes this module using the given library path as the plugin. + // Returns true on success. False means that the plugin can not be used. + bool InitAsLibrary(const FilePath& path); + + // Initializes this module for the given out of process proxy. This takes + // ownership of the given pointer, even in the failure case. + void InitAsProxied(PluginDelegate::OutOfProcessProxy* out_of_process_proxy); static const PPB_Core* GetCore(); + // Returns a pointer to the local GetInterface function for retrieving + // PPB interfaces. + static GetInterfaceFunc GetLocalGetInterfaceFunc(); + + // Returns the module handle. This may be used before Init() is called (the + // proxy needs this information to set itself up properly). PP_Module pp_module() const { return pp_module_; } void set_name(const std::string& name) { name_ = name; } @@ -94,6 +106,8 @@ class PluginModule : public base::RefCounted<PluginModule>, // but the delegate lives only on the plugin instance so we need one of them. PluginInstance* GetSomeInstance() const; + // Calls the plugin's GetInterface and returns the given interface pointer, + // which could be NULL. const void* GetPluginInterface(const char* name) const; // This module is associated with a set of instances. The PluginInstance @@ -119,24 +133,17 @@ class PluginModule : public base::RefCounted<PluginModule>, void RemovePluginObject(PluginObject* plugin_object); private: - 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, - EntryPoints* entry_points); - - // Dispatcher for out-of-process plugins. This will be null when the plugin - // is being run in-process. - scoped_ptr<pp::proxy::HostDispatcher> dispatcher_; + // Calls the InitializeModule entrypoint. The entrypoint must have been + // set and the plugin must not be out of process (we don't maintain + // entrypoints in that case). + bool InitializeModule(); PP_Module pp_module_; - bool initialized_; + // Manages the out of process proxy interface. The presence of this + // pointer indicates that the plugin is running out of process and that the + // entry_points_ aren't valid. + scoped_ptr<PluginDelegate::OutOfProcessProxy> out_of_process_proxy_; // Holds a reference to the base::NativeLibrary handle if this PluginModule // instance wraps functions loaded from a library. Can be NULL. If @@ -144,8 +151,9 @@ class PluginModule : public base::RefCounted<PluginModule>, // during destruction. base::NativeLibrary library_; - // Contains pointers to the entry points of the actual plugin - // implementation. These will be NULL for out-of-process plugins. + // Contains pointers to the entry points of the actual plugin implementation. + // These will be NULL for out-of-process plugins, which is indicated by the + // presence of the out_of_process_proxy_ value. EntryPoints entry_points_; // The name of the module. |