Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Side by Side Diff: webkit/glue/plugins/pepper_plugin_module.cc

Issue 5828003: Move the Pepper implementation from webkit/glue/plugins/pepper_* to... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/plugins/pepper_plugin_module.h ('k') | webkit/glue/plugins/pepper_plugin_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "webkit/glue/plugins/pepper_plugin_module.h"
6
7 #include <set>
8
9 #include "base/command_line.h"
10 #include "base/message_loop.h"
11 #include "base/message_loop_proxy.h"
12 #include "base/logging.h"
13 #include "base/scoped_ptr.h"
14 #include "base/time.h"
15 #include "ppapi/c/dev/ppb_buffer_dev.h"
16 #include "ppapi/c/dev/ppb_char_set_dev.h"
17 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
18 #include "ppapi/c/dev/ppb_directory_reader_dev.h"
19 #include "ppapi/c/dev/ppb_file_io_dev.h"
20 #include "ppapi/c/dev/ppb_file_io_trusted_dev.h"
21 #include "ppapi/c/dev/ppb_file_system_dev.h"
22 #include "ppapi/c/dev/ppb_find_dev.h"
23 #include "ppapi/c/dev/ppb_font_dev.h"
24 #include "ppapi/c/dev/ppb_fullscreen_dev.h"
25 #include "ppapi/c/dev/ppb_graphics_3d_dev.h"
26 #include "ppapi/c/dev/ppb_opengles_dev.h"
27 #include "ppapi/c/dev/ppb_scrollbar_dev.h"
28 #include "ppapi/c/dev/ppb_testing_dev.h"
29 #include "ppapi/c/dev/ppb_transport_dev.h"
30 #include "ppapi/c/dev/ppb_url_util_dev.h"
31 #include "ppapi/c/dev/ppb_var_deprecated.h"
32 #include "ppapi/c/dev/ppb_video_decoder_dev.h"
33 #include "ppapi/c/dev/ppb_widget_dev.h"
34 #include "ppapi/c/dev/ppb_zoom_dev.h"
35 #include "ppapi/c/pp_module.h"
36 #include "ppapi/c/pp_resource.h"
37 #include "ppapi/c/pp_var.h"
38 #include "ppapi/c/ppb_class.h"
39 #include "ppapi/c/ppb_core.h"
40 #include "ppapi/c/ppb_graphics_2d.h"
41 #include "ppapi/c/ppb_image_data.h"
42 #include "ppapi/c/ppb_instance.h"
43 #include "ppapi/c/ppb_url_loader.h"
44 #include "ppapi/c/ppb_url_request_info.h"
45 #include "ppapi/c/ppb_url_response_info.h"
46 #include "ppapi/c/ppb_var.h"
47 #include "ppapi/c/ppp.h"
48 #include "ppapi/c/ppp_instance.h"
49 #include "ppapi/c/trusted/ppb_image_data_trusted.h"
50 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
51 #include "webkit/glue/plugins/pepper_audio.h"
52 #include "webkit/glue/plugins/pepper_buffer.h"
53 #include "webkit/glue/plugins/pepper_common.h"
54 #include "webkit/glue/plugins/pepper_char_set.h"
55 #include "webkit/glue/plugins/pepper_class.h"
56 #include "webkit/glue/plugins/pepper_cursor_control.h"
57 #include "webkit/glue/plugins/pepper_directory_reader.h"
58 #include "webkit/glue/plugins/pepper_file_chooser.h"
59 #include "webkit/glue/plugins/pepper_file_io.h"
60 #include "webkit/glue/plugins/pepper_file_ref.h"
61 #include "webkit/glue/plugins/pepper_file_system.h"
62 #include "webkit/glue/plugins/pepper_font.h"
63 #include "webkit/glue/plugins/pepper_graphics_2d.h"
64 #include "webkit/glue/plugins/pepper_image_data.h"
65 #include "webkit/glue/plugins/pepper_plugin_instance.h"
66 #include "webkit/glue/plugins/pepper_plugin_object.h"
67 #include "webkit/glue/plugins/pepper_private.h"
68 #include "webkit/glue/plugins/pepper_private2.h"
69 #include "webkit/glue/plugins/pepper_resource_tracker.h"
70 #include "webkit/glue/plugins/pepper_scrollbar.h"
71 #include "webkit/glue/plugins/pepper_transport.h"
72 #include "webkit/glue/plugins/pepper_url_loader.h"
73 #include "webkit/glue/plugins/pepper_url_request_info.h"
74 #include "webkit/glue/plugins/pepper_url_response_info.h"
75 #include "webkit/glue/plugins/pepper_url_util.h"
76 #include "webkit/glue/plugins/pepper_var.h"
77 #include "webkit/glue/plugins/pepper_video_decoder.h"
78 #include "webkit/glue/plugins/pepper_widget.h"
79 #include "webkit/glue/plugins/ppb_private.h"
80 #include "webkit/glue/plugins/ppb_private2.h"
81
82 #ifdef ENABLE_GPU
83 #include "webkit/glue/plugins/pepper_graphics_3d.h"
84 #endif // ENABLE_GPU
85
86 namespace pepper {
87
88 namespace {
89
90 // Maintains all currently loaded plugin libs for validating PP_Module
91 // identifiers.
92 typedef std::set<PluginModule*> PluginModuleSet;
93
94 PluginModuleSet* GetLivePluginSet() {
95 static PluginModuleSet live_plugin_libs;
96 return &live_plugin_libs;
97 }
98
99 base::MessageLoopProxy* GetMainThreadMessageLoop() {
100 static scoped_refptr<base::MessageLoopProxy> proxy(
101 base::MessageLoopProxy::CreateForCurrentThread());
102 return proxy.get();
103 }
104
105 // PPB_Core --------------------------------------------------------------------
106
107 void AddRefResource(PP_Resource resource) {
108 if (!ResourceTracker::Get()->AddRefResource(resource)) {
109 DLOG(WARNING) << "AddRefResource()ing a nonexistent resource";
110 }
111 }
112
113 void ReleaseResource(PP_Resource resource) {
114 if (!ResourceTracker::Get()->UnrefResource(resource)) {
115 DLOG(WARNING) << "ReleaseResource()ing a nonexistent resource";
116 }
117 }
118
119 void* MemAlloc(size_t num_bytes) {
120 return malloc(num_bytes);
121 }
122
123 void MemFree(void* ptr) {
124 free(ptr);
125 }
126
127 double GetTime() {
128 return base::Time::Now().ToDoubleT();
129 }
130
131 double GetTickTime() {
132 // TODO(brettw) http://code.google.com/p/chromium/issues/detail?id=57448
133 // This should be a tick timer rather than wall clock time, but needs to
134 // match message times, which also currently use wall clock time.
135 return GetTime();
136 }
137
138 void CallOnMainThread(int delay_in_msec,
139 PP_CompletionCallback callback,
140 int32_t result) {
141 GetMainThreadMessageLoop()->PostDelayedTask(
142 FROM_HERE,
143 NewRunnableFunction(callback.func, callback.user_data, result),
144 delay_in_msec);
145 }
146
147 PP_Bool IsMainThread() {
148 return BoolToPPBool(GetMainThreadMessageLoop()->BelongsToCurrentThread());
149 }
150
151 const PPB_Core core_interface = {
152 &AddRefResource,
153 &ReleaseResource,
154 &MemAlloc,
155 &MemFree,
156 &GetTime,
157 &GetTickTime,
158 &CallOnMainThread,
159 &IsMainThread
160 };
161
162 // PPB_Testing -----------------------------------------------------------------
163
164 PP_Bool ReadImageData(PP_Resource device_context_2d,
165 PP_Resource image,
166 const PP_Point* top_left) {
167 scoped_refptr<Graphics2D> context(
168 Resource::GetAs<Graphics2D>(device_context_2d));
169 if (!context.get())
170 return PP_FALSE;
171 return BoolToPPBool(context->ReadImageData(image, top_left));
172 }
173
174 void RunMessageLoop() {
175 bool old_state = MessageLoop::current()->NestableTasksAllowed();
176 MessageLoop::current()->SetNestableTasksAllowed(true);
177 MessageLoop::current()->Run();
178 MessageLoop::current()->SetNestableTasksAllowed(old_state);
179 }
180
181 void QuitMessageLoop() {
182 MessageLoop::current()->QuitNow();
183 }
184
185 uint32_t GetLiveObjectCount(PP_Module module_id) {
186 PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
187 if (!module)
188 return static_cast<uint32_t>(-1);
189 return ResourceTracker::Get()->GetLiveObjectsForModule(module);
190 }
191
192 const PPB_Testing_Dev testing_interface = {
193 &ReadImageData,
194 &RunMessageLoop,
195 &QuitMessageLoop,
196 &GetLiveObjectCount
197 };
198
199 // GetInterface ----------------------------------------------------------------
200
201 const void* GetInterface(const char* name) {
202 if (strcmp(name, PPB_CORE_INTERFACE) == 0)
203 return &core_interface;
204 if (strcmp(name, PPB_VAR_DEPRECATED_INTERFACE) == 0)
205 return Var::GetDeprecatedInterface();
206 if (strcmp(name, PPB_VAR_INTERFACE) == 0)
207 return Var::GetInterface();
208 if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0)
209 return PluginInstance::GetInterface();
210 if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0)
211 return ImageData::GetInterface();
212 if (strcmp(name, PPB_IMAGEDATA_TRUSTED_INTERFACE) == 0)
213 return ImageData::GetTrustedInterface();
214 if (strcmp(name, PPB_AUDIO_CONFIG_DEV_INTERFACE) == 0)
215 return AudioConfig::GetInterface();
216 if (strcmp(name, PPB_AUDIO_DEV_INTERFACE) == 0)
217 return Audio::GetInterface();
218 if (strcmp(name, PPB_AUDIO_TRUSTED_DEV_INTERFACE) == 0)
219 return Audio::GetTrustedInterface();
220 if (strcmp(name, PPB_GRAPHICS_2D_INTERFACE) == 0)
221 return Graphics2D::GetInterface();
222 #ifdef ENABLE_GPU
223 if (strcmp(name, PPB_GRAPHICS_3D_DEV_INTERFACE) == 0)
224 return Graphics3D::GetInterface();
225 if (strcmp(name, PPB_OPENGLES_DEV_INTERFACE) == 0)
226 return Graphics3D::GetOpenGLESInterface();
227 #endif // ENABLE_GPU
228 if (strcmp(name, PPB_TRANSPORT_DEV_INTERFACE) == 0)
229 return Transport::GetInterface();
230 if (strcmp(name, PPB_URLLOADER_INTERFACE) == 0)
231 return URLLoader::GetInterface();
232 if (strcmp(name, PPB_URLLOADERTRUSTED_INTERFACE) == 0)
233 return URLLoader::GetTrustedInterface();
234 if (strcmp(name, PPB_URLREQUESTINFO_INTERFACE) == 0)
235 return URLRequestInfo::GetInterface();
236 if (strcmp(name, PPB_URLRESPONSEINFO_INTERFACE) == 0)
237 return URLResponseInfo::GetInterface();
238 if (strcmp(name, PPB_BUFFER_DEV_INTERFACE) == 0)
239 return Buffer::GetInterface();
240 if (strcmp(name, PPB_FILEREF_DEV_INTERFACE) == 0)
241 return FileRef::GetInterface();
242 if (strcmp(name, PPB_FILEIO_DEV_INTERFACE) == 0)
243 return FileIO::GetInterface();
244 if (strcmp(name, PPB_FILEIOTRUSTED_DEV_INTERFACE) == 0)
245 return FileIO::GetTrustedInterface();
246 if (strcmp(name, PPB_FILESYSTEM_DEV_INTERFACE) == 0)
247 return FileSystem::GetInterface();
248 if (strcmp(name, PPB_DIRECTORYREADER_DEV_INTERFACE) == 0)
249 return DirectoryReader::GetInterface();
250 if (strcmp(name, PPB_WIDGET_DEV_INTERFACE) == 0)
251 return Widget::GetInterface();
252 if (strcmp(name, PPB_SCROLLBAR_DEV_INTERFACE) == 0)
253 return Scrollbar::GetInterface();
254 if (strcmp(name, PPB_FONT_DEV_INTERFACE) == 0)
255 return Font::GetInterface();
256 if (strcmp(name, PPB_FIND_DEV_INTERFACE) == 0)
257 return PluginInstance::GetFindInterface();
258 if (strcmp(name, PPB_FULLSCREEN_DEV_INTERFACE) == 0)
259 return PluginInstance::GetFullscreenInterface();
260 if (strcmp(name, PPB_URLUTIL_DEV_INTERFACE) == 0)
261 return UrlUtil::GetInterface();
262 if (strcmp(name, PPB_PRIVATE_INTERFACE) == 0)
263 return Private::GetInterface();
264 if (strcmp(name, PPB_PRIVATE2_INTERFACE) == 0)
265 return Private2::GetInterface();
266 if (strcmp(name, PPB_FILECHOOSER_DEV_INTERFACE) == 0)
267 return FileChooser::GetInterface();
268 if (strcmp(name, PPB_VIDEODECODER_DEV_INTERFACE) == 0)
269 return VideoDecoder::GetInterface();
270 if (strcmp(name, PPB_CHAR_SET_DEV_INTERFACE) == 0)
271 return CharSet::GetInterface();
272 if (strcmp(name, PPB_CURSOR_CONTROL_DEV_INTERFACE) == 0)
273 return GetCursorControlInterface();
274 if (strcmp(name, PPB_ZOOM_DEV_INTERFACE) == 0)
275 return PluginInstance::GetZoomInterface();
276 if (strcmp(name, PPB_CLASS_INTERFACE) == 0)
277 return VarObjectClass::GetInterface();
278
279 // Only support the testing interface when the command line switch is
280 // specified. This allows us to prevent people from (ab)using this interface
281 // in production code.
282 if (strcmp(name, PPB_TESTING_DEV_INTERFACE) == 0) {
283 if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing"))
284 return &testing_interface;
285 }
286 return NULL;
287 }
288
289 // Gets the PPAPI entry points from the given library and places them into the
290 // given structure. Returns true on success.
291 bool LoadEntryPointsFromLibrary(const base::NativeLibrary& library,
292 PluginModule::EntryPoints* entry_points) {
293 entry_points->get_interface =
294 reinterpret_cast<PluginModule::GetInterfaceFunc>(
295 base::GetFunctionPointerFromNativeLibrary(library,
296 "PPP_GetInterface"));
297 if (!entry_points->get_interface) {
298 LOG(WARNING) << "No PPP_GetInterface in plugin library";
299 return false;
300 }
301
302 entry_points->initialize_module =
303 reinterpret_cast<PluginModule::PPP_InitializeModuleFunc>(
304 base::GetFunctionPointerFromNativeLibrary(library,
305 "PPP_InitializeModule"));
306 if (!entry_points->initialize_module) {
307 LOG(WARNING) << "No PPP_InitializeModule in plugin library";
308 return false;
309 }
310
311 // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to
312 // be NULL.
313 entry_points->shutdown_module =
314 reinterpret_cast<PluginModule::PPP_ShutdownModuleFunc>(
315 base::GetFunctionPointerFromNativeLibrary(library,
316 "PPP_ShutdownModule"));
317
318 return true;
319 }
320
321 } // namespace
322
323 PluginModule::EntryPoints::EntryPoints()
324 : get_interface(NULL),
325 initialize_module(NULL),
326 shutdown_module(NULL) {
327 }
328
329 // PluginModule ----------------------------------------------------------------
330
331 PluginModule::PluginModule() : library_(NULL) {
332 pp_module_ = ResourceTracker::Get()->AddModule(this);
333 GetMainThreadMessageLoop(); // Initialize the main thread message loop.
334 GetLivePluginSet()->insert(this);
335 }
336
337 PluginModule::~PluginModule() {
338 // Free all the plugin objects. This will automatically clear the back-
339 // pointer from the NPObject so WebKit can't call into the plugin any more.
340 //
341 // Swap out the set so we can delete from it (the objects will try to
342 // unregister themselves inside the delete call).
343 PluginObjectSet plugin_object_copy;
344 live_plugin_objects_.swap(plugin_object_copy);
345 for (PluginObjectSet::iterator i = live_plugin_objects_.begin();
346 i != live_plugin_objects_.end(); ++i)
347 delete *i;
348
349 // When the module is being deleted, there should be no more instances still
350 // holding a reference to us.
351 DCHECK(instances_.empty());
352
353 GetLivePluginSet()->erase(this);
354
355 if (entry_points_.shutdown_module)
356 entry_points_.shutdown_module();
357
358 if (library_)
359 base::UnloadNativeLibrary(library_);
360
361 ResourceTracker::Get()->ModuleDeleted(pp_module_);
362 }
363
364 bool PluginModule::InitAsInternalPlugin(const EntryPoints& entry_points) {
365 entry_points_ = entry_points;
366 return InitializeModule();
367 }
368
369 bool PluginModule::InitAsLibrary(const FilePath& path) {
370 base::NativeLibrary library = base::LoadNativeLibrary(path);
371 if (!library)
372 return false;
373
374 if (!LoadEntryPointsFromLibrary(library, &entry_points_) ||
375 !InitializeModule()) {
376 base::UnloadNativeLibrary(library);
377 return false;
378 }
379
380 library_ = library;
381 return true;
382 }
383
384 void PluginModule::InitAsProxied(
385 PluginDelegate::OutOfProcessProxy* out_of_process_proxy) {
386 DCHECK(!out_of_process_proxy_.get());
387 out_of_process_proxy_.reset(out_of_process_proxy);
388 }
389
390 // static
391 const PPB_Core* PluginModule::GetCore() {
392 return &core_interface;
393 }
394
395 // static
396 PluginModule::GetInterfaceFunc PluginModule::GetLocalGetInterfaceFunc() {
397 return &GetInterface;
398 }
399
400 PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) {
401 const PPP_Instance* plugin_instance_interface =
402 reinterpret_cast<const PPP_Instance*>(GetPluginInterface(
403 PPP_INSTANCE_INTERFACE));
404 if (!plugin_instance_interface) {
405 LOG(WARNING) << "Plugin doesn't support instance interface, failing.";
406 return NULL;
407 }
408 PluginInstance* instance = new PluginInstance(delegate, this,
409 plugin_instance_interface);
410 if (out_of_process_proxy_.get())
411 out_of_process_proxy_->AddInstance(instance->pp_instance());
412 return instance;
413 }
414
415 PluginInstance* PluginModule::GetSomeInstance() const {
416 // This will generally crash later if there is not actually any instance to
417 // return, so we force a crash now to make bugs easier to track down.
418 CHECK(!instances_.empty());
419 return *instances_.begin();
420 }
421
422 const void* PluginModule::GetPluginInterface(const char* name) const {
423 if (out_of_process_proxy_.get())
424 return out_of_process_proxy_->GetProxiedInterface(name);
425
426 // In-process plugins.
427 if (!entry_points_.get_interface)
428 return NULL;
429 return entry_points_.get_interface(name);
430 }
431
432 void PluginModule::InstanceCreated(PluginInstance* instance) {
433 instances_.insert(instance);
434 }
435
436 void PluginModule::InstanceDeleted(PluginInstance* instance) {
437 if (out_of_process_proxy_.get())
438 out_of_process_proxy_->RemoveInstance(instance->pp_instance());
439 instances_.erase(instance);
440 }
441
442 void PluginModule::AddNPObjectVar(ObjectVar* object_var) {
443 DCHECK(np_object_to_object_var_.find(object_var->np_object()) ==
444 np_object_to_object_var_.end()) << "ObjectVar already in map";
445 np_object_to_object_var_[object_var->np_object()] = object_var;
446 }
447
448 void PluginModule::RemoveNPObjectVar(ObjectVar* object_var) {
449 NPObjectToObjectVarMap::iterator found =
450 np_object_to_object_var_.find(object_var->np_object());
451 if (found == np_object_to_object_var_.end()) {
452 NOTREACHED() << "ObjectVar not registered.";
453 return;
454 }
455 if (found->second != object_var) {
456 NOTREACHED() << "ObjectVar doesn't match.";
457 return;
458 }
459 np_object_to_object_var_.erase(found);
460 }
461
462 ObjectVar* PluginModule::ObjectVarForNPObject(NPObject* np_object) const {
463 NPObjectToObjectVarMap::const_iterator found =
464 np_object_to_object_var_.find(np_object);
465 if (found == np_object_to_object_var_.end())
466 return NULL;
467 return found->second;
468 }
469
470 void PluginModule::AddPluginObject(PluginObject* plugin_object) {
471 DCHECK(live_plugin_objects_.find(plugin_object) ==
472 live_plugin_objects_.end());
473 live_plugin_objects_.insert(plugin_object);
474 }
475
476 void PluginModule::RemovePluginObject(PluginObject* plugin_object) {
477 // Don't actually verify that the object is in the set since during module
478 // deletion we'll be in the process of freeing them.
479 live_plugin_objects_.erase(plugin_object);
480 }
481
482 bool PluginModule::InitializeModule() {
483 DCHECK(!out_of_process_proxy_.get()) << "Don't call for proxied modules.";
484 int retval = entry_points_.initialize_module(pp_module(), &GetInterface);
485 if (retval != 0) {
486 LOG(WARNING) << "PPP_InitializeModule returned failure " << retval;
487 return false;
488 }
489 return true;
490 }
491
492 } // namespace pepper
OLDNEW
« no previous file with comments | « webkit/glue/plugins/pepper_plugin_module.h ('k') | webkit/glue/plugins/pepper_plugin_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698