blob: e136f97c9e353d5a42c196914dd7392702e90ccf [file] [log] [blame]
[email protected]cec1b8d2010-03-24 00:21:341// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/plugin_service.h"
6
[email protected]ceac9972011-01-13 01:51:147#include <vector>
8
[email protected]d48f1e0c2009-02-12 20:57:549#include "base/command_line.h"
[email protected]9c49ff02010-01-27 01:20:5510#include "base/path_service.h"
[email protected]d70539de2009-06-24 22:17:0611#include "base/string_util.h"
[email protected]34b99632011-01-01 01:01:0612#include "base/threading/thread.h"
[email protected]be1ce6a72010-08-03 14:35:2213#include "base/utf_string_conversions.h"
[email protected]cec1b8d2010-03-24 00:21:3414#include "base/values.h"
[email protected]44f9c952011-01-02 06:05:3915#include "base/synchronization/waitable_event.h"
initial.commit09911bf2008-07-26 23:55:2916#include "chrome/browser/browser_process.h"
[email protected]017a7a112010-10-12 16:38:2717#include "chrome/browser/browser_thread.h"
initial.commit09911bf2008-07-26 23:55:2918#include "chrome/browser/chrome_plugin_host.h"
[email protected]eaa7dd182010-12-14 11:09:0019#include "chrome/browser/extensions/extension_service.h"
[email protected]0a8b1e22010-07-02 09:31:1120#include "chrome/browser/plugin_updater.h"
[email protected]8ecad5e2010-12-02 21:18:3321#include "chrome/browser/profiles/profile.h"
[email protected]8c8657d62009-01-16 18:31:2622#include "chrome/browser/renderer_host/render_process_host.h"
initial.commit09911bf2008-07-26 23:55:2923#include "chrome/common/chrome_plugin_lib.h"
[email protected]9c49ff02010-01-27 01:20:5524#include "chrome/common/chrome_paths.h"
[email protected]d48f1e0c2009-02-12 20:57:5425#include "chrome/common/chrome_switches.h"
[email protected]2290cb862010-06-02 16:50:5826#include "chrome/common/default_plugin.h"
[email protected]5b1a0e22009-05-26 19:00:5827#include "chrome/common/extensions/extension.h"
[email protected]7477ea6f2009-12-22 23:28:1528#include "chrome/common/gpu_plugin.h"
initial.commit09911bf2008-07-26 23:55:2929#include "chrome/common/logging_chrome.h"
[email protected]894bb502009-05-21 22:39:5730#include "chrome/common/notification_type.h"
31#include "chrome/common/notification_service.h"
[email protected]4e0616e2010-05-28 14:55:5332#include "chrome/common/pepper_plugin_registry.h"
[email protected]4e59e812010-04-06 20:51:1633#include "chrome/common/plugin_messages.h"
[email protected]b547fd42009-04-23 23:16:2734#include "chrome/common/render_messages.h"
[email protected]191eb3f72010-12-21 06:27:5035#include "webkit/plugins/npapi/plugin_constants_win.h"
36#include "webkit/plugins/npapi/plugin_list.h"
37#include "webkit/plugins/npapi/webplugininfo.h"
38
[email protected]d8c7cbcc2009-10-02 19:00:3139#ifndef DISABLE_NACL
[email protected]d032f492009-09-29 00:33:4640#include "native_client/src/trusted/plugin/nacl_entry_points.h"
[email protected]d8c7cbcc2009-10-02 19:00:3141#endif
[email protected]6fdd4182010-10-14 23:59:2642
43#if defined(OS_CHROMEOS)
44#include "chrome/browser/chromeos/plugin_selection_policy.h"
45#endif
initial.commit09911bf2008-07-26 23:55:2946
[email protected]a96ec6a2009-11-04 17:27:0847#if defined(OS_MACOSX)
48static void NotifyPluginsOfActivation() {
[email protected]f8b3ef82010-10-11 02:45:5249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]a96ec6a2009-11-04 17:27:0850
[email protected]d27893f62010-07-03 05:47:4251 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a96ec6a2009-11-04 17:27:0852 !iter.Done(); ++iter) {
53 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
54 plugin->OnAppActivation();
55 }
56}
57#endif
58
[email protected]634d23d2011-01-19 10:38:1959static void PurgePluginListCache(bool reload_pages) {
60 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
61 !it.IsAtEnd(); it.Advance()) {
62 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
63 }
64}
65
66#if defined(OS_LINUX)
67// Delegate class for monitoring directories.
68class PluginDirWatcherDelegate : public FilePathWatcher::Delegate {
69 virtual void OnFilePathChanged(const FilePath& path) {
70 VLOG(1) << "Watched path changed: " << path.value();
71 // Make the plugin list update itself
72 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
73 }
74 virtual void OnError() {
75 // TODO(pastarmovj): Add some sensible error handling. Maybe silently
76 // stopping the watcher would be enough. Or possibly restart it.
77 NOTREACHED();
78 }
79};
80#endif
81
initial.commit09911bf2008-07-26 23:55:2982// static
[email protected]51549da2009-11-21 08:43:3983bool PluginService::enable_chrome_plugins_ = true;
84
85// static
[email protected]cec1b8d2010-03-24 00:21:3486void PluginService::InitGlobalInstance(Profile* profile) {
[email protected]f8b3ef82010-10-11 02:45:5287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]cec1b8d2010-03-24 00:21:3488
[email protected]0a8b1e22010-07-02 09:31:1189 // We first group the plugins and then figure out which groups to disable.
[email protected]8e8bb6d2010-12-13 08:18:5590 PluginUpdater::GetInstance()->DisablePluginGroupsFromPrefs(profile);
[email protected]7bf795d92010-05-22 00:14:2891
[email protected]cec1b8d2010-03-24 00:21:3492 // Have Chrome plugins write their data to the profile directory.
93 GetInstance()->SetChromePluginDataDir(profile->GetPath());
94}
95
96// static
initial.commit09911bf2008-07-26 23:55:2997PluginService* PluginService::GetInstance() {
98 return Singleton<PluginService>::get();
99}
100
[email protected]51549da2009-11-21 08:43:39101// static
102void PluginService::EnableChromePlugins(bool enable) {
103 enable_chrome_plugins_ = enable;
104}
105
initial.commit09911bf2008-07-26 23:55:29106PluginService::PluginService()
107 : main_message_loop_(MessageLoop::current()),
initial.commit09911bf2008-07-26 23:55:29108 resource_dispatcher_host_(NULL),
[email protected]f77d87622010-07-30 17:43:17109 ui_locale_(g_browser_process->GetApplicationLocale()) {
[email protected]4e0616e2010-05-28 14:55:53110 RegisterPepperPlugins();
111
initial.commit09911bf2008-07-26 23:55:29112 // Have the NPAPI plugin list search for Chrome plugins as well.
113 ChromePluginLib::RegisterPluginsWithNPAPI();
[email protected]9a1c4262010-06-29 21:50:27114
115 // Load any specified on the command line as well.
[email protected]d48f1e0c2009-02-12 20:57:54116 const CommandLine* command_line = CommandLine::ForCurrentProcess();
[email protected]c4e52f0d2009-11-06 19:55:16117 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin);
[email protected]7bf795d92010-05-22 00:14:28118 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:50119 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
[email protected]9a1c4262010-06-29 21:50:27120 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir);
121 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:50122 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path);
[email protected]7bf795d92010-05-22 00:14:28123
[email protected]2290cb862010-06-02 16:50:58124 chrome::RegisterInternalDefaultPlugin();
125
[email protected]7bf795d92010-05-22 00:14:28126 // Register the internal Flash and PDF, if available.
127 if (!CommandLine::ForCurrentProcess()->HasSwitch(
128 switches::kDisableInternalFlash) &&
129 PathService::Get(chrome::FILE_FLASH_PLUGIN, &path)) {
[email protected]191eb3f72010-12-21 06:27:50130 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
[email protected]35fa6a22009-08-15 00:04:01131 }
[email protected]d7ce4272010-03-27 01:06:01132
[email protected]d8c7cbcc2009-10-02 19:00:31133#ifndef DISABLE_NACL
[email protected]5cad70a82010-09-03 22:14:11134 if (command_line->HasSwitch(switches::kInternalNaCl)) {
135 RegisterInternalNaClPlugin();
136 }
[email protected]d8c7cbcc2009-10-02 19:00:31137#endif
[email protected]b547fd42009-04-23 23:16:27138
[email protected]6fdd4182010-10-14 23:59:26139#if defined(OS_CHROMEOS)
140 plugin_selection_policy_ = new chromeos::PluginSelectionPolicy;
141 plugin_selection_policy_->StartInit();
142#endif
143
[email protected]7477ea6f2009-12-22 23:28:15144 chrome::RegisterInternalGPUPlugin();
145
[email protected]634d23d2011-01-19 10:38:19146 // Start watching for changes in the plugin list. This means watching
147 // for changes in the Windows registry keys and on both Windows and POSIX
148 // watch for changes in the paths that are expected to contain plugins.
[email protected]b547fd42009-04-23 23:16:27149#if defined(OS_WIN)
150 hkcu_key_.Create(
[email protected]191eb3f72010-12-21 06:27:50151 HKEY_CURRENT_USER, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
[email protected]b547fd42009-04-23 23:16:27152 hklm_key_.Create(
[email protected]191eb3f72010-12-21 06:27:50153 HKEY_LOCAL_MACHINE, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
[email protected]e06f4d52011-01-19 07:28:46154 if (hkcu_key_.StartWatching() == ERROR_SUCCESS) {
[email protected]b547fd42009-04-23 23:16:27155 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event()));
156 hkcu_watcher_.StartWatching(hkcu_event_.get(), this);
157 }
158
[email protected]e06f4d52011-01-19 07:28:46159 if (hklm_key_.StartWatching() == ERROR_SUCCESS) {
[email protected]b547fd42009-04-23 23:16:27160 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event()));
161 hklm_watcher_.StartWatching(hklm_event_.get(), this);
162 }
[email protected]9c49ff02010-01-27 01:20:55163#elif defined(OS_POSIX) && !defined(OS_MACOSX)
164 // Also find plugins in a user-specific plugins dir,
165 // e.g. ~/.config/chromium/Plugins.
166 FilePath user_data_dir;
167 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
[email protected]191eb3f72010-12-21 06:27:50168 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(
[email protected]9c49ff02010-01-27 01:20:55169 user_data_dir.Append("Plugins"));
170 }
[email protected]b547fd42009-04-23 23:16:27171#endif
[email protected]634d23d2011-01-19 10:38:19172// The FilePathWatcher produces too many false positives on MacOS (access time
173// updates?) which will lead to enforcing updates of the plugins way too often.
174// On ChromeOS the user can't install plugins anyway and on Windows all
175// important plugins register themselves in the registry so no need to do that.
176#if defined(OS_LINUX)
177 file_watcher_delegate_ = new PluginDirWatcherDelegate();
178 // Get the list of all paths for registering the FilePathWatchers
179 // that will track and if needed reload the list of plugins on runtime.
180 std::vector<FilePath> plugin_dirs;
181 webkit::npapi::PluginList::Singleton()->GetPluginDirectories(
182 &plugin_dirs);
[email protected]894bb502009-05-21 22:39:57183
[email protected]634d23d2011-01-19 10:38:19184 for (size_t i = 0; i < plugin_dirs.size(); ++i) {
185 FilePathWatcher* watcher = new FilePathWatcher();
186 // FilePathWatcher can not handle non-absolute paths under windows.
187 // We don't watch for file changes in windows now but if this should ever
188 // be extended to Windows these lines might save some time of debugging.
189#if defined(OS_WIN)
190 if (!plugin_dirs[i].IsAbsolute())
191 continue;
192#endif
193 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value();
194 BrowserThread::PostTask(
195 BrowserThread::FILE, FROM_HERE,
196 NewRunnableFunction(
197 &PluginService::RegisterFilePathWatcher,
198 watcher, plugin_dirs[i], file_watcher_delegate_));
199 file_watchers_.push_back(watcher);
200 }
201#endif
[email protected]ae09ca62009-08-21 19:46:46202 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
[email protected]894bb502009-05-21 22:39:57203 NotificationService::AllSources());
204 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
205 NotificationService::AllSources());
[email protected]a96ec6a2009-11-04 17:27:08206#if defined(OS_MACOSX)
207 // We need to know when the browser comes forward so we can bring modal plugin
208 // windows forward too.
209 registrar_.Add(this, NotificationType::APP_ACTIVATED,
210 NotificationService::AllSources());
211#endif
[email protected]5f101bbe2010-10-08 08:01:16212 registrar_.Add(this, NotificationType::PLUGIN_ENABLE_STATUS_CHANGED,
213 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29214}
215
216PluginService::~PluginService() {
[email protected]b547fd42009-04-23 23:16:27217#if defined(OS_WIN)
218 // Release the events since they're owned by RegKey, not WaitableEvent.
219 hkcu_watcher_.StopWatching();
220 hklm_watcher_.StopWatching();
221 hkcu_event_->Release();
222 hklm_event_->Release();
223#endif
initial.commit09911bf2008-07-26 23:55:29224}
225
initial.commit09911bf2008-07-26 23:55:29226void PluginService::LoadChromePlugins(
227 ResourceDispatcherHost* resource_dispatcher_host) {
[email protected]51549da2009-11-21 08:43:39228 if (!enable_chrome_plugins_)
229 return;
230
initial.commit09911bf2008-07-26 23:55:29231 resource_dispatcher_host_ = resource_dispatcher_host;
232 ChromePluginLib::LoadChromePlugins(GetCPBrowserFuncsForBrowser());
233}
234
[email protected]f7011fcb2009-01-28 21:54:32235void PluginService::SetChromePluginDataDir(const FilePath& data_dir) {
initial.commit09911bf2008-07-26 23:55:29236 chrome_plugin_data_dir_ = data_dir;
237}
238
[email protected]f7011fcb2009-01-28 21:54:32239const FilePath& PluginService::GetChromePluginDataDir() {
initial.commit09911bf2008-07-26 23:55:29240 return chrome_plugin_data_dir_;
241}
242
[email protected]f77d87622010-07-30 17:43:17243const std::string& PluginService::GetUILocale() {
initial.commit09911bf2008-07-26 23:55:29244 return ui_locale_;
245}
246
[email protected]28ab7f92009-01-06 21:39:04247PluginProcessHost* PluginService::FindPluginProcess(
248 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29250
[email protected]d27893f62010-07-03 05:47:42251 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a436d922009-02-13 23:16:42252 !iter.Done(); ++iter) {
253 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
254 if (plugin->info().path == plugin_path)
255 return plugin;
256 }
257
initial.commit09911bf2008-07-26 23:55:29258 return NULL;
259}
260
261PluginProcessHost* PluginService::FindOrStartPluginProcess(
[email protected]610c0892009-09-08 19:46:18262 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29264
[email protected]8b8a554d2010-11-18 13:26:40265 PluginProcessHost* plugin_host = FindPluginProcess(plugin_path);
initial.commit09911bf2008-07-26 23:55:29266 if (plugin_host)
267 return plugin_host;
268
[email protected]191eb3f72010-12-21 06:27:50269 webkit::npapi::WebPluginInfo info;
270 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath(
271 plugin_path, &info)) {
[email protected]a27a9382009-02-11 23:55:10272 return NULL;
273 }
274
initial.commit09911bf2008-07-26 23:55:29275 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]8b8a554d2010-11-18 13:26:40276 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
277 if (!new_host->Init(info, ui_locale_)) {
278 NOTREACHED(); // Init is not expected to fail
initial.commit09911bf2008-07-26 23:55:29279 return NULL;
280 }
[email protected]a436d922009-02-13 23:16:42281
[email protected]8b8a554d2010-11-18 13:26:40282 return new_host.release();
initial.commit09911bf2008-07-26 23:55:29283}
284
285void PluginService::OpenChannelToPlugin(
[email protected]610c0892009-09-08 19:46:18286 const GURL& url,
287 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39288 PluginProcessHost::Client* client) {
[email protected]6fdd4182010-10-14 23:59:26289 // The PluginList::GetFirstAllowedPluginInfo may need to load the
290 // plugins. Don't do it on the IO thread.
291 BrowserThread::PostTask(
292 BrowserThread::FILE, FROM_HERE,
293 NewRunnableMethod(
294 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
[email protected]46b69e42010-11-02 12:26:39295 url, mime_type, client));
[email protected]6fdd4182010-10-14 23:59:26296}
297
298void PluginService::GetAllowedPluginForOpenChannelToPlugin(
[email protected]6fdd4182010-10-14 23:59:26299 const GURL& url,
300 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39301 PluginProcessHost::Client* client) {
[email protected]6fdd4182010-10-14 23:59:26302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]191eb3f72010-12-21 06:27:50303 webkit::npapi::WebPluginInfo info;
[email protected]6fdd4182010-10-14 23:59:26304 bool found = GetFirstAllowedPluginInfo(url, mime_type, &info, NULL);
305 FilePath plugin_path;
306 if (found && info.enabled)
307 plugin_path = FilePath(info.path);
308
309 // Now we jump back to the IO thread to finish opening the channel.
310 BrowserThread::PostTask(
311 BrowserThread::IO, FROM_HERE,
312 NewRunnableMethod(
313 this, &PluginService::FinishOpenChannelToPlugin,
[email protected]46b69e42010-11-02 12:26:39314 plugin_path, client));
[email protected]6fdd4182010-10-14 23:59:26315}
316
317void PluginService::FinishOpenChannelToPlugin(
[email protected]6fdd4182010-10-14 23:59:26318 const FilePath& plugin_path,
[email protected]46b69e42010-11-02 12:26:39319 PluginProcessHost::Client* client) {
[email protected]f8b3ef82010-10-11 02:45:52320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20a793e2010-10-12 06:50:08321
[email protected]610c0892009-09-08 19:46:18322 PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path);
[email protected]46b69e42010-11-02 12:26:39323 if (plugin_host)
324 plugin_host->OpenChannelToPlugin(client);
325 else
326 client->OnError();
initial.commit09911bf2008-07-26 23:55:29327}
328
[email protected]6fdd4182010-10-14 23:59:26329bool PluginService::GetFirstAllowedPluginInfo(
330 const GURL& url,
331 const std::string& mime_type,
[email protected]191eb3f72010-12-21 06:27:50332 webkit::npapi::WebPluginInfo* info,
[email protected]6fdd4182010-10-14 23:59:26333 std::string* actual_mime_type) {
334 // GetPluginInfoArray may need to load the plugins, so we need to be
335 // on the FILE thread.
336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
337 bool allow_wildcard = true;
338#if defined(OS_CHROMEOS)
[email protected]191eb3f72010-12-21 06:27:50339 std::vector<webkit::npapi::WebPluginInfo> info_array;
[email protected]6fdd4182010-10-14 23:59:26340 std::vector<std::string> actual_mime_types;
[email protected]191eb3f72010-12-21 06:27:50341 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
[email protected]6fdd4182010-10-14 23:59:26342 url, mime_type, allow_wildcard, &info_array, &actual_mime_types);
343
344 // Now we filter by the plugin selection policy.
345 int allowed_index = plugin_selection_policy_->FindFirstAllowed(url,
346 info_array);
347 if (!info_array.empty() && allowed_index >= 0) {
348 *info = info_array[allowed_index];
349 if (actual_mime_type)
350 *actual_mime_type = actual_mime_types[allowed_index];
351 return true;
352 }
353 return false;
354#else
[email protected]191eb3f72010-12-21 06:27:50355 return webkit::npapi::PluginList::Singleton()->GetPluginInfo(
[email protected]6fdd4182010-10-14 23:59:26356 url, mime_type, allow_wildcard, info, actual_mime_type);
357#endif
358}
359
[email protected]580522632009-08-17 21:55:55360void PluginService::OnWaitableEventSignaled(
361 base::WaitableEvent* waitable_event) {
[email protected]b547fd42009-04-23 23:16:27362#if defined(OS_WIN)
363 if (waitable_event == hkcu_event_.get()) {
364 hkcu_key_.StartWatching();
365 } else {
366 hklm_key_.StartWatching();
367 }
368
[email protected]191eb3f72010-12-21 06:27:50369 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]b78e168b2009-09-21 22:05:45370 PurgePluginListCache(true);
[email protected]634d23d2011-01-19 10:38:19371#else
372 // This event should only get signaled on a Windows machine.
373 NOTREACHED();
[email protected]9de09f82009-08-17 20:13:53374#endif // defined(OS_WIN)
[email protected]b547fd42009-04-23 23:16:27375}
[email protected]894bb502009-05-21 22:39:57376
[email protected]4e59e812010-04-06 20:51:16377static void ForceShutdownPlugin(const FilePath& plugin_path) {
378 PluginProcessHost* plugin =
379 PluginService::GetInstance()->FindPluginProcess(plugin_path);
380 if (plugin)
381 plugin->ForceShutdown();
382}
383
[email protected]894bb502009-05-21 22:39:57384void PluginService::Observe(NotificationType type,
385 const NotificationSource& source,
386 const NotificationDetails& details) {
387 switch (type.value) {
[email protected]ae09ca62009-08-21 19:46:46388 case NotificationType::EXTENSION_LOADED: {
[email protected]9adb9692010-10-29 23:14:02389 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]b78e168b2009-09-21 22:05:45390 bool plugins_changed = false;
[email protected]ee5e3792009-10-13 23:23:47391 for (size_t i = 0; i < extension->plugins().size(); ++i) {
[email protected]ae09ca62009-08-21 19:46:46392 const Extension::PluginInfo& plugin = extension->plugins()[i];
[email protected]191eb3f72010-12-21 06:27:50393 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
394 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(plugin.path);
[email protected]b78e168b2009-09-21 22:05:45395 plugins_changed = true;
[email protected]ae09ca62009-08-21 19:46:46396 if (!plugin.is_public)
397 private_plugins_[plugin.path] = extension->url();
[email protected]c533bb22009-06-03 19:06:11398 }
[email protected]b78e168b2009-09-21 22:05:45399 if (plugins_changed)
400 PurgePluginListCache(false);
[email protected]894bb502009-05-21 22:39:57401 break;
402 }
403
404 case NotificationType::EXTENSION_UNLOADED: {
[email protected]a9f39a312010-12-23 22:14:27405 const Extension* extension =
406 Details<UnloadedExtensionInfo>(details)->extension;
[email protected]b78e168b2009-09-21 22:05:45407 bool plugins_changed = false;
[email protected]ee5e3792009-10-13 23:23:47408 for (size_t i = 0; i < extension->plugins().size(); ++i) {
[email protected]b78e168b2009-09-21 22:05:45409 const Extension::PluginInfo& plugin = extension->plugins()[i];
[email protected]f8b3ef82010-10-11 02:45:52410 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
411 NewRunnableFunction(&ForceShutdownPlugin,
412 plugin.path));
[email protected]191eb3f72010-12-21 06:27:50413 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
414 webkit::npapi::PluginList::Singleton()->RemoveExtraPluginPath(
415 plugin.path);
[email protected]b78e168b2009-09-21 22:05:45416 plugins_changed = true;
417 if (!plugin.is_public)
418 private_plugins_.erase(plugin.path);
419 }
420 if (plugins_changed)
421 PurgePluginListCache(false);
[email protected]894bb502009-05-21 22:39:57422 break;
423 }
424
[email protected]a96ec6a2009-11-04 17:27:08425#if defined(OS_MACOSX)
426 case NotificationType::APP_ACTIVATED: {
[email protected]f8b3ef82010-10-11 02:45:52427 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
428 NewRunnableFunction(&NotifyPluginsOfActivation));
[email protected]a96ec6a2009-11-04 17:27:08429 break;
430 }
431#endif
432
[email protected]5f101bbe2010-10-08 08:01:16433 case NotificationType::PLUGIN_ENABLE_STATUS_CHANGED: {
434 PurgePluginListCache(false);
435 break;
436 }
[email protected]894bb502009-05-21 22:39:57437 default:
[email protected]634d23d2011-01-19 10:38:19438 NOTREACHED();
[email protected]894bb502009-05-21 22:39:57439 }
440}
[email protected]9dd9e8382009-06-05 18:23:21441
[email protected]7a13e792010-08-03 08:18:24442bool PluginService::PrivatePluginAllowedForURL(const FilePath& plugin_path,
443 const GURL& url) {
[email protected]9dd9e8382009-06-05 18:23:21444 if (url.is_empty())
445 return true; // Caller wants all plugins.
446
447 PrivatePluginMap::iterator it = private_plugins_.find(plugin_path);
448 if (it == private_plugins_.end())
449 return true; // This plugin is not private, so it's allowed everywhere.
450
451 // We do a dumb compare of scheme and host, rather than using the domain
452 // service, since we only care about this for extensions.
453 const GURL& required_url = it->second;
454 return (url.scheme() == required_url.scheme() &&
455 url.host() == required_url.host());
456}
[email protected]4e0616e2010-05-28 14:55:53457
458void PluginService::RegisterPepperPlugins() {
459 std::vector<PepperPluginInfo> plugins;
460 PepperPluginRegistry::GetList(&plugins);
461 for (size_t i = 0; i < plugins.size(); ++i) {
[email protected]191eb3f72010-12-21 06:27:50462 webkit::npapi::PluginVersionInfo info;
[email protected]4e0616e2010-05-28 14:55:53463 info.path = plugins[i].path;
[email protected]2fb3e362010-07-02 18:05:44464 info.product_name = plugins[i].name.empty() ?
465 plugins[i].path.BaseName().ToWStringHack() :
466 ASCIIToWide(plugins[i].name);
467 info.file_description = ASCIIToWide(plugins[i].description);
468 info.file_extensions = ASCIIToWide(plugins[i].file_extensions);
469 info.file_description = ASCIIToWide(plugins[i].type_descriptions);
[email protected]4e0616e2010-05-28 14:55:53470 info.mime_types = ASCIIToWide(JoinString(plugins[i].mime_types, '|'));
471
472 // These NPAPI entry points will never be called. TODO(darin): Come up
473 // with a cleaner way to register pepper plugins with the NPAPI PluginList,
474 // or perhaps refactor the PluginList to be less specific to NPAPI.
475 memset(&info.entry_points, 0, sizeof(info.entry_points));
476
[email protected]191eb3f72010-12-21 06:27:50477 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info);
[email protected]4e0616e2010-05-28 14:55:53478 }
479}
[email protected]634d23d2011-01-19 10:38:19480
481#if defined(OS_LINUX)
482// static
483void PluginService::RegisterFilePathWatcher(
484 FilePathWatcher *watcher,
485 const FilePath& path,
486 FilePathWatcher::Delegate* delegate) {
487 bool result = watcher->Watch(path, delegate);
488 DCHECK(result);
489}
490#endif