Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / plugins / ppapi / plugin_module.cc
blob0325c6017b8e5fd5f23e4a7018f334fe75354f2a
1 // Copyright (c) 2012 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.
5 #include "webkit/plugins/ppapi/plugin_module.h"
7 #include <set>
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/message_loop_proxy.h"
15 #include "base/time.h"
16 #include "ppapi/c/dev/ppb_audio_input_dev.h"
17 #include "ppapi/c/dev/ppb_buffer_dev.h"
18 #include "ppapi/c/dev/ppb_char_set_dev.h"
19 #include "ppapi/c/dev/ppb_crypto_dev.h"
20 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
21 #include "ppapi/c/dev/ppb_device_ref_dev.h"
22 #include "ppapi/c/dev/ppb_directory_reader_dev.h"
23 #include "ppapi/c/dev/ppb_file_chooser_dev.h"
24 #include "ppapi/c/dev/ppb_find_dev.h"
25 #include "ppapi/c/dev/ppb_font_dev.h"
26 #include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h"
27 #include "ppapi/c/dev/ppb_graphics_2d_dev.h"
28 #include "ppapi/c/dev/ppb_memory_dev.h"
29 #include "ppapi/c/dev/ppb_opengles2ext_dev.h"
30 #include "ppapi/c/dev/ppb_printing_dev.h"
31 #include "ppapi/c/dev/ppb_resource_array_dev.h"
32 #include "ppapi/c/dev/ppb_scrollbar_dev.h"
33 #include "ppapi/c/dev/ppb_testing_dev.h"
34 #include "ppapi/c/dev/ppb_text_input_dev.h"
35 #include "ppapi/c/dev/ppb_trace_event_dev.h"
36 #include "ppapi/c/dev/ppb_truetype_font_dev.h"
37 #include "ppapi/c/dev/ppb_url_util_dev.h"
38 #include "ppapi/c/dev/ppb_var_array_dev.h"
39 #include "ppapi/c/dev/ppb_var_deprecated.h"
40 #include "ppapi/c/dev/ppb_var_dictionary_dev.h"
41 #include "ppapi/c/dev/ppb_video_capture_dev.h"
42 #include "ppapi/c/dev/ppb_video_decoder_dev.h"
43 #include "ppapi/c/dev/ppb_view_dev.h"
44 #include "ppapi/c/dev/ppb_widget_dev.h"
45 #include "ppapi/c/dev/ppb_zoom_dev.h"
46 #include "ppapi/c/extensions/dev/ppb_ext_alarms_dev.h"
47 #include "ppapi/c/extensions/dev/ppb_ext_socket_dev.h"
48 #include "ppapi/c/pp_module.h"
49 #include "ppapi/c/pp_resource.h"
50 #include "ppapi/c/pp_var.h"
51 #include "ppapi/c/ppb_audio.h"
52 #include "ppapi/c/ppb_audio_config.h"
53 #include "ppapi/c/ppb_console.h"
54 #include "ppapi/c/ppb_core.h"
55 #include "ppapi/c/ppb_file_io.h"
56 #include "ppapi/c/ppb_file_ref.h"
57 #include "ppapi/c/ppb_file_system.h"
58 #include "ppapi/c/ppb_fullscreen.h"
59 #include "ppapi/c/ppb_graphics_2d.h"
60 #include "ppapi/c/ppb_graphics_3d.h"
61 #include "ppapi/c/ppb_image_data.h"
62 #include "ppapi/c/ppb_instance.h"
63 #include "ppapi/c/ppb_messaging.h"
64 #include "ppapi/c/ppb_mouse_cursor.h"
65 #include "ppapi/c/ppb_mouse_lock.h"
66 #include "ppapi/c/ppb_opengles2.h"
67 #include "ppapi/c/ppb_url_loader.h"
68 #include "ppapi/c/ppb_url_request_info.h"
69 #include "ppapi/c/ppb_url_response_info.h"
70 #include "ppapi/c/ppb_var.h"
71 #include "ppapi/c/ppb_var_array_buffer.h"
72 #include "ppapi/c/ppb_view.h"
73 #include "ppapi/c/ppp.h"
74 #include "ppapi/c/ppp_instance.h"
75 #include "ppapi/c/private/ppb_file_io_private.h"
76 #include "ppapi/c/private/ppb_file_ref_private.h"
77 #include "ppapi/c/private/ppb_flash.h"
78 #include "ppapi/c/private/ppb_flash_clipboard.h"
79 #include "ppapi/c/private/ppb_flash_device_id.h"
80 #include "ppapi/c/private/ppb_flash_file.h"
81 #include "ppapi/c/private/ppb_flash_font_file.h"
82 #include "ppapi/c/private/ppb_flash_fullscreen.h"
83 #include "ppapi/c/private/ppb_flash_menu.h"
84 #include "ppapi/c/private/ppb_flash_message_loop.h"
85 #include "ppapi/c/private/ppb_flash_print.h"
86 #include "ppapi/c/private/ppb_gpu_blacklist_private.h"
87 #include "ppapi/c/private/ppb_host_resolver_private.h"
88 #include "ppapi/c/private/ppb_instance_private.h"
89 #include "ppapi/c/private/ppb_network_list_private.h"
90 #include "ppapi/c/private/ppb_network_monitor_private.h"
91 #include "ppapi/c/private/ppb_pdf.h"
92 #include "ppapi/c/private/ppb_proxy_private.h"
93 #include "ppapi/c/private/ppb_talk_private.h"
94 #include "ppapi/c/private/ppb_tcp_server_socket_private.h"
95 #include "ppapi/c/private/ppb_tcp_socket_private.h"
96 #include "ppapi/c/private/ppb_udp_socket_private.h"
97 #include "ppapi/c/private/ppb_uma_private.h"
98 #include "ppapi/c/private/ppb_x509_certificate_private.h"
99 #include "ppapi/c/trusted/ppb_audio_trusted.h"
100 #include "ppapi/c/trusted/ppb_broker_trusted.h"
101 #include "ppapi/c/trusted/ppb_browser_font_trusted.h"
102 #include "ppapi/c/trusted/ppb_buffer_trusted.h"
103 #include "ppapi/c/trusted/ppb_char_set_trusted.h"
104 #include "ppapi/c/trusted/ppb_file_chooser_trusted.h"
105 #include "ppapi/c/trusted/ppb_file_io_trusted.h"
106 #include "ppapi/c/trusted/ppb_graphics_3d_trusted.h"
107 #include "ppapi/c/trusted/ppb_image_data_trusted.h"
108 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
109 #include "ppapi/shared_impl/callback_tracker.h"
110 #include "ppapi/shared_impl/ppapi_switches.h"
111 #include "ppapi/shared_impl/ppb_input_event_shared.h"
112 #include "ppapi/shared_impl/ppb_opengles2_shared.h"
113 #include "ppapi/shared_impl/ppb_var_shared.h"
114 #include "ppapi/shared_impl/time_conversion.h"
115 #include "ppapi/thunk/enter.h"
116 #include "ppapi/thunk/ppb_graphics_2d_api.h"
117 #include "ppapi/thunk/thunk.h"
118 #include "webkit/plugins/plugin_switches.h"
119 #include "webkit/plugins/ppapi/common.h"
120 #include "webkit/plugins/ppapi/host_globals.h"
121 #include "webkit/plugins/ppapi/ppapi_interface_factory.h"
122 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
123 #include "webkit/plugins/ppapi/ppb_gpu_blacklist_private_impl.h"
124 #include "webkit/plugins/ppapi/ppb_image_data_impl.h"
125 #include "webkit/plugins/ppapi/ppb_proxy_impl.h"
126 #include "webkit/plugins/ppapi/ppb_scrollbar_impl.h"
127 #include "webkit/plugins/ppapi/ppb_uma_private_impl.h"
128 #include "webkit/plugins/ppapi/ppb_var_deprecated_impl.h"
129 #include "webkit/plugins/ppapi/ppb_video_decoder_impl.h"
131 using ppapi::InputEventData;
132 using ppapi::PpapiGlobals;
133 using ppapi::TimeTicksToPPTimeTicks;
134 using ppapi::TimeToPPTime;
135 using ppapi::thunk::EnterResource;
136 using ppapi::thunk::PPB_Graphics2D_API;
137 using ppapi::thunk::PPB_InputEvent_API;
139 namespace webkit {
140 namespace ppapi {
142 namespace {
144 // Global tracking info for PPAPI plugins. This is lazily created before the
145 // first plugin is allocated, and leaked on shutdown.
147 // Note that we don't want a Singleton here since destroying this object will
148 // try to free some stuff that requires WebKit, and Singletons are destroyed
149 // after WebKit.
150 webkit::ppapi::HostGlobals* host_globals = NULL;
152 // Maintains all currently loaded plugin libs for validating PP_Module
153 // identifiers.
154 typedef std::set<PluginModule*> PluginModuleSet;
156 PluginModuleSet* GetLivePluginSet() {
157 CR_DEFINE_STATIC_LOCAL(PluginModuleSet, live_plugin_libs, ());
158 return &live_plugin_libs;
161 // PPB_Core --------------------------------------------------------------------
163 void AddRefResource(PP_Resource resource) {
164 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(resource);
167 void ReleaseResource(PP_Resource resource) {
168 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(resource);
171 PP_Time GetTime() {
172 return TimeToPPTime(base::Time::Now());
175 PP_TimeTicks GetTickTime() {
176 return TimeTicksToPPTimeTicks(base::TimeTicks::Now());
179 void CallOnMainThread(int delay_in_msec,
180 PP_CompletionCallback callback,
181 int32_t result) {
182 if (callback.func) {
183 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostDelayedTask(
184 FROM_HERE,
185 base::Bind(callback.func, callback.user_data, result),
186 base::TimeDelta::FromMilliseconds(delay_in_msec));
190 PP_Bool IsMainThread() {
191 return BoolToPPBool(PpapiGlobals::Get()->
192 GetMainThreadMessageLoop()->BelongsToCurrentThread());
195 const PPB_Core core_interface = {
196 &AddRefResource,
197 &ReleaseResource,
198 &GetTime,
199 &GetTickTime,
200 &CallOnMainThread,
201 &IsMainThread
204 // PPB_Testing -----------------------------------------------------------------
206 PP_Bool ReadImageData(PP_Resource device_context_2d,
207 PP_Resource image,
208 const PP_Point* top_left) {
209 EnterResource<PPB_Graphics2D_API> enter(device_context_2d, true);
210 if (enter.failed())
211 return PP_FALSE;
212 return BoolToPPBool(enter.object()->ReadImageData(image, top_left));
215 void RunMessageLoop(PP_Instance instance) {
216 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
217 MessageLoop::current()->Run();
220 void QuitMessageLoop(PP_Instance instance) {
221 MessageLoop::current()->QuitNow();
224 uint32_t GetLiveObjectsForInstance(PP_Instance instance_id) {
225 return HostGlobals::Get()->GetResourceTracker()->GetLiveObjectsForInstance(
226 instance_id);
229 PP_Bool IsOutOfProcess() {
230 return PP_FALSE;
233 void SimulateInputEvent(PP_Instance instance, PP_Resource input_event) {
234 PluginInstance* plugin_instance = host_globals->GetInstance(instance);
235 if (!plugin_instance)
236 return;
238 EnterResource<PPB_InputEvent_API> enter(input_event, false);
239 if (enter.failed())
240 return;
242 const InputEventData& input_event_data = enter.object()->GetInputEventData();
243 plugin_instance->SimulateInputEvent(input_event_data);
246 PP_Var GetDocumentURL(PP_Instance instance, PP_URLComponents_Dev* components) {
247 PluginInstance* plugin_instance = host_globals->GetInstance(instance);
248 if (!plugin_instance)
249 return PP_MakeUndefined();
250 return plugin_instance->GetDocumentURL(instance, components);
253 uint32_t GetLiveVars(PP_Var live_vars[], uint32_t array_size) {
254 std::vector<PP_Var> vars =
255 PpapiGlobals::Get()->GetVarTracker()->GetLiveVars();
256 for (size_t i = 0u;
257 i < std::min(static_cast<size_t>(array_size), vars.size());
258 ++i)
259 live_vars[i] = vars[i];
260 return vars.size();
263 const PPB_Testing_Dev testing_interface = {
264 &ReadImageData,
265 &RunMessageLoop,
266 &QuitMessageLoop,
267 &GetLiveObjectsForInstance,
268 &IsOutOfProcess,
269 &SimulateInputEvent,
270 &GetDocumentURL,
271 &GetLiveVars
274 // GetInterface ----------------------------------------------------------------
276 const void* InternalGetInterface(const char* name) {
277 // Allow custom interface factories first stab at the GetInterface call.
278 const void* custom_interface =
279 PpapiInterfaceFactoryManager::GetInstance()->GetInterface(name);
280 if (custom_interface)
281 return custom_interface;
283 // TODO(brettw) put these in a hash map for better performance.
284 #define UNPROXIED_IFACE(api_name, iface_str, iface_struct) \
285 if (strcmp(name, iface_str) == 0) \
286 return ::ppapi::thunk::Get##iface_struct##_Thunk();
287 #define PROXIED_IFACE(api_name, iface_str, iface_struct) \
288 UNPROXIED_IFACE(api_name, iface_str, iface_struct)
290 #include "ppapi/thunk/interfaces_ppb_public_stable.h"
291 #include "ppapi/thunk/interfaces_ppb_public_dev.h"
292 #include "ppapi/thunk/interfaces_ppb_private.h"
293 #include "ppapi/thunk/interfaces_ppb_private_no_permissions.h"
294 #include "ppapi/thunk/interfaces_ppb_private_flash.h"
296 #undef UNPROXIED_API
297 #undef PROXIED_IFACE
299 // Please keep alphabetized by interface macro name with "special" stuff at
300 // the bottom.
301 if (strcmp(name, PPB_AUDIO_TRUSTED_INTERFACE_0_6) == 0)
302 return ::ppapi::thunk::GetPPB_AudioTrusted_0_6_Thunk();
303 if (strcmp(name, PPB_BUFFER_TRUSTED_INTERFACE_0_1) == 0)
304 return ::ppapi::thunk::GetPPB_BufferTrusted_0_1_Thunk();
305 if (strcmp(name, PPB_CORE_INTERFACE_1_0) == 0)
306 return &core_interface;
307 if (strcmp(name, PPB_GPUBLACKLIST_PRIVATE_INTERFACE) == 0)
308 return PPB_GpuBlacklist_Private_Impl::GetInterface();
309 if (strcmp(name, PPB_GRAPHICS_3D_TRUSTED_INTERFACE_1_0) == 0)
310 return ::ppapi::thunk::GetPPB_Graphics3DTrusted_1_0_Thunk();
311 if (strcmp(name, PPB_IMAGEDATA_TRUSTED_INTERFACE_0_4) == 0)
312 return ::ppapi::thunk::GetPPB_ImageDataTrusted_0_4_Thunk();
313 if (strcmp(name, PPB_INPUT_EVENT_INTERFACE_1_0) == 0)
314 return ::ppapi::thunk::GetPPB_InputEvent_1_0_Thunk();
315 if (strcmp(name, PPB_INSTANCE_PRIVATE_INTERFACE_0_1) == 0)
316 return ::ppapi::thunk::GetPPB_Instance_Private_0_1_Thunk();
317 if (strcmp(name, PPB_OPENGLES2_INTERFACE) == 0)
318 return ::ppapi::PPB_OpenGLES2_Shared::GetInterface();
319 if (strcmp(name, PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE) == 0)
320 return ::ppapi::PPB_OpenGLES2_Shared::GetInstancedArraysInterface();
321 if (strcmp(name, PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE) == 0)
322 return ::ppapi::PPB_OpenGLES2_Shared::GetFramebufferBlitInterface();
323 if (strcmp(name, PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE) == 0)
324 return ::ppapi::PPB_OpenGLES2_Shared::GetFramebufferMultisampleInterface();
325 if (strcmp(name, PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE) == 0)
326 return ::ppapi::PPB_OpenGLES2_Shared::GetChromiumEnableFeatureInterface();
327 if (strcmp(name, PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE) == 0)
328 return ::ppapi::PPB_OpenGLES2_Shared::GetChromiumMapSubInterface();
329 if (strcmp(name, PPB_OPENGLES2_CHROMIUMMAPSUB_DEV_INTERFACE_1_0) == 0)
330 return ::ppapi::PPB_OpenGLES2_Shared::GetChromiumMapSubInterface();
331 if (strcmp(name, PPB_OPENGLES2_QUERY_INTERFACE) == 0)
332 return ::ppapi::PPB_OpenGLES2_Shared::GetQueryInterface();
333 if (strcmp(name, PPB_PROXY_PRIVATE_INTERFACE) == 0)
334 return PPB_Proxy_Impl::GetInterface();
335 if (strcmp(name, PPB_UMA_PRIVATE_INTERFACE) == 0)
336 return PPB_UMA_Private_Impl::GetInterface();
337 if (strcmp(name, PPB_URLLOADERTRUSTED_INTERFACE_0_3) == 0)
338 return ::ppapi::thunk::GetPPB_URLLoaderTrusted_0_3_Thunk();
339 if (strcmp(name, PPB_VAR_DEPRECATED_INTERFACE) == 0)
340 return PPB_Var_Deprecated_Impl::GetVarDeprecatedInterface();
341 if (strcmp(name, PPB_VAR_INTERFACE_1_0) == 0)
342 return ::ppapi::PPB_Var_Shared::GetVarInterface1_0();
343 if (strcmp(name, PPB_VAR_INTERFACE_1_1) == 0)
344 return ::ppapi::PPB_Var_Shared::GetVarInterface1_1();
345 if (strcmp(name, PPB_VAR_ARRAY_BUFFER_INTERFACE_1_0) == 0)
346 return ::ppapi::PPB_Var_Shared::GetVarArrayBufferInterface1_0();
348 // Only support the testing interface when the command line switch is
349 // specified. This allows us to prevent people from (ab)using this interface
350 // in production code.
351 if (CommandLine::ForCurrentProcess()->HasSwitch(
352 switches::kEnablePepperTesting)) {
353 if (strcmp(name, PPB_TESTING_DEV_INTERFACE) == 0 ||
354 strcmp(name, PPB_TESTING_DEV_INTERFACE_0_9) == 0) {
355 return &testing_interface;
358 return NULL;
361 const void* GetInterface(const char* name) {
362 // All interfaces should be used on the main thread.
363 CHECK(IsMainThread());
365 return InternalGetInterface(name);
368 // Gets the PPAPI entry points from the given library and places them into the
369 // given structure. Returns true on success.
370 bool LoadEntryPointsFromLibrary(const base::NativeLibrary& library,
371 PluginModule::EntryPoints* entry_points) {
372 entry_points->get_interface =
373 reinterpret_cast<PluginModule::GetInterfaceFunc>(
374 base::GetFunctionPointerFromNativeLibrary(library,
375 "PPP_GetInterface"));
376 if (!entry_points->get_interface) {
377 LOG(WARNING) << "No PPP_GetInterface in plugin library";
378 return false;
381 entry_points->initialize_module =
382 reinterpret_cast<PluginModule::PPP_InitializeModuleFunc>(
383 base::GetFunctionPointerFromNativeLibrary(library,
384 "PPP_InitializeModule"));
385 if (!entry_points->initialize_module) {
386 LOG(WARNING) << "No PPP_InitializeModule in plugin library";
387 return false;
390 // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to
391 // be NULL.
392 entry_points->shutdown_module =
393 reinterpret_cast<PluginModule::PPP_ShutdownModuleFunc>(
394 base::GetFunctionPointerFromNativeLibrary(library,
395 "PPP_ShutdownModule"));
397 return true;
400 } // namespace
402 PluginModule::EntryPoints::EntryPoints()
403 : get_interface(NULL),
404 initialize_module(NULL),
405 shutdown_module(NULL) {
408 // PluginModule ----------------------------------------------------------------
410 PluginModule::PluginModule(const std::string& name,
411 const base::FilePath& path,
412 PluginDelegate::ModuleLifetime* lifetime_delegate,
413 const ::ppapi::PpapiPermissions& perms)
414 : lifetime_delegate_(lifetime_delegate),
415 callback_tracker_(new ::ppapi::CallbackTracker),
416 is_in_destructor_(false),
417 is_crashed_(false),
418 broker_(NULL),
419 library_(NULL),
420 name_(name),
421 path_(path),
422 permissions_(perms),
423 reserve_instance_id_(NULL) {
424 // Ensure the globals object is created.
425 if (!host_globals)
426 host_globals = new HostGlobals;
428 memset(&entry_points_, 0, sizeof(entry_points_));
429 pp_module_ = HostGlobals::Get()->AddModule(this);
430 GetLivePluginSet()->insert(this);
433 PluginModule::~PluginModule() {
434 // In the past there have been crashes reentering the plugin module
435 // destructor. Catch if that happens again earlier.
436 CHECK(!is_in_destructor_);
437 is_in_destructor_ = true;
439 // When the module is being deleted, there should be no more instances still
440 // holding a reference to us.
441 DCHECK(instances_.empty());
443 // Some resources and other stuff are hung off of the embedder state, which
444 // should be torn down before the routing stuff below.
445 embedder_state_.reset();
447 GetLivePluginSet()->erase(this);
449 callback_tracker_->AbortAll();
451 if (entry_points_.shutdown_module)
452 entry_points_.shutdown_module();
454 if (library_)
455 base::UnloadNativeLibrary(library_);
457 // Notifications that we've been deleted should be last.
458 HostGlobals::Get()->ModuleDeleted(pp_module_);
459 if (!is_crashed_ && lifetime_delegate_) {
460 // When the plugin crashes, we immediately tell the lifetime delegate that
461 // we're gone, so we don't want to tell it again.
462 lifetime_delegate_->PluginModuleDead(this);
465 // Don't add stuff here, the two notifications that the module object has
466 // been deleted should be last. This allows, for example,
467 // PPB_Proxy.IsInModuleDestructor to map PP_Module to this class during the
468 // previous parts of the destructor.
471 void PluginModule::SetEmbedderState(scoped_ptr<EmbedderState> state) {
472 embedder_state_ = state.Pass();
475 PluginModule::EmbedderState* PluginModule::GetEmbedderState() {
476 return embedder_state_.get();
479 bool PluginModule::InitAsInternalPlugin(const EntryPoints& entry_points) {
480 if (InitializeModule(entry_points)) {
481 entry_points_ = entry_points;
482 return true;
484 return false;
487 bool PluginModule::InitAsLibrary(const base::FilePath& path) {
488 base::NativeLibrary library = base::LoadNativeLibrary(path, NULL);
489 if (!library)
490 return false;
492 EntryPoints entry_points;
494 if (!LoadEntryPointsFromLibrary(library, &entry_points) ||
495 !InitializeModule(entry_points)) {
496 base::UnloadNativeLibrary(library);
497 return false;
499 entry_points_ = entry_points;
500 library_ = library;
501 return true;
504 void PluginModule::InitAsProxied(
505 PluginDelegate::OutOfProcessProxy* out_of_process_proxy) {
506 DCHECK(!out_of_process_proxy_.get());
507 out_of_process_proxy_.reset(out_of_process_proxy);
510 scoped_refptr<PluginModule> PluginModule::CreateModuleForNaClInstance() {
511 // Create a new module, but don't set the lifetime delegate. This isn't a
512 // plugin in the usual sense, so it isn't tracked by the browser.
513 scoped_refptr<PluginModule> nacl_module(
514 new PluginModule(name_,
515 path_,
516 NULL, // no lifetime_delegate
517 permissions_));
518 return nacl_module;
521 PP_NaClResult PluginModule::InitAsProxiedNaCl(PluginInstance* instance) {
522 DCHECK(out_of_process_proxy_.get());
523 // InitAsProxied (for the trusted/out-of-process case) initializes only the
524 // module, and one or more instances are added later. In this case, the
525 // PluginInstance was already created as in-process, so we missed the proxy
526 // AddInstance step and must do it now.
527 out_of_process_proxy_->AddInstance(instance->pp_instance());
528 // In NaCl, we need to tell the instance to reset itself as proxied. This will
529 // clear cached interface pointers and send DidCreate (etc) to the plugin
530 // side of the proxy.
531 return instance->ResetAsProxied(this);
534 bool PluginModule::IsProxied() const {
535 return !!out_of_process_proxy_;
538 base::ProcessId PluginModule::GetPeerProcessId() {
539 if (out_of_process_proxy_.get())
540 return out_of_process_proxy_->GetPeerProcessId();
541 return base::kNullProcessId;
544 // static
545 const PPB_Core* PluginModule::GetCore() {
546 return &core_interface;
549 // static
550 PluginModule::GetInterfaceFunc PluginModule::GetLocalGetInterfaceFunc() {
551 return &GetInterface;
554 // static
555 bool PluginModule::SupportsInterface(const char* name) {
556 return !!InternalGetInterface(name);
559 PluginInstance* PluginModule::CreateInstance(
560 PluginDelegate* delegate,
561 WebKit::WebPluginContainer* container,
562 const GURL& plugin_url) {
563 PluginInstance* instance = PluginInstance::Create(delegate, this, container,
564 plugin_url);
565 if (!instance) {
566 LOG(WARNING) << "Plugin doesn't support instance interface, failing.";
567 return NULL;
569 if (out_of_process_proxy_.get())
570 out_of_process_proxy_->AddInstance(instance->pp_instance());
571 return instance;
574 PluginInstance* PluginModule::GetSomeInstance() const {
575 // This will generally crash later if there is not actually any instance to
576 // return, so we force a crash now to make bugs easier to track down.
577 CHECK(!instances_.empty());
578 return *instances_.begin();
581 const void* PluginModule::GetPluginInterface(const char* name) const {
582 if (out_of_process_proxy_.get())
583 return out_of_process_proxy_->GetProxiedInterface(name);
585 // In-process plugins.
586 if (!entry_points_.get_interface)
587 return NULL;
588 return entry_points_.get_interface(name);
591 void PluginModule::InstanceCreated(PluginInstance* instance) {
592 instances_.insert(instance);
595 void PluginModule::InstanceDeleted(PluginInstance* instance) {
596 if (out_of_process_proxy_.get())
597 out_of_process_proxy_->RemoveInstance(instance->pp_instance());
598 instances_.erase(instance);
601 scoped_refptr< ::ppapi::CallbackTracker> PluginModule::GetCallbackTracker() {
602 return callback_tracker_;
605 void PluginModule::PluginCrashed() {
606 DCHECK(!is_crashed_); // Should only get one notification.
607 is_crashed_ = true;
609 // Notify all instances that they crashed.
610 for (PluginInstanceSet::iterator i = instances_.begin();
611 i != instances_.end(); ++i)
612 (*i)->InstanceCrashed();
614 if (lifetime_delegate_)
615 lifetime_delegate_->PluginModuleDead(this);
618 void PluginModule::SetReserveInstanceIDCallback(
619 PP_Bool (*reserve)(PP_Module, PP_Instance)) {
620 DCHECK(!reserve_instance_id_) << "Only expect one set.";
621 reserve_instance_id_ = reserve;
624 bool PluginModule::ReserveInstanceID(PP_Instance instance) {
625 if (reserve_instance_id_)
626 return PPBoolToBool(reserve_instance_id_(pp_module_, instance));
627 return true; // Instance ID is usable.
630 void PluginModule::SetBroker(PluginDelegate::Broker* broker) {
631 DCHECK(!broker_ || !broker);
632 broker_ = broker;
635 PluginDelegate::Broker* PluginModule::GetBroker() {
636 return broker_;
639 bool PluginModule::InitializeModule(const EntryPoints& entry_points) {
640 DCHECK(!out_of_process_proxy_.get()) << "Don't call for proxied modules.";
641 DCHECK(entry_points.initialize_module != NULL);
642 int retval = entry_points.initialize_module(pp_module(), &GetInterface);
643 if (retval != 0) {
644 LOG(WARNING) << "PPP_InitializeModule returned failure " << retval;
645 return false;
647 return true;
650 } // namespace ppapi
651 } // namespace webkit