• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 :
62     public base::RefCounted<PluginModule>,
63     public base::SupportsWeakPtr<PluginModule> {
64  public:
65   typedef std::set<PepperPluginInstanceImpl*> PluginInstanceSet;
66 
67   // You must call one of the Init functions after the constructor to create a
68   // module of the type you desire.
69   //
70   // The module lifetime delegate is a non-owning pointer that must outlive
71   // all plugin modules. In practice it will be a global singleton that
72   // tracks which modules are alive.
73   PluginModule(const std::string& name,
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 
renderer_ppapi_host()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).
pp_module()135   PP_Module pp_module() const { return pp_module_; }
136 
name()137   const std::string& name() const { return name_; }
path()138   const base::FilePath& path() const { return path_; }
permissions()139   const ppapi::PpapiPermissions& permissions() const { return permissions_; }
140 
141   PepperPluginInstanceImpl* CreateInstance(
142       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 
GetAllInstances()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 
is_in_destructor()170   bool is_in_destructor() const { return is_in_destructor_; }
is_crashed()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(
182       PP_Bool (*reserve)(PP_Module, PP_Instance));
183   bool ReserveInstanceID(PP_Instance instance);
184 
185   // These should only be called from the main thread.
186   void SetBroker(PepperBroker* broker);
187   PepperBroker* GetBroker();
188 
189   // Create a new HostDispatcher for proxying, hook it to the PluginModule,
190   // and perform other common initialization.
191   RendererPpapiHostImpl* CreateOutOfProcessModule(
192       RenderFrameImpl* render_frame,
193       const base::FilePath& path,
194       ppapi::PpapiPermissions permissions,
195       const IPC::ChannelHandle& channel_handle,
196       base::ProcessId plugin_pid,
197       int plugin_child_id,
198       bool is_external);
199 
200   // In production we purposely leak the HostGlobals object but in unittest
201   // code, this can interfere with subsequent tests. This deletes the
202   // existing HostGlobals. A new one will be constructed when a PluginModule is
203   // instantiated.
204   static void ResetHostGlobalsForTest();
205 
206   // Attempts to create a PPAPI plugin for the given filepath. On success, it
207   // will return the newly-created module.
208   //
209   // There are two reasons for failure. The first is that the plugin isn't
210   // a PPAPI plugin. In this case, |*pepper_plugin_was_registered| will be set
211   // to false and the caller may want to fall back on creating an NPAPI plugin.
212   // the second is that the plugin failed to initialize. In this case,
213   // |*pepper_plugin_was_registered| will be set to true and the caller should
214   // not fall back on any other plugin types.
215   static scoped_refptr<PluginModule> Create(RenderFrameImpl* render_frame,
216                                             const WebPluginInfo& webplugin_info,
217                                             bool* pepper_plugin_was_registered);
218 
219  private:
220   friend class base::RefCounted<PluginModule>;
221   ~PluginModule();
222   // Calls the InitializeModule entrypoint. The entrypoint must have been
223   // set and the plugin must not be out of process (we don't maintain
224   // entrypoints in that case).
225   bool InitializeModule(const PepperPluginInfo::EntryPoints& entry_points);
226 
227   scoped_ptr<RendererPpapiHostImpl> renderer_ppapi_host_;
228 
229   // Tracker for completion callbacks, used mainly to ensure that all callbacks
230   // are properly aborted on module shutdown.
231   scoped_refptr<ppapi::CallbackTracker> callback_tracker_;
232 
233   PP_Module pp_module_;
234 
235   // True when we're running in the destructor. This allows us to write some
236   // assertions.
237   bool is_in_destructor_;
238 
239   // True if the plugin is running out-of-process and has crashed.
240   bool is_crashed_;
241 
242   // Manages the out of process proxy interface. The presence of this
243   // pointer indicates that the plugin is running out of process and that the
244   // entry_points_ aren't valid.
245   scoped_ptr<HostDispatcherWrapper> host_dispatcher_wrapper_;
246 
247   // Non-owning pointer to the broker for this plugin module, if one exists.
248   // It is populated and cleared in the main thread.
249   PepperBroker* broker_;
250 
251   // Holds a reference to the base::NativeLibrary handle if this PluginModule
252   // instance wraps functions loaded from a library.  Can be NULL.  If
253   // |library_| is non-NULL, PluginModule will attempt to unload the library
254   // during destruction.
255   base::NativeLibrary library_;
256 
257   // Contains pointers to the entry points of the actual plugin implementation.
258   // These will be NULL for out-of-process plugins, which is indicated by the
259   // presence of the host_dispatcher_wrapper_ value.
260   PepperPluginInfo::EntryPoints entry_points_;
261 
262   // The name and file location of the module.
263   const std::string name_;
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