Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CONTENT_RENDERER_PEPPER_PLUGIN_MODULE_H_
      6 #define CONTENT_RENDERER_PEPPER_PLUGIN_MODULE_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/files/file_path.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/native_library.h"
     18 #include "base/process/process.h"
     19 #include "content/common/content_export.h"
     20 #include "content/public/common/pepper_plugin_info.h"
     21 #include "ppapi/c/pp_bool.h"
     22 #include "ppapi/c/pp_instance.h"
     23 #include "ppapi/c/ppb_core.h"
     24 #include "ppapi/c/private/ppb_instance_private.h"
     25 #include "ppapi/shared_impl/ppapi_permissions.h"
     26 
     27 typedef void* NPIdentifier;
     28 
     29 class GURL;
     30 
     31 namespace base {
     32 class FilePath;
     33 }
     34 
     35 namespace ppapi {
     36 class CallbackTracker;
     37 class WebKitForwarding;
     38 }  // namespace ppapi
     39 
     40 namespace IPC {
     41 struct ChannelHandle;
     42 }
     43 
     44 namespace blink {
     45 class WebPluginContainer;
     46 }  // namespace blink
     47 
     48 namespace content {
     49 class HostDispatcherWrapper;
     50 class PepperPluginInstanceImpl;
     51 class PepperBroker;
     52 class RendererPpapiHostImpl;
     53 class RenderFrameImpl;
     54 struct WebPluginInfo;
     55 
     56 // Represents one plugin library loaded into one renderer. This library may
     57 // have multiple instances.
     58 //
     59 // Note: to get from a PP_Instance to a PepperPluginInstance*, use the
     60 // ResourceTracker.
     61 class CONTENT_EXPORT PluginModule : public base::RefCounted<PluginModule>,
     62                                     public base::SupportsWeakPtr<PluginModule> {
     63  public:
     64   typedef std::set<PepperPluginInstanceImpl*> PluginInstanceSet;
     65 
     66   // You must call one of the Init functions after the constructor to create a
     67   // module of the type you desire.
     68   //
     69   // The module lifetime delegate is a non-owning pointer that must outlive
     70   // all plugin modules. In practice it will be a global singleton that
     71   // tracks which modules are alive.
     72   PluginModule(const std::string& name,
     73                const std::string& version,
     74                const base::FilePath& path,
     75                const ppapi::PpapiPermissions& perms);
     76 
     77   // Sets the given class as being associated with this module. It will be
     78   // deleted when the module is destroyed. You can only set it once, subsequent
     79   // sets will assert.
     80   void SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl> host);
     81 
     82   // Initializes this module as an internal plugin with the given entrypoints.
     83   // This is used for "plugins" compiled into Chrome. Returns true on success.
     84   // False means that the plugin can not be used.
     85   bool InitAsInternalPlugin(const PepperPluginInfo::EntryPoints& entry_points);
     86 
     87   // Initializes this module using the given library path as the plugin.
     88   // Returns true on success. False means that the plugin can not be used.
     89   bool InitAsLibrary(const base::FilePath& path);
     90 
     91   // Initializes this module for the given out of process proxy. This takes
     92   // ownership of the given pointer, even in the failure case.
     93   void InitAsProxied(HostDispatcherWrapper* host_dispatcher_wrapper);
     94 
     95   // Creates a new module for an external plugin instance that will be using the
     96   // IPC proxy. We can't use the existing module, or new instances of the plugin
     97   // can't be created.
     98   scoped_refptr<PluginModule> CreateModuleForExternalPluginInstance();
     99 
    100   // Initializes the external plugin module for the out of process proxy.
    101   // InitAsProxied must be called before calling InitAsProxiedExternalPlugin.
    102   // Returns a result code indicating whether the proxy started successfully or
    103   // there was an error.
    104   PP_ExternalPluginResult InitAsProxiedExternalPlugin(
    105       PepperPluginInstanceImpl* instance);
    106 
    107   bool IsProxied() const;
    108 
    109   // Returns the peer process ID if the plugin is running out of process;
    110   // returns |base::kNullProcessId| otherwise.
    111   base::ProcessId GetPeerProcessId();
    112 
    113   // Returns the plugin child process ID if the plugin is running out of
    114   // process. Returns 0 otherwise. This is the ID that the browser process uses
    115   // to idetify the child process for the plugin. This isn't directly useful
    116   // from our process (the renderer) except in messages to the browser to
    117   // disambiguate plugins.
    118   int GetPluginChildId();
    119 
    120   static const PPB_Core* GetCore();
    121 
    122   // Returns whether an interface is supported. This method can be called from
    123   // the browser process and used for interface matching before plugin
    124   // registration.
    125   // NOTE: those custom interfaces provided by ContentRendererClient will not be
    126   // considered when called on the browser process.
    127   static bool SupportsInterface(const char* name);
    128 
    129   RendererPpapiHostImpl* renderer_ppapi_host() {
    130     return renderer_ppapi_host_.get();
    131   }
    132 
    133   // Returns the module handle. This may be used before Init() is called (the
    134   // proxy needs this information to set itself up properly).
    135   PP_Module pp_module() const { return pp_module_; }
    136 
    137   const std::string& name() const { return name_; }
    138   const std::string& version() const { return version_; }
    139   const base::FilePath& path() const { return path_; }
    140   const ppapi::PpapiPermissions& permissions() const { return permissions_; }
    141 
    142   PepperPluginInstanceImpl* CreateInstance(RenderFrameImpl* render_frame,
    143                                            blink::WebPluginContainer* container,
    144                                            const GURL& plugin_url);
    145 
    146   // Returns "some" plugin instance associated with this module. This is not
    147   // guaranteed to be any one in particular. This is normally used to execute
    148   // callbacks up to the browser layer that are not inherently per-instance,
    149   // but the helper lives only on the plugin instance so we need one of them.
    150   PepperPluginInstanceImpl* GetSomeInstance() const;
    151 
    152   const PluginInstanceSet& GetAllInstances() const { return instances_; }
    153 
    154   // Calls the plugin's GetInterface and returns the given interface pointer,
    155   // which could be NULL.
    156   const void* GetPluginInterface(const char* name) const;
    157 
    158   // This module is associated with a set of instances. The PluginInstance
    159   // object declares its association with this module in its destructor and
    160   // releases us in its destructor.
    161   void InstanceCreated(PepperPluginInstanceImpl* instance);
    162   void InstanceDeleted(PepperPluginInstanceImpl* instance);
    163 
    164   scoped_refptr<ppapi::CallbackTracker> GetCallbackTracker();
    165 
    166   // Called when running out of process and the plugin crashed. This will
    167   // release relevant resources and update all affected instances.
    168   void PluginCrashed();
    169 
    170   bool is_in_destructor() const { return is_in_destructor_; }
    171   bool is_crashed() const { return is_crashed_; }
    172 
    173   // Reserves the given instance is unique within the plugin, checking for
    174   // collisions. See PPB_Proxy_Private for more information.
    175   //
    176   // The setter will set the callback which is set up when the proxy
    177   // initializes. The Reserve function will call the previously set callback if
    178   // it exists to validate the ID. If the callback has not been set (such as
    179   // for in-process plugins), the Reserve function will assume that the ID is
    180   // usable and will return true.
    181   void SetReserveInstanceIDCallback(PP_Bool (*reserve)(PP_Module, PP_Instance));
    182   bool ReserveInstanceID(PP_Instance instance);
    183 
    184   // These should only be called from the main thread.
    185   void SetBroker(PepperBroker* broker);
    186   PepperBroker* GetBroker();
    187 
    188   // Create a new HostDispatcher for proxying, hook it to the PluginModule,
    189   // and perform other common initialization.
    190   RendererPpapiHostImpl* CreateOutOfProcessModule(
    191       RenderFrameImpl* render_frame,
    192       const base::FilePath& path,
    193       ppapi::PpapiPermissions permissions,
    194       const IPC::ChannelHandle& channel_handle,
    195       base::ProcessId plugin_pid,
    196       int plugin_child_id,
    197       bool is_external);
    198 
    199   // In production we purposely leak the HostGlobals object but in unittest
    200   // code, this can interfere with subsequent tests. This deletes the
    201   // existing HostGlobals. A new one will be constructed when a PluginModule is
    202   // instantiated.
    203   static void ResetHostGlobalsForTest();
    204 
    205   // Attempts to create a PPAPI plugin for the given filepath. On success, it
    206   // will return the newly-created module.
    207   //
    208   // There are two reasons for failure. The first is that the plugin isn't
    209   // a PPAPI plugin. In this case, |*pepper_plugin_was_registered| will be set
    210   // to false and the caller may want to fall back on creating an NPAPI plugin.
    211   // the second is that the plugin failed to initialize. In this case,
    212   // |*pepper_plugin_was_registered| will be set to true and the caller should
    213   // not fall back on any other plugin types.
    214   static scoped_refptr<PluginModule> Create(RenderFrameImpl* render_frame,
    215                                             const WebPluginInfo& webplugin_info,
    216                                             bool* pepper_plugin_was_registered);
    217 
    218  private:
    219   friend class base::RefCounted<PluginModule>;
    220   ~PluginModule();
    221   // Calls the InitializeModule entrypoint. The entrypoint must have been
    222   // set and the plugin must not be out of process (we don't maintain
    223   // entrypoints in that case).
    224   bool InitializeModule(const PepperPluginInfo::EntryPoints& entry_points);
    225 
    226   scoped_ptr<RendererPpapiHostImpl> renderer_ppapi_host_;
    227 
    228   // Tracker for completion callbacks, used mainly to ensure that all callbacks
    229   // are properly aborted on module shutdown.
    230   scoped_refptr<ppapi::CallbackTracker> callback_tracker_;
    231 
    232   PP_Module pp_module_;
    233 
    234   // True when we're running in the destructor. This allows us to write some
    235   // assertions.
    236   bool is_in_destructor_;
    237 
    238   // True if the plugin is running out-of-process and has crashed.
    239   bool is_crashed_;
    240 
    241   // Manages the out of process proxy interface. The presence of this
    242   // pointer indicates that the plugin is running out of process and that the
    243   // entry_points_ aren't valid.
    244   scoped_ptr<HostDispatcherWrapper> host_dispatcher_wrapper_;
    245 
    246   // Non-owning pointer to the broker for this plugin module, if one exists.
    247   // It is populated and cleared in the main thread.
    248   PepperBroker* broker_;
    249 
    250   // Holds a reference to the base::NativeLibrary handle if this PluginModule
    251   // instance wraps functions loaded from a library.  Can be NULL.  If
    252   // |library_| is non-NULL, PluginModule will attempt to unload the library
    253   // during destruction.
    254   base::NativeLibrary library_;
    255 
    256   // Contains pointers to the entry points of the actual plugin implementation.
    257   // These will be NULL for out-of-process plugins, which is indicated by the
    258   // presence of the host_dispatcher_wrapper_ value.
    259   PepperPluginInfo::EntryPoints entry_points_;
    260 
    261   // The name, version, and file location of the module.
    262   const std::string name_;
    263   const std::string version_;
    264   const base::FilePath path_;
    265 
    266   ppapi::PpapiPermissions permissions_;
    267 
    268   // Non-owning pointers to all instances associated with this module. When
    269   // there are no more instances, this object should be deleted.
    270   PluginInstanceSet instances_;
    271 
    272   PP_Bool (*reserve_instance_id_)(PP_Module, PP_Instance);
    273 
    274   DISALLOW_COPY_AND_ASSIGN(PluginModule);
    275 };
    276 
    277 }  // namespace content
    278 
    279 #endif  // CONTENT_RENDERER_PEPPER_PLUGIN_MODULE_H_
    280