| 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 |