diff options
-rw-r--r-- | chrome/chrome_browser.gypi | 1 | ||||
-rw-r--r-- | chrome/chrome_renderer.gypi | 1 | ||||
-rw-r--r-- | chrome/common/pepper_plugin_registry.cc | 9 | ||||
-rw-r--r-- | chrome/renderer/DEPS | 1 | ||||
-rw-r--r-- | chrome/renderer/pepper_plugin_delegate_impl.cc | 88 | ||||
-rw-r--r-- | chrome/renderer/pepper_plugin_delegate_impl.h | 3 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 25 | ||||
-rw-r--r-- | ppapi/proxy/host_dispatcher.cc | 12 | ||||
-rw-r--r-- | ppapi/proxy/host_dispatcher.h | 5 | ||||
-rw-r--r-- | ppapi/shared_impl/DEPS | 5 | ||||
-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 | ||||
-rw-r--r-- | webkit/glue/webkit_glue.gypi | 1 |
15 files changed, 263 insertions, 205 deletions
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 4c529b3a..b53706a 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -27,6 +27,7 @@ '../app/app.gyp:app_resources', '../app/app.gyp:app_strings', '../media/media.gyp:media', + '../ppapi/ppapi.gyp:ppapi_proxy', # For PpapiMsg_LoadPlugin '../printing/printing.gyp:printing', '../skia/skia.gyp:skia', '../third_party/bzip2/bzip2.gyp:bzip2', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 8a6f73c..87889aa 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -15,6 +15,7 @@ 'chrome_resources', 'chrome_strings', 'safe_browsing_proto', + '../ppapi/ppapi.gyp:ppapi_proxy', '../printing/printing.gyp:printing', '../skia/skia.gyp:skia', '../third_party/hunspell/hunspell.gyp:hunspell', diff --git a/chrome/common/pepper_plugin_registry.cc b/chrome/common/pepper_plugin_registry.cc index 60668f2..a9d979f 100644 --- a/chrome/common/pepper_plugin_registry.cc +++ b/chrome/common/pepper_plugin_registry.cc @@ -211,9 +211,8 @@ PepperPluginRegistry::PepperPluginRegistry() { it != internal_plugin_info.end(); ++it) { const FilePath& path = it->path; - ModuleHandle module = - pepper::PluginModule::CreateInternalModule(it->entry_points); - if (!module) { + ModuleHandle module(new pepper::PluginModule); + if (!module->InitAsInternalPlugin(it->entry_points)) { DLOG(ERROR) << "Failed to load pepper module: " << path.value(); continue; } @@ -231,8 +230,8 @@ PepperPluginRegistry::PepperPluginRegistry() { continue; // Only preload in-process plugins. const FilePath& path = plugins[i].path; - ModuleHandle module = pepper::PluginModule::CreateModule(path); - if (!module) { + ModuleHandle module(new pepper::PluginModule); + if (!module->InitAsLibrary(path)) { DLOG(ERROR) << "Failed to load pepper module: " << path.value(); continue; } diff --git a/chrome/renderer/DEPS b/chrome/renderer/DEPS index 02bb449..9b488d4 100644 --- a/chrome/renderer/DEPS +++ b/chrome/renderer/DEPS @@ -8,6 +8,7 @@ include_rules = [ "+media/filters", "+media/video", "+ppapi/c", + "+ppapi/proxy", "+sandbox/src", "+skia", "+webkit/extensions", diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index c3a85d9..a949ffb8 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <cmath> - #include "chrome/renderer/pepper_plugin_delegate_impl.h" +#include <cmath> + #include "app/l10n_util.h" #include "app/surface/transport_dib.h" #include "base/callback.h" @@ -18,6 +18,7 @@ #include "base/utf_string_conversions.h" #include "chrome/common/child_thread.h" #include "chrome/common/file_system/file_system_dispatcher.h" +#include "chrome/common/pepper_plugin_registry.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" #include "chrome/renderer/audio_message_filter.h" @@ -32,6 +33,7 @@ #include "grit/locale_settings.h" #include "ipc/ipc_channel_handle.h" #include "ppapi/c/dev/pp_video_dev.h" +#include "ppapi/proxy/host_dispatcher.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" @@ -47,6 +49,10 @@ #include "chrome/renderer/render_thread.h" #endif +#if defined(OS_POSIX) +#include "ipc/ipc_channel_posix.h" +#endif + using WebKit::WebView; namespace { @@ -413,6 +419,60 @@ class PlatformVideoDecoderImpl DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl); }; +class DispatcherWrapper : public pepper::PluginDelegate::OutOfProcessProxy { + public: + DispatcherWrapper() {} + virtual ~DispatcherWrapper() {} + + bool Init(base::ProcessHandle plugin_process_handle, + IPC::ChannelHandle channel_handle, + PP_Module pp_module, + pp::proxy::Dispatcher::GetInterfaceFunc local_get_interface); + + // OutOfProcessProxy implementation. + virtual const void* GetProxiedInterface(const char* name) { + return dispatcher_->GetProxiedInterface(name); + } + virtual void AddInstance(PP_Instance instance) { + pp::proxy::HostDispatcher::SetForInstance(instance, dispatcher_.get()); + } + virtual void RemoveInstance(PP_Instance instance) { + pp::proxy::HostDispatcher::RemoveForInstance(instance); + } + + private: + scoped_ptr<pp::proxy::HostDispatcher> dispatcher_; +}; + +bool DispatcherWrapper::Init( + base::ProcessHandle plugin_process_handle, + IPC::ChannelHandle channel_handle, + PP_Module pp_module, + pp::proxy::Dispatcher::GetInterfaceFunc local_get_interface) { + dispatcher_.reset(new pp::proxy::HostDispatcher( + plugin_process_handle, pp_module, local_get_interface)); + +#if defined(OS_POSIX) + // If we received a ChannelHandle, register it now. + if (channel_handle.socket.fd >= 0) + IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); +#endif + + if (!dispatcher_->InitWithChannel( + ChildProcess::current()->io_message_loop(), channel_handle.name, + true, ChildProcess::current()->GetShutDownEvent())) { + dispatcher_.reset(); + return false; + } + + if (!dispatcher_->InitializeModule()) { + // TODO(brettw) does the module get unloaded in this case? + dispatcher_.reset(); + return false; + } + return true; +} + } // namespace PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderView* render_view) @@ -424,19 +484,29 @@ PepperPluginDelegateImpl::~PepperPluginDelegateImpl() { } scoped_refptr<pepper::PluginModule> -PepperPluginDelegateImpl::CreateOutOfProcessPepperPlugin( - const FilePath& path) { +PepperPluginDelegateImpl::CreatePepperPlugin(const FilePath& path) { + // Easy case is in-process plugins. + if (!PepperPluginRegistry::GetInstance()->RunOutOfProcessForPlugin(path)) + return PepperPluginRegistry::GetInstance()->GetModule(path); + + // Out of process: have the browser start the plugin process for us. base::ProcessHandle plugin_process_handle = NULL; IPC::ChannelHandle channel_handle; render_view_->Send(new ViewHostMsg_OpenChannelToPepperPlugin( path, &plugin_process_handle, &channel_handle)); if (channel_handle.name.empty()) return scoped_refptr<pepper::PluginModule>(); // Couldn't be initialized. - return pepper::PluginModule::CreateOutOfProcessModule( - ChildProcess::current()->io_message_loop(), - plugin_process_handle, - channel_handle, - ChildProcess::current()->GetShutDownEvent()); + + // Create a new HostDispatcher for the proxying, and hook it to a new + // PluginModule. + scoped_refptr<pepper::PluginModule> module(new pepper::PluginModule); + scoped_ptr<DispatcherWrapper> dispatcher(new DispatcherWrapper); + if (!dispatcher->Init(plugin_process_handle, channel_handle, + module->pp_module(), + pepper::PluginModule::GetLocalGetInterfaceFunc())) + return scoped_refptr<pepper::PluginModule>(); + module->InitAsProxied(dispatcher.release()); + return module; } void PepperPluginDelegateImpl::ViewInitiatedPaint() { diff --git a/chrome/renderer/pepper_plugin_delegate_impl.h b/chrome/renderer/pepper_plugin_delegate_impl.h index 9402ae2..d59be3b 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.h +++ b/chrome/renderer/pepper_plugin_delegate_impl.h @@ -44,8 +44,7 @@ class PepperPluginDelegateImpl explicit PepperPluginDelegateImpl(RenderView* render_view); virtual ~PepperPluginDelegateImpl(); - scoped_refptr<pepper::PluginModule> CreateOutOfProcessPepperPlugin( - const FilePath& path); + scoped_refptr<pepper::PluginModule> CreatePepperPlugin(const FilePath& path); // Called by RenderView to tell us about painting events, these two functions // just correspond to the DidInitiatePaint and DidFlushPaint in R.V.. diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index f62a2e9..74f84e1c 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -834,12 +834,12 @@ WebPlugin* RenderView::CreatePluginNoCheck(WebFrame* frame, &info, &setting, &mime_type)); if (!found || !info.enabled) return NULL; + scoped_refptr<pepper::PluginModule> pepper_module( - PepperPluginRegistry::GetInstance()->GetModule(info.path)); + pepper_delegate_.CreatePepperPlugin(info.path)); if (pepper_module) return CreatePepperPlugin(frame, params, info.path, pepper_module.get()); - else - return CreateNPAPIPlugin(frame, params, info.path, mime_type); + return CreateNPAPIPlugin(frame, params, info.path, mime_type); } void RenderView::RegisterPluginDelegate(WebPluginDelegateProxy* delegate) { @@ -2753,21 +2753,10 @@ WebPlugin* RenderView::createPlugin(WebFrame* frame, if (info.path.value() == kDefaultPluginLibraryName || plugin_setting == CONTENT_SETTING_ALLOW || host_setting == CONTENT_SETTING_ALLOW) { - scoped_refptr<pepper::PluginModule> pepper_module; - if (PepperPluginRegistry::GetInstance()->RunOutOfProcessForPlugin( - info.path)) { - pepper_module = - pepper_delegate_.CreateOutOfProcessPepperPlugin(info.path); - } else { - pepper_module = - PepperPluginRegistry::GetInstance()->GetModule(info.path); - } - if (pepper_module) { - return CreatePepperPlugin(frame, - params, - info.path, - pepper_module.get()); - } + scoped_refptr<pepper::PluginModule> pepper_module( + pepper_delegate_.CreatePepperPlugin(info.path)); + if (pepper_module) + return CreatePepperPlugin(frame, params, info.path, pepper_module.get()); return CreateNPAPIPlugin(frame, params, info.path, actual_mime_type); } std::string resource; diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index fd9801c..6e7a1f4 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc @@ -7,6 +7,7 @@ #include <map> #include "base/logging.h" +#include "ppapi/c/dev/ppb_var_deprecated.h" #include "ppapi/proxy/host_var_serialization_rules.h" #include "ppapi/proxy/ppapi_messages.h" @@ -21,10 +22,13 @@ InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; } // namespace HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, - const PPB_Var_Deprecated* var_interface, PP_Module module, GetInterfaceFunc local_get_interface) : Dispatcher(remote_process_handle, local_get_interface) { + set_pp_module(module); + const PPB_Var_Deprecated* var_interface = + static_cast<const PPB_Var_Deprecated*>( + local_get_interface(PPB_VAR_DEPRECATED_INTERFACE)); SetSerializationRules(new HostVarSerializationRules(var_interface, module)); } @@ -33,6 +37,12 @@ HostDispatcher::~HostDispatcher() { Send(new PpapiMsg_Shutdown()); } +bool HostDispatcher::InitializeModule() { + bool init_result = false; + Send(new PpapiMsg_InitializeModule(pp_module(), &init_result)); + return init_result; +} + // static HostDispatcher* HostDispatcher::GetForInstance(PP_Instance instance) { if (!g_instance_to_dispatcher) diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h index f968652..f5b91b4 100644 --- a/ppapi/proxy/host_dispatcher.h +++ b/ppapi/proxy/host_dispatcher.h @@ -38,11 +38,14 @@ class HostDispatcher : public Dispatcher { // // You must call Dispatcher::InitWithChannel after the constructor. HostDispatcher(base::ProcessHandle host_process_handle, - const PPB_Var_Deprecated* var_interface, PP_Module module, GetInterfaceFunc local_get_interface); ~HostDispatcher(); + // Calls the plugin's PPP_InitializeModule function and returns true if + // the call succeeded. + bool InitializeModule(); + // The host side maintains a mapping from PP_Instance to Dispatcher so // that we can send the messages to the right channel. static HostDispatcher* GetForInstance(PP_Instance instance); diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS index 84fea55..578728a 100644 --- a/ppapi/shared_impl/DEPS +++ b/ppapi/shared_impl/DEPS @@ -1,4 +1,9 @@ include_rules = [ "+base", + + # Since this is used by the implementation in /webkit, we don't want it to + # depend on IPC. + "-ipc", + "-ppapi/cpp", ] 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. diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 0f9816d..83aeb2e 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -147,7 +147,6 @@ '<(DEPTH)/base/base.gyp:base_i18n', '<(DEPTH)/gpu/gpu.gyp:gles2_implementation', '<(DEPTH)/net/net.gyp:net', - '<(DEPTH)/ppapi/ppapi.gyp:ppapi_proxy', '<(DEPTH)/ppapi/ppapi.gyp:ppapi_shared_impl', '<(DEPTH)/printing/printing.gyp:printing', '<(DEPTH)/skia/skia.gyp:skia', |