blob: 7ba4fa549e6f0a425ea0405e8005ba4f1a2f500c [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"
initial.commit09911bf2008-07-26 23:55:2917#include "chrome/browser/browser_process.h"
[email protected]0a8b1e22010-07-02 09:31:1118#include "chrome/browser/plugin_updater.h"
[email protected]8ecad5e2010-12-02 21:18:3319#include "chrome/browser/profiles/profile.h"
[email protected]9c49ff02010-01-27 01:20:5520#include "chrome/common/chrome_paths.h"
[email protected]d48f1e0c2009-02-12 20:57:5421#include "chrome/common/chrome_switches.h"
[email protected]2290cb862010-06-02 16:50:5822#include "chrome/common/default_plugin.h"
initial.commit09911bf2008-07-26 23:55:2923#include "chrome/common/logging_chrome.h"
[email protected]4e0616e2010-05-28 14:55:5324#include "chrome/common/pepper_plugin_registry.h"
[email protected]b547fd42009-04-23 23:16:2725#include "chrome/common/render_messages.h"
[email protected]a0421732011-02-23 03:55:4026#include "content/browser/browser_thread.h"
[email protected]a01efd22011-03-01 00:38:3227#include "content/browser/ppapi_plugin_process_host.h"
[email protected]a0421732011-02-23 03:55:4028#include "content/browser/renderer_host/render_process_host.h"
29#include "content/browser/renderer_host/render_view_host.h"
[email protected]7f070d42011-03-09 20:25:3230#include "content/common/notification_service.h"
31#include "content/common/notification_type.h"
[email protected]105303e2011-03-14 22:16:1032#include "content/common/plugin_messages.h"
[email protected]191eb3f72010-12-21 06:27:5033#include "webkit/plugins/npapi/plugin_constants_win.h"
34#include "webkit/plugins/npapi/plugin_list.h"
35#include "webkit/plugins/npapi/webplugininfo.h"
36
[email protected]6fdd4182010-10-14 23:59:2637#if defined(OS_CHROMEOS)
38#include "chrome/browser/chromeos/plugin_selection_policy.h"
39#endif
initial.commit09911bf2008-07-26 23:55:2940
[email protected]a96ec6a2009-11-04 17:27:0841#if defined(OS_MACOSX)
42static void NotifyPluginsOfActivation() {
[email protected]f8b3ef82010-10-11 02:45:5243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]a96ec6a2009-11-04 17:27:0844
[email protected]d27893f62010-07-03 05:47:4245 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a96ec6a2009-11-04 17:27:0846 !iter.Done(); ++iter) {
47 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
48 plugin->OnAppActivation();
49 }
50}
51#endif
52
[email protected]634d23d2011-01-19 10:38:1953#if defined(OS_LINUX)
54// Delegate class for monitoring directories.
55class PluginDirWatcherDelegate : public FilePathWatcher::Delegate {
[email protected]7b3ee8b2011-04-01 18:48:1956 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE {
[email protected]634d23d2011-01-19 10:38:1957 VLOG(1) << "Watched path changed: " << path.value();
58 // Make the plugin list update itself
59 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
60 }
[email protected]7b3ee8b2011-04-01 18:48:1961 virtual void OnFilePathError(const FilePath& path) OVERRIDE {
[email protected]634d23d2011-01-19 10:38:1962 // TODO(pastarmovj): Add some sensible error handling. Maybe silently
63 // stopping the watcher would be enough. Or possibly restart it.
64 NOTREACHED();
65 }
66};
67#endif
68
initial.commit09911bf2008-07-26 23:55:2969// static
[email protected]cec1b8d2010-03-24 00:21:3470void PluginService::InitGlobalInstance(Profile* profile) {
[email protected]f8b3ef82010-10-11 02:45:5271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]cec1b8d2010-03-24 00:21:3472
[email protected]24ff43d72011-03-01 13:28:5873 // We first group the plugins and then figure out which groups to
74 // enable or disable.
75 PluginUpdater::GetInstance()->UpdatePluginGroupsStateFromPrefs(profile);
[email protected]cec1b8d2010-03-24 00:21:3476}
77
78// static
initial.commit09911bf2008-07-26 23:55:2979PluginService* PluginService::GetInstance() {
80 return Singleton<PluginService>::get();
81}
82
83PluginService::PluginService()
84 : main_message_loop_(MessageLoop::current()),
[email protected]f77d87622010-07-30 17:43:1785 ui_locale_(g_browser_process->GetApplicationLocale()) {
[email protected]4e0616e2010-05-28 14:55:5386 RegisterPepperPlugins();
87
[email protected]9a1c4262010-06-29 21:50:2788 // Load any specified on the command line as well.
[email protected]d48f1e0c2009-02-12 20:57:5489 const CommandLine* command_line = CommandLine::ForCurrentProcess();
[email protected]c4e52f0d2009-11-06 19:55:1690 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin);
[email protected]7bf795d92010-05-22 00:14:2891 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:5092 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
[email protected]9a1c4262010-06-29 21:50:2793 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir);
94 if (!path.empty())
[email protected]191eb3f72010-12-21 06:27:5095 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path);
[email protected]7bf795d92010-05-22 00:14:2896
[email protected]2290cb862010-06-02 16:50:5897 chrome::RegisterInternalDefaultPlugin();
98
[email protected]7bf795d92010-05-22 00:14:2899 // Register the internal Flash and PDF, if available.
100 if (!CommandLine::ForCurrentProcess()->HasSwitch(
101 switches::kDisableInternalFlash) &&
102 PathService::Get(chrome::FILE_FLASH_PLUGIN, &path)) {
[email protected]191eb3f72010-12-21 06:27:50103 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
[email protected]35fa6a22009-08-15 00:04:01104 }
[email protected]d7ce4272010-03-27 01:06:01105
[email protected]6fdd4182010-10-14 23:59:26106#if defined(OS_CHROMEOS)
107 plugin_selection_policy_ = new chromeos::PluginSelectionPolicy;
108 plugin_selection_policy_->StartInit();
109#endif
110
[email protected]634d23d2011-01-19 10:38:19111 // Start watching for changes in the plugin list. This means watching
112 // for changes in the Windows registry keys and on both Windows and POSIX
113 // watch for changes in the paths that are expected to contain plugins.
[email protected]b547fd42009-04-23 23:16:27114#if defined(OS_WIN)
115 hkcu_key_.Create(
[email protected]191eb3f72010-12-21 06:27:50116 HKEY_CURRENT_USER, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
[email protected]b547fd42009-04-23 23:16:27117 hklm_key_.Create(
[email protected]191eb3f72010-12-21 06:27:50118 HKEY_LOCAL_MACHINE, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY);
[email protected]e06f4d52011-01-19 07:28:46119 if (hkcu_key_.StartWatching() == ERROR_SUCCESS) {
[email protected]b547fd42009-04-23 23:16:27120 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event()));
121 hkcu_watcher_.StartWatching(hkcu_event_.get(), this);
122 }
123
[email protected]e06f4d52011-01-19 07:28:46124 if (hklm_key_.StartWatching() == ERROR_SUCCESS) {
[email protected]b547fd42009-04-23 23:16:27125 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event()));
126 hklm_watcher_.StartWatching(hklm_event_.get(), this);
127 }
[email protected]9c49ff02010-01-27 01:20:55128#elif defined(OS_POSIX) && !defined(OS_MACOSX)
129 // Also find plugins in a user-specific plugins dir,
130 // e.g. ~/.config/chromium/Plugins.
131 FilePath user_data_dir;
132 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
[email protected]191eb3f72010-12-21 06:27:50133 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(
[email protected]9c49ff02010-01-27 01:20:55134 user_data_dir.Append("Plugins"));
135 }
[email protected]b547fd42009-04-23 23:16:27136#endif
[email protected]634d23d2011-01-19 10:38:19137// The FilePathWatcher produces too many false positives on MacOS (access time
138// updates?) which will lead to enforcing updates of the plugins way too often.
139// On ChromeOS the user can't install plugins anyway and on Windows all
140// important plugins register themselves in the registry so no need to do that.
141#if defined(OS_LINUX)
142 file_watcher_delegate_ = new PluginDirWatcherDelegate();
143 // Get the list of all paths for registering the FilePathWatchers
144 // that will track and if needed reload the list of plugins on runtime.
145 std::vector<FilePath> plugin_dirs;
146 webkit::npapi::PluginList::Singleton()->GetPluginDirectories(
147 &plugin_dirs);
[email protected]894bb502009-05-21 22:39:57148
[email protected]634d23d2011-01-19 10:38:19149 for (size_t i = 0; i < plugin_dirs.size(); ++i) {
150 FilePathWatcher* watcher = new FilePathWatcher();
151 // FilePathWatcher can not handle non-absolute paths under windows.
152 // We don't watch for file changes in windows now but if this should ever
153 // be extended to Windows these lines might save some time of debugging.
154#if defined(OS_WIN)
155 if (!plugin_dirs[i].IsAbsolute())
156 continue;
157#endif
158 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value();
159 BrowserThread::PostTask(
160 BrowserThread::FILE, FROM_HERE,
161 NewRunnableFunction(
162 &PluginService::RegisterFilePathWatcher,
163 watcher, plugin_dirs[i], file_watcher_delegate_));
164 file_watchers_.push_back(watcher);
165 }
166#endif
[email protected]a96ec6a2009-11-04 17:27:08167#if defined(OS_MACOSX)
168 // We need to know when the browser comes forward so we can bring modal plugin
169 // windows forward too.
170 registrar_.Add(this, NotificationType::APP_ACTIVATED,
171 NotificationService::AllSources());
172#endif
[email protected]5f101bbe2010-10-08 08:01:16173 registrar_.Add(this, NotificationType::PLUGIN_ENABLE_STATUS_CHANGED,
174 NotificationService::AllSources());
[email protected]c8f73ab2011-01-22 00:05:17175 registrar_.Add(this,
176 NotificationType::RENDERER_PROCESS_CLOSED,
177 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29178}
179
180PluginService::~PluginService() {
[email protected]b547fd42009-04-23 23:16:27181#if defined(OS_WIN)
182 // Release the events since they're owned by RegKey, not WaitableEvent.
183 hkcu_watcher_.StopWatching();
184 hklm_watcher_.StopWatching();
[email protected]c247cab2011-01-21 01:58:42185 if (hkcu_event_.get())
186 hkcu_event_->Release();
187 if (hklm_event_.get())
188 hklm_event_->Release();
[email protected]b547fd42009-04-23 23:16:27189#endif
initial.commit09911bf2008-07-26 23:55:29190}
191
[email protected]f77d87622010-07-30 17:43:17192const std::string& PluginService::GetUILocale() {
initial.commit09911bf2008-07-26 23:55:29193 return ui_locale_;
194}
195
[email protected]a08ebea2011-02-13 17:50:20196PluginProcessHost* PluginService::FindNpapiPluginProcess(
[email protected]28ab7f92009-01-06 21:39:04197 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29199
[email protected]d27893f62010-07-03 05:47:42200 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
[email protected]a436d922009-02-13 23:16:42201 !iter.Done(); ++iter) {
202 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
203 if (plugin->info().path == plugin_path)
204 return plugin;
205 }
206
initial.commit09911bf2008-07-26 23:55:29207 return NULL;
208}
209
[email protected]a08ebea2011-02-13 17:50:20210PpapiPluginProcessHost* PluginService::FindPpapiPluginProcess(
[email protected]610c0892009-09-08 19:46:18211 const FilePath& plugin_path) {
[email protected]f8b3ef82010-10-11 02:45:52212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29213
[email protected]a08ebea2011-02-13 17:50:20214 for (BrowserChildProcessHost::Iterator iter(
215 ChildProcessInfo::PPAPI_PLUGIN_PROCESS);
216 !iter.Done(); ++iter) {
217 PpapiPluginProcessHost* plugin =
218 static_cast<PpapiPluginProcessHost*>(*iter);
219 if (plugin->plugin_path() == plugin_path)
220 return plugin;
221 }
222
223 return NULL;
224}
225
[email protected]eb415bf0e2011-04-14 02:45:42226PpapiBrokerProcessHost* PluginService::FindPpapiBrokerProcess(
227 const FilePath& broker_path) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
229
230 for (BrowserChildProcessHost::Iterator iter(
231 ChildProcessInfo::PPAPI_BROKER_PROCESS);
232 !iter.Done(); ++iter) {
233 PpapiBrokerProcessHost* broker =
234 static_cast<PpapiBrokerProcessHost*>(*iter);
235 if (broker->broker_path() == broker_path)
236 return broker;
237 }
238
239 return NULL;
240}
241
[email protected]a08ebea2011-02-13 17:50:20242PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
243 const FilePath& plugin_path) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
245
246 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path);
initial.commit09911bf2008-07-26 23:55:29247 if (plugin_host)
248 return plugin_host;
249
[email protected]191eb3f72010-12-21 06:27:50250 webkit::npapi::WebPluginInfo info;
251 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath(
252 plugin_path, &info)) {
[email protected]a27a9382009-02-11 23:55:10253 return NULL;
254 }
255
initial.commit09911bf2008-07-26 23:55:29256 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]8b8a554d2010-11-18 13:26:40257 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
258 if (!new_host->Init(info, ui_locale_)) {
[email protected]a08ebea2011-02-13 17:50:20259 NOTREACHED(); // Init is not expected to fail.
initial.commit09911bf2008-07-26 23:55:29260 return NULL;
261 }
[email protected]8b8a554d2010-11-18 13:26:40262 return new_host.release();
initial.commit09911bf2008-07-26 23:55:29263}
264
[email protected]a08ebea2011-02-13 17:50:20265PpapiPluginProcessHost* PluginService::FindOrStartPpapiPluginProcess(
266 const FilePath& plugin_path) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
268
269 PpapiPluginProcessHost* plugin_host = FindPpapiPluginProcess(plugin_path);
270 if (plugin_host)
271 return plugin_host;
272
[email protected]eb415bf0e2011-04-14 02:45:42273 // Validate that the plugin is actually registered.
274 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]a08ebea2011-02-13 17:50:20275 if (!info)
276 return NULL;
277
278 // This plugin isn't loaded by any plugin process, so create a new process.
279 scoped_ptr<PpapiPluginProcessHost> new_host(new PpapiPluginProcessHost);
[email protected]277a1112011-03-19 06:03:56280 if (!new_host->Init(*info)) {
[email protected]a08ebea2011-02-13 17:50:20281 NOTREACHED(); // Init is not expected to fail.
282 return NULL;
283 }
284 return new_host.release();
285}
286
[email protected]eb415bf0e2011-04-14 02:45:42287PpapiBrokerProcessHost* PluginService::FindOrStartPpapiBrokerProcess(
288 const FilePath& plugin_path) {
289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
290
291 PpapiBrokerProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
292 if (plugin_host)
293 return plugin_host;
294
295 // Validate that the plugin is actually registered.
296 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
297 if (!info)
298 return NULL;
299
300 // TODO(ddorwin): Uncomment once out of process is supported.
301 // DCHECK(info->is_out_of_process);
302
303 // This broker isn't loaded by any broker process, so create a new process.
304 scoped_ptr<PpapiBrokerProcessHost> new_host(
305 new PpapiBrokerProcessHost);
306 if (!new_host->Init(*info)) {
307 NOTREACHED(); // Init is not expected to fail.
308 return NULL;
309 }
310 return new_host.release();
311}
312
[email protected]a08ebea2011-02-13 17:50:20313void PluginService::OpenChannelToNpapiPlugin(
[email protected]c8f73ab2011-01-22 00:05:17314 int render_process_id,
315 int render_view_id,
[email protected]610c0892009-09-08 19:46:18316 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 // The PluginList::GetFirstAllowedPluginInfo may need to load the
320 // plugins. Don't do it on the IO thread.
321 BrowserThread::PostTask(
322 BrowserThread::FILE, FROM_HERE,
323 NewRunnableMethod(
324 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
[email protected]c8f73ab2011-01-22 00:05:17325 render_process_id, render_view_id, url, mime_type, client));
[email protected]6fdd4182010-10-14 23:59:26326}
327
[email protected]a08ebea2011-02-13 17:50:20328void PluginService::OpenChannelToPpapiPlugin(
329 const FilePath& path,
330 PpapiPluginProcessHost::Client* client) {
331 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(path);
332 if (plugin_host)
333 plugin_host->OpenChannelToPlugin(client);
334 else // Send error.
335 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
336}
337
[email protected]eb415bf0e2011-04-14 02:45:42338void PluginService::OpenChannelToPpapiBroker(
339 const FilePath& path,
340 PpapiBrokerProcessHost::Client* client) {
341 PpapiBrokerProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(path);
342 if (plugin_host)
343 plugin_host->OpenChannelToPpapiBroker(client);
344 else // Send error.
345 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
346}
347
[email protected]6fdd4182010-10-14 23:59:26348void PluginService::GetAllowedPluginForOpenChannelToPlugin(
[email protected]c8f73ab2011-01-22 00:05:17349 int render_process_id,
350 int render_view_id,
[email protected]6fdd4182010-10-14 23:59:26351 const GURL& url,
352 const std::string& mime_type,
[email protected]46b69e42010-11-02 12:26:39353 PluginProcessHost::Client* client) {
[email protected]6fdd4182010-10-14 23:59:26354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]191eb3f72010-12-21 06:27:50355 webkit::npapi::WebPluginInfo info;
[email protected]c8f73ab2011-01-22 00:05:17356 bool found = GetFirstAllowedPluginInfo(
357 render_process_id, render_view_id, url, mime_type, &info, NULL);
[email protected]6fdd4182010-10-14 23:59:26358 FilePath plugin_path;
[email protected]b83ff222011-01-24 17:37:12359 if (found && webkit::npapi::IsPluginEnabled(info))
[email protected]6fdd4182010-10-14 23:59:26360 plugin_path = FilePath(info.path);
361
362 // Now we jump back to the IO thread to finish opening the channel.
363 BrowserThread::PostTask(
364 BrowserThread::IO, FROM_HERE,
365 NewRunnableMethod(
366 this, &PluginService::FinishOpenChannelToPlugin,
[email protected]46b69e42010-11-02 12:26:39367 plugin_path, client));
[email protected]6fdd4182010-10-14 23:59:26368}
369
370void PluginService::FinishOpenChannelToPlugin(
[email protected]6fdd4182010-10-14 23:59:26371 const FilePath& plugin_path,
[email protected]46b69e42010-11-02 12:26:39372 PluginProcessHost::Client* client) {
[email protected]f8b3ef82010-10-11 02:45:52373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20a793e2010-10-12 06:50:08374
[email protected]a08ebea2011-02-13 17:50:20375 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path);
[email protected]46b69e42010-11-02 12:26:39376 if (plugin_host)
377 plugin_host->OpenChannelToPlugin(client);
378 else
379 client->OnError();
initial.commit09911bf2008-07-26 23:55:29380}
381
[email protected]6fdd4182010-10-14 23:59:26382bool PluginService::GetFirstAllowedPluginInfo(
[email protected]c8f73ab2011-01-22 00:05:17383 int render_process_id,
384 int render_view_id,
[email protected]6fdd4182010-10-14 23:59:26385 const GURL& url,
386 const std::string& mime_type,
[email protected]191eb3f72010-12-21 06:27:50387 webkit::npapi::WebPluginInfo* info,
[email protected]6fdd4182010-10-14 23:59:26388 std::string* actual_mime_type) {
389 // GetPluginInfoArray may need to load the plugins, so we need to be
390 // on the FILE thread.
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
392 bool allow_wildcard = true;
393#if defined(OS_CHROMEOS)
[email protected]191eb3f72010-12-21 06:27:50394 std::vector<webkit::npapi::WebPluginInfo> info_array;
[email protected]6fdd4182010-10-14 23:59:26395 std::vector<std::string> actual_mime_types;
[email protected]191eb3f72010-12-21 06:27:50396 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
[email protected]6fdd4182010-10-14 23:59:26397 url, mime_type, allow_wildcard, &info_array, &actual_mime_types);
398
399 // Now we filter by the plugin selection policy.
400 int allowed_index = plugin_selection_policy_->FindFirstAllowed(url,
401 info_array);
402 if (!info_array.empty() && allowed_index >= 0) {
403 *info = info_array[allowed_index];
404 if (actual_mime_type)
405 *actual_mime_type = actual_mime_types[allowed_index];
406 return true;
407 }
408 return false;
409#else
[email protected]c8f73ab2011-01-22 00:05:17410 {
[email protected]5c19e8b2011-01-22 00:18:47411 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17412 for (size_t i = 0; i < overridden_plugins_.size(); ++i) {
413 if (overridden_plugins_[i].render_process_id == render_process_id &&
414 overridden_plugins_[i].render_view_id == render_view_id &&
415 overridden_plugins_[i].url == url) {
[email protected]79f0fa752011-01-27 20:01:47416 if (actual_mime_type)
417 *actual_mime_type = mime_type;
[email protected]c8f73ab2011-01-22 00:05:17418 *info = overridden_plugins_[i].plugin;
419 return true;
420 }
421 }
422 }
[email protected]191eb3f72010-12-21 06:27:50423 return webkit::npapi::PluginList::Singleton()->GetPluginInfo(
[email protected]6fdd4182010-10-14 23:59:26424 url, mime_type, allow_wildcard, info, actual_mime_type);
425#endif
426}
427
[email protected]580522632009-08-17 21:55:55428void PluginService::OnWaitableEventSignaled(
429 base::WaitableEvent* waitable_event) {
[email protected]b547fd42009-04-23 23:16:27430#if defined(OS_WIN)
431 if (waitable_event == hkcu_event_.get()) {
432 hkcu_key_.StartWatching();
433 } else {
434 hklm_key_.StartWatching();
435 }
436
[email protected]191eb3f72010-12-21 06:27:50437 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]b78e168b2009-09-21 22:05:45438 PurgePluginListCache(true);
[email protected]634d23d2011-01-19 10:38:19439#else
440 // This event should only get signaled on a Windows machine.
441 NOTREACHED();
[email protected]9de09f82009-08-17 20:13:53442#endif // defined(OS_WIN)
[email protected]b547fd42009-04-23 23:16:27443}
[email protected]894bb502009-05-21 22:39:57444
445void PluginService::Observe(NotificationType type,
446 const NotificationSource& source,
447 const NotificationDetails& details) {
448 switch (type.value) {
[email protected]a96ec6a2009-11-04 17:27:08449#if defined(OS_MACOSX)
450 case NotificationType::APP_ACTIVATED: {
[email protected]f8b3ef82010-10-11 02:45:52451 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
452 NewRunnableFunction(&NotifyPluginsOfActivation));
[email protected]a96ec6a2009-11-04 17:27:08453 break;
454 }
455#endif
456
[email protected]5f101bbe2010-10-08 08:01:16457 case NotificationType::PLUGIN_ENABLE_STATUS_CHANGED: {
[email protected]b83ff222011-01-24 17:37:12458 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
[email protected]5f101bbe2010-10-08 08:01:16459 PurgePluginListCache(false);
460 break;
461 }
[email protected]c8f73ab2011-01-22 00:05:17462 case NotificationType::RENDERER_PROCESS_CLOSED: {
463 int render_process_id = Source<RenderProcessHost>(source).ptr()->id();
464
[email protected]5c19e8b2011-01-22 00:18:47465 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17466 for (size_t i = 0; i < overridden_plugins_.size(); ++i) {
467 if (overridden_plugins_[i].render_process_id == render_process_id) {
468 overridden_plugins_.erase(overridden_plugins_.begin() + i);
469 break;
470 }
471 }
472 break;
473 }
[email protected]894bb502009-05-21 22:39:57474 default:
[email protected]634d23d2011-01-19 10:38:19475 NOTREACHED();
[email protected]894bb502009-05-21 22:39:57476 }
477}
[email protected]9dd9e8382009-06-05 18:23:21478
[email protected]bd5174d2011-03-11 01:02:56479void PluginService::OverridePluginForTab(const OverriddenPlugin& plugin) {
[email protected]5c19e8b2011-01-22 00:18:47480 base::AutoLock auto_lock(overridden_plugins_lock_);
[email protected]c8f73ab2011-01-22 00:05:17481 overridden_plugins_.push_back(plugin);
482}
483
[email protected]2de307592011-04-05 21:16:58484void PluginService::PurgePluginListCache(bool reload_pages) {
485 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
486 !it.IsAtEnd(); it.Advance()) {
487 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages));
488 }
489}
490
491void PluginService::RestrictPluginToUrl(const FilePath& plugin_path,
492 const GURL& url) {
493 base::AutoLock auto_lock(restricted_plugin_lock_);
494 if (url.is_empty()) {
495 restricted_plugin_.erase(plugin_path);
496 } else {
497 restricted_plugin_[plugin_path] = url;
498 }
499}
500
501bool PluginService::PluginAllowedForURL(const FilePath& plugin_path,
502 const GURL& url) {
503 if (url.is_empty())
504 return true; // Caller wants all plugins.
505
506 base::AutoLock auto_lock(restricted_plugin_lock_);
507
508 RestrictedPluginMap::iterator it = restricted_plugin_.find(plugin_path);
509 if (it == restricted_plugin_.end())
510 return true; // This plugin is not restricted, so it's allowed everywhere.
511
512 const GURL& required_url = it->second;
513 return (url.scheme() == required_url.scheme() &&
514 url.host() == required_url.host());
515}
516
[email protected]4e0616e2010-05-28 14:55:53517void PluginService::RegisterPepperPlugins() {
[email protected]84396dbc2011-04-14 06:33:42518 // TODO(abarth): It seems like the PepperPluginRegistry should do this work.
[email protected]a08ebea2011-02-13 17:50:20519 PepperPluginRegistry::ComputeList(&ppapi_plugins_);
[email protected]a08ebea2011-02-13 17:50:20520 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) {
[email protected]84396dbc2011-04-14 06:33:42521 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(
522 ppapi_plugins_[i].ToWebPluginInfo());
[email protected]4e0616e2010-05-28 14:55:53523 }
524}
[email protected]634d23d2011-01-19 10:38:19525
[email protected]eb415bf0e2011-04-14 02:45:42526// There should generally be very few plugins so a brute-force search is fine.
527PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo(
528 const FilePath& plugin_path) {
529 PepperPluginInfo* info = NULL;
530 for (size_t i = 0; i < ppapi_plugins_.size(); i++) {
531 if (ppapi_plugins_[i].path == plugin_path) {
532 info = &ppapi_plugins_[i];
533 break;
534 }
535 }
536 return info;
537}
538
[email protected]634d23d2011-01-19 10:38:19539#if defined(OS_LINUX)
540// static
541void PluginService::RegisterFilePathWatcher(
542 FilePathWatcher *watcher,
543 const FilePath& path,
544 FilePathWatcher::Delegate* delegate) {
[email protected]7b3ee8b2011-04-01 18:48:19545 bool result = watcher->Watch(path, delegate);
[email protected]634d23d2011-01-19 10:38:19546 DCHECK(result);
547}
548#endif