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