Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: chrome/browser/plugin_service.cc

Issue 6163003: Added automatic update for plugins based on watching file changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Limited the file watcher to Linux only. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/plugin_service.h ('k') | webkit/plugins/npapi/plugin_list.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/plugin_service.h" 5 #include "chrome/browser/plugin_service.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/stl_util-inl.h"
11 #include "base/string_util.h" 12 #include "base/string_util.h"
12 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
13 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 #include "base/synchronization/waitable_event.h" 16 #include "base/synchronization/waitable_event.h"
16 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/browser_thread.h" 18 #include "chrome/browser/browser_thread.h"
18 #include "chrome/browser/chrome_plugin_host.h" 19 #include "chrome/browser/chrome_plugin_host.h"
19 #include "chrome/browser/extensions/extension_service.h" 20 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/plugin_updater.h" 21 #include "chrome/browser/plugin_updater.h"
(...skipping 28 matching lines...) Expand all
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
50 51
51 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); 52 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
52 !iter.Done(); ++iter) { 53 !iter.Done(); ++iter) {
53 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); 54 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
54 plugin->OnAppActivation(); 55 plugin->OnAppActivation();
55 } 56 }
56 } 57 }
57 #endif 58 #endif
58 59
60 static void PurgePluginListCache(bool reload_pages) {
61 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
62 !it.IsAtEnd(); it.Advance()) {
63 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
64 }
65 }
66
67 #if defined(OS_LINUX)
68 // Delegate class for monitoring directories.
69 class PluginDirWatcherDelegate : public FilePathWatcher::Delegate {
70 virtual void OnFilePathChanged(const FilePath& path) {
71 VLOG(1) << "Watched path changed: " << path.value();
72 // Make the plugin list update itself
73 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
74 }
75 virtual void OnError() {
76 // TODO(pastarmovj): Add some sensible error handling. Maybe silently
77 // stopping the watcher would be enough. Or possibly restart it.
78 NOTREACHED();
79 }
80 };
81 #endif
82
59 // static 83 // static
60 bool PluginService::enable_chrome_plugins_ = true; 84 bool PluginService::enable_chrome_plugins_ = true;
61 85
62 // static 86 // static
63 void PluginService::InitGlobalInstance(Profile* profile) { 87 void PluginService::InitGlobalInstance(Profile* profile) {
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
65 89
66 // We first group the plugins and then figure out which groups to disable. 90 // We first group the plugins and then figure out which groups to disable.
67 PluginUpdater::GetInstance()->DisablePluginGroupsFromPrefs(profile); 91 PluginUpdater::GetInstance()->DisablePluginGroupsFromPrefs(profile);
68 92
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 137 }
114 #endif 138 #endif
115 139
116 #if defined(OS_CHROMEOS) 140 #if defined(OS_CHROMEOS)
117 plugin_selection_policy_ = new chromeos::PluginSelectionPolicy; 141 plugin_selection_policy_ = new chromeos::PluginSelectionPolicy;
118 plugin_selection_policy_->StartInit(); 142 plugin_selection_policy_->StartInit();
119 #endif 143 #endif
120 144
121 chrome::RegisterInternalGPUPlugin(); 145 chrome::RegisterInternalGPUPlugin();
122 146
147 // Start watching for changes in the plugin list. This means watching
148 // for changes in the Windows registry keys and on both Windows and POSIX
149 // watch for changes in the paths that are expected to contain plugins.
123 #if defined(OS_WIN) 150 #if defined(OS_WIN)
124 hkcu_key_.Create( 151 hkcu_key_.Create(
125 HKEY_CURRENT_USER, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY); 152 HKEY_CURRENT_USER, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
126 hklm_key_.Create( 153 hklm_key_.Create(
127 HKEY_LOCAL_MACHINE, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY); 154 HKEY_LOCAL_MACHINE, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
128 if (hkcu_key_.StartWatching()) { 155 if (hkcu_key_.StartWatching()) {
129 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event())); 156 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event()));
130 hkcu_watcher_.StartWatching(hkcu_event_.get(), this); 157 hkcu_watcher_.StartWatching(hkcu_event_.get(), this);
131 } 158 }
132 159
133 if (hklm_key_.StartWatching()) { 160 if (hklm_key_.StartWatching()) {
134 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event())); 161 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event()));
135 hklm_watcher_.StartWatching(hklm_event_.get(), this); 162 hklm_watcher_.StartWatching(hklm_event_.get(), this);
136 } 163 }
137 #elif defined(OS_POSIX) && !defined(OS_MACOSX) 164 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
138 // Also find plugins in a user-specific plugins dir, 165 // Also find plugins in a user-specific plugins dir,
139 // e.g. ~/.config/chromium/Plugins. 166 // e.g. ~/.config/chromium/Plugins.
140 FilePath user_data_dir; 167 FilePath user_data_dir;
141 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { 168 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
142 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir( 169 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(
143 user_data_dir.Append("Plugins")); 170 user_data_dir.Append("Plugins"));
144 } 171 }
145 #endif 172 #endif
173 // The FilePathWatcher produces too many false positives on MacOS (access time
174 // updates?) which will lead to enforcing updates of the plugins way too often.
175 // On ChromeOS the user can't install plugins anywaya and on Windows all
176 // important pluigns register themselves in the registry so no need to do that.
jam 2011/01/18 20:21:31 nit: plugins
177 #if defined(OS_LINUX)
178 file_watcher_delegate_ = new PluginDirWatcherDelegate();
179 // Get the list of all paths for registering the FilePathWatchers
180 // that will track and if needed reload the list of plugins on runtime.
181 std::vector<FilePath> plugin_dirs;
182 webkit::npapi::PluginList::Singleton()->GetPluginDirectories(
183 &plugin_dirs);
146 184
185 for (size_t i = 0; i < plugin_dirs.size(); ++i) {
186 FilePathWatcher* watcher = new FilePathWatcher();
187 // FilePathWatcher can not handle non-absolute paths under windows.
188 // We don't watch for file changes in windows now but if this should ever
189 // be extended to Windows these lines might save some time of debugging.
190 #if defined(OS_WIN)
191 if (!plugin_dirs[i].IsAbsolute())
192 continue;
193 #endif
194 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value();
195 BrowserThread::PostTask(
196 BrowserThread::FILE, FROM_HERE,
197 NewRunnableFunction(
198 &PluginService::RegisterFilePathWatcher,
199 watcher, plugin_dirs[i], file_watcher_delegate_));
200 file_watchers_.push_back(watcher);
201 }
202 #endif
147 registrar_.Add(this, NotificationType::EXTENSION_LOADED, 203 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
148 NotificationService::AllSources()); 204 NotificationService::AllSources());
149 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, 205 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
150 NotificationService::AllSources()); 206 NotificationService::AllSources());
151 #if defined(OS_MACOSX) 207 #if defined(OS_MACOSX)
152 // We need to know when the browser comes forward so we can bring modal plugin 208 // We need to know when the browser comes forward so we can bring modal plugin
153 // windows forward too. 209 // windows forward too.
154 registrar_.Add(this, NotificationType::APP_ACTIVATED, 210 registrar_.Add(this, NotificationType::APP_ACTIVATED,
155 NotificationService::AllSources()); 211 NotificationService::AllSources());
156 #endif 212 #endif
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 *actual_mime_type = actual_mime_types[allowed_index]; 351 *actual_mime_type = actual_mime_types[allowed_index];
296 return true; 352 return true;
297 } 353 }
298 return false; 354 return false;
299 #else 355 #else
300 return webkit::npapi::PluginList::Singleton()->GetPluginInfo( 356 return webkit::npapi::PluginList::Singleton()->GetPluginInfo(
301 url, mime_type, allow_wildcard, info, actual_mime_type); 357 url, mime_type, allow_wildcard, info, actual_mime_type);
302 #endif 358 #endif
303 } 359 }
304 360
305 static void PurgePluginListCache(bool reload_pages) {
306 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
307 !it.IsAtEnd(); it.Advance()) {
308 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
309 }
310 }
311
312 void PluginService::OnWaitableEventSignaled( 361 void PluginService::OnWaitableEventSignaled(
313 base::WaitableEvent* waitable_event) { 362 base::WaitableEvent* waitable_event) {
314 #if defined(OS_WIN) 363 #if defined(OS_WIN)
315 if (waitable_event == hkcu_event_.get()) { 364 if (waitable_event == hkcu_event_.get()) {
316 hkcu_key_.StartWatching(); 365 hkcu_key_.StartWatching();
317 } else { 366 } else {
318 hklm_key_.StartWatching(); 367 hklm_key_.StartWatching();
319 } 368 }
320 369
321 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); 370 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
322 PurgePluginListCache(true); 371 PurgePluginListCache(true);
372 #else
373 // This event should only get signaled on a Windows machine.
374 NOTREACHED();
323 #endif // defined(OS_WIN) 375 #endif // defined(OS_WIN)
324 } 376 }
325 377
326 static void ForceShutdownPlugin(const FilePath& plugin_path) { 378 static void ForceShutdownPlugin(const FilePath& plugin_path) {
327 PluginProcessHost* plugin = 379 PluginProcessHost* plugin =
328 PluginService::GetInstance()->FindPluginProcess(plugin_path); 380 PluginService::GetInstance()->FindPluginProcess(plugin_path);
329 if (plugin) 381 if (plugin)
330 plugin->ForceShutdown(); 382 plugin->ForceShutdown();
331 } 383 }
332 384
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 NewRunnableFunction(&NotifyPluginsOfActivation)); 429 NewRunnableFunction(&NotifyPluginsOfActivation));
378 break; 430 break;
379 } 431 }
380 #endif 432 #endif
381 433
382 case NotificationType::PLUGIN_ENABLE_STATUS_CHANGED: { 434 case NotificationType::PLUGIN_ENABLE_STATUS_CHANGED: {
383 PurgePluginListCache(false); 435 PurgePluginListCache(false);
384 break; 436 break;
385 } 437 }
386 default: 438 default:
387 DCHECK(false); 439 NOTREACHED();
388 } 440 }
389 } 441 }
390 442
391 bool PluginService::PrivatePluginAllowedForURL(const FilePath& plugin_path, 443 bool PluginService::PrivatePluginAllowedForURL(const FilePath& plugin_path,
392 const GURL& url) { 444 const GURL& url) {
393 if (url.is_empty()) 445 if (url.is_empty())
394 return true; // Caller wants all plugins. 446 return true; // Caller wants all plugins.
395 447
396 PrivatePluginMap::iterator it = private_plugins_.find(plugin_path); 448 PrivatePluginMap::iterator it = private_plugins_.find(plugin_path);
397 if (it == private_plugins_.end()) 449 if (it == private_plugins_.end())
(...skipping 21 matching lines...) Expand all
419 info.mime_types = ASCIIToWide(JoinString(plugins[i].mime_types, '|')); 471 info.mime_types = ASCIIToWide(JoinString(plugins[i].mime_types, '|'));
420 472
421 // These NPAPI entry points will never be called. TODO(darin): Come up 473 // These NPAPI entry points will never be called. TODO(darin): Come up
422 // with a cleaner way to register pepper plugins with the NPAPI PluginList, 474 // with a cleaner way to register pepper plugins with the NPAPI PluginList,
423 // or perhaps refactor the PluginList to be less specific to NPAPI. 475 // or perhaps refactor the PluginList to be less specific to NPAPI.
424 memset(&info.entry_points, 0, sizeof(info.entry_points)); 476 memset(&info.entry_points, 0, sizeof(info.entry_points));
425 477
426 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info); 478 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info);
427 } 479 }
428 } 480 }
481
482 #if defined(OS_LINUX)
483 // static
484 void PluginService::RegisterFilePathWatcher(
485 FilePathWatcher *watcher,
486 const FilePath& path,
487 FilePathWatcher::Delegate* delegate) {
488 bool result = watcher->Watch(path, delegate);
489 DCHECK(result);
490 }
491 #endif
OLDNEW
« no previous file with comments | « chrome/browser/plugin_service.h ('k') | webkit/plugins/npapi/plugin_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698