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 |