blob: 154d0629103c353424865c234c686c9d6053cb4a [file] [log] [blame]
[email protected]a08ebea2011-02-13 17:50:201// Copyright (c) 2011 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
[email protected]a0421732011-02-23 03:55:405#include "content/browser/plugin_service.h"
initial.commit09911bf2008-07-26 23:55:296
[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]7b3ee8b2011-04-01 18:48:1910#include "base/compiler_specific.h"
[email protected]9c49ff02010-01-27 01:20:5511#include "base/path_service.h"
[email protected]d70539de2009-06-24 22:17:0612#include "base/string_util.h"
[email protected]7f070d42011-03-09 20:25:3213#include "base/synchronization/waitable_event.h"
[email protected]34b99632011-01-01 01:01:0614#include "base/threading/thread.h"
[email protected]be1ce6a72010-08-03 14:35:2215#include "base/utf_string_conversions.h"
[email protected]cec1b8d2010-03-24 00:21:3416#include "base/values.h"
[email protected]a0421732011-02-23 03:55:4017#include "content/browser/browser_thread.h"
[email protected]de23f3f2011-05-18 16:20:2318#include "content/browser/content_browser_client.h"
[email protected]a01efd22011-03-01 00:38:3219#include "content/browser/ppapi_plugin_process_host.h"
[email protected]a0421732011-02-23 03:55:4020#include "content/browser/renderer_host/render_process_host.h"
21#include "content/browser/renderer_host/render_view_host.h"
[email protected]d259a8e2011-05-18 22:31:0922#include "content/browser/resource_context.h"
[email protected]432115822011-07-10 15:52:2723#include "content/common/content_notification_types.h"
[email protected]4287a3d2011-06-13 23:56:5124#include "content/common/content_switches.h"
[email protected]7f070d42011-03-09 20:25:3225#include "content/common/notification_service.h"
[email protected]cebc3dc2011-04-18 17:15:0026#include "content/common/pepper_plugin_registry.h"
[email protected]105303e2011-03-14 22:16:1027#include "content/common/plugin_messages.h"
[email protected]38b592902011-04-16 02:08:4228#include "content/common/view_messages.h"
[email protected]191eb3f72010-12-21 06:27:5029#include "webkit/plugins/npapi/plugin_constants_win.h"
30#include "webkit/plugins/npapi/plugin_list.h"
31#include "webkit/plugins/npapi/webplugininfo.h"
32
[email protected]e63c4d72011-05-31 22:38:2933#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]493c8002011-04-14 16:56:0134using ::base::files::FilePathWatcher;
35#endif
36
[email protected]a96ec6a2009-11-04 17:27:0837#if defined(OS_MACOSX)
38static void NotifyPluginsOfActivation() {
[email protected]f8b3ef82010-10-11 02:45:5239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]a96ec6a2009-11-04 17:27:0840
[email protected]d27893f62010-07-03 05:47:4241 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a96ec6a2009-11-04 17:27:0842 !iter.Done(); ++iter) {
43 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
44 plugin->OnAppActivation();
45 }
46}
[email protected]e63c4d72011-05-31 22:38:2947#elif defined(OS_POSIX)
[email protected]634d23d2011-01-19 10:38:1948// Delegate class for monitoring directories.
49class PluginDirWatcherDelegate : public FilePathWatcher::Delegate {
[email protected]7b3ee8b2011-04-01 18:48:1950 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE {
[email protected]634d23d2011-01-19 10:38:1951 VLOG(1) << "Watched path changed: " << path.value();
52 // Make the plugin list update itself
53 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
54 }
[email protected]7b3ee8b2011-04-01 18:48:1955 virtual void OnFilePathError(const FilePath& path) OVERRIDE {
[email protected]634d23d2011-01-19 10:38:1956 // TODO(pastarmovj): Add some sensible error handling. Maybe silently
57 // stopping the watcher would be enough. Or possibly restart it.
58 NOTREACHED();
59 }
60};
61#endif
62
initial.commit09911bf2008-07-26 23:55:2963// static
64PluginService* PluginService::GetInstance() {
65 return Singleton<PluginService>::get();
66}
67
68PluginService::PluginService()
[email protected]de23f3f2011-05-18 16:20:2369 : ui_locale_(
70 content::GetContentClient()->browser()->GetApplicationLocale()) {
[email protected]4e0616e2010-05-28 14:55:5371 RegisterPepperPlugins();
72
[email protected]9a1c4262010-06-29 21:50:2773 // Load any specified on the command line as well.
[email protected]d48f1e0c2009-02-12 20:57:5474 const CommandLine* command_line = CommandLine::ForCurrentProcess();
[email protected]c4e52f0d2009-11-06 19:55:1675 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin);
[email protected]7bf795d92010-05-22 00:14:2876 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:5077 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
[email protected]9a1c4262010-06-29 21:50:2778 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir);
79 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:5080 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path);
[email protected]7bf795d92010-05-22 00:14:2881
[email protected]634d23d2011-01-19 10:38:1982 // Start watching for changes in the plugin list. This means watching
83 // for changes in the Windows registry keys and on both Windows and POSIX
84 // watch for changes in the paths that are expected to contain plugins.
[email protected]b547fd42009-04-23 23:16:2785#if defined(OS_WIN)
[email protected]86ec4f6e2011-04-20 16:21:1986 if (hkcu_key_.Create(HKEY_CURRENT_USER,
87 webkit::npapi::kRegistryMozillaPlugins,
88 KEY_NOTIFY) == ERROR_SUCCESS) {
89 if (hkcu_key_.StartWatching() == ERROR_SUCCESS) {
90 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event()));
91 hkcu_watcher_.StartWatching(hkcu_event_.get(), this);
92 }
[email protected]b547fd42009-04-23 23:16:2793 }
[email protected]86ec4f6e2011-04-20 16:21:1994 if (hklm_key_.Create(HKEY_LOCAL_MACHINE,
95 webkit::npapi::kRegistryMozillaPlugins,
96 KEY_NOTIFY) == ERROR_SUCCESS) {
97 if (hklm_key_.StartWatching() == ERROR_SUCCESS) {
98 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event()));
99 hklm_watcher_.StartWatching(hklm_event_.get(), this);
100 }
[email protected]b547fd42009-04-23 23:16:27101 }
[email protected]e63c4d72011-05-31 22:38:29102#elif defined(OS_MACOSX)
103 // We need to know when the browser comes forward so we can bring modal plugin
104 // windows forward too.
[email protected]432115822011-07-10 15:52:27105 registrar_.Add(this, content::NOTIFICATION_APP_ACTIVATED,
[email protected]e63c4d72011-05-31 22:38:29106 NotificationService::AllSources());
107#elif defined(OS_POSIX)
[email protected]634d23d2011-01-19 10:38:19108// The FilePathWatcher produces too many false positives on MacOS (access time
109// updates?) which will lead to enforcing updates of the plugins way too often.
110// On ChromeOS the user can't install plugins anyway and on Windows all
111// important plugins register themselves in the registry so no need to do that.
[email protected]634d23d2011-01-19 10:38:19112 file_watcher_delegate_ = new PluginDirWatcherDelegate();
113 // Get the list of all paths for registering the FilePathWatchers
114 // that will track and if needed reload the list of plugins on runtime.
115 std::vector<FilePath> plugin_dirs;
116 webkit::npapi::PluginList::Singleton()->GetPluginDirectories(
117 &plugin_dirs);
[email protected]894bb502009-05-21 22:39:57118
[email protected]634d23d2011-01-19 10:38:19119 for (size_t i = 0; i < plugin_dirs.size(); ++i) {
[email protected]634d23d2011-01-19 10:38:19120 // FilePathWatcher can not handle non-absolute paths under windows.
121 // We don't watch for file changes in windows now but if this should ever
122 // be extended to Windows these lines might save some time of debugging.
123#if defined(OS_WIN)
124 if (!plugin_dirs[i].IsAbsolute())
125 continue;
126#endif
[email protected]493c8002011-04-14 16:56:01127 FilePathWatcher* watcher = new FilePathWatcher();
[email protected]634d23d2011-01-19 10:38:19128 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value();
129 BrowserThread::PostTask(
130 BrowserThread::FILE, FROM_HERE,
131 NewRunnableFunction(
132 &PluginService::RegisterFilePathWatcher,
133 watcher, plugin_dirs[i], file_watcher_delegate_));
134 file_watchers_.push_back(watcher);
135 }
136#endif
[email protected]432115822011-07-10 15:52:27137 registrar_.Add(this, content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
[email protected]5f101bbe2010-10-08 08:01:16138 NotificationService::AllSources());
[email protected]c8f73ab2011-01-22 00:05:17139 registrar_.Add(this,
[email protected]432115822011-07-10 15:52:27140 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
[email protected]c8f73ab2011-01-22 00:05:17141 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29142}
143
144PluginService::~PluginService() {
[email protected]b547fd42009-04-23 23:16:27145#if defined(OS_WIN)
146 // Release the events since they're owned by RegKey, not WaitableEvent.
147 hkcu_watcher_.StopWatching();
148 hklm_watcher_.StopWatching();
[email protected]c247cab2011-01-21 01:58:42149 if (hkcu_event_.get())
150 hkcu_event_->Release();
151 if (hklm_event_.get())
152 hklm_event_->Release();
[email protected]b547fd42009-04-23 23:16:27153#endif
initial.commit09911bf2008-07-26 23:55:29154}
155
[email protected]f77d87622010-07-30 17:43:17156const std::string& PluginService::GetUILocale() {
initial.commit09911bf2008-07-26 23:55:29157 return ui_locale_;
158}
159
[email protected]a08ebea2011-02-13 17:50:20160PluginProcessHost* PluginService::FindNpapiPluginProcess(
[email protected]28ab7f92009-01-06 21:39:04161 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29163
[email protected]d27893f62010-07-03 05:47:42164 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a436d922009-02-13 23:16:42165 !iter.Done(); ++iter) {
166 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
167 if (plugin->info().path == plugin_path)
168 return plugin;
169 }
170
initial.commit09911bf2008-07-26 23:55:29171 return NULL;
172}
173
[email protected]a08ebea2011-02-13 17:50:20174PpapiPluginProcessHost* PluginService::FindPpapiPluginProcess(
[email protected]610c0892009-09-08 19:46:18175 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29177
[email protected]a08ebea2011-02-13 17:50:20178 for (BrowserChildProcessHost::Iterator iter(
179 ChildProcessInfo::PPAPI_PLUGIN_PROCESS);
180 !iter.Done(); ++iter) {
181 PpapiPluginProcessHost* plugin =
182 static_cast<PpapiPluginProcessHost*>(*iter);
183 if (plugin->plugin_path() == plugin_path)
184 return plugin;
185 }
186
187 return NULL;
188}
189
[email protected]eb415bf0e2011-04-14 02:45:42190PpapiBrokerProcessHost* PluginService::FindPpapiBrokerProcess(
191 const FilePath& broker_path) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
193
194 for (BrowserChildProcessHost::Iterator iter(
195 ChildProcessInfo::PPAPI_BROKER_PROCESS);
196 !iter.Done(); ++iter) {
197 PpapiBrokerProcessHost* broker =
198 static_cast<PpapiBrokerProcessHost*>(*iter);
199 if (broker->broker_path() == broker_path)
200 return broker;
201 }
202
203 return NULL;
204}
205
[email protected]a08ebea2011-02-13 17:50:20206PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
207 const FilePath& plugin_path) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
209
210 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path);
initial.commit09911bf2008-07-26 23:55:29211 if (plugin_host)
212 return plugin_host;
213
[email protected]191eb3f72010-12-21 06:27:50214 webkit::npapi::WebPluginInfo info;
215 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath(
216 plugin_path, &info)) {
[email protected]a27a9382009-02-11 23:55:10217 return NULL;
218 }
219
initial.commit09911bf2008-07-26 23:55:29220 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]8b8a554d2010-11-18 13:26:40221 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
222 if (!new_host->Init(info, ui_locale_)) {
[email protected]a08ebea2011-02-13 17:50:20223 NOTREACHED(); // Init is not expected to fail.
initial.commit09911bf2008-07-26 23:55:29224 return NULL;
225 }
[email protected]8b8a554d2010-11-18 13:26:40226 return new_host.release();
initial.commit09911bf2008-07-26 23:55:29227}
228
[email protected]a08ebea2011-02-13 17:50:20229PpapiPluginProcessHost* PluginService::FindOrStartPpapiPluginProcess(
[email protected]d259a8e2011-05-18 22:31:09230 const FilePath& plugin_path,
231 PpapiPluginProcessHost::Client* client) {
[email protected]a08ebea2011-02-13 17:50:20232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
233
234 PpapiPluginProcessHost* plugin_host = FindPpapiPluginProcess(plugin_path);
235 if (plugin_host)
236 return plugin_host;
237
[email protected]eb415bf0e2011-04-14 02:45:42238 // Validate that the plugin is actually registered.
239 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]a08ebea2011-02-13 17:50:20240 if (!info)
241 return NULL;
242
243 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]d259a8e2011-05-18 22:31:09244 scoped_ptr<PpapiPluginProcessHost> new_host(new PpapiPluginProcessHost(
245 client->GetResourceContext()->host_resolver()));
[email protected]277a1112011-03-19 06:03:56246 if (!new_host->Init(*info)) {
[email protected]a08ebea2011-02-13 17:50:20247 NOTREACHED(); // Init is not expected to fail.
248 return NULL;
249 }
250 return new_host.release();
251}
252
[email protected]eb415bf0e2011-04-14 02:45:42253PpapiBrokerProcessHost* PluginService::FindOrStartPpapiBrokerProcess(
254 const FilePath& plugin_path) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256
257 PpapiBrokerProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
258 if (plugin_host)
259 return plugin_host;
260
261 // Validate that the plugin is actually registered.
262 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
263 if (!info)
264 return NULL;
265
266 // TODO(ddorwin): Uncomment once out of process is supported.
267 // DCHECK(info->is_out_of_process);
268
269 // This broker isn't loaded by any broker process, so create a new process.
270 scoped_ptr<PpapiBrokerProcessHost> new_host(
271 new PpapiBrokerProcessHost);
272 if (!new_host->Init(*info)) {
273 NOTREACHED(); // Init is not expected to fail.
274 return NULL;
275 }
276 return new_host.release();
277}
278
[email protected]a08ebea2011-02-13 17:50:20279void PluginService::OpenChannelToNpapiPlugin(
[email protected]c8f73ab2011-01-22 00:05:17280 int render_process_id,
281 int render_view_id,
[email protected]610c0892009-09-08 19:46:18282 const GURL& url,
283 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39284 PluginProcessHost::Client* client) {
[email protected]11e1c182011-05-17 20:26:27285 // The PluginList::GetPluginInfo may need to load the plugins. Don't do it on
286 // the IO thread.
[email protected]6fdd4182010-10-14 23:59:26287 BrowserThread::PostTask(
288 BrowserThread::FILE, FROM_HERE,
289 NewRunnableMethod(
290 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
[email protected]c8f73ab2011-01-22 00:05:17291 render_process_id, render_view_id, url, mime_type, client));
[email protected]6fdd4182010-10-14 23:59:26292}
293
[email protected]a08ebea2011-02-13 17:50:20294void PluginService::OpenChannelToPpapiPlugin(
295 const FilePath& path,
296 PpapiPluginProcessHost::Client* client) {
[email protected]d259a8e2011-05-18 22:31:09297 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
298 path, client);
[email protected]a08ebea2011-02-13 17:50:20299 if (plugin_host)
300 plugin_host->OpenChannelToPlugin(client);
301 else // Send error.
302 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
303}
304
[email protected]eb415bf0e2011-04-14 02:45:42305void PluginService::OpenChannelToPpapiBroker(
306 const FilePath& path,
307 PpapiBrokerProcessHost::Client* client) {
308 PpapiBrokerProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(path);
309 if (plugin_host)
310 plugin_host->OpenChannelToPpapiBroker(client);
311 else // Send error.
312 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
313}
314
[email protected]6fdd4182010-10-14 23:59:26315void PluginService::GetAllowedPluginForOpenChannelToPlugin(
[email protected]c8f73ab2011-01-22 00:05:17316 int render_process_id,
317 int render_view_id,
[email protected]6fdd4182010-10-14 23:59:26318 const GURL& url,
319 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39320 PluginProcessHost::Client* client) {
[email protected]6fdd4182010-10-14 23:59:26321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]191eb3f72010-12-21 06:27:50322 webkit::npapi::WebPluginInfo info;
[email protected]11e1c182011-05-17 20:26:27323 bool found = GetPluginInfo(
[email protected]c8f73ab2011-01-22 00:05:17324 render_process_id, render_view_id, url, mime_type, &info, NULL);
[email protected]6fdd4182010-10-14 23:59:26325 FilePath plugin_path;
[email protected]68598072011-07-29 08:21:28326 if (found)
[email protected]6fdd4182010-10-14 23:59:26327 plugin_path = FilePath(info.path);
328
329 // Now we jump back to the IO thread to finish opening the channel.
330 BrowserThread::PostTask(
331 BrowserThread::IO, FROM_HERE,
332 NewRunnableMethod(
333 this, &PluginService::FinishOpenChannelToPlugin,
[email protected]46b69e42010-11-02 12:26:39334 plugin_path, client));
[email protected]6fdd4182010-10-14 23:59:26335}
336
337void PluginService::FinishOpenChannelToPlugin(
[email protected]6fdd4182010-10-14 23:59:26338 const FilePath& plugin_path,
[email protected]46b69e42010-11-02 12:26:39339 PluginProcessHost::Client* client) {
[email protected]f8b3ef82010-10-11 02:45:52340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20a793e2010-10-12 06:50:08341
[email protected]a08ebea2011-02-13 17:50:20342 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path);
[email protected]46b69e42010-11-02 12:26:39343 if (plugin_host)
344 plugin_host->OpenChannelToPlugin(client);
345 else
346 client->OnError();
initial.commit09911bf2008-07-26 23:55:29347}
348
[email protected]11e1c182011-05-17 20:26:27349bool PluginService::GetPluginInfo(int render_process_id,
350 int render_view_id,
351 const GURL& url,
352 const std::string& mime_type,
353 webkit::npapi::WebPluginInfo* info,
354 std::string* actual_mime_type) {
[email protected]6fdd4182010-10-14 23:59:26355 // GetPluginInfoArray may need to load the plugins, so we need to be
356 // on the FILE thread.
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]c8f73ab2011-01-22 00:05:17358 {
[email protected]5c19e8b2011-01-22 00:18:47359 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17360 for (size_t i = 0; i < overridden_plugins_.size(); ++i) {
361 if (overridden_plugins_[i].render_process_id == render_process_id &&
362 overridden_plugins_[i].render_view_id == render_view_id &&
363 overridden_plugins_[i].url == url) {
[email protected]79f0fa752011-01-27 20:01:47364 if (actual_mime_type)
365 *actual_mime_type = mime_type;
[email protected]c8f73ab2011-01-22 00:05:17366 *info = overridden_plugins_[i].plugin;
367 return true;
368 }
369 }
370 }
[email protected]68598072011-07-29 08:21:28371 bool allow_wildcard = true;
372 std::vector<webkit::npapi::WebPluginInfo> plugins;
373 std::vector<std::string> mime_types;
374 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
375 url, mime_type, allow_wildcard, NULL, &plugins, &mime_types);
376 for (size_t i = 0; i < plugins.size(); ++i) {
377 if (webkit::npapi::IsPluginEnabled(plugins[i])) {
378 *info = plugins[i];
379 if (actual_mime_type)
380 *actual_mime_type = mime_types[i];
381 return true;
382 }
383 }
384 return false;
[email protected]6fdd4182010-10-14 23:59:26385}
386
[email protected]580522632009-08-17 21:55:55387void PluginService::OnWaitableEventSignaled(
388 base::WaitableEvent* waitable_event) {
[email protected]b547fd42009-04-23 23:16:27389#if defined(OS_WIN)
390 if (waitable_event == hkcu_event_.get()) {
391 hkcu_key_.StartWatching();
392 } else {
393 hklm_key_.StartWatching();
394 }
395
[email protected]191eb3f72010-12-21 06:27:50396 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]b78e168b2009-09-21 22:05:45397 PurgePluginListCache(true);
[email protected]634d23d2011-01-19 10:38:19398#else
399 // This event should only get signaled on a Windows machine.
400 NOTREACHED();
[email protected]9de09f82009-08-17 20:13:53401#endif // defined(OS_WIN)
[email protected]b547fd42009-04-23 23:16:27402}
[email protected]894bb502009-05-21 22:39:57403
[email protected]432115822011-07-10 15:52:27404void PluginService::Observe(int type,
[email protected]894bb502009-05-21 22:39:57405 const NotificationSource& source,
406 const NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27407 switch (type) {
[email protected]a96ec6a2009-11-04 17:27:08408#if defined(OS_MACOSX)
[email protected]432115822011-07-10 15:52:27409 case content::NOTIFICATION_APP_ACTIVATED: {
[email protected]f8b3ef82010-10-11 02:45:52410 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
411 NewRunnableFunction(&NotifyPluginsOfActivation));
[email protected]a96ec6a2009-11-04 17:27:08412 break;
413 }
414#endif
415
[email protected]432115822011-07-10 15:52:27416 case content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED: {
[email protected]b83ff222011-01-24 17:37:12417 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]5f101bbe2010-10-08 08:01:16418 PurgePluginListCache(false);
419 break;
420 }
[email protected]432115822011-07-10 15:52:27421 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
[email protected]c8f73ab2011-01-22 00:05:17422 int render_process_id = Source<RenderProcessHost>(source).ptr()->id();
423
[email protected]5c19e8b2011-01-22 00:18:47424 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17425 for (size_t i = 0; i < overridden_plugins_.size(); ++i) {
426 if (overridden_plugins_[i].render_process_id == render_process_id) {
427 overridden_plugins_.erase(overridden_plugins_.begin() + i);
428 break;
429 }
430 }
431 break;
432 }
[email protected]894bb502009-05-21 22:39:57433 default:
[email protected]634d23d2011-01-19 10:38:19434 NOTREACHED();
[email protected]894bb502009-05-21 22:39:57435 }
436}
[email protected]9dd9e8382009-06-05 18:23:21437
[email protected]bd5174d2011-03-11 01:02:56438void PluginService::OverridePluginForTab(const OverriddenPlugin& plugin) {
[email protected]5c19e8b2011-01-22 00:18:47439 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17440 overridden_plugins_.push_back(plugin);
441}
442
[email protected]2de307592011-04-05 21:16:58443void PluginService::PurgePluginListCache(bool reload_pages) {
444 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
445 !it.IsAtEnd(); it.Advance()) {
446 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
447 }
448}
449
450void PluginService::RestrictPluginToUrl(const FilePath& plugin_path,
451 const GURL& url) {
452 base::AutoLock auto_lock(restricted_plugin_lock_);
453 if (url.is_empty()) {
454 restricted_plugin_.erase(plugin_path);
455 } else {
456 restricted_plugin_[plugin_path] = url;
457 }
458}
459
460bool PluginService::PluginAllowedForURL(const FilePath& plugin_path,
461 const GURL& url) {
462 if (url.is_empty())
463 return true; // Caller wants all plugins.
464
465 base::AutoLock auto_lock(restricted_plugin_lock_);
466
467 RestrictedPluginMap::iterator it = restricted_plugin_.find(plugin_path);
468 if (it == restricted_plugin_.end())
469 return true; // This plugin is not restricted, so it's allowed everywhere.
470
471 const GURL& required_url = it->second;
472 return (url.scheme() == required_url.scheme() &&
473 url.host() == required_url.host());
474}
475
[email protected]4e0616e2010-05-28 14:55:53476void PluginService::RegisterPepperPlugins() {
[email protected]84396dbc2011-04-14 06:33:42477 // TODO(abarth): It seems like the PepperPluginRegistry should do this work.
[email protected]a08ebea2011-02-13 17:50:20478 PepperPluginRegistry::ComputeList(&ppapi_plugins_);
479 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) {
[email protected]84396dbc2011-04-14 06:33:42480 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(
481 ppapi_plugins_[i].ToWebPluginInfo());
[email protected]4e0616e2010-05-28 14:55:53482 }
483}
[email protected]634d23d2011-01-19 10:38:19484
[email protected]eb415bf0e2011-04-14 02:45:42485// There should generally be very few plugins so a brute-force search is fine.
486PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo(
487 const FilePath& plugin_path) {
488 PepperPluginInfo* info = NULL;
489 for (size_t i = 0; i < ppapi_plugins_.size(); i++) {
490 if (ppapi_plugins_[i].path == plugin_path) {
491 info = &ppapi_plugins_[i];
492 break;
493 }
494 }
495 return info;
496}
497
[email protected]e63c4d72011-05-31 22:38:29498#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]634d23d2011-01-19 10:38:19499// static
500void PluginService::RegisterFilePathWatcher(
501 FilePathWatcher *watcher,
502 const FilePath& path,
503 FilePathWatcher::Delegate* delegate) {
[email protected]7b3ee8b2011-04-01 18:48:19504 bool result = watcher->Watch(path, delegate);
[email protected]634d23d2011-01-19 10:38:19505 DCHECK(result);
506}
507#endif