blob: 7ca5b2220d11e0fe3dee44e7215f602c046b0a65 [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]d48f1e0c2009-02-12 20:57:547#include "base/command_line.h"
[email protected]7b3ee8b2011-04-01 18:48:198#include "base/compiler_specific.h"
[email protected]9c49ff02010-01-27 01:20:559#include "base/path_service.h"
[email protected]d70539de2009-06-24 22:17:0610#include "base/string_util.h"
[email protected]7f070d42011-03-09 20:25:3211#include "base/synchronization/waitable_event.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]a0421732011-02-23 03:55:4015#include "content/browser/browser_thread.h"
[email protected]de23f3f2011-05-18 16:20:2316#include "content/browser/content_browser_client.h"
[email protected]a01efd22011-03-01 00:38:3217#include "content/browser/ppapi_plugin_process_host.h"
[email protected]a0421732011-02-23 03:55:4018#include "content/browser/renderer_host/render_process_host.h"
19#include "content/browser/renderer_host/render_view_host.h"
[email protected]d259a8e2011-05-18 22:31:0920#include "content/browser/resource_context.h"
[email protected]432115822011-07-10 15:52:2721#include "content/common/content_notification_types.h"
[email protected]4287a3d2011-06-13 23:56:5122#include "content/common/content_switches.h"
[email protected]7f070d42011-03-09 20:25:3223#include "content/common/notification_service.h"
[email protected]cebc3dc2011-04-18 17:15:0024#include "content/common/pepper_plugin_registry.h"
[email protected]105303e2011-03-14 22:16:1025#include "content/common/plugin_messages.h"
[email protected]38b592902011-04-16 02:08:4226#include "content/common/view_messages.h"
[email protected]191eb3f72010-12-21 06:27:5027#include "webkit/plugins/npapi/plugin_constants_win.h"
28#include "webkit/plugins/npapi/plugin_list.h"
[email protected]91d9f3d2011-08-14 05:24:4429#include "webkit/plugins/webplugininfo.h"
[email protected]191eb3f72010-12-21 06:27:5030
[email protected]e63c4d72011-05-31 22:38:2931#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]493c8002011-04-14 16:56:0132using ::base::files::FilePathWatcher;
33#endif
34
[email protected]a96ec6a2009-11-04 17:27:0835#if defined(OS_MACOSX)
36static void NotifyPluginsOfActivation() {
[email protected]f8b3ef82010-10-11 02:45:5237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]a96ec6a2009-11-04 17:27:0838
[email protected]d27893f62010-07-03 05:47:4239 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a96ec6a2009-11-04 17:27:0840 !iter.Done(); ++iter) {
41 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
42 plugin->OnAppActivation();
43 }
44}
[email protected]e63c4d72011-05-31 22:38:2945#elif defined(OS_POSIX)
[email protected]634d23d2011-01-19 10:38:1946// Delegate class for monitoring directories.
47class PluginDirWatcherDelegate : public FilePathWatcher::Delegate {
[email protected]7b3ee8b2011-04-01 18:48:1948 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE {
[email protected]634d23d2011-01-19 10:38:1949 VLOG(1) << "Watched path changed: " << path.value();
50 // Make the plugin list update itself
51 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
52 }
[email protected]7b3ee8b2011-04-01 18:48:1953 virtual void OnFilePathError(const FilePath& path) OVERRIDE {
[email protected]634d23d2011-01-19 10:38:1954 // TODO(pastarmovj): Add some sensible error handling. Maybe silently
55 // stopping the watcher would be enough. Or possibly restart it.
56 NOTREACHED();
57 }
58};
59#endif
60
initial.commit09911bf2008-07-26 23:55:2961// static
62PluginService* PluginService::GetInstance() {
63 return Singleton<PluginService>::get();
64}
65
66PluginService::PluginService()
[email protected]de23f3f2011-05-18 16:20:2367 : ui_locale_(
68 content::GetContentClient()->browser()->GetApplicationLocale()) {
[email protected]4e0616e2010-05-28 14:55:5369 RegisterPepperPlugins();
70
[email protected]9a1c4262010-06-29 21:50:2771 // Load any specified on the command line as well.
[email protected]d48f1e0c2009-02-12 20:57:5472 const CommandLine* command_line = CommandLine::ForCurrentProcess();
[email protected]c4e52f0d2009-11-06 19:55:1673 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin);
[email protected]7bf795d92010-05-22 00:14:2874 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:5075 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
[email protected]9a1c4262010-06-29 21:50:2776 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir);
77 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:5078 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path);
[email protected]7bf795d92010-05-22 00:14:2879
[email protected]634d23d2011-01-19 10:38:1980 // Start watching for changes in the plugin list. This means watching
81 // for changes in the Windows registry keys and on both Windows and POSIX
82 // watch for changes in the paths that are expected to contain plugins.
[email protected]b547fd42009-04-23 23:16:2783#if defined(OS_WIN)
[email protected]86ec4f6e2011-04-20 16:21:1984 if (hkcu_key_.Create(HKEY_CURRENT_USER,
85 webkit::npapi::kRegistryMozillaPlugins,
86 KEY_NOTIFY) == ERROR_SUCCESS) {
87 if (hkcu_key_.StartWatching() == ERROR_SUCCESS) {
88 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event()));
89 hkcu_watcher_.StartWatching(hkcu_event_.get(), this);
90 }
[email protected]b547fd42009-04-23 23:16:2791 }
[email protected]86ec4f6e2011-04-20 16:21:1992 if (hklm_key_.Create(HKEY_LOCAL_MACHINE,
93 webkit::npapi::kRegistryMozillaPlugins,
94 KEY_NOTIFY) == ERROR_SUCCESS) {
95 if (hklm_key_.StartWatching() == ERROR_SUCCESS) {
96 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event()));
97 hklm_watcher_.StartWatching(hklm_event_.get(), this);
98 }
[email protected]b547fd42009-04-23 23:16:2799 }
[email protected]e63c4d72011-05-31 22:38:29100#elif defined(OS_MACOSX)
101 // We need to know when the browser comes forward so we can bring modal plugin
102 // windows forward too.
[email protected]432115822011-07-10 15:52:27103 registrar_.Add(this, content::NOTIFICATION_APP_ACTIVATED,
[email protected]e63c4d72011-05-31 22:38:29104 NotificationService::AllSources());
105#elif defined(OS_POSIX)
[email protected]634d23d2011-01-19 10:38:19106// The FilePathWatcher produces too many false positives on MacOS (access time
107// updates?) which will lead to enforcing updates of the plugins way too often.
108// On ChromeOS the user can't install plugins anyway and on Windows all
109// important plugins register themselves in the registry so no need to do that.
[email protected]634d23d2011-01-19 10:38:19110 file_watcher_delegate_ = new PluginDirWatcherDelegate();
111 // Get the list of all paths for registering the FilePathWatchers
112 // that will track and if needed reload the list of plugins on runtime.
113 std::vector<FilePath> plugin_dirs;
114 webkit::npapi::PluginList::Singleton()->GetPluginDirectories(
115 &plugin_dirs);
[email protected]894bb502009-05-21 22:39:57116
[email protected]634d23d2011-01-19 10:38:19117 for (size_t i = 0; i < plugin_dirs.size(); ++i) {
[email protected]634d23d2011-01-19 10:38:19118 // FilePathWatcher can not handle non-absolute paths under windows.
119 // We don't watch for file changes in windows now but if this should ever
120 // be extended to Windows these lines might save some time of debugging.
121#if defined(OS_WIN)
122 if (!plugin_dirs[i].IsAbsolute())
123 continue;
124#endif
[email protected]493c8002011-04-14 16:56:01125 FilePathWatcher* watcher = new FilePathWatcher();
[email protected]634d23d2011-01-19 10:38:19126 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value();
127 BrowserThread::PostTask(
128 BrowserThread::FILE, FROM_HERE,
129 NewRunnableFunction(
130 &PluginService::RegisterFilePathWatcher,
131 watcher, plugin_dirs[i], file_watcher_delegate_));
132 file_watchers_.push_back(watcher);
133 }
134#endif
[email protected]432115822011-07-10 15:52:27135 registrar_.Add(this, content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
[email protected]5f101bbe2010-10-08 08:01:16136 NotificationService::AllSources());
[email protected]c8f73ab2011-01-22 00:05:17137 registrar_.Add(this,
[email protected]432115822011-07-10 15:52:27138 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
[email protected]c8f73ab2011-01-22 00:05:17139 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29140}
141
142PluginService::~PluginService() {
[email protected]b547fd42009-04-23 23:16:27143#if defined(OS_WIN)
144 // Release the events since they're owned by RegKey, not WaitableEvent.
145 hkcu_watcher_.StopWatching();
146 hklm_watcher_.StopWatching();
[email protected]c247cab2011-01-21 01:58:42147 if (hkcu_event_.get())
148 hkcu_event_->Release();
149 if (hklm_event_.get())
150 hklm_event_->Release();
[email protected]b547fd42009-04-23 23:16:27151#endif
initial.commit09911bf2008-07-26 23:55:29152}
153
[email protected]f77d87622010-07-30 17:43:17154const std::string& PluginService::GetUILocale() {
initial.commit09911bf2008-07-26 23:55:29155 return ui_locale_;
156}
157
[email protected]a08ebea2011-02-13 17:50:20158PluginProcessHost* PluginService::FindNpapiPluginProcess(
[email protected]28ab7f92009-01-06 21:39:04159 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29161
[email protected]d27893f62010-07-03 05:47:42162 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a436d922009-02-13 23:16:42163 !iter.Done(); ++iter) {
164 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
165 if (plugin->info().path == plugin_path)
166 return plugin;
167 }
168
initial.commit09911bf2008-07-26 23:55:29169 return NULL;
170}
171
[email protected]a08ebea2011-02-13 17:50:20172PpapiPluginProcessHost* PluginService::FindPpapiPluginProcess(
[email protected]610c0892009-09-08 19:46:18173 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29175
[email protected]a08ebea2011-02-13 17:50:20176 for (BrowserChildProcessHost::Iterator iter(
177 ChildProcessInfo::PPAPI_PLUGIN_PROCESS);
178 !iter.Done(); ++iter) {
179 PpapiPluginProcessHost* plugin =
180 static_cast<PpapiPluginProcessHost*>(*iter);
181 if (plugin->plugin_path() == plugin_path)
182 return plugin;
183 }
184
185 return NULL;
186}
187
[email protected]eb415bf0e2011-04-14 02:45:42188PpapiBrokerProcessHost* PluginService::FindPpapiBrokerProcess(
189 const FilePath& broker_path) {
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
191
192 for (BrowserChildProcessHost::Iterator iter(
193 ChildProcessInfo::PPAPI_BROKER_PROCESS);
194 !iter.Done(); ++iter) {
195 PpapiBrokerProcessHost* broker =
196 static_cast<PpapiBrokerProcessHost*>(*iter);
197 if (broker->broker_path() == broker_path)
198 return broker;
199 }
200
201 return NULL;
202}
203
[email protected]a08ebea2011-02-13 17:50:20204PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
205 const FilePath& plugin_path) {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
207
208 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path);
initial.commit09911bf2008-07-26 23:55:29209 if (plugin_host)
210 return plugin_host;
211
[email protected]91d9f3d2011-08-14 05:24:44212 webkit::WebPluginInfo info;
[email protected]191eb3f72010-12-21 06:27:50213 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath(
214 plugin_path, &info)) {
[email protected]a27a9382009-02-11 23:55:10215 return NULL;
216 }
217
initial.commit09911bf2008-07-26 23:55:29218 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]8b8a554d2010-11-18 13:26:40219 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
220 if (!new_host->Init(info, ui_locale_)) {
[email protected]a08ebea2011-02-13 17:50:20221 NOTREACHED(); // Init is not expected to fail.
initial.commit09911bf2008-07-26 23:55:29222 return NULL;
223 }
[email protected]8b8a554d2010-11-18 13:26:40224 return new_host.release();
initial.commit09911bf2008-07-26 23:55:29225}
226
[email protected]a08ebea2011-02-13 17:50:20227PpapiPluginProcessHost* PluginService::FindOrStartPpapiPluginProcess(
[email protected]d259a8e2011-05-18 22:31:09228 const FilePath& plugin_path,
229 PpapiPluginProcessHost::Client* client) {
[email protected]a08ebea2011-02-13 17:50:20230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
231
232 PpapiPluginProcessHost* plugin_host = FindPpapiPluginProcess(plugin_path);
233 if (plugin_host)
234 return plugin_host;
235
[email protected]eb415bf0e2011-04-14 02:45:42236 // Validate that the plugin is actually registered.
237 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]a08ebea2011-02-13 17:50:20238 if (!info)
239 return NULL;
240
241 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]d259a8e2011-05-18 22:31:09242 scoped_ptr<PpapiPluginProcessHost> new_host(new PpapiPluginProcessHost(
243 client->GetResourceContext()->host_resolver()));
[email protected]277a1112011-03-19 06:03:56244 if (!new_host->Init(*info)) {
[email protected]a08ebea2011-02-13 17:50:20245 NOTREACHED(); // Init is not expected to fail.
246 return NULL;
247 }
248 return new_host.release();
249}
250
[email protected]eb415bf0e2011-04-14 02:45:42251PpapiBrokerProcessHost* PluginService::FindOrStartPpapiBrokerProcess(
252 const FilePath& plugin_path) {
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
254
255 PpapiBrokerProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
256 if (plugin_host)
257 return plugin_host;
258
259 // Validate that the plugin is actually registered.
260 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
261 if (!info)
262 return NULL;
263
264 // TODO(ddorwin): Uncomment once out of process is supported.
265 // DCHECK(info->is_out_of_process);
266
267 // This broker isn't loaded by any broker process, so create a new process.
268 scoped_ptr<PpapiBrokerProcessHost> new_host(
269 new PpapiBrokerProcessHost);
270 if (!new_host->Init(*info)) {
271 NOTREACHED(); // Init is not expected to fail.
272 return NULL;
273 }
274 return new_host.release();
275}
276
[email protected]a08ebea2011-02-13 17:50:20277void PluginService::OpenChannelToNpapiPlugin(
[email protected]c8f73ab2011-01-22 00:05:17278 int render_process_id,
279 int render_view_id,
[email protected]610c0892009-09-08 19:46:18280 const GURL& url,
281 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39282 PluginProcessHost::Client* client) {
[email protected]11e1c182011-05-17 20:26:27283 // The PluginList::GetPluginInfo may need to load the plugins. Don't do it on
284 // the IO thread.
[email protected]6fdd4182010-10-14 23:59:26285 BrowserThread::PostTask(
286 BrowserThread::FILE, FROM_HERE,
287 NewRunnableMethod(
288 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
[email protected]c8f73ab2011-01-22 00:05:17289 render_process_id, render_view_id, url, mime_type, client));
[email protected]6fdd4182010-10-14 23:59:26290}
291
[email protected]a08ebea2011-02-13 17:50:20292void PluginService::OpenChannelToPpapiPlugin(
293 const FilePath& path,
294 PpapiPluginProcessHost::Client* client) {
[email protected]d259a8e2011-05-18 22:31:09295 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
296 path, client);
[email protected]a08ebea2011-02-13 17:50:20297 if (plugin_host)
298 plugin_host->OpenChannelToPlugin(client);
299 else // Send error.
300 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
301}
302
[email protected]eb415bf0e2011-04-14 02:45:42303void PluginService::OpenChannelToPpapiBroker(
304 const FilePath& path,
305 PpapiBrokerProcessHost::Client* client) {
306 PpapiBrokerProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(path);
307 if (plugin_host)
308 plugin_host->OpenChannelToPpapiBroker(client);
309 else // Send error.
310 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
311}
312
[email protected]6fdd4182010-10-14 23:59:26313void PluginService::GetAllowedPluginForOpenChannelToPlugin(
[email protected]c8f73ab2011-01-22 00:05:17314 int render_process_id,
315 int render_view_id,
[email protected]6fdd4182010-10-14 23:59:26316 const GURL& url,
317 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39318 PluginProcessHost::Client* client) {
[email protected]6fdd4182010-10-14 23:59:26319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]91d9f3d2011-08-14 05:24:44320 webkit::WebPluginInfo info;
[email protected]11e1c182011-05-17 20:26:27321 bool found = GetPluginInfo(
[email protected]c8f73ab2011-01-22 00:05:17322 render_process_id, render_view_id, url, mime_type, &info, NULL);
[email protected]6fdd4182010-10-14 23:59:26323 FilePath plugin_path;
[email protected]68598072011-07-29 08:21:28324 if (found)
[email protected]6fdd4182010-10-14 23:59:26325 plugin_path = FilePath(info.path);
326
327 // Now we jump back to the IO thread to finish opening the channel.
328 BrowserThread::PostTask(
329 BrowserThread::IO, FROM_HERE,
330 NewRunnableMethod(
331 this, &PluginService::FinishOpenChannelToPlugin,
[email protected]46b69e42010-11-02 12:26:39332 plugin_path, client));
[email protected]6fdd4182010-10-14 23:59:26333}
334
335void PluginService::FinishOpenChannelToPlugin(
[email protected]6fdd4182010-10-14 23:59:26336 const FilePath& plugin_path,
[email protected]46b69e42010-11-02 12:26:39337 PluginProcessHost::Client* client) {
[email protected]f8b3ef82010-10-11 02:45:52338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20a793e2010-10-12 06:50:08339
[email protected]a08ebea2011-02-13 17:50:20340 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path);
[email protected]46b69e42010-11-02 12:26:39341 if (plugin_host)
342 plugin_host->OpenChannelToPlugin(client);
343 else
344 client->OnError();
initial.commit09911bf2008-07-26 23:55:29345}
346
[email protected]11e1c182011-05-17 20:26:27347bool PluginService::GetPluginInfo(int render_process_id,
348 int render_view_id,
349 const GURL& url,
350 const std::string& mime_type,
[email protected]91d9f3d2011-08-14 05:24:44351 webkit::WebPluginInfo* info,
[email protected]11e1c182011-05-17 20:26:27352 std::string* actual_mime_type) {
[email protected]6fdd4182010-10-14 23:59:26353 // GetPluginInfoArray may need to load the plugins, so we need to be
354 // on the FILE thread.
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]c8f73ab2011-01-22 00:05:17356 {
[email protected]5c19e8b2011-01-22 00:18:47357 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17358 for (size_t i = 0; i < overridden_plugins_.size(); ++i) {
359 if (overridden_plugins_[i].render_process_id == render_process_id &&
360 overridden_plugins_[i].render_view_id == render_view_id &&
[email protected]6b14feb2011-08-16 11:22:56361 (overridden_plugins_[i].url == url ||
362 overridden_plugins_[i].url.is_empty())) {
[email protected]79f0fa752011-01-27 20:01:47363 if (actual_mime_type)
364 *actual_mime_type = mime_type;
[email protected]c8f73ab2011-01-22 00:05:17365 *info = overridden_plugins_[i].plugin;
366 return true;
367 }
368 }
369 }
[email protected]68598072011-07-29 08:21:28370 bool allow_wildcard = true;
[email protected]91d9f3d2011-08-14 05:24:44371 std::vector<webkit::WebPluginInfo> plugins;
[email protected]68598072011-07-29 08:21:28372 std::vector<std::string> mime_types;
373 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
374 url, mime_type, allow_wildcard, NULL, &plugins, &mime_types);
375 for (size_t i = 0; i < plugins.size(); ++i) {
[email protected]91d9f3d2011-08-14 05:24:44376 if (webkit::IsPluginEnabled(plugins[i])) {
[email protected]68598072011-07-29 08:21:28377 *info = plugins[i];
378 if (actual_mime_type)
379 *actual_mime_type = mime_types[i];
380 return true;
381 }
382 }
383 return false;
[email protected]6fdd4182010-10-14 23:59:26384}
385
[email protected]580522632009-08-17 21:55:55386void PluginService::OnWaitableEventSignaled(
387 base::WaitableEvent* waitable_event) {
[email protected]b547fd42009-04-23 23:16:27388#if defined(OS_WIN)
389 if (waitable_event == hkcu_event_.get()) {
390 hkcu_key_.StartWatching();
391 } else {
392 hklm_key_.StartWatching();
393 }
394
[email protected]191eb3f72010-12-21 06:27:50395 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]b78e168b2009-09-21 22:05:45396 PurgePluginListCache(true);
[email protected]634d23d2011-01-19 10:38:19397#else
398 // This event should only get signaled on a Windows machine.
399 NOTREACHED();
[email protected]9de09f82009-08-17 20:13:53400#endif // defined(OS_WIN)
[email protected]b547fd42009-04-23 23:16:27401}
[email protected]894bb502009-05-21 22:39:57402
[email protected]432115822011-07-10 15:52:27403void PluginService::Observe(int type,
[email protected]894bb502009-05-21 22:39:57404 const NotificationSource& source,
405 const NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27406 switch (type) {
[email protected]a96ec6a2009-11-04 17:27:08407#if defined(OS_MACOSX)
[email protected]432115822011-07-10 15:52:27408 case content::NOTIFICATION_APP_ACTIVATED: {
[email protected]f8b3ef82010-10-11 02:45:52409 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
410 NewRunnableFunction(&NotifyPluginsOfActivation));
[email protected]a96ec6a2009-11-04 17:27:08411 break;
412 }
413#endif
414
[email protected]432115822011-07-10 15:52:27415 case content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED: {
[email protected]b83ff222011-01-24 17:37:12416 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]5f101bbe2010-10-08 08:01:16417 PurgePluginListCache(false);
418 break;
419 }
[email protected]432115822011-07-10 15:52:27420 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
[email protected]c8f73ab2011-01-22 00:05:17421 int render_process_id = Source<RenderProcessHost>(source).ptr()->id();
422
[email protected]5c19e8b2011-01-22 00:18:47423 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17424 for (size_t i = 0; i < overridden_plugins_.size(); ++i) {
425 if (overridden_plugins_[i].render_process_id == render_process_id) {
426 overridden_plugins_.erase(overridden_plugins_.begin() + i);
427 break;
428 }
429 }
430 break;
431 }
[email protected]894bb502009-05-21 22:39:57432 default:
[email protected]634d23d2011-01-19 10:38:19433 NOTREACHED();
[email protected]894bb502009-05-21 22:39:57434 }
435}
[email protected]9dd9e8382009-06-05 18:23:21436
[email protected]bd5174d2011-03-11 01:02:56437void PluginService::OverridePluginForTab(const OverriddenPlugin& plugin) {
[email protected]5c19e8b2011-01-22 00:18:47438 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17439 overridden_plugins_.push_back(plugin);
440}
441
[email protected]2de307592011-04-05 21:16:58442void PluginService::PurgePluginListCache(bool reload_pages) {
443 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
444 !it.IsAtEnd(); it.Advance()) {
445 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
446 }
447}
448
449void PluginService::RestrictPluginToUrl(const FilePath& plugin_path,
450 const GURL& url) {
451 base::AutoLock auto_lock(restricted_plugin_lock_);
452 if (url.is_empty()) {
453 restricted_plugin_.erase(plugin_path);
454 } else {
455 restricted_plugin_[plugin_path] = url;
456 }
457}
458
459bool PluginService::PluginAllowedForURL(const FilePath& plugin_path,
460 const GURL& url) {
461 if (url.is_empty())
462 return true; // Caller wants all plugins.
463
464 base::AutoLock auto_lock(restricted_plugin_lock_);
465
466 RestrictedPluginMap::iterator it = restricted_plugin_.find(plugin_path);
467 if (it == restricted_plugin_.end())
468 return true; // This plugin is not restricted, so it's allowed everywhere.
469
470 const GURL& required_url = it->second;
471 return (url.scheme() == required_url.scheme() &&
472 url.host() == required_url.host());
473}
474
[email protected]4e0616e2010-05-28 14:55:53475void PluginService::RegisterPepperPlugins() {
[email protected]84396dbc2011-04-14 06:33:42476 // TODO(abarth): It seems like the PepperPluginRegistry should do this work.
[email protected]a08ebea2011-02-13 17:50:20477 PepperPluginRegistry::ComputeList(&ppapi_plugins_);
478 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) {
[email protected]84396dbc2011-04-14 06:33:42479 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(
480 ppapi_plugins_[i].ToWebPluginInfo());
[email protected]4e0616e2010-05-28 14:55:53481 }
482}
[email protected]634d23d2011-01-19 10:38:19483
[email protected]eb415bf0e2011-04-14 02:45:42484// There should generally be very few plugins so a brute-force search is fine.
485PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo(
486 const FilePath& plugin_path) {
487 PepperPluginInfo* info = NULL;
488 for (size_t i = 0; i < ppapi_plugins_.size(); i++) {
[email protected]6b14feb2011-08-16 11:22:56489 if (ppapi_plugins_[i].path == plugin_path) {
490 info = &ppapi_plugins_[i];
491 break;
492 }
[email protected]eb415bf0e2011-04-14 02:45:42493 }
[email protected]076117592011-08-17 03:16:41494 if (info)
495 return info;
496 // We did not find the plugin in our list. But wait! the plugin can also
497 // be a latecomer, as it happens with pepper flash. This information
498 // can be obtained from the PluginList singleton and we can use it to
499 // construct it and add it to the list. This same deal needs to be done
500 // in the renderer side in PepperPluginRegistry.
501 webkit::WebPluginInfo webplugin_info;
502 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath(
503 plugin_path, &webplugin_info))
504 return NULL;
505 PepperPluginInfo new_pepper_info;
506 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info))
507 return NULL;
508 ppapi_plugins_.push_back(new_pepper_info);
509 return &ppapi_plugins_[ppapi_plugins_.size() - 1];
[email protected]eb415bf0e2011-04-14 02:45:42510}
511
[email protected]e63c4d72011-05-31 22:38:29512#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]634d23d2011-01-19 10:38:19513// static
514void PluginService::RegisterFilePathWatcher(
515 FilePathWatcher *watcher,
516 const FilePath& path,
517 FilePathWatcher::Delegate* delegate) {
[email protected]7b3ee8b2011-04-01 18:48:19518 bool result = watcher->Watch(path, delegate);
[email protected]634d23d2011-01-19 10:38:19519 DCHECK(result);
520}
521#endif