summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-19 10:38:19 +0000
committerpastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-19 10:38:19 +0000
commit634d23d868d58c80eb320cc6d0e01c14bb47276d (patch)
treef9eb0a9f1c1614fcdb2f1ef7179a5dd59a67703e
parentd14663340d1209756f73a3034335121aa602f3a0 (diff)
downloadchromium_src-634d23d868d58c80eb320cc6d0e01c14bb47276d.zip
chromium_src-634d23d868d58c80eb320cc6d0e01c14bb47276d.tar.gz
chromium_src-634d23d868d58c80eb320cc6d0e01c14bb47276d.tar.bz2
Added automatic update for plugins based on watching file changes.
BUG=48383 TEST=Add or remove some files to a default plugin location and check in about:plugins whether the change got detected. Also part of integration tests. Review URL: http://codereview.chromium.org/6163003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71783 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/plugin_service.cc80
-rw-r--r--chrome/browser/plugin_service.h19
-rw-r--r--webkit/plugins/npapi/plugin_list.h6
3 files changed, 93 insertions, 12 deletions
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index cadc7e2..e136f97c 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -56,6 +56,29 @@ static void NotifyPluginsOfActivation() {
}
#endif
+static void PurgePluginListCache(bool reload_pages) {
+ for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
+ !it.IsAtEnd(); it.Advance()) {
+ it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
+ }
+}
+
+#if defined(OS_LINUX)
+// Delegate class for monitoring directories.
+class PluginDirWatcherDelegate : public FilePathWatcher::Delegate {
+ virtual void OnFilePathChanged(const FilePath& path) {
+ VLOG(1) << "Watched path changed: " << path.value();
+ // Make the plugin list update itself
+ webkit::npapi::PluginList::Singleton()->RefreshPlugins();
+ }
+ virtual void OnError() {
+ // TODO(pastarmovj): Add some sensible error handling. Maybe silently
+ // stopping the watcher would be enough. Or possibly restart it.
+ NOTREACHED();
+ }
+};
+#endif
+
// static
bool PluginService::enable_chrome_plugins_ = true;
@@ -120,6 +143,9 @@ PluginService::PluginService()
chrome::RegisterInternalGPUPlugin();
+ // Start watching for changes in the plugin list. This means watching
+ // for changes in the Windows registry keys and on both Windows and POSIX
+ // watch for changes in the paths that are expected to contain plugins.
#if defined(OS_WIN)
hkcu_key_.Create(
HKEY_CURRENT_USER, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
@@ -143,7 +169,36 @@ PluginService::PluginService()
user_data_dir.Append("Plugins"));
}
#endif
-
+// The FilePathWatcher produces too many false positives on MacOS (access time
+// updates?) which will lead to enforcing updates of the plugins way too often.
+// On ChromeOS the user can't install plugins anyway and on Windows all
+// important plugins register themselves in the registry so no need to do that.
+#if defined(OS_LINUX)
+ file_watcher_delegate_ = new PluginDirWatcherDelegate();
+ // Get the list of all paths for registering the FilePathWatchers
+ // that will track and if needed reload the list of plugins on runtime.
+ std::vector<FilePath> plugin_dirs;
+ webkit::npapi::PluginList::Singleton()->GetPluginDirectories(
+ &plugin_dirs);
+
+ for (size_t i = 0; i < plugin_dirs.size(); ++i) {
+ FilePathWatcher* watcher = new FilePathWatcher();
+ // FilePathWatcher can not handle non-absolute paths under windows.
+ // We don't watch for file changes in windows now but if this should ever
+ // be extended to Windows these lines might save some time of debugging.
+#if defined(OS_WIN)
+ if (!plugin_dirs[i].IsAbsolute())
+ continue;
+#endif
+ VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value();
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableFunction(
+ &PluginService::RegisterFilePathWatcher,
+ watcher, plugin_dirs[i], file_watcher_delegate_));
+ file_watchers_.push_back(watcher);
+ }
+#endif
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
NotificationService::AllSources());
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
@@ -302,13 +357,6 @@ bool PluginService::GetFirstAllowedPluginInfo(
#endif
}
-static void PurgePluginListCache(bool reload_pages) {
- for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
- !it.IsAtEnd(); it.Advance()) {
- it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
- }
-}
-
void PluginService::OnWaitableEventSignaled(
base::WaitableEvent* waitable_event) {
#if defined(OS_WIN)
@@ -320,6 +368,9 @@ void PluginService::OnWaitableEventSignaled(
webkit::npapi::PluginList::Singleton()->RefreshPlugins();
PurgePluginListCache(true);
+#else
+ // This event should only get signaled on a Windows machine.
+ NOTREACHED();
#endif // defined(OS_WIN)
}
@@ -384,7 +435,7 @@ void PluginService::Observe(NotificationType type,
break;
}
default:
- DCHECK(false);
+ NOTREACHED();
}
}
@@ -426,3 +477,14 @@ void PluginService::RegisterPepperPlugins() {
webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info);
}
}
+
+#if defined(OS_LINUX)
+// static
+void PluginService::RegisterFilePathWatcher(
+ FilePathWatcher *watcher,
+ const FilePath& path,
+ FilePathWatcher::Delegate* delegate) {
+ bool result = watcher->Watch(path, delegate);
+ DCHECK(result);
+}
+#endif
diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h
index e90f6a7..5e03c09 100644
--- a/chrome/browser/plugin_service.h
+++ b/chrome/browser/plugin_service.h
@@ -14,6 +14,7 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/hash_tables.h"
+#include "base/scoped_vector.h"
#include "base/singleton.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "build/build_config.h"
@@ -28,6 +29,10 @@
#include "base/win/registry.h"
#endif
+#if defined(OS_LINUX)
+#include "chrome/browser/file_path_watcher/file_path_watcher.h"
+#endif
+
#if defined(OS_CHROMEOS)
namespace chromeos {
class PluginSelectionPolicy;
@@ -40,6 +45,7 @@ class Message;
class MessageLoop;
class Profile;
+class PluginDirWatcherDelegate;
class ResourceDispatcherHost;
namespace net {
@@ -144,6 +150,14 @@ class PluginService
const FilePath& plugin_path,
PluginProcessHost::Client* client);
+#if defined(OS_LINUX)
+ // Registers a new FilePathWatcher for a given path.
+ static void RegisterFilePathWatcher(
+ FilePathWatcher* watcher,
+ const FilePath& path,
+ FilePathWatcher::Delegate* delegate);
+#endif
+
// mapping between plugin path and PluginProcessHost
typedef base::hash_map<FilePath, PluginProcessHost*> PluginMap;
PluginMap plugin_hosts_;
@@ -181,6 +195,11 @@ class PluginService
base::WaitableEventWatcher hklm_watcher_;
#endif
+#if defined(OS_LINUX)
+ ScopedVector<FilePathWatcher> file_watchers_;
+ scoped_refptr<PluginDirWatcherDelegate> file_watcher_delegate_;
+#endif
+
// Set to true if chrome plugins are enabled. Defaults to true.
static bool enable_chrome_plugins_;
diff --git a/webkit/plugins/npapi/plugin_list.h b/webkit/plugins/npapi/plugin_list.h
index 553b554..84026eb 100644
--- a/webkit/plugins/npapi/plugin_list.h
+++ b/webkit/plugins/npapi/plugin_list.h
@@ -97,6 +97,9 @@ class PluginList {
// Same as above, but specifies a directory in which to search for plugins.
void AddExtraPluginDir(const FilePath& plugin_dir);
+ // Get the ordered list of directories from which to load plugins
+ void GetPluginDirectories(std::vector<FilePath>* plugin_dirs);
+
// 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().
@@ -283,9 +286,6 @@ class PluginList {
// Do any initialization.
void PlatformInit();
- // Get the ordered list of directories from which to load plugins
- void GetPluginDirectories(std::vector<FilePath>* plugin_dirs);
-
//
// Command-line switches
//