plugin_module.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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
27typedef void* NPIdentifier;
28
29class GURL;
30
31namespace base {
32class FilePath;
33}
34
35namespace ppapi {
36class CallbackTracker;
37class WebKitForwarding;
38}  // namespace ppapi
39
40namespace IPC {
41struct ChannelHandle;
42}
43
44namespace blink {
45class WebPluginContainer;
46}  // namespace blink
47
48namespace content {
49class HostDispatcherWrapper;
50class PepperPluginInstanceImpl;
51class PepperBroker;
52class RendererPpapiHostImpl;
53class RenderFrameImpl;
54struct 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.
61class 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
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 base::FilePath& path() const { return path_; }
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
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(
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