diff options
Diffstat (limited to 'remoting/host/plugin/host_plugin.cc')
-rw-r--r-- | remoting/host/plugin/host_plugin.cc | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/remoting/host/plugin/host_plugin.cc b/remoting/host/plugin/host_plugin.cc index f901a03..0776372 100644 --- a/remoting/host/plugin/host_plugin.cc +++ b/remoting/host/plugin/host_plugin.cc @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/stringize_macros.h" +#include "remoting/base/plugin_message_loop_proxy.h" #include "remoting/host/plugin/host_plugin_utils.h" #include "remoting/host/plugin/host_script_object.h" #include "third_party/npapi/bindings/npapi.h" @@ -58,7 +59,7 @@ base::AtExitManager* g_at_exit_manager = NULL; // NPAPI plugin implementation for remoting host. // Documentation for most of the calls in this class can be found here: // https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins -class HostNPPlugin { +class HostNPPlugin : public remoting::PluginMessageLoopProxy::Delegate { public: // |mode| is the display mode of plug-in. Values: // NP_EMBED: (1) Instance was created by an EMBED tag and shares the browser @@ -66,7 +67,10 @@ class HostNPPlugin { // NP_FULL: (2) Instance was created by a separate file and is the primary // content in the window. HostNPPlugin(NPP instance, uint16 mode) - : instance_(instance), scriptable_object_(NULL) {} + : instance_(instance), + scriptable_object_(NULL), + np_thread_id_(base::PlatformThread::CurrentId()) { + } ~HostNPPlugin() { if (scriptable_object_) { @@ -146,11 +150,49 @@ class HostNPPlugin { return scriptable_object_; } + // PluginMessageLoopProxy::Delegate implementation. + virtual bool RunOnPluginThread( + int delay_ms, void(function)(void*), void* data) OVERRIDE { + if (delay_ms == 0) { + g_npnetscape_funcs->pluginthreadasynccall(instance_, function, data); + } else { + base::AutoLock auto_lock(timers_lock_); + uint32_t timer_id = g_npnetscape_funcs->scheduletimer( + instance_, delay_ms, false, &NPDelayedTaskSpringboard); + DelayedTask task = {function, data}; + timers_[timer_id] = task; + } + return true; + } + + virtual bool IsPluginThread() OVERRIDE { + return np_thread_id_ == base::PlatformThread::CurrentId(); + } + + static void NPDelayedTaskSpringboard(NPP npp, uint32_t timer_id) { + HostNPPlugin* self = reinterpret_cast<HostNPPlugin*>(npp->pdata); + DelayedTask task; + { + base::AutoLock auto_lock(self->timers_lock_); + std::map<uint32_t, DelayedTask>::iterator it = + self->timers_.find(timer_id); + CHECK(it != self->timers_.end()); + task = it->second; + self->timers_.erase(it); + } + task.function(task.data); + } + private: struct ScriptableNPObject : public NPObject { HostNPScriptObject* scriptable_object; }; + struct DelayedTask { + void (*function)(void*); + void* data; + }; + static HostNPScriptObject* ScriptableFromObject(NPObject* obj) { return reinterpret_cast<ScriptableNPObject*>(obj)->scriptable_object; } @@ -160,10 +202,11 @@ class HostNPPlugin { ScriptableNPObject* object = reinterpret_cast<ScriptableNPObject*>( g_npnetscape_funcs->memalloc(sizeof(ScriptableNPObject))); + HostNPPlugin* plugin = reinterpret_cast<HostNPPlugin*>(npp->pdata); object->_class = aClass; object->referenceCount = 1; - object->scriptable_object = new HostNPScriptObject(npp, object); + object->scriptable_object = new HostNPScriptObject(npp, object, plugin); if (!object->scriptable_object->Init()) { Deallocate(object); object = NULL; @@ -290,6 +333,10 @@ class HostNPPlugin { NPP instance_; NPObject* scriptable_object_; + + base::PlatformThreadId np_thread_id_; + std::map<uint32_t, DelayedTask> timers_; + base::Lock timers_lock_; }; // Utility functions to map NPAPI Entry Points to C++ Objects. |