OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/glue/plugins/pepper_plugin_module.h" | 5 #include "webkit/glue/plugins/pepper_plugin_module.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 #include "webkit/glue/plugins/pepper_file_ref.h" | 37 #include "webkit/glue/plugins/pepper_file_ref.h" |
38 #include "webkit/glue/plugins/pepper_file_system.h" | 38 #include "webkit/glue/plugins/pepper_file_system.h" |
39 #include "webkit/glue/plugins/pepper_image_data.h" | 39 #include "webkit/glue/plugins/pepper_image_data.h" |
40 #include "webkit/glue/plugins/pepper_plugin_instance.h" | 40 #include "webkit/glue/plugins/pepper_plugin_instance.h" |
41 #include "webkit/glue/plugins/pepper_resource_tracker.h" | 41 #include "webkit/glue/plugins/pepper_resource_tracker.h" |
42 #include "webkit/glue/plugins/pepper_url_loader.h" | 42 #include "webkit/glue/plugins/pepper_url_loader.h" |
43 #include "webkit/glue/plugins/pepper_url_request_info.h" | 43 #include "webkit/glue/plugins/pepper_url_request_info.h" |
44 #include "webkit/glue/plugins/pepper_url_response_info.h" | 44 #include "webkit/glue/plugins/pepper_url_response_info.h" |
45 #include "webkit/glue/plugins/pepper_var.h" | 45 #include "webkit/glue/plugins/pepper_var.h" |
46 | 46 |
47 typedef bool (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface); | |
48 typedef void (*PPP_ShutdownModuleFunc)(); | |
49 | |
50 namespace pepper { | 47 namespace pepper { |
51 | 48 |
52 namespace { | 49 namespace { |
53 | 50 |
54 // Maintains all currently loaded plugin libs for validating PP_Module | 51 // Maintains all currently loaded plugin libs for validating PP_Module |
55 // identifiers. | 52 // identifiers. |
56 typedef std::set<PluginModule*> PluginModuleSet; | 53 typedef std::set<PluginModule*> PluginModuleSet; |
57 | 54 |
58 PluginModuleSet* GetLivePluginSet() { | 55 PluginModuleSet* GetLivePluginSet() { |
59 static PluginModuleSet live_plugin_libs; | 56 static PluginModuleSet live_plugin_libs; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 // in production code. | 177 // in production code. |
181 if (strcmp(name, PPB_TESTING_INTERFACE) == 0) { | 178 if (strcmp(name, PPB_TESTING_INTERFACE) == 0) { |
182 if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing")) | 179 if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing")) |
183 return &testing_interface; | 180 return &testing_interface; |
184 } | 181 } |
185 return NULL; | 182 return NULL; |
186 } | 183 } |
187 | 184 |
188 } // namespace | 185 } // namespace |
189 | 186 |
190 PluginModule::PluginModule(const FilePath& filename) | 187 PluginModule::PluginModule() |
191 : filename_(filename), | 188 : initialized_(false), |
192 initialized_(false), | 189 library_(NULL) { |
193 library_(0), | |
194 ppp_get_interface_(NULL) { | |
195 GetMainThreadMessageLoop(); // Initialize the main thread message loop. | 190 GetMainThreadMessageLoop(); // Initialize the main thread message loop. |
196 GetLivePluginSet()->insert(this); | 191 GetLivePluginSet()->insert(this); |
197 } | 192 } |
198 | 193 |
199 PluginModule::~PluginModule() { | 194 PluginModule::~PluginModule() { |
200 // When the module is being deleted, there should be no more instances still | 195 // When the module is being deleted, there should be no more instances still |
201 // holding a reference to us. | 196 // holding a reference to us. |
202 DCHECK(instances_.empty()); | 197 DCHECK(instances_.empty()); |
203 | 198 |
204 GetLivePluginSet()->erase(this); | 199 GetLivePluginSet()->erase(this); |
205 | 200 |
206 if (library_) { | 201 if (entry_points_.shutdown_module) |
207 PPP_ShutdownModuleFunc shutdown_module = | 202 entry_points_.shutdown_module(); |
208 reinterpret_cast<PPP_ShutdownModuleFunc>( | 203 |
209 base::GetFunctionPointerFromNativeLibrary(library_, | 204 if (library_) |
210 "PPP_ShutdownModule")); | |
211 if (shutdown_module) | |
212 shutdown_module(); | |
213 base::UnloadNativeLibrary(library_); | 205 base::UnloadNativeLibrary(library_); |
214 } | |
215 } | 206 } |
216 | 207 |
217 // static | 208 // static |
218 scoped_refptr<PluginModule> PluginModule::CreateModule( | 209 scoped_refptr<PluginModule> PluginModule::CreateModule( |
219 const FilePath& filename) { | 210 const FilePath& path) { |
220 // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one. | 211 // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one. |
221 | 212 |
222 scoped_refptr<PluginModule> lib(new PluginModule(filename)); | 213 scoped_refptr<PluginModule> lib(new PluginModule()); |
223 if (!lib->Load()) | 214 if (!lib->InitFromFile(path)) |
224 lib = NULL; | 215 return NULL; |
| 216 |
225 return lib; | 217 return lib; |
226 } | 218 } |
227 | 219 |
| 220 scoped_refptr<PluginModule> PluginModule::CreateInternalModule( |
| 221 EntryPoints entry_points) { |
| 222 scoped_refptr<PluginModule> lib(new PluginModule()); |
| 223 if (!lib->InitFromEntryPoints(entry_points)) |
| 224 return NULL; |
| 225 |
| 226 return lib; |
| 227 } |
| 228 |
228 // static | 229 // static |
229 PluginModule* PluginModule::FromPPModule(PP_Module module) { | 230 PluginModule* PluginModule::FromPPModule(PP_Module module) { |
230 PluginModule* lib = reinterpret_cast<PluginModule*>(module); | 231 PluginModule* lib = reinterpret_cast<PluginModule*>(module); |
231 if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end()) | 232 if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end()) |
232 return NULL; // Invalid plugin. | 233 return NULL; // Invalid plugin. |
233 return lib; | 234 return lib; |
234 } | 235 } |
235 | 236 |
236 bool PluginModule::Load() { | 237 bool PluginModule::InitFromEntryPoints(const EntryPoints& entry_points) { |
237 if (initialized_) | 238 if (initialized_) |
238 return true; | 239 return true; |
239 initialized_ = true; | |
240 | 240 |
241 library_ = base::LoadNativeLibrary(filename_); | 241 // Attempt to run the initialization funciton. |
242 if (!library_) | 242 int retval = entry_points.initialize_module(GetPPModule(), &GetInterface); |
243 return false; | |
244 | |
245 // Save the GetInterface function pointer for later. | |
246 ppp_get_interface_ = | |
247 reinterpret_cast<PPP_GetInterfaceFunc>( | |
248 base::GetFunctionPointerFromNativeLibrary(library_, | |
249 "PPP_GetInterface")); | |
250 if (!ppp_get_interface_) { | |
251 LOG(WARNING) << "No PPP_GetInterface in plugin library"; | |
252 return false; | |
253 } | |
254 | |
255 // Call the plugin initialize function. | |
256 PPP_InitializeModuleFunc initialize_module = | |
257 reinterpret_cast<PPP_InitializeModuleFunc>( | |
258 base::GetFunctionPointerFromNativeLibrary(library_, | |
259 "PPP_InitializeModule")); | |
260 if (!initialize_module) { | |
261 LOG(WARNING) << "No PPP_InitializeModule in plugin library"; | |
262 return false; | |
263 } | |
264 int retval = initialize_module(GetPPModule(), &GetInterface); | |
265 if (retval != 0) { | 243 if (retval != 0) { |
266 LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; | 244 LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; |
267 return false; | 245 return false; |
268 } | 246 } |
269 | 247 |
| 248 entry_points_ = entry_points; |
| 249 initialized_ = true; |
270 return true; | 250 return true; |
271 } | 251 } |
| 252 |
| 253 bool PluginModule::InitFromFile(const FilePath& path) { |
| 254 if (initialized_) |
| 255 return true; |
| 256 |
| 257 base::NativeLibrary library = base::LoadNativeLibrary(path); |
| 258 if (!library) |
| 259 return false; |
| 260 |
| 261 EntryPoints entry_points; |
| 262 if (!LoadEntryPoints(library, &entry_points) || |
| 263 !InitFromEntryPoints(entry_points)) { |
| 264 base::UnloadNativeLibrary(library); |
| 265 return false; |
| 266 } |
| 267 |
| 268 // We let InitFromEntryPoints() handle setting the all the internal state |
| 269 // of the object other than the |library_| reference. |
| 270 library_ = library; |
| 271 return true; |
| 272 } |
| 273 |
| 274 // static |
| 275 bool PluginModule::LoadEntryPoints(const base::NativeLibrary& library, |
| 276 EntryPoints* entry_points) { |
| 277 |
| 278 entry_points->get_interface = |
| 279 reinterpret_cast<PPP_GetInterfaceFunc>( |
| 280 base::GetFunctionPointerFromNativeLibrary(library, |
| 281 "PPP_GetInterface")); |
| 282 if (!entry_points->get_interface) { |
| 283 LOG(WARNING) << "No PPP_GetInterface in plugin library"; |
| 284 return false; |
| 285 } |
| 286 |
| 287 entry_points->initialize_module = |
| 288 reinterpret_cast<PPP_InitializeModuleFunc>( |
| 289 base::GetFunctionPointerFromNativeLibrary(library, |
| 290 "PPP_InitializeModule")); |
| 291 if (!entry_points->initialize_module) { |
| 292 LOG(WARNING) << "No PPP_InitializeModule in plugin library"; |
| 293 return false; |
| 294 } |
| 295 |
| 296 // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to |
| 297 // be NULL. |
| 298 entry_points->shutdown_module = |
| 299 reinterpret_cast<PPP_ShutdownModuleFunc>( |
| 300 base::GetFunctionPointerFromNativeLibrary(library, |
| 301 "PPP_ShutdownModule")); |
| 302 |
| 303 return true; |
| 304 } |
272 | 305 |
273 PP_Module PluginModule::GetPPModule() const { | 306 PP_Module PluginModule::GetPPModule() const { |
274 return reinterpret_cast<intptr_t>(this); | 307 return reinterpret_cast<intptr_t>(this); |
275 } | 308 } |
276 | 309 |
277 PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { | 310 PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { |
278 const PPP_Instance* plugin_instance_interface = | 311 const PPP_Instance* plugin_instance_interface = |
279 reinterpret_cast<const PPP_Instance*>(GetPluginInterface( | 312 reinterpret_cast<const PPP_Instance*>(GetPluginInterface( |
280 PPP_INSTANCE_INTERFACE)); | 313 PPP_INSTANCE_INTERFACE)); |
281 if (!plugin_instance_interface) { | 314 if (!plugin_instance_interface) { |
282 LOG(WARNING) << "Plugin doesn't support instance interface, failing."; | 315 LOG(WARNING) << "Plugin doesn't support instance interface, failing."; |
283 return NULL; | 316 return NULL; |
284 } | 317 } |
285 return new PluginInstance(delegate, this, plugin_instance_interface); | 318 return new PluginInstance(delegate, this, plugin_instance_interface); |
286 } | 319 } |
287 | 320 |
288 PluginInstance* PluginModule::GetSomeInstance() const { | 321 PluginInstance* PluginModule::GetSomeInstance() const { |
289 // This will generally crash later if there is not actually any instance to | 322 // This will generally crash later if there is not actually any instance to |
290 // return, so we force a crash now to make bugs easier to track down. | 323 // return, so we force a crash now to make bugs easier to track down. |
291 CHECK(!instances_.empty()); | 324 CHECK(!instances_.empty()); |
292 return *instances_.begin(); | 325 return *instances_.begin(); |
293 } | 326 } |
294 | 327 |
295 const void* PluginModule::GetPluginInterface(const char* name) const { | 328 const void* PluginModule::GetPluginInterface(const char* name) const { |
296 if (!ppp_get_interface_) | 329 if (!entry_points_.get_interface) |
297 return NULL; | 330 return NULL; |
298 return ppp_get_interface_(name); | 331 return entry_points_.get_interface(name); |
299 } | 332 } |
300 | 333 |
301 void PluginModule::InstanceCreated(PluginInstance* instance) { | 334 void PluginModule::InstanceCreated(PluginInstance* instance) { |
302 instances_.insert(instance); | 335 instances_.insert(instance); |
303 } | 336 } |
304 | 337 |
305 void PluginModule::InstanceDeleted(PluginInstance* instance) { | 338 void PluginModule::InstanceDeleted(PluginInstance* instance) { |
306 instances_.erase(instance); | 339 instances_.erase(instance); |
307 } | 340 } |
308 | 341 |
309 } // namespace pepper | 342 } // namespace pepper |
OLD | NEW |