summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/plugin_lib.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue/plugins/plugin_lib.cc')
-rw-r--r--webkit/glue/plugins/plugin_lib.cc349
1 files changed, 0 insertions, 349 deletions
diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc
deleted file mode 100644
index 4ae4da4..0000000
--- a/webkit/glue/plugins/plugin_lib.cc
+++ /dev/null
@@ -1,349 +0,0 @@
-// Copyright (c) 2010 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 "webkit/glue/plugins/plugin_lib.h"
-
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/metrics/stats_counters.h"
-#include "base/string_util.h"
-#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/plugins/plugin_instance.h"
-#include "webkit/glue/plugins/plugin_host.h"
-#include "webkit/glue/plugins/plugin_list.h"
-
-namespace NPAPI {
-
-const char kPluginLibrariesLoadedCounter[] = "PluginLibrariesLoaded";
-const char kPluginInstancesActiveCounter[] = "PluginInstancesActive";
-
-// A list of all the instantiated plugins.
-static std::vector<scoped_refptr<PluginLib> >* g_loaded_libs;
-
-PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
- // We can only have one PluginLib object per plugin as it controls the per
- // instance function calls (i.e. NP_Initialize and NP_Shutdown). So we keep
- // a map of PluginLib objects.
- if (!g_loaded_libs)
- g_loaded_libs = new std::vector<scoped_refptr<PluginLib> >;
-
- for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
- if ((*g_loaded_libs)[i]->plugin_info().path == filename)
- return (*g_loaded_libs)[i];
- }
-
- WebPluginInfo info;
- const PluginEntryPoints* entry_points = NULL;
- if (!PluginList::Singleton()->ReadPluginInfo(filename, &info, &entry_points))
- return NULL;
-
- return new PluginLib(info, entry_points);
-}
-
-void PluginLib::UnloadAllPlugins() {
- if (g_loaded_libs) {
- // PluginLib::Unload() can remove items from the list and even delete
- // the list when it removes the last item, so we must work with a copy
- // of the list so that we don't get the carpet removed under our feet.
- std::vector<scoped_refptr<PluginLib> > loaded_libs(*g_loaded_libs);
- for (size_t i = 0; i < loaded_libs.size(); ++i)
- loaded_libs[i]->Unload();
-
- if (g_loaded_libs && g_loaded_libs->empty()) {
- delete g_loaded_libs;
- g_loaded_libs = NULL;
- }
- }
-}
-
-void PluginLib::ShutdownAllPlugins() {
- if (g_loaded_libs) {
- for (size_t i = 0; i < g_loaded_libs->size(); ++i)
- (*g_loaded_libs)[i]->Shutdown();
- }
-}
-
-PluginLib::PluginLib(const WebPluginInfo& info,
- const PluginEntryPoints* entry_points)
- : web_plugin_info_(info),
- library_(NULL),
- initialized_(false),
- saved_data_(0),
- instance_count_(0),
- skip_unload_(false) {
- base::StatsCounter(kPluginLibrariesLoadedCounter).Increment();
- memset(static_cast<void*>(&plugin_funcs_), 0, sizeof(plugin_funcs_));
- g_loaded_libs->push_back(make_scoped_refptr(this));
-
- if (entry_points) {
- internal_ = true;
- entry_points_ = *entry_points;
- } else {
- internal_ = false;
- // We will read the entry points from the plugin directly.
- memset(&entry_points_, 0, sizeof(entry_points_));
- }
-}
-
-PluginLib::~PluginLib() {
- base::StatsCounter(kPluginLibrariesLoadedCounter).Decrement();
- if (saved_data_ != 0) {
- // TODO - delete the savedData object here
- }
-}
-
-NPPluginFuncs* PluginLib::functions() {
- return &plugin_funcs_;
-}
-
-NPError PluginLib::NP_Initialize() {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value()
- << "): initialized=" << initialized_;
- if (initialized_)
- return NPERR_NO_ERROR;
-
- if (!Load())
- return NPERR_MODULE_LOAD_FAILED_ERROR;
-
- PluginHost* host = PluginHost::Singleton();
- if (host == 0)
- return NPERR_GENERIC_ERROR;
-
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
- NPError rv = entry_points_.np_initialize(host->host_functions(),
- &plugin_funcs_);
-#else
- NPError rv = entry_points_.np_initialize(host->host_functions());
-#if defined(OS_MACOSX)
- // On the Mac, we need to get entry points after calling np_initialize to
- // match the behavior of other browsers.
- if (rv == NPERR_NO_ERROR) {
- rv = entry_points_.np_getentrypoints(&plugin_funcs_);
- }
-#endif // OS_MACOSX
-#endif
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value()
- << "): result=" << rv;
- initialized_ = (rv == NPERR_NO_ERROR);
- return rv;
-}
-
-void PluginLib::NP_Shutdown(void) {
- DCHECK(initialized_);
- entry_points_.np_shutdown();
-}
-
-void PluginLib::PreventLibraryUnload() {
- skip_unload_ = true;
-}
-
-PluginInstance* PluginLib::CreateInstance(const std::string& mime_type) {
- PluginInstance* new_instance = new PluginInstance(this, mime_type);
- instance_count_++;
- base::StatsCounter(kPluginInstancesActiveCounter).Increment();
- DCHECK_NE(static_cast<PluginInstance*>(NULL), new_instance);
- return new_instance;
-}
-
-void PluginLib::CloseInstance() {
- base::StatsCounter(kPluginInstancesActiveCounter).Decrement();
- instance_count_--;
- // If a plugin is running in its own process it will get unloaded on process
- // shutdown.
- if ((instance_count_ == 0) && webkit_glue::IsPluginRunningInRendererProcess())
- Unload();
-}
-
-bool PluginLib::Load() {
- if (library_)
- return true;
-
- bool rv = false;
- base::NativeLibrary library = 0;
-
- if (!internal_) {
-#if defined(OS_WIN)
- // This is to work around a bug in the Real player recorder plugin which
- // intercepts LoadLibrary calls from chrome.dll and wraps NPAPI functions
- // provided by the plugin. It crashes if the media player plugin is being
- // loaded. Workaround is to load the dll dynamically by getting the
- // LoadLibrary API address from kernel32.dll which bypasses the recorder
- // plugin.
- if (web_plugin_info_.name.find(L"Windows Media Player") !=
- std::wstring::npos) {
- library = base::LoadNativeLibraryDynamically(web_plugin_info_.path);
- } else {
- library = base::LoadNativeLibrary(web_plugin_info_.path);
- }
-#else // OS_WIN
- library = base::LoadNativeLibrary(web_plugin_info_.path);
-#endif // OS_WIN
- if (library == 0) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Couldn't load plugin " << web_plugin_info_.path.value();
- return rv;
- }
-
-#if defined(OS_MACOSX)
- // According to the WebKit source, QuickTime at least requires us to call
- // UseResFile on the plugin resources before loading.
- if (library->bundle_resource_ref != -1)
- UseResFile(library->bundle_resource_ref);
-#endif
-
- rv = true; // assume success now
-
- entry_points_.np_initialize =
- (NP_InitializeFunc)base::GetFunctionPointerFromNativeLibrary(library,
- "NP_Initialize");
- if (entry_points_.np_initialize == 0)
- rv = false;
-
-#if defined(OS_WIN) || defined(OS_MACOSX)
- entry_points_.np_getentrypoints =
- (NP_GetEntryPointsFunc)base::GetFunctionPointerFromNativeLibrary(
- library, "NP_GetEntryPoints");
- if (entry_points_.np_getentrypoints == 0)
- rv = false;
-#endif
-
- entry_points_.np_shutdown =
- (NP_ShutdownFunc)base::GetFunctionPointerFromNativeLibrary(library,
- "NP_Shutdown");
- if (entry_points_.np_shutdown == 0)
- rv = false;
- } else {
- rv = true;
- }
-
- if (rv) {
- plugin_funcs_.size = sizeof(plugin_funcs_);
- plugin_funcs_.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
-#if !defined(OS_POSIX)
- if (entry_points_.np_getentrypoints(&plugin_funcs_) != NPERR_NO_ERROR)
- rv = false;
-#else
- // On Linux and Mac, we get the plugin entry points during NP_Initialize.
-#endif
- }
-
- if (!internal_) {
- if (rv) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Plugin " << web_plugin_info_.path.value()
- << " loaded successfully.";
- library_ = library;
- } else {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Plugin " << web_plugin_info_.path.value()
- << " failed to load, unloading.";
- base::UnloadNativeLibrary(library);
- }
- }
-
- return rv;
-}
-
-// This class implements delayed NP_Shutdown and FreeLibrary on the plugin dll.
-class FreePluginLibraryTask : public Task {
- public:
- FreePluginLibraryTask(const FilePath& path,
- base::NativeLibrary library,
- NP_ShutdownFunc shutdown_func)
- : path_(path),
- library_(library),
- NP_Shutdown_(shutdown_func) {
- }
-
- ~FreePluginLibraryTask() {}
-
- void Run() {
- if (NP_Shutdown_) {
- // Don't call NP_Shutdown if the library has been reloaded since this task
- // was posted.
- bool reloaded = false;
- if (g_loaded_libs) {
- for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
- if ((*g_loaded_libs)[i]->plugin_info().path == path_)
- reloaded = true;
- }
- }
- if (!reloaded)
- NP_Shutdown_();
- }
-
- if (library_) {
- // Always call base::UnloadNativeLibrary so that the system reference
- // count is decremented.
- base::UnloadNativeLibrary(library_);
- library_ = NULL;
- }
- }
-
- private:
- FilePath path_;
- base::NativeLibrary library_;
- NP_ShutdownFunc NP_Shutdown_;
- DISALLOW_COPY_AND_ASSIGN(FreePluginLibraryTask);
-};
-
-void PluginLib::Unload() {
- if (!internal_ && library_) {
- // In case of single process mode, a plugin can delete itself
- // by executing a script. So delay the unloading of the library
- // so that the plugin will have a chance to unwind.
- bool defer_unload = webkit_glue::IsPluginRunningInRendererProcess();
-
-/* TODO(dglazkov): Revisit when re-enabling the JSC build.
-#if USE(JSC)
- // The plugin NPAPI instances may still be around. Delay the
- // NP_Shutdown and FreeLibrary calls at least till the next
- // peek message.
- defer_unload = true;
-#endif
-*/
-
- if (defer_unload) {
- FreePluginLibraryTask* free_library_task =
- new FreePluginLibraryTask(web_plugin_info_.path,
- skip_unload_ ? NULL : library_,
- entry_points_.np_shutdown);
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Scheduling delayed unload for plugin "
- << web_plugin_info_.path.value();
- MessageLoop::current()->PostTask(FROM_HERE, free_library_task);
- } else {
- Shutdown();
- if (!skip_unload_) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Unloading plugin " << web_plugin_info_.path.value();
- base::UnloadNativeLibrary(library_);
- }
- }
-
- library_ = NULL;
- }
-
- for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
- if ((*g_loaded_libs)[i].get() == this) {
- g_loaded_libs->erase(g_loaded_libs->begin() + i);
- break;
- }
- }
- if (g_loaded_libs->empty()) {
- delete g_loaded_libs;
- g_loaded_libs = NULL;
- }
-}
-
-void PluginLib::Shutdown() {
- if (initialized_ && !internal_) {
- NP_Shutdown();
- initialized_ = false;
- }
-}
-
-} // namespace NPAPI