| Index: content/child/npapi/plugin_lib.cc
|
| diff --git a/content/child/npapi/plugin_lib.cc b/content/child/npapi/plugin_lib.cc
|
| deleted file mode 100644
|
| index a472c0ae4627a7afe28aa61e9167d12cc1505cd0..0000000000000000000000000000000000000000
|
| --- a/content/child/npapi/plugin_lib.cc
|
| +++ /dev/null
|
| @@ -1,333 +0,0 @@
|
| -// Copyright (c) 2011 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 "content/child/npapi/plugin_lib.h"
|
| -
|
| -#include <stddef.h>
|
| -#include <string.h>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/location.h"
|
| -#include "base/logging.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/thread_task_runner_handle.h"
|
| -#include "build/build_config.h"
|
| -#include "content/child/npapi/plugin_host.h"
|
| -#include "content/child/npapi/plugin_instance.h"
|
| -#include "content/common/plugin_list.h"
|
| -
|
| -namespace content {
|
| -
|
| -// A list of all the instantiated plugins.
|
| -static std::vector<scoped_refptr<PluginLib> >* g_loaded_libs;
|
| -
|
| -PluginLib* PluginLib::CreatePluginLib(const base::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].get();
|
| - }
|
| -
|
| - WebPluginInfo info;
|
| - if (!PluginList::Singleton()->ReadPluginInfo(filename, &info))
|
| - return NULL;
|
| -
|
| - return new PluginLib(info);
|
| -}
|
| -
|
| -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)
|
| - : web_plugin_info_(info),
|
| - library_(NULL),
|
| - initialized_(false),
|
| - saved_data_(0),
|
| - instance_count_(0),
|
| - skip_unload_(false),
|
| - defer_unload_(false) {
|
| - memset(static_cast<void*>(&plugin_funcs_), 0, sizeof(plugin_funcs_));
|
| - g_loaded_libs->push_back(make_scoped_refptr(this));
|
| -
|
| - memset(&entry_points_, 0, sizeof(entry_points_));
|
| -}
|
| -
|
| -PluginLib::~PluginLib() {
|
| - 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();
|
| -}
|
| -
|
| -NPError PluginLib::NP_ClearSiteData(const char* site,
|
| - uint64_t flags,
|
| - uint64_t max_age) {
|
| - DCHECK(initialized_);
|
| - if (plugin_funcs_.clearsitedata)
|
| - return plugin_funcs_.clearsitedata(site, flags, max_age);
|
| - return NPERR_INVALID_FUNCTABLE_ERROR;
|
| -}
|
| -
|
| -char** PluginLib::NP_GetSitesWithData() {
|
| - DCHECK(initialized_);
|
| - if (plugin_funcs_.getsiteswithdata)
|
| - return plugin_funcs_.getsiteswithdata();
|
| - return NULL;
|
| -}
|
| -
|
| -void PluginLib::PreventLibraryUnload() {
|
| - skip_unload_ = true;
|
| -}
|
| -
|
| -PluginInstance* PluginLib::CreateInstance(const std::string& mime_type) {
|
| - PluginInstance* new_instance = new PluginInstance(this, mime_type);
|
| - instance_count_++;
|
| - DCHECK_NE(static_cast<PluginInstance*>(NULL), new_instance);
|
| - return new_instance;
|
| -}
|
| -
|
| -void PluginLib::CloseInstance() {
|
| - instance_count_--;
|
| - // If a plugin is running in its own process it will get unloaded on process
|
| - // shutdown.
|
| - if ((instance_count_ == 0) && !defer_unload_)
|
| - Unload();
|
| -}
|
| -
|
| -bool PluginLib::Load() {
|
| - if (library_)
|
| - return true;
|
| -
|
| - bool rv = false;
|
| - base::NativeLibrary library = 0;
|
| - base::NativeLibraryLoadError error;
|
| -
|
| -#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, &error);
|
| - }
|
| -#else
|
| - library = base::LoadNativeLibrary(web_plugin_info_.path, &error);
|
| -#endif
|
| -
|
| - if (!library) {
|
| - LOG_IF(ERROR, PluginList::DebugPluginLoading())
|
| - << "Couldn't load plugin " << web_plugin_info_.path.value() << " "
|
| - << error.ToString();
|
| - 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;
|
| -
|
| - 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 (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 is a helper to help perform a delayed NP_Shutdown and FreeLibrary on the
|
| -// plugin dll.
|
| -void FreePluginLibraryHelper(const base::FilePath& path,
|
| - base::NativeLibrary library,
|
| - NP_ShutdownFunc shutdown_func) {
|
| - if (shutdown_func) {
|
| - // 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;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - if (!reloaded)
|
| - shutdown_func();
|
| - }
|
| -
|
| - if (library) {
|
| - // Always call base::UnloadNativeLibrary so that the system reference
|
| - // count is decremented.
|
| - base::UnloadNativeLibrary(library);
|
| - }
|
| -}
|
| -
|
| -void PluginLib::Unload() {
|
| - if (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.
|
| -/* 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_) {
|
| - LOG_IF(ERROR, PluginList::DebugPluginLoading())
|
| - << "Scheduling delayed unload for plugin "
|
| - << web_plugin_info_.path.value();
|
| - base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| - FROM_HERE, base::Bind(&FreePluginLibraryHelper, web_plugin_info_.path,
|
| - skip_unload_ ? NULL : library_,
|
| - entry_points_.np_shutdown));
|
| - } 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_) {
|
| - NP_Shutdown();
|
| - initialized_ = false;
|
| - }
|
| -}
|
| -
|
| -} // namespace content
|
|
|