summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 17:15:00 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 17:15:00 +0000
commitcebc3dc5b2649fba2dd4e5c38197f367cbe296ad (patch)
tree5fdabab303791a373f741fed1caf15b4b967012f /content
parent197d77b84fe78fd08bdfc72553b297111142a9f2 (diff)
downloadchromium_src-cebc3dc5b2649fba2dd4e5c38197f367cbe296ad.zip
chromium_src-cebc3dc5b2649fba2dd4e5c38197f367cbe296ad.tar.gz
chromium_src-cebc3dc5b2649fba2dd4e5c38197f367cbe296ad.tar.bz2
Move PepperPluginRegistry to content, while leaving the Chrome specific bits (NaCl, registration of Chrome plugins like pdf/remoting/flash) behind.
Review URL: http://codereview.chromium.org/6869051 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81959 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/plugin_service.cc2
-rw-r--r--content/browser/ppapi_broker_process_host.cc2
-rw-r--r--content/browser/ppapi_plugin_process_host.cc2
-rw-r--r--content/browser/zygote_main_linux.cc2
-rw-r--r--content/common/content_client.h9
-rw-r--r--content/common/pepper_plugin_registry.cc233
-rw-r--r--content/common/pepper_plugin_registry.h125
-rw-r--r--content/content_common.gypi2
-rw-r--r--content/renderer/pepper_plugin_delegate_impl.cc2
-rw-r--r--content/renderer/render_view.cc2
10 files changed, 373 insertions, 8 deletions
diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc
index 703235e..581e404 100644
--- a/content/browser/plugin_service.cc
+++ b/content/browser/plugin_service.cc
@@ -21,7 +21,6 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/default_plugin.h"
#include "chrome/common/logging_chrome.h"
-#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/common/render_messages.h"
#include "content/browser/browser_thread.h"
#include "content/browser/ppapi_plugin_process_host.h"
@@ -29,6 +28,7 @@
#include "content/browser/renderer_host/render_view_host.h"
#include "content/common/notification_service.h"
#include "content/common/notification_type.h"
+#include "content/common/pepper_plugin_registry.h"
#include "content/common/plugin_messages.h"
#include "content/common/view_messages.h"
#include "webkit/plugins/npapi/plugin_constants_win.h"
diff --git a/content/browser/ppapi_broker_process_host.cc b/content/browser/ppapi_broker_process_host.cc
index a0c8498..57298de 100644
--- a/content/browser/ppapi_broker_process_host.cc
+++ b/content/browser/ppapi_broker_process_host.cc
@@ -9,10 +9,10 @@
#include "base/process_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/common/render_messages.h"
#include "content/browser/plugin_service.h"
#include "content/browser/renderer_host/render_message_filter.h"
+#include "content/common/pepper_plugin_registry.h"
#include "ipc/ipc_switches.h"
#include "ppapi/proxy/ppapi_messages.h"
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
index a19e57a..f1729d8 100644
--- a/content/browser/ppapi_plugin_process_host.cc
+++ b/content/browser/ppapi_plugin_process_host.cc
@@ -9,10 +9,10 @@
#include "base/process_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/common/render_messages.h"
#include "content/browser/plugin_service.h"
#include "content/browser/renderer_host/render_message_filter.h"
+#include "content/common/pepper_plugin_registry.h"
#include "ipc/ipc_switches.h"
#include "ppapi/proxy/ppapi_messages.h"
diff --git a/content/browser/zygote_main_linux.cc b/content/browser/zygote_main_linux.cc
index a0d0ef0..ef9dd0b 100644
--- a/content/browser/zygote_main_linux.cc
+++ b/content/browser/zygote_main_linux.cc
@@ -38,10 +38,10 @@
#include "crypto/nss_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pepper_plugin_registry.h"
#include "content/common/chrome_descriptors.h"
#include "content/common/font_config_ipc_linux.h"
#include "content/common/main_function_params.h"
+#include "content/common/pepper_plugin_registry.h"
#include "content/common/process_watcher.h"
#include "content/common/result_codes.h"
#include "content/common/sandbox_methods_linux.h"
diff --git a/content/common/content_client.h b/content/common/content_client.h
index 9b7da6f..f0a272e 100644
--- a/content/common/content_client.h
+++ b/content/common/content_client.h
@@ -6,10 +6,13 @@
#define CONTENT_COMMON_CONTENT_CLIENT_H_
#pragma once
+#include <vector>
+
#include "base/basictypes.h"
class GURL;
struct GPUInfo;
+struct PepperPluginInfo;
namespace content {
@@ -36,13 +39,15 @@ class ContentClient {
ContentRendererClient* renderer() { return renderer_; }
void set_renderer(ContentRendererClient* r) { renderer_ = r; }
- // Sets the URL that is logged if the child process crashes. Use GURL() to
- // clear the URL.
+ // Sets the currently active URL. Use GURL() to clear the URL.
virtual void SetActiveURL(const GURL& url) {}
// Sets the data on the current gpu.
virtual void SetGpuInfo(const GPUInfo& gpu_info) {}
+ // Gives the embedder a chance to register its own pepper plugins.
+ virtual void AddPepperPlugins(std::vector<PepperPluginInfo>* plugins) {}
+
private:
// The embedder API for participating in browser logic.
ContentBrowserClient* browser_;
diff --git a/content/common/pepper_plugin_registry.cc b/content/common/pepper_plugin_registry.cc
new file mode 100644
index 0000000..2da9a0f
--- /dev/null
+++ b/content/common/pepper_plugin_registry.cc
@@ -0,0 +1,233 @@
+// 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/common/pepper_plugin_registry.h"
+
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/native_library.h"
+#include "base/string_split.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "content/common/child_process.h"
+#include "content/common/content_client.h"
+#include "content/common/content_switches.h"
+#include "webkit/plugins/npapi/plugin_list.h"
+
+namespace {
+
+// Appends any plugins from the command line to the given vector.
+void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
+ bool out_of_process =
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);
+ const std::string value =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kRegisterPepperPlugins);
+ if (value.empty())
+ return;
+
+ // FORMAT:
+ // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
+ // plugin-entry =
+ // <file-path> +
+ // ["#" + <name> + ["#" + <description> + ["#" + <version>]]] +
+ // *1( LWS + ";" + LWS + <mime-type> )
+
+ std::vector<std::string> modules;
+ base::SplitString(value, ',', &modules);
+ for (size_t i = 0; i < modules.size(); ++i) {
+ std::vector<std::string> parts;
+ base::SplitString(modules[i], ';', &parts);
+ if (parts.size() < 2) {
+ DLOG(ERROR) << "Required mime-type not found";
+ continue;
+ }
+
+ std::vector<std::string> name_parts;
+ base::SplitString(parts[0], '#', &name_parts);
+
+ PepperPluginInfo plugin;
+ plugin.is_out_of_process = out_of_process;
+#if defined(OS_WIN)
+ // This means we can't provide plugins from non-ASCII paths, but
+ // since this switch is only for development I don't think that's
+ // too awful.
+ plugin.path = FilePath(ASCIIToUTF16(name_parts[0]));
+#else
+ plugin.path = FilePath(name_parts[0]);
+#endif
+ if (name_parts.size() > 1)
+ plugin.name = name_parts[1];
+ if (name_parts.size() > 2)
+ plugin.description = name_parts[2];
+ if (name_parts.size() > 3)
+ plugin.version = name_parts[3];
+ for (size_t j = 1; j < parts.size(); ++j) {
+ webkit::npapi::WebPluginMimeType mime_type(parts[j],
+ std::string(),
+ plugin.description);
+ plugin.mime_types.push_back(mime_type);
+ }
+
+ plugins->push_back(plugin);
+ }
+}
+
+} // namespace
+
+webkit::npapi::WebPluginInfo PepperPluginInfo::ToWebPluginInfo() const {
+ webkit::npapi::WebPluginInfo info;
+
+ info.name = name.empty() ? path.BaseName().LossyDisplayName() :
+ ASCIIToUTF16(name);
+ info.path = path;
+ info.version = ASCIIToUTF16(version);
+ info.desc = ASCIIToUTF16(description);
+ info.mime_types = mime_types;
+
+ webkit::npapi::WebPluginInfo::EnabledStates enabled_state =
+ webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
+
+ if (!enabled) {
+ enabled_state =
+ webkit::npapi::WebPluginInfo::USER_DISABLED_POLICY_UNMANAGED;
+ }
+
+ info.enabled = enabled_state;
+ return info;
+}
+
+PepperPluginInfo::PepperPluginInfo()
+ : is_internal(false),
+ is_out_of_process(false),
+ enabled(true) {
+}
+
+PepperPluginInfo::~PepperPluginInfo() {
+}
+
+// static
+PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
+ static PepperPluginRegistry* registry = NULL;
+ // This object leaks. It is a temporary hack to work around a crash.
+ // http://code.google.com/p/chromium/issues/detail?id=63234
+ if (!registry)
+ registry = new PepperPluginRegistry;
+ return registry;
+}
+
+// static
+void PepperPluginRegistry::ComputeList(std::vector<PepperPluginInfo>* plugins) {
+ content::GetContentClient()->AddPepperPlugins(plugins);
+ ComputePluginsFromCommandLine(plugins);
+}
+
+// static
+void PepperPluginRegistry::PreloadModules() {
+ std::vector<PepperPluginInfo> plugins;
+ ComputeList(&plugins);
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (!plugins[i].is_internal) {
+ base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
+ LOG_IF(WARNING, !library) << "Unable to load plugin "
+ << plugins[i].path.value();
+ }
+ }
+}
+
+const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
+ const FilePath& path) const {
+ for (size_t i = 0; i < plugin_list_.size(); ++i) {
+ if (path == plugin_list_[i].path)
+ return &plugin_list_[i];
+ }
+ return NULL;
+}
+
+webkit::ppapi::PluginModule* PepperPluginRegistry::GetLiveModule(
+ const FilePath& path) {
+ NonOwningModuleMap::iterator it = live_modules_.find(path);
+ if (it == live_modules_.end())
+ return NULL;
+ return it->second;
+}
+
+void PepperPluginRegistry::AddLiveModule(const FilePath& path,
+ webkit::ppapi::PluginModule* module) {
+ DCHECK(live_modules_.find(path) == live_modules_.end());
+ live_modules_[path] = module;
+}
+
+void PepperPluginRegistry::PluginModuleDead(
+ webkit::ppapi::PluginModule* dead_module) {
+ // DANGER: Don't dereference the dead_module pointer! It may be in the
+ // process of being deleted.
+
+ // Modules aren't destroyed very often and there are normally at most a
+ // couple of them. So for now we just do a brute-force search.
+ for (NonOwningModuleMap::iterator i = live_modules_.begin();
+ i != live_modules_.end(); ++i) {
+ if (i->second == dead_module) {
+ live_modules_.erase(i);
+ return;
+ }
+ }
+ NOTREACHED(); // Should have always found the module above.
+}
+
+PepperPluginRegistry::~PepperPluginRegistry() {
+ // Explicitly clear all preloaded modules first. This will cause callbacks
+ // to erase these modules from the live_modules_ list, and we don't want
+ // that to happen implicitly out-of-order.
+ preloaded_modules_.clear();
+
+ DCHECK(live_modules_.empty());
+}
+
+PepperPluginRegistry::PepperPluginRegistry() {
+ ComputeList(&plugin_list_);
+
+ // Note that in each case, AddLiveModule must be called before completing
+ // initialization. If we bail out (in the continue clauses) before saving
+ // the initialized module, it will still try to unregister itself in its
+ // destructor.
+ for (size_t i = 0; i < plugin_list_.size(); i++) {
+ const PepperPluginInfo& current = plugin_list_[i];
+ if (current.is_out_of_process)
+ continue; // Out of process plugins need no special pre-initialization.
+
+ scoped_refptr<webkit::ppapi::PluginModule> module =
+ new webkit::ppapi::PluginModule(current.name, current.path, this);
+ AddLiveModule(current.path, module);
+ if (current.is_internal) {
+ if (!module->InitAsInternalPlugin(current.internal_entry_points)) {
+ DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
+ continue;
+ }
+ } else {
+ // Preload all external plugins we're not running out of process.
+ if (!module->InitAsLibrary(current.path)) {
+ DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
+ continue;
+ }
+ }
+ preloaded_modules_[current.path] = module;
+ }
+}
+
+MessageLoop* PepperPluginRegistry::GetIPCMessageLoop() {
+ // This is called only in the renderer so we know we have a child process.
+ DCHECK(ChildProcess::current()) << "Must be in the renderer.";
+ return ChildProcess::current()->io_message_loop();
+}
+
+base::WaitableEvent* PepperPluginRegistry::GetShutdownEvent() {
+ DCHECK(ChildProcess::current()) << "Must be in the renderer.";
+ return ChildProcess::current()->GetShutDownEvent();
+}
+
+std::set<PP_Instance>* PepperPluginRegistry::GetGloballySeenInstanceIDSet() {
+ // This function is not needed on the host side of the proxy.
+ return NULL;
+}
diff --git a/content/common/pepper_plugin_registry.h b/content/common/pepper_plugin_registry.h
new file mode 100644
index 0000000..22de281
--- /dev/null
+++ b/content/common/pepper_plugin_registry.h
@@ -0,0 +1,125 @@
+// 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.
+
+#ifndef CONTENT_COMMON_PEPPER_PLUGIN_REGISTRY_H_
+#define CONTENT_COMMON_PEPPER_PLUGIN_REGISTRY_H_
+#pragma once
+
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/file_path.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "webkit/plugins/npapi/webplugininfo.h"
+#include "webkit/plugins/ppapi/plugin_delegate.h"
+#include "webkit/plugins/ppapi/plugin_module.h"
+
+struct PepperPluginInfo {
+ PepperPluginInfo();
+ ~PepperPluginInfo();
+
+ webkit::npapi::WebPluginInfo ToWebPluginInfo() const;
+
+ // Indicates internal plugins for which there's not actually a library.
+ // These plugins are implemented in the Chrome binary using a separate set
+ // of entry points (see internal_entry_points below).
+ // Defaults to false.
+ bool is_internal;
+
+ // True when this plugin should be run out of process. Defaults to false.
+ bool is_out_of_process;
+
+ // Whether the plugin is enabled. Defaults to true.
+ bool enabled;
+
+ FilePath path; // Internal plugins have "internal-[name]" as path.
+ std::string name;
+ std::string description;
+ std::string version;
+ std::vector<webkit::npapi::WebPluginMimeType> mime_types;
+
+ // When is_internal is set, this contains the function pointers to the
+ // entry points for the internal plugins.
+ webkit::ppapi::PluginModule::EntryPoints internal_entry_points;
+};
+
+// This class holds references to all of the known pepper plugin modules.
+//
+// It keeps two lists. One list of preloaded in-process modules, and one list
+// is a list of all live modules (some of which may be out-of-process and hence
+// not preloaded).
+class PepperPluginRegistry
+ : public webkit::ppapi::PluginDelegate::ModuleLifetime,
+ public pp::proxy::Dispatcher::Delegate {
+ public:
+ ~PepperPluginRegistry();
+
+ static PepperPluginRegistry* GetInstance();
+
+ // Computes the list of known pepper plugins.
+ //
+ // This method is static so that it can be used by the browser process, which
+ // has no need to load the pepper plugin modules. It will re-compute the
+ // plugin list every time it is called. Generally, code in the registry should
+ // be using the cached plugin_list_ instead.
+ static void ComputeList(std::vector<PepperPluginInfo>* plugins);
+
+ // Loads the (native) libraries but does not initialize them (i.e., does not
+ // call PPP_InitializeModule). This is needed by the zygote on Linux to get
+ // access to the plugins before entering the sandbox.
+ static void PreloadModules();
+
+ // Retrieves the information associated with the given plugin path. The
+ // return value will be NULL if there is no such plugin.
+ //
+ // The returned pointer is owned by the PluginRegistry.
+ const PepperPluginInfo* GetInfoForPlugin(const FilePath& path) const;
+
+ // Returns an existing loaded module for the given path. It will search for
+ // both preloaded in-process or currently active (non crashed) out-of-process
+ // plugins matching the given name. Returns NULL if the plugin hasn't been
+ // loaded.
+ webkit::ppapi::PluginModule* GetLiveModule(const FilePath& path);
+
+ // Notifies the registry that a new non-preloaded module has been created.
+ // This is normally called for out-of-process plugins. Once this is called,
+ // the module is available to be returned by GetModule(). The module will
+ // automatically unregister itself by calling PluginModuleDestroyed().
+ void AddLiveModule(const FilePath& path, webkit::ppapi::PluginModule* module);
+
+ // ModuleLifetime implementation.
+ virtual void PluginModuleDead(webkit::ppapi::PluginModule* dead_module);
+
+ private:
+ PepperPluginRegistry();
+
+ // Dispatcher::Delegate implementation.
+ virtual MessageLoop* GetIPCMessageLoop();
+ virtual base::WaitableEvent* GetShutdownEvent();
+ virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet();
+
+ // All known pepper plugins.
+ std::vector<PepperPluginInfo> plugin_list_;
+
+ // Plugins that have been preloaded so they can be executed in-process in
+ // the renderer (the sandbox prevents on-demand loading).
+ typedef std::map<FilePath, scoped_refptr<webkit::ppapi::PluginModule> >
+ OwningModuleMap;
+ OwningModuleMap preloaded_modules_;
+
+ // A list of non-owning pointers to all currently-live plugin modules. This
+ // includes both preloaded ones in preloaded_modules_, and out-of-process
+ // modules whose lifetime is managed externally. This will contain only
+ // non-crashed modules. If an out-of-process module crashes, it may
+ // continue as long as there are WebKit references to it, but it will not
+ // appear in this list.
+ typedef std::map<FilePath, webkit::ppapi::PluginModule*> NonOwningModuleMap;
+ NonOwningModuleMap live_modules_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperPluginRegistry);
+};
+
+#endif // CONTENT_COMMON_PEPPER_PLUGIN_REGISTRY_H_
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 7a4c001..6a427c6 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -159,6 +159,8 @@
'common/pepper_file_messages.h',
'common/pepper_messages.cc',
'common/pepper_messages.h',
+ 'common/pepper_plugin_registry.cc',
+ 'common/pepper_plugin_registry.h',
'common/plugin_carbon_interpose_constants_mac.cc',
'common/plugin_carbon_interpose_constants_mac.h',
'common/plugin_messages.h',
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc
index f17a21f6..840c36e 100644
--- a/content/renderer/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper_plugin_delegate_impl.cc
@@ -15,13 +15,13 @@
#include "base/sync_socket.h"
#include "base/task.h"
#include "base/time.h"
-#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/common/render_messages.h"
#include "content/common/audio_messages.h"
#include "content/common/child_process_messages.h"
#include "content/common/child_thread.h"
#include "content/common/file_system/file_system_dispatcher.h"
#include "content/common/pepper_file_messages.h"
+#include "content/common/pepper_plugin_registry.h"
#include "content/common/pepper_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/audio_message_filter.h"
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index a8c30e5..ec7bb75 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -21,7 +21,6 @@
#include "base/sys_string_conversions.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
-#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/common/render_messages.h"
#include "content/common/appcache/appcache_dispatcher.h"
#include "content/common/bindings_policy.h"
@@ -35,6 +34,7 @@
#include "content/common/json_value_serializer.h"
#include "content/common/notification_service.h"
#include "content/common/pepper_messages.h"
+#include "content/common/pepper_plugin_registry.h"
#include "content/common/quota_dispatcher.h"
#include "content/common/renderer_preferences.h"
#include "content/common/url_constants.h"