summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension.cc13
-rw-r--r--chrome/browser/extensions/extension.h10
-rw-r--r--chrome/browser/extensions/extensions_service.cc17
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc2
-rw-r--r--chrome/browser/plugin_service.cc6
-rw-r--r--chrome/browser/plugin_service.h5
-rw-r--r--chrome/test/data/extensions/good/extension2/2/manifest.json3
-rw-r--r--webkit/glue/plugins/plugin_list.cc20
-rw-r--r--webkit/glue/plugins/plugin_list.h10
9 files changed, 80 insertions, 6 deletions
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
index b886d85..d75ed5e 100644
--- a/chrome/browser/extensions/extension.cc
+++ b/chrome/browser/extensions/extension.cc
@@ -25,6 +25,7 @@ const wchar_t* Extension::kNameKey = L"name";
const wchar_t* Extension::kRunAtKey = L"run_at";
const wchar_t* Extension::kVersionKey = L"version";
const wchar_t* Extension::kZipHashKey = L"zip_hash";
+const wchar_t* Extension::kPluginsDirKey = L"plugins_dir";
const char* Extension::kRunAtDocumentStartValue = "document_start";
const char* Extension::kRunAtDocumentEndValue = "document_end";
@@ -67,6 +68,8 @@ const char* Extension::kInvalidVersionError =
"Required value 'version' is missing or invalid.";
const char* Extension::kInvalidZipHashError =
"Required key 'zip_hash' is missing or invalid.";
+const char* Extension::kInvalidPluginsDirError =
+ "Invalid value for 'plugins_dir'.";
const std::string Extension::VersionString() const {
return version_->GetString();
@@ -230,6 +233,16 @@ bool Extension::InitFromValue(const DictionaryValue& source,
}
}
+ // Initialize plugins dir (optional).
+ if (source.HasKey(kPluginsDirKey)) {
+ std::string plugins_dir;
+ if (!source.GetString(kPluginsDirKey, &plugins_dir)) {
+ *error = kInvalidPluginsDirError;
+ return false;
+ }
+ plugins_dir_ = path_.AppendASCII(plugins_dir);
+ }
+
// Initialize content scripts (optional).
if (source.HasKey(kContentScriptsKey)) {
ListValue* list_value;
diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h
index eae110c..cc44cd5 100644
--- a/chrome/browser/extensions/extension.h
+++ b/chrome/browser/extensions/extension.h
@@ -47,6 +47,7 @@ class Extension {
static const wchar_t* kRunAtKey;
static const wchar_t* kVersionKey;
static const wchar_t* kZipHashKey;
+ static const wchar_t* kPluginsDirKey;
// Some values expected in manifests.
static const char* kRunAtDocumentStartValue;
@@ -69,6 +70,7 @@ class Extension {
static const char* kInvalidRunAtError;
static const char* kInvalidVersionError;
static const char* kInvalidZipHashError;
+ static const char* kInvalidPluginsDirError;
// Creates an absolute url to a resource inside an extension. The
// |extension_url| argument should be the url() from an Extension object. The
@@ -117,6 +119,11 @@ class Extension {
return content_scripts_;
}
+ // Path to the directory of NPAPI plugins that the extension contains.
+ const FilePath& plugins_dir() const {
+ return plugins_dir_;
+ }
+
// Initialize the extension from a parsed manifest.
bool InitFromValue(const DictionaryValue& value, std::string* error);
@@ -142,6 +149,9 @@ class Extension {
// Paths to the content scripts the extension contains.
UserScriptList content_scripts_;
+ // Path to the directory of NPAPI plugins that the extension contains.
+ FilePath plugins_dir_;
+
// A SHA1 hash of the contents of the zip file. Note that this key is only
// present in the manifest that's prepended to the zip. The inner manifest
// will not have this key.
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 13d43a5..2f10da0 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -15,6 +15,7 @@
#include "net/base/file_stream.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/user_script_master.h"
+#include "chrome/browser/plugin_service.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/unzip.h"
@@ -101,9 +102,23 @@ void ExtensionsService::OnExtensionsLoadedFromDirectory(
extensions_.insert(extensions_.end(), new_extensions->begin(),
new_extensions->end());
- // Tell UserScriptMaster about any scripts in the loaded extensions.
+ bool found_plugin = false;
+
+ // TODO: Fix race here. A page could need a user script on startup, before
+ // the user script is loaded. We need to freeze the renderer in that case.
+ // TODO(mpcomplete): We also need to force a renderer to refresh its cache of
+ // the plugin list when we inject user scripts, since it could have a stale
+ // version by the time extensions are loaded.
+
for (ExtensionList::iterator extension = extensions_.begin();
extension != extensions_.end(); ++extension) {
+ // Tell NPAPI about any plugins in the loaded extensions.
+ if (!(*extension)->plugins_dir().empty()) {
+ PluginService::GetInstance()->AddExtraPluginDir(
+ (*extension)->plugins_dir());
+ }
+
+ // Tell UserScriptMaster about any scripts in the loaded extensions.
const UserScriptList& scripts = (*extension)->content_scripts();
for (UserScriptList::const_iterator script = scripts.begin();
script != scripts.end(); ++script) {
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 4c38801..6040823 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -177,6 +177,8 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
frontend->extensions()->at(1)->name());
EXPECT_EQ(std::string(""),
frontend->extensions()->at(1)->description());
+ EXPECT_EQ(frontend->extensions()->at(1)->path().AppendASCII("npapi").value(),
+ frontend->extensions()->at(1)->plugins_dir().value());
ASSERT_EQ(0u, frontend->extensions()->at(1)->content_scripts().size());
EXPECT_EQ(std::string("com.google.myextension3"),
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index 7889f79..ea25346 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -69,6 +69,12 @@ const FilePath& PluginService::GetChromePluginDataDir() {
return chrome_plugin_data_dir_;
}
+void PluginService::AddExtraPluginDir(const FilePath& plugin_dir) {
+ AutoLock lock(lock_);
+ NPAPI::PluginList::ResetPluginsLoaded();
+ NPAPI::PluginList::AddExtraPluginDir(plugin_dir);
+}
+
const std::wstring& PluginService::GetUILocale() {
return ui_locale_;
}
diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h
index 42c0cf6..d4f9368 100644
--- a/chrome/browser/plugin_service.h
+++ b/chrome/browser/plugin_service.h
@@ -47,6 +47,11 @@ class PluginService {
void SetChromePluginDataDir(const FilePath& data_dir);
const FilePath& GetChromePluginDataDir();
+ // Add an extra plugin directory to scan when we actually do the loading.
+ // This will force a refresh of the plugin list the next time plugins are
+ // requested.
+ void AddExtraPluginDir(const FilePath& plugin_dir);
+
// Gets the browser's UI locale.
const std::wstring& GetUILocale();
diff --git a/chrome/test/data/extensions/good/extension2/2/manifest.json b/chrome/test/data/extensions/good/extension2/2/manifest.json
index 4e157c4..5e727ec 100644
--- a/chrome/test/data/extensions/good/extension2/2/manifest.json
+++ b/chrome/test/data/extensions/good/extension2/2/manifest.json
@@ -2,5 +2,6 @@
"format_version": 1,
"id": "com.google.myextension2",
"version": "1.0.0.0",
- "name": "My extension 2"
+ "name": "My extension 2",
+ "plugins_dir": "npapi"
}
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index 3f308d6..a2e369e 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -36,17 +36,25 @@ PluginList* PluginList::Singleton() {
}
// static
-void PluginList::AddExtraPluginPath(const FilePath& plugin_path) {
+void PluginList::ResetPluginsLoaded() {
// We access the singleton directly, and not through Singleton(), since
// we don't want LoadPlugins() to be called.
- DCHECK(!g_singleton.Pointer()->plugins_loaded_);
+ g_singleton.Pointer()->plugins_loaded_ = false;
+}
+// static
+void PluginList::AddExtraPluginPath(const FilePath& plugin_path) {
+ DCHECK(!g_singleton.Pointer()->plugins_loaded_);
g_singleton.Pointer()->extra_plugin_paths_.push_back(plugin_path);
}
+// static
+void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) {
+ DCHECK(!g_singleton.Pointer()->plugins_loaded_);
+ g_singleton.Pointer()->extra_plugin_dirs_.push_back(plugin_dir);
+}
+
void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) {
- // We access the singleton directly, and not through Singleton(), since
- // we don't want LoadPlugins() to be called.
DCHECK(!g_singleton.Pointer()->plugins_loaded_);
g_singleton.Pointer()->internal_plugins_.push_back(info);
}
@@ -157,6 +165,10 @@ void PluginList::LoadPlugins(bool refresh) {
LoadPluginsFromDir(directories_to_scan[i]);
}
+ for (size_t i = 0; i < extra_plugin_dirs_.size(); ++i) {
+ LoadPluginsFromDir(extra_plugin_dirs_[i]);
+ }
+
for (size_t i = 0; i < extra_plugin_paths_.size(); ++i)
LoadPlugin(extra_plugin_paths_[i]);
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index d64131e..3b7b84a 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -75,11 +75,18 @@ class PluginList {
// the first time.
static PluginList* Singleton();
+ // Clear the plugins_loaded_ bit to force a refresh next time we retrieve
+ // plugins.
+ static void ResetPluginsLoaded();
+
// Add an extra plugin to load when we actually do the loading. This is
// static because we want to be able to add to it without searching the disk
// for plugins. Must be called before the plugins have been loaded.
static void AddExtraPluginPath(const FilePath& plugin_path);
+ // Same as above, but specifies a directory in which to search for plugins.
+ static void AddExtraPluginDir(const FilePath& plugin_dir);
+
// Register an internal plugin with the specified plugin information and
// function pointers. An internal plugin must be registered before it can
// be loaded using PluginList::LoadPlugin().
@@ -204,6 +211,9 @@ class PluginList {
// Extra plugin paths that we want to search when loading.
std::vector<FilePath> extra_plugin_paths_;
+ // Extra plugin directories that we want to search when loading.
+ std::vector<FilePath> extra_plugin_dirs_;
+
// Holds information about internal plugins.
std::vector<PluginVersionInfo> internal_plugins_;