Index: remoting/host/plugin/host_plugin.cc |
diff --git a/remoting/host/plugin/host_plugin.cc b/remoting/host/plugin/host_plugin.cc |
deleted file mode 100644 |
index 213ea89d78b3e7f29f181f78f5adb1413e0c991b..0000000000000000000000000000000000000000 |
--- a/remoting/host/plugin/host_plugin.cc |
+++ /dev/null |
@@ -1,574 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include <stdio.h> |
-#include <string.h> |
- |
-#include <string> |
-#include <vector> |
- |
-#include "base/at_exit.h" |
-#include "base/basictypes.h" |
-#include "base/command_line.h" |
-#include "base/logging.h" |
-#include "base/strings/stringize_macros.h" |
-#include "net/socket/ssl_server_socket.h" |
-#include "remoting/base/plugin_thread_task_runner.h" |
-#include "remoting/base/resources.h" |
-#include "remoting/base/string_resources.h" |
-#include "remoting/host/plugin/host_log_handler.h" |
-#include "remoting/host/plugin/host_plugin_utils.h" |
-#include "remoting/host/plugin/host_script_object.h" |
-#if defined(OS_WIN) |
-#include "ui/gfx/win/dpi.h" |
-#endif |
-#include "third_party/npapi/bindings/npapi.h" |
-#include "third_party/npapi/bindings/npfunctions.h" |
-#include "third_party/npapi/bindings/npruntime.h" |
-#include "ui/base/l10n/l10n_util.h" |
- |
-// Symbol export is handled with a separate def file on Windows. |
-#if defined (__GNUC__) && __GNUC__ >= 4 |
-#define EXPORT __attribute__((visibility("default"))) |
-#else |
-#define EXPORT |
-#endif |
- |
-#if defined(OS_WIN) |
-// TODO(wez): libvpx expects these 64-bit division functions to be provided |
-// by libgcc.a, which we aren't linked against. These implementations can |
-// be removed once we have native MSVC libvpx builds for Windows. |
-extern "C" { |
- |
-int64_t __cdecl __divdi3(int64_t a, int64_t b) { |
- return a / b; |
-} |
-uint64_t __cdecl __udivdi3(uint64_t a, uint64_t b) { |
- return a / b; |
-} |
- |
-} |
-#endif |
- |
-using remoting::g_npnetscape_funcs; |
-using remoting::HostLogHandler; |
-using remoting::HostNPScriptObject; |
-using remoting::StringFromNPIdentifier; |
- |
-namespace { |
- |
-bool g_initialized = false; |
- |
-base::AtExitManager* g_at_exit_manager = NULL; |
- |
-// The plugin name and description returned by GetValue(). |
-std::string* g_ui_name = NULL; |
-std::string* g_ui_description = 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 : public remoting::PluginThreadTaskRunner::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 |
- // window with other content. |
- // 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) { |
- plugin_task_runner_ = new remoting::PluginThreadTaskRunner(this); |
- plugin_auto_task_runner_ = |
- new remoting::AutoThreadTaskRunner( |
- plugin_task_runner_, |
- base::Bind(&remoting::PluginThreadTaskRunner::Quit, |
- plugin_task_runner_)); |
- } |
- |
- virtual ~HostNPPlugin() { |
- if (scriptable_object_) { |
- DCHECK_EQ(scriptable_object_->referenceCount, 1UL); |
- g_npnetscape_funcs->releaseobject(scriptable_object_); |
- scriptable_object_ = NULL; |
- } |
- |
- // Process tasks on |plugin_task_runner_| until all references to |
- // |plugin_auto_task_runner_| have been dropped. This requires that the |
- // browser has dropped any script object references - see above. |
- plugin_auto_task_runner_ = NULL; |
- plugin_task_runner_->DetachAndRunShutdownLoop(); |
- } |
- |
- bool Init(int16 argc, char** argn, char** argv, NPSavedData* saved) { |
-#if defined(OS_MACOSX) |
- // Use the modern CoreGraphics and Cocoa models when available, since |
- // QuickDraw and Carbon are deprecated. |
- // The drawing and event models don't change anything for this plugin, since |
- // none of the functions affected by the models actually do anything. |
- // This does however keep the plugin from breaking when Chromium eventually |
- // drops support for QuickDraw and Carbon, and it also keeps the browser |
- // from sending Null Events once a second to support old Carbon based |
- // timers. |
- // Chromium should always be supporting the newer models. |
- |
- // Sanity check to see if Chromium supports the CoreGraphics drawing model. |
- NPBool supports_core_graphics = false; |
- NPError err = g_npnetscape_funcs->getvalue(instance_, |
- NPNVsupportsCoreGraphicsBool, |
- &supports_core_graphics); |
- if (err == NPERR_NO_ERROR && supports_core_graphics) { |
- // Switch to CoreGraphics drawing model. |
- g_npnetscape_funcs->setvalue(instance_, NPPVpluginDrawingModel, |
- reinterpret_cast<void*>(NPDrawingModelCoreGraphics)); |
- } else { |
- LOG(ERROR) << "No Core Graphics support"; |
- return false; |
- } |
- |
- // Sanity check to see if Chromium supports the Cocoa event model. |
- NPBool supports_cocoa = false; |
- err = g_npnetscape_funcs->getvalue(instance_, NPNVsupportsCocoaBool, |
- &supports_cocoa); |
- if (err == NPERR_NO_ERROR && supports_cocoa) { |
- // Switch to Cocoa event model. |
- g_npnetscape_funcs->setvalue(instance_, NPPVpluginEventModel, |
- reinterpret_cast<void*>(NPEventModelCocoa)); |
- } else { |
- LOG(ERROR) << "No Cocoa Event Model support"; |
- return false; |
- } |
-#endif // OS_MACOSX |
- net::EnableSSLServerSockets(); |
- return true; |
- } |
- |
- bool Save(NPSavedData** saved) { |
- return true; |
- } |
- |
- NPObject* GetScriptableObject() { |
- if (!scriptable_object_) { |
- // Must be static. If it is a temporary, objects created by this |
- // method will fail in weird and wonderful ways later. |
- static NPClass npc_ref_object = { |
- NP_CLASS_STRUCT_VERSION, |
- &Allocate, |
- &Deallocate, |
- &Invalidate, |
- &HasMethod, |
- &Invoke, |
- &InvokeDefault, |
- &HasProperty, |
- &GetProperty, |
- &SetProperty, |
- &RemoveProperty, |
- &Enumerate, |
- NULL |
- }; |
- scriptable_object_ = g_npnetscape_funcs->createobject(instance_, |
- &npc_ref_object); |
- } |
- return scriptable_object_; |
- } |
- |
- // PluginThreadTaskRunner::Delegate implementation. |
- virtual bool RunOnPluginThread( |
- base::TimeDelta delay, void(function)(void*), void* data) OVERRIDE { |
- if (delay == base::TimeDelta()) { |
- g_npnetscape_funcs->pluginthreadasynccall(instance_, function, data); |
- } else { |
- base::AutoLock auto_lock(timers_lock_); |
- uint32_t timer_id = g_npnetscape_funcs->scheduletimer( |
- instance_, delay.InMilliseconds(), false, &NPDelayedTaskSpringboard); |
- DelayedTask task = {function, data}; |
- timers_[timer_id] = task; |
- } |
- return true; |
- } |
- |
- void SetWindow(NPWindow* np_window) { |
- if (scriptable_object_) { |
- ScriptableFromObject(scriptable_object_)->SetWindow(np_window); |
- } |
- } |
- |
- 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; |
- } |
- |
- static NPObject* Allocate(NPP npp, NPClass* aClass) { |
- VLOG(2) << "static Allocate"; |
- 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, plugin->plugin_auto_task_runner_); |
- return object; |
- } |
- |
- static void Deallocate(NPObject* npobj) { |
- VLOG(2) << "static Deallocate"; |
- if (npobj) { |
- Invalidate(npobj); |
- g_npnetscape_funcs->memfree(npobj); |
- } |
- } |
- |
- static void Invalidate(NPObject* npobj) { |
- if (npobj) { |
- ScriptableNPObject* object = reinterpret_cast<ScriptableNPObject*>(npobj); |
- if (object->scriptable_object) { |
- delete object->scriptable_object; |
- object->scriptable_object = NULL; |
- } |
- } |
- } |
- |
- static bool HasMethod(NPObject* obj, NPIdentifier method_name) { |
- VLOG(2) << "static HasMethod"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- std::string method_name_string = StringFromNPIdentifier(method_name); |
- if (method_name_string.empty()) |
- return false; |
- return scriptable->HasMethod(method_name_string); |
- } |
- |
- static bool InvokeDefault(NPObject* obj, |
- const NPVariant* args, |
- uint32_t argCount, |
- NPVariant* result) { |
- VLOG(2) << "static InvokeDefault"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- return scriptable->InvokeDefault(args, argCount, result); |
- } |
- |
- static bool Invoke(NPObject* obj, |
- NPIdentifier method_name, |
- const NPVariant* args, |
- uint32_t argCount, |
- NPVariant* result) { |
- VLOG(2) << "static Invoke"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) |
- return false; |
- std::string method_name_string = StringFromNPIdentifier(method_name); |
- if (method_name_string.empty()) |
- return false; |
- return scriptable->Invoke(method_name_string, args, argCount, result); |
- } |
- |
- static bool HasProperty(NPObject* obj, NPIdentifier property_name) { |
- VLOG(2) << "static HasProperty"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- std::string property_name_string = StringFromNPIdentifier(property_name); |
- if (property_name_string.empty()) |
- return false; |
- return scriptable->HasProperty(property_name_string); |
- } |
- |
- static bool GetProperty(NPObject* obj, |
- NPIdentifier property_name, |
- NPVariant* result) { |
- VLOG(2) << "static GetProperty"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- std::string property_name_string = StringFromNPIdentifier(property_name); |
- if (property_name_string.empty()) |
- return false; |
- return scriptable->GetProperty(property_name_string, result); |
- } |
- |
- static bool SetProperty(NPObject* obj, |
- NPIdentifier property_name, |
- const NPVariant* value) { |
- VLOG(2) << "static SetProperty"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- std::string property_name_string = StringFromNPIdentifier(property_name); |
- if (property_name_string.empty()) |
- return false; |
- return scriptable->SetProperty(property_name_string, value); |
- } |
- |
- static bool RemoveProperty(NPObject* obj, NPIdentifier property_name) { |
- VLOG(2) << "static RemoveProperty"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- std::string property_name_string = StringFromNPIdentifier(property_name); |
- if (property_name_string.empty()) |
- return false; |
- return scriptable->RemoveProperty(property_name_string); |
- } |
- |
- static bool Enumerate(NPObject* obj, |
- NPIdentifier** value, |
- uint32_t* count) { |
- VLOG(2) << "static Enumerate"; |
- HostNPScriptObject* scriptable = ScriptableFromObject(obj); |
- if (!scriptable) return false; |
- std::vector<std::string> values; |
- bool is_good = scriptable->Enumerate(&values); |
- if (is_good) { |
- *count = values.size(); |
- *value = reinterpret_cast<NPIdentifier*>( |
- g_npnetscape_funcs->memalloc(sizeof(NPIdentifier) * (*count))); |
- for (uint32_t i = 0; i < *count; ++i) { |
- (*value)[i] = |
- g_npnetscape_funcs->getstringidentifier(values[i].c_str()); |
- } |
- } |
- return is_good; |
- } |
- |
- NPP instance_; |
- NPObject* scriptable_object_; |
- |
- scoped_refptr<remoting::PluginThreadTaskRunner> plugin_task_runner_; |
- scoped_refptr<remoting::AutoThreadTaskRunner> plugin_auto_task_runner_; |
- |
- std::map<uint32_t, DelayedTask> timers_; |
- base::Lock timers_lock_; |
-}; |
- |
-void InitializePlugin() { |
- if (g_initialized) |
- return; |
- |
- g_initialized = true; |
- g_at_exit_manager = new base::AtExitManager; |
- |
- // Init an empty command line for common objects that use it. |
- base::CommandLine::Init(0, NULL); |
- |
- if (remoting::LoadResources("")) { |
- g_ui_name = new std::string( |
- l10n_util::GetStringUTF8(IDS_REMOTING_HOST_PLUGIN_NAME)); |
- g_ui_description = new std::string( |
- l10n_util::GetStringUTF8(IDS_REMOTING_HOST_PLUGIN_DESCRIPTION)); |
- } else { |
- g_ui_name = new std::string(); |
- g_ui_description = new std::string(); |
- } |
-} |
- |
-void ShutdownPlugin() { |
- delete g_ui_name; |
- delete g_ui_description; |
- |
- remoting::UnloadResources(); |
- |
- delete g_at_exit_manager; |
-} |
- |
-// Utility functions to map NPAPI Entry Points to C++ Objects. |
-HostNPPlugin* PluginFromInstance(NPP instance) { |
- return reinterpret_cast<HostNPPlugin*>(instance->pdata); |
-} |
- |
-NPError CreatePlugin(NPMIMEType pluginType, |
- NPP instance, |
- uint16 mode, |
- int16 argc, |
- char** argn, |
- char** argv, |
- NPSavedData* saved) { |
- VLOG(2) << "CreatePlugin"; |
- |
- // Register a global log handler. |
- // The LogMessage registration code is not thread-safe, so we need to perform |
- // this while we're running in a single thread. |
- HostLogHandler::RegisterLogMessageHandler(); |
- |
- HostNPPlugin* plugin = new HostNPPlugin(instance, mode); |
- instance->pdata = plugin; |
- if (!plugin->Init(argc, argn, argv, saved)) { |
- delete plugin; |
- instance->pdata = NULL; |
- return NPERR_INVALID_PLUGIN_ERROR; |
- } else { |
- return NPERR_NO_ERROR; |
- } |
-} |
- |
-NPError DestroyPlugin(NPP instance, |
- NPSavedData** save) { |
- VLOG(2) << "DestroyPlugin"; |
- |
- // Normally, we would unregister the global log handler that we registered |
- // in CreatePlugin. However, the LogHandler registration code is not thread- |
- // safe so we could crash if we update (register or unregister) the |
- // LogHandler while it's being read on another thread. |
- // At this point, all our threads should be shutdown, but it's safer to leave |
- // the handler registered until we're completely destroyed. |
- |
- HostNPPlugin* plugin = PluginFromInstance(instance); |
- if (plugin) { |
- plugin->Save(save); |
- delete plugin; |
- instance->pdata = NULL; |
- return NPERR_NO_ERROR; |
- } else { |
- return NPERR_INVALID_PLUGIN_ERROR; |
- } |
-} |
- |
-NPError GetValue(NPP instance, NPPVariable variable, void* value) { |
- // NP_GetValue() can be called before NP_Initialize(). |
- InitializePlugin(); |
- |
- switch (variable) { |
- default: |
- VLOG(2) << "GetValue - default " << variable; |
- return NPERR_GENERIC_ERROR; |
- case NPPVpluginNameString: |
- VLOG(2) << "GetValue - name string"; |
- *reinterpret_cast<const char**>(value) = g_ui_name->c_str(); |
- break; |
- case NPPVpluginDescriptionString: |
- VLOG(2) << "GetValue - description string"; |
- *reinterpret_cast<const char**>(value) = g_ui_description->c_str(); |
- break; |
- case NPPVpluginNeedsXEmbed: |
- VLOG(2) << "GetValue - NeedsXEmbed"; |
- *(static_cast<NPBool*>(value)) = true; |
- break; |
- case NPPVpluginScriptableNPObject: |
- VLOG(2) << "GetValue - scriptable object"; |
- HostNPPlugin* plugin = PluginFromInstance(instance); |
- if (!plugin) |
- return NPERR_INVALID_PLUGIN_ERROR; |
- NPObject* scriptable_object = plugin->GetScriptableObject(); |
- g_npnetscape_funcs->retainobject(scriptable_object); |
- *reinterpret_cast<NPObject**>(value) = scriptable_object; |
- break; |
- } |
- return NPERR_NO_ERROR; |
-} |
- |
-NPError HandleEvent(NPP instance, void* ev) { |
- VLOG(2) << "HandleEvent"; |
- return NPERR_NO_ERROR; |
-} |
- |
-NPError SetWindow(NPP instance, NPWindow* pNPWindow) { |
- VLOG(2) << "SetWindow"; |
- HostNPPlugin* plugin = PluginFromInstance(instance); |
- if (plugin) { |
- plugin->SetWindow(pNPWindow); |
- } |
- return NPERR_NO_ERROR; |
-} |
- |
-} // namespace |
- |
-#if defined(OS_WIN) |
-BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { |
- switch (dwReason) { |
- case DLL_PROCESS_ATTACH: |
- DisableThreadLibraryCalls(hModule); |
- break; |
- case DLL_PROCESS_DETACH: |
- case DLL_THREAD_ATTACH: |
- case DLL_THREAD_DETACH: |
- break; |
- } |
- return TRUE; |
-} |
-#endif |
- |
-// The actual required NPAPI Entry points |
- |
-extern "C" { |
- |
-EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* nppfuncs) { |
- VLOG(2) << "NP_GetEntryPoints"; |
- nppfuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; |
- nppfuncs->newp = &CreatePlugin; |
- nppfuncs->destroy = &DestroyPlugin; |
- nppfuncs->getvalue = &GetValue; |
- nppfuncs->event = &HandleEvent; |
- nppfuncs->setwindow = &SetWindow; |
- |
- return NPERR_NO_ERROR; |
-} |
- |
-EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs |
-#if defined(OS_POSIX) && !defined(OS_MACOSX) |
- , NPPluginFuncs* nppfuncs |
-#endif |
- ) { |
- VLOG(2) << "NP_Initialize"; |
- InitializePlugin(); |
- |
- if (npnetscape_funcs == NULL) |
- return NPERR_INVALID_FUNCTABLE_ERROR; |
- |
- if (((npnetscape_funcs->version & 0xff00) >> 8) > NP_VERSION_MAJOR) |
- return NPERR_INCOMPATIBLE_VERSION_ERROR; |
- |
- g_npnetscape_funcs = npnetscape_funcs; |
-#if defined(OS_POSIX) && !defined(OS_MACOSX) |
- NP_GetEntryPoints(nppfuncs); |
-#endif |
- |
-#if defined(OS_WIN) |
- gfx::EnableHighDPISupport(); |
-#endif |
- |
- return NPERR_NO_ERROR; |
-} |
- |
-EXPORT NPError API_CALL NP_Shutdown() { |
- VLOG(2) << "NP_Shutdown"; |
- ShutdownPlugin(); |
- |
- return NPERR_NO_ERROR; |
-} |
- |
-#if defined(OS_POSIX) && !defined(OS_MACOSX) |
-EXPORT const char* API_CALL NP_GetMIMEDescription(void) { |
- VLOG(2) << "NP_GetMIMEDescription"; |
- return STRINGIZE(HOST_PLUGIN_MIME_TYPE) "::"; |
-} |
- |
-EXPORT NPError API_CALL NP_GetValue(void* npp, |
- NPPVariable variable, |
- void* value) { |
- return GetValue((NPP)npp, variable, value); |
-} |
-#endif |
- |
-} // extern "C" |