| 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 13 matching lines...) Expand all Loading... |
| 24 #include "third_party/ppapi/c/pp_module.h" | 24 #include "third_party/ppapi/c/pp_module.h" |
| 25 #include "third_party/ppapi/c/pp_resource.h" | 25 #include "third_party/ppapi/c/pp_resource.h" |
| 26 #include "third_party/ppapi/c/pp_var.h" | 26 #include "third_party/ppapi/c/pp_var.h" |
| 27 #include "webkit/glue/plugins/pepper_buffer.h" | 27 #include "webkit/glue/plugins/pepper_buffer.h" |
| 28 #include "webkit/glue/plugins/pepper_device_context_2d.h" | 28 #include "webkit/glue/plugins/pepper_device_context_2d.h" |
| 29 #include "webkit/glue/plugins/pepper_image_data.h" | 29 #include "webkit/glue/plugins/pepper_image_data.h" |
| 30 #include "webkit/glue/plugins/pepper_plugin_instance.h" | 30 #include "webkit/glue/plugins/pepper_plugin_instance.h" |
| 31 #include "webkit/glue/plugins/pepper_resource_tracker.h" | 31 #include "webkit/glue/plugins/pepper_resource_tracker.h" |
| 32 #include "webkit/glue/plugins/pepper_var.h" | 32 #include "webkit/glue/plugins/pepper_var.h" |
| 33 | 33 |
| 34 typedef bool (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface); |
| 35 typedef void (*PPP_ShutdownModuleFunc)(); |
| 36 |
| 34 namespace pepper { | 37 namespace pepper { |
| 35 | 38 |
| 36 namespace { | 39 namespace { |
| 37 | 40 |
| 38 // Maintains all currently loaded plugin libs for validating PP_Module | 41 // Maintains all currently loaded plugin libs for validating PP_Module |
| 39 // identifiers. | 42 // identifiers. |
| 40 typedef std::set<PluginModule*> PluginModuleSet; | 43 typedef std::set<PluginModule*> PluginModuleSet; |
| 41 | 44 |
| 42 PluginModuleSet* GetLivePluginSet() { | 45 PluginModuleSet* GetLivePluginSet() { |
| 43 static PluginModuleSet live_plugin_libs; | 46 static PluginModuleSet live_plugin_libs; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 // in production code. | 151 // in production code. |
| 149 if (strcmp(name, PPB_TESTING_INTERFACE) == 0) { | 152 if (strcmp(name, PPB_TESTING_INTERFACE) == 0) { |
| 150 if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing")) | 153 if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing")) |
| 151 return &testing_interface; | 154 return &testing_interface; |
| 152 } | 155 } |
| 153 return NULL; | 156 return NULL; |
| 154 } | 157 } |
| 155 | 158 |
| 156 } // namespace | 159 } // namespace |
| 157 | 160 |
| 158 PluginModule::PluginModule() | 161 PluginModule::PluginModule(const FilePath& filename) |
| 159 : initialized_(false), | 162 : filename_(filename), |
| 160 library_(NULL) { | 163 initialized_(false), |
| 164 library_(0), |
| 165 ppp_get_interface_(NULL) { |
| 161 GetMainThreadMessageLoop(); // Initialize the main thread message loop. | 166 GetMainThreadMessageLoop(); // Initialize the main thread message loop. |
| 162 GetLivePluginSet()->insert(this); | 167 GetLivePluginSet()->insert(this); |
| 163 } | 168 } |
| 164 | 169 |
| 165 PluginModule::~PluginModule() { | 170 PluginModule::~PluginModule() { |
| 166 // When the module is being deleted, there should be no more instances still | 171 // When the module is being deleted, there should be no more instances still |
| 167 // holding a reference to us. | 172 // holding a reference to us. |
| 168 DCHECK(instances_.empty()); | 173 DCHECK(instances_.empty()); |
| 169 | 174 |
| 170 GetLivePluginSet()->erase(this); | 175 GetLivePluginSet()->erase(this); |
| 171 | 176 |
| 172 if (entry_points_.shutdown_module) | 177 if (library_) { |
| 173 entry_points_.shutdown_module(); | 178 PPP_ShutdownModuleFunc shutdown_module = |
| 174 | 179 reinterpret_cast<PPP_ShutdownModuleFunc>( |
| 175 if (library_) | 180 base::GetFunctionPointerFromNativeLibrary(library_, |
| 181 "PPP_ShutdownModule")); |
| 182 if (shutdown_module) |
| 183 shutdown_module(); |
| 176 base::UnloadNativeLibrary(library_); | 184 base::UnloadNativeLibrary(library_); |
| 185 } |
| 177 } | 186 } |
| 178 | 187 |
| 179 // static | 188 // static |
| 180 scoped_refptr<PluginModule> PluginModule::CreateModule( | 189 scoped_refptr<PluginModule> PluginModule::CreateModule( |
| 181 const FilePath& path) { | 190 const FilePath& filename) { |
| 182 // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one. | 191 // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one. |
| 183 | 192 |
| 184 scoped_refptr<PluginModule> lib(new PluginModule()); | 193 scoped_refptr<PluginModule> lib(new PluginModule(filename)); |
| 185 if (!lib->InitFromFile(path)) | 194 if (!lib->Load()) |
| 186 return NULL; | 195 lib = NULL; |
| 187 | |
| 188 return lib; | |
| 189 } | |
| 190 | |
| 191 scoped_refptr<PluginModule> PluginModule::CreateInternalModule( | |
| 192 EntryPoints entry_points) { | |
| 193 scoped_refptr<PluginModule> lib(new PluginModule()); | |
| 194 if (!lib->InitFromEntryPoints(entry_points)) | |
| 195 return NULL; | |
| 196 | |
| 197 return lib; | 196 return lib; |
| 198 } | 197 } |
| 199 | 198 |
| 200 // static | 199 // static |
| 201 PluginModule* PluginModule::FromPPModule(PP_Module module) { | 200 PluginModule* PluginModule::FromPPModule(PP_Module module) { |
| 202 PluginModule* lib = reinterpret_cast<PluginModule*>(module); | 201 PluginModule* lib = reinterpret_cast<PluginModule*>(module); |
| 203 if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end()) | 202 if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end()) |
| 204 return NULL; // Invalid plugin. | 203 return NULL; // Invalid plugin. |
| 205 return lib; | 204 return lib; |
| 206 } | 205 } |
| 207 | 206 |
| 208 bool PluginModule::InitFromEntryPoints(const EntryPoints& entry_points) { | 207 bool PluginModule::Load() { |
| 209 if (initialized_) | 208 if (initialized_) |
| 210 return true; | 209 return true; |
| 210 initialized_ = true; |
| 211 | 211 |
| 212 // Attempt to run the initialization funciton. | 212 library_ = base::LoadNativeLibrary(filename_); |
| 213 int retval = entry_points.initialize_module(GetPPModule(), &GetInterface); | 213 if (!library_) |
| 214 return false; |
| 215 |
| 216 // Save the GetInterface function pointer for later. |
| 217 ppp_get_interface_ = |
| 218 reinterpret_cast<PPP_GetInterfaceFunc>( |
| 219 base::GetFunctionPointerFromNativeLibrary(library_, |
| 220 "PPP_GetInterface")); |
| 221 if (!ppp_get_interface_) { |
| 222 LOG(WARNING) << "No PPP_GetInterface in plugin library"; |
| 223 return false; |
| 224 } |
| 225 |
| 226 // Call the plugin initialize function. |
| 227 PPP_InitializeModuleFunc initialize_module = |
| 228 reinterpret_cast<PPP_InitializeModuleFunc>( |
| 229 base::GetFunctionPointerFromNativeLibrary(library_, |
| 230 "PPP_InitializeModule")); |
| 231 if (!initialize_module) { |
| 232 LOG(WARNING) << "No PPP_InitializeModule in plugin library"; |
| 233 return false; |
| 234 } |
| 235 int retval = initialize_module(GetPPModule(), &GetInterface); |
| 214 if (retval != 0) { | 236 if (retval != 0) { |
| 215 LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; | 237 LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; |
| 216 return false; | 238 return false; |
| 217 } | 239 } |
| 218 | 240 |
| 219 entry_points_ = entry_points; | |
| 220 initialized_ = true; | |
| 221 return true; | 241 return true; |
| 222 } | 242 } |
| 223 | 243 |
| 224 bool PluginModule::InitFromFile(const FilePath& path) { | |
| 225 if (initialized_) | |
| 226 return true; | |
| 227 | |
| 228 base::NativeLibrary library = base::LoadNativeLibrary(path); | |
| 229 if (!library) | |
| 230 return false; | |
| 231 | |
| 232 EntryPoints entry_points; | |
| 233 if (!LoadEntryPoints(library, &entry_points) || | |
| 234 !InitFromEntryPoints(entry_points)) { | |
| 235 base::UnloadNativeLibrary(library); | |
| 236 return false; | |
| 237 } | |
| 238 | |
| 239 // We let InitFromEntryPoints() handle setting the all the internal state | |
| 240 // of the object other than the |library_| reference. | |
| 241 library_ = library; | |
| 242 return true; | |
| 243 } | |
| 244 | |
| 245 // static | |
| 246 bool PluginModule::LoadEntryPoints(const base::NativeLibrary& library, | |
| 247 EntryPoints* entry_points) { | |
| 248 | |
| 249 entry_points->get_interface = | |
| 250 reinterpret_cast<PPP_GetInterfaceFunc>( | |
| 251 base::GetFunctionPointerFromNativeLibrary(library, | |
| 252 "PPP_GetInterface")); | |
| 253 if (!entry_points->get_interface) { | |
| 254 LOG(WARNING) << "No PPP_GetInterface in plugin library"; | |
| 255 return false; | |
| 256 } | |
| 257 | |
| 258 entry_points->initialize_module = | |
| 259 reinterpret_cast<PPP_InitializeModuleFunc>( | |
| 260 base::GetFunctionPointerFromNativeLibrary(library, | |
| 261 "PPP_InitializeModule")); | |
| 262 if (!entry_points->initialize_module) { | |
| 263 LOG(WARNING) << "No PPP_InitializeModule in plugin library"; | |
| 264 return false; | |
| 265 } | |
| 266 | |
| 267 // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to | |
| 268 // be NULL. | |
| 269 entry_points->shutdown_module = | |
| 270 reinterpret_cast<PPP_ShutdownModuleFunc>( | |
| 271 base::GetFunctionPointerFromNativeLibrary(library, | |
| 272 "PPP_ShutdownModule")); | |
| 273 | |
| 274 return true; | |
| 275 } | |
| 276 | |
| 277 PP_Module PluginModule::GetPPModule() const { | 244 PP_Module PluginModule::GetPPModule() const { |
| 278 return reinterpret_cast<intptr_t>(this); | 245 return reinterpret_cast<intptr_t>(this); |
| 279 } | 246 } |
| 280 | 247 |
| 281 PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { | 248 PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { |
| 282 const PPP_Instance* plugin_instance_interface = | 249 const PPP_Instance* plugin_instance_interface = |
| 283 reinterpret_cast<const PPP_Instance*>(GetPluginInterface( | 250 reinterpret_cast<const PPP_Instance*>(GetPluginInterface( |
| 284 PPP_INSTANCE_INTERFACE)); | 251 PPP_INSTANCE_INTERFACE)); |
| 285 if (!plugin_instance_interface) { | 252 if (!plugin_instance_interface) { |
| 286 LOG(WARNING) << "Plugin doesn't support instance interface, failing."; | 253 LOG(WARNING) << "Plugin doesn't support instance interface, failing."; |
| 287 return NULL; | 254 return NULL; |
| 288 } | 255 } |
| 289 return new PluginInstance(delegate, this, plugin_instance_interface); | 256 return new PluginInstance(delegate, this, plugin_instance_interface); |
| 290 } | 257 } |
| 291 | 258 |
| 292 PluginInstance* PluginModule::GetSomeInstance() const { | 259 PluginInstance* PluginModule::GetSomeInstance() const { |
| 293 // This will generally crash later if there is not actually any instance to | 260 // This will generally crash later if there is not actually any instance to |
| 294 // return, so we force a crash now to make bugs easier to track down. | 261 // return, so we force a crash now to make bugs easier to track down. |
| 295 CHECK(!instances_.empty()); | 262 CHECK(!instances_.empty()); |
| 296 return *instances_.begin(); | 263 return *instances_.begin(); |
| 297 } | 264 } |
| 298 | 265 |
| 299 const void* PluginModule::GetPluginInterface(const char* name) const { | 266 const void* PluginModule::GetPluginInterface(const char* name) const { |
| 300 if (!entry_points_.get_interface) | 267 if (!ppp_get_interface_) |
| 301 return NULL; | 268 return NULL; |
| 302 return entry_points_.get_interface(name); | 269 return ppp_get_interface_(name); |
| 303 } | 270 } |
| 304 | 271 |
| 305 void PluginModule::InstanceCreated(PluginInstance* instance) { | 272 void PluginModule::InstanceCreated(PluginInstance* instance) { |
| 306 instances_.insert(instance); | 273 instances_.insert(instance); |
| 307 } | 274 } |
| 308 | 275 |
| 309 void PluginModule::InstanceDeleted(PluginInstance* instance) { | 276 void PluginModule::InstanceDeleted(PluginInstance* instance) { |
| 310 instances_.erase(instance); | 277 instances_.erase(instance); |
| 311 } | 278 } |
| 312 | 279 |
| 313 } // namespace pepper | 280 } // namespace pepper |
| OLD | NEW |