diff options
author | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-19 10:38:19 +0000 |
---|---|---|
committer | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-19 10:38:19 +0000 |
commit | 634d23d868d58c80eb320cc6d0e01c14bb47276d (patch) | |
tree | f9eb0a9f1c1614fcdb2f1ef7179a5dd59a67703e | |
parent | d14663340d1209756f73a3034335121aa602f3a0 (diff) | |
download | chromium_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.cc | 80 | ||||
-rw-r--r-- | chrome/browser/plugin_service.h | 19 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_list.h | 6 |
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 // |