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

Side by Side Diff: webkit/glue/plugins/plugin_list.cc

Issue 6012002: Move the NPAPI files from webkit/glue/plugins to webkit/plugins/npapi and put... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/plugins/plugin_list.h ('k') | webkit/glue/plugins/plugin_list_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/glue/plugins/plugin_list.h"
6
7 #include <algorithm>
8
9 #include "base/command_line.h"
10 #include "base/lazy_instance.h"
11 #include "base/logging.h"
12 #include "base/string_split.h"
13 #include "base/string_util.h"
14 #include "base/sys_string_conversions.h"
15 #include "base/utf_string_conversions.h"
16 #include "googleurl/src/gurl.h"
17 #include "net/base/mime_util.h"
18 #include "webkit/glue/plugins/plugin_constants_win.h"
19 #include "webkit/glue/plugins/plugin_lib.h"
20 #include "webkit/glue/webkit_glue.h"
21 #include "webkit/plugins/plugin_switches.h"
22
23 #if defined(OS_POSIX)
24 #include "base/stl_util-inl.h"
25 #include "base/third_party/valgrind/valgrind.h"
26 #endif // defined(OS_POSIX)
27
28 namespace NPAPI {
29
30 #if defined(OS_MACOSX)
31 // Plugin Groups for Mac.
32 // Plugins are listed here as soon as vulnerabilities and solutions
33 // (new versions) are published.
34 // TODO(panayiotis): Get the Real Player version on Mac, somehow.
35 static const VersionRangeDefinition kQuicktimeVersionRange[] = {
36 { "", "", "7.6.6" }
37 };
38 static const VersionRangeDefinition kJavaVersionRange[] = {
39 { "", "", "" }
40 };
41 static const VersionRangeDefinition kFlashVersionRange[] = {
42 { "", "", "10.1.102" }
43 };
44 static const VersionRangeDefinition kSilverlightVersionRange[] = {
45 { "0", "4", "3.0.50106.0" },
46 { "4", "5", "" }
47 };
48 static const VersionRangeDefinition kFlip4MacVersionRange[] = {
49 { "", "", "2.2.1" }
50 };
51 static const VersionRangeDefinition kShockwaveVersionRange[] = {
52 { "", "", "11.5.9.615" }
53 };
54 static const PluginGroupDefinition kGroupDefinitions[] = {
55 { "apple-quicktime", "Quicktime", "QuickTime Plug-in", kQuicktimeVersionRange,
56 arraysize(kQuicktimeVersionRange),
57 "http://www.apple.com/quicktime/download/" },
58 { "java-runtime-environment", "Java", "Java", kJavaVersionRange,
59 arraysize(kJavaVersionRange), "http://support.apple.com/kb/HT1338" },
60 { "adobe-flash-player", "Flash", "Shockwave Flash", kFlashVersionRange,
61 arraysize(kFlashVersionRange), "http://get.adobe.com/flashplayer/" },
62 { "silverlight", "Silverlight", "Silverlight", kSilverlightVersionRange,
63 arraysize(kSilverlightVersionRange),
64 "http://www.microsoft.com/getsilverlight/" },
65 { "flip4mac", "Flip4Mac", "Flip4Mac", kFlip4MacVersionRange,
66 arraysize(kFlip4MacVersionRange),
67 "http://www.telestream.net/flip4mac-wmv/overview.htm" },
68 { "shockwave", "Shockwave", "Shockwave for Director", kShockwaveVersionRange,
69 arraysize(kShockwaveVersionRange),
70 "http://www.adobe.com/shockwave/download/" }
71 };
72
73 #elif defined(OS_WIN)
74 // TODO(panayiotis): We should group "RealJukebox NS Plugin" with the rest of
75 // the RealPlayer files.
76 static const VersionRangeDefinition kQuicktimeVersionRange[] = {
77 { "", "", "7.6.8" }
78 };
79 static const VersionRangeDefinition kJavaVersionRange[] = {
80 { "0", "7", "6.0.220" } // "220" is not a typo.
81 };
82 static const VersionRangeDefinition kAdobeReaderVersionRange[] = {
83 { "10", "11", "" },
84 { "9", "10", "9.4.1" },
85 { "0", "9", "8.2.5" }
86 };
87 static const VersionRangeDefinition kFlashVersionRange[] = {
88 { "", "", "10.1.102" }
89 };
90 static const VersionRangeDefinition kSilverlightVersionRange[] = {
91 { "0", "4", "3.0.50106.0" },
92 { "4", "5", "" }
93 };
94 static const VersionRangeDefinition kShockwaveVersionRange[] = {
95 { "", "", "11.5.9.615" }
96 };
97 static const VersionRangeDefinition kDivXVersionRange[] = {
98 { "", "", "1.4.3.4" }
99 };
100 static const PluginGroupDefinition kGroupDefinitions[] = {
101 { "apple-quicktime", "Quicktime", "QuickTime Plug-in", kQuicktimeVersionRange,
102 arraysize(kQuicktimeVersionRange),
103 "http://www.apple.com/quicktime/download/" },
104 { "java-runtime-environment", "Java 6", "Java", kJavaVersionRange,
105 arraysize(kJavaVersionRange), "http://www.java.com/" },
106 { "adobe-reader", PluginGroup::kAdobeReaderGroupName, "Adobe Acrobat",
107 kAdobeReaderVersionRange, arraysize(kAdobeReaderVersionRange),
108 "http://get.adobe.com/reader/" },
109 { "adobe-flash-player", "Flash", "Shockwave Flash", kFlashVersionRange,
110 arraysize(kFlashVersionRange), "http://get.adobe.com/flashplayer/" },
111 { "silverlight", "Silverlight", "Silverlight", kSilverlightVersionRange,
112 arraysize(kSilverlightVersionRange),
113 "http://www.microsoft.com/getsilverlight/" },
114 { "shockwave", "Shockwave", "Shockwave for Director", kShockwaveVersionRange,
115 arraysize(kShockwaveVersionRange),
116 "http://www.adobe.com/shockwave/download/" },
117 { "divx-player", "DivX Player", "DivX Web Player", kDivXVersionRange,
118 arraysize(kDivXVersionRange),
119 "http://download.divx.com/divx/autoupdate/player/"
120 "DivXWebPlayerInstaller.exe" },
121 // These are here for grouping, no vulnerabilities known.
122 { "windows-media-player", "Windows Media Player", "Windows Media Player",
123 NULL, 0, "" },
124 { "microsoft-office", "Microsoft Office", "Microsoft Office",
125 NULL, 0, "" },
126 // TODO(panayiotis): The vulnerable versions are
127 // (v >= 6.0.12.1040 && v <= 6.0.12.1663)
128 // || v == 6.0.12.1698 || v == 6.0.12.1741
129 { "realplayer", "RealPlayer", "RealPlayer", NULL, 0,
130 "www.real.com/realplayer/downloads" },
131 };
132
133 #else
134 static const PluginGroupDefinition kGroupDefinitions[] = {};
135 #endif
136
137 // static
138 const PluginGroupDefinition* PluginList::GetPluginGroupDefinitions() {
139 return kGroupDefinitions;
140 }
141
142 // static
143 size_t PluginList::GetPluginGroupDefinitionsSize() {
144 // TODO(viettrungluu): |arraysize()| doesn't work with zero-size arrays.
145 return ARRAYSIZE_UNSAFE(kGroupDefinitions);
146 }
147
148 base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED);
149
150 // static
151 PluginList* PluginList::Singleton() {
152 return g_singleton.Pointer();
153 }
154
155 // static
156 bool PluginList::DebugPluginLoading() {
157 return CommandLine::ForCurrentProcess()->HasSwitch(
158 switches::kDebugPluginLoading);
159 }
160
161 bool PluginList::PluginsLoaded() {
162 AutoLock lock(lock_);
163 return plugins_loaded_;
164 }
165
166 void PluginList::RefreshPlugins() {
167 AutoLock lock(lock_);
168 plugins_need_refresh_ = true;
169 }
170
171 void PluginList::AddExtraPluginPath(const FilePath& plugin_path) {
172 // Chrome OS only loads plugins from /opt/google/chrome/plugins.
173 #if !defined(OS_CHROMEOS)
174 AutoLock lock(lock_);
175 extra_plugin_paths_.push_back(plugin_path);
176 #endif
177 }
178
179 void PluginList::RemoveExtraPluginPath(const FilePath& plugin_path) {
180 AutoLock lock(lock_);
181 std::vector<FilePath>::iterator it =
182 std::find(extra_plugin_paths_.begin(), extra_plugin_paths_.end(),
183 plugin_path);
184 if (it != extra_plugin_paths_.end())
185 extra_plugin_paths_.erase(it);
186 }
187
188 void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) {
189 // Chrome OS only loads plugins from /opt/google/chrome/plugins.
190 #if !defined(OS_CHROMEOS)
191 AutoLock lock(lock_);
192 extra_plugin_dirs_.push_back(plugin_dir);
193 #endif
194 }
195
196 void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) {
197 AutoLock lock(lock_);
198 internal_plugins_.push_back(info);
199 }
200
201 void PluginList::UnregisterInternalPlugin(const FilePath& path) {
202 AutoLock lock(lock_);
203 for (size_t i = 0; i < internal_plugins_.size(); i++) {
204 if (internal_plugins_[i].path == path) {
205 internal_plugins_.erase(internal_plugins_.begin() + i);
206 return;
207 }
208 }
209 NOTREACHED();
210 }
211
212 bool PluginList::ReadPluginInfo(const FilePath& filename,
213 WebPluginInfo* info,
214 const PluginEntryPoints** entry_points) {
215 {
216 AutoLock lock(lock_);
217 for (size_t i = 0; i < internal_plugins_.size(); ++i) {
218 if (filename == internal_plugins_[i].path) {
219 *entry_points = &internal_plugins_[i].entry_points;
220 return CreateWebPluginInfo(internal_plugins_[i], info);
221 }
222 }
223 }
224
225 // Not an internal plugin.
226 *entry_points = NULL;
227
228 return PluginLib::ReadWebPluginInfo(filename, info);
229 }
230
231 bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
232 WebPluginInfo* info) {
233 std::vector<std::string> mime_types, file_extensions;
234 std::vector<string16> descriptions;
235 base::SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types);
236 base::SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions);
237 base::SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions);
238
239 info->mime_types.clear();
240
241 if (mime_types.empty()) {
242 LOG_IF(ERROR, PluginList::DebugPluginLoading())
243 << "Plugin " << pvi.product_name << " has no MIME types, skipping";
244 return false;
245 }
246
247 info->name = WideToUTF16(pvi.product_name);
248 info->desc = WideToUTF16(pvi.file_description);
249 info->version = WideToUTF16(pvi.file_version);
250 info->path = pvi.path;
251 info->enabled = true;
252
253 for (size_t i = 0; i < mime_types.size(); ++i) {
254 WebPluginMimeType mime_type;
255 mime_type.mime_type = StringToLowerASCII(mime_types[i]);
256 if (file_extensions.size() > i)
257 base::SplitString(file_extensions[i], ',', &mime_type.file_extensions);
258
259 if (descriptions.size() > i) {
260 mime_type.description = descriptions[i];
261
262 // On Windows, the description likely has a list of file extensions
263 // embedded in it (e.g. "SurfWriter file (*.swr)"). Remove an extension
264 // list from the description if it is present.
265 size_t ext = mime_type.description.find(ASCIIToUTF16("(*"));
266 if (ext != string16::npos) {
267 if (ext > 1 && mime_type.description[ext -1] == ' ')
268 ext--;
269
270 mime_type.description.erase(ext);
271 }
272 }
273
274 info->mime_types.push_back(mime_type);
275 }
276
277 return true;
278 }
279
280 PluginList::PluginList()
281 : plugins_loaded_(false),
282 plugins_need_refresh_(false),
283 disable_outdated_plugins_(false),
284 next_priority_(0) {
285 PlatformInit();
286 AddHardcodedPluginGroups();
287 }
288
289 bool PluginList::ShouldDisableGroup(const string16& group_name) {
290 AutoLock lock(lock_);
291 if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) {
292 disabled_groups_.insert(group_name);
293 return true;
294 }
295 return disabled_groups_.count(group_name) > 0;
296 }
297
298 void PluginList::LoadPlugins(bool refresh) {
299 // Don't want to hold the lock while loading new plugins, so we don't block
300 // other methods if they're called on other threads.
301 std::vector<FilePath> extra_plugin_paths;
302 std::vector<FilePath> extra_plugin_dirs;
303 std::vector<PluginVersionInfo> internal_plugins;
304 {
305 AutoLock lock(lock_);
306 if (plugins_loaded_ && !refresh && !plugins_need_refresh_)
307 return;
308
309 // Clear the refresh bit now, because it might get set again before we
310 // reach the end of the method.
311 plugins_need_refresh_ = false;
312 extra_plugin_paths = extra_plugin_paths_;
313 extra_plugin_dirs = extra_plugin_dirs_;
314 internal_plugins = internal_plugins_;
315 }
316
317 std::vector<WebPluginInfo> new_plugins;
318 std::set<FilePath> visited_plugins;
319
320 std::vector<FilePath> directories_to_scan;
321 GetPluginDirectories(&directories_to_scan);
322
323 // Load internal plugins first so that, if both an internal plugin and a
324 // "discovered" plugin want to handle the same type, the internal plugin
325 // will have precedence.
326 for (size_t i = 0; i < internal_plugins.size(); ++i) {
327 if (internal_plugins[i].path.value() == kDefaultPluginLibraryName)
328 continue;
329 LoadPlugin(internal_plugins[i].path, &new_plugins);
330 }
331
332 for (size_t i = 0; i < extra_plugin_paths.size(); ++i) {
333 const FilePath& path = extra_plugin_paths[i];
334 if (visited_plugins.find(path) != visited_plugins.end())
335 continue;
336 LoadPlugin(path, &new_plugins);
337 visited_plugins.insert(path);
338 }
339
340 for (size_t i = 0; i < extra_plugin_dirs.size(); ++i) {
341 LoadPluginsFromDir(extra_plugin_dirs[i], &new_plugins, &visited_plugins);
342 }
343
344 for (size_t i = 0; i < directories_to_scan.size(); ++i) {
345 LoadPluginsFromDir(directories_to_scan[i], &new_plugins, &visited_plugins);
346 }
347
348 #if defined(OS_WIN)
349 LoadPluginsFromRegistry(&new_plugins, &visited_plugins);
350 #endif
351
352 // Load the default plugin last.
353 if (webkit_glue::IsDefaultPluginEnabled())
354 LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins);
355
356 // Disable all of the plugins and plugin groups that are disabled by policy.
357 // There's currenly a bug that makes it impossible to correctly re-enable
358 // plugins or plugin-groups to their original, "pre-policy" state, so
359 // plugins and groups are only changed to a more "safe" state after a policy
360 // change, i.e. from enabled to disabled. See bug 54681.
361 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
362 it != plugin_groups_.end(); ++it) {
363 PluginGroup* group = it->second;
364 string16 group_name = group->GetGroupName();
365 if (ShouldDisableGroup(group_name)) {
366 group->Enable(false);
367 }
368
369 if (disable_outdated_plugins_) {
370 group->DisableOutdatedPlugins();
371 }
372 if (!group->Enabled()) {
373 AutoLock lock(lock_);
374 disabled_groups_.insert(group_name);
375 }
376 }
377
378 // Only update the data now since loading plugins can take a while.
379 AutoLock lock(lock_);
380
381 plugins_ = new_plugins;
382 plugins_loaded_ = true;
383 }
384
385 void PluginList::LoadPlugin(const FilePath& path,
386 std::vector<WebPluginInfo>* plugins) {
387 LOG_IF(ERROR, PluginList::DebugPluginLoading())
388 << "Loading plugin " << path.value();
389
390 WebPluginInfo plugin_info;
391 const PluginEntryPoints* entry_points;
392
393 if (!ReadPluginInfo(path, &plugin_info, &entry_points))
394 return;
395
396 if (!ShouldLoadPlugin(plugin_info, plugins))
397 return;
398
399 if (path.value() != kDefaultPluginLibraryName
400 #if defined(OS_WIN) && !defined(NDEBUG)
401 && path.BaseName().value() != L"npspy.dll" // Make an exception for NPSPY
402 #endif
403 ) {
404 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) {
405 // TODO: don't load global handlers for now.
406 // WebKit hands to the Plugin before it tries
407 // to handle mimeTypes on its own.
408 const std::string &mime_type = plugin_info.mime_types[i].mime_type;
409 if (mime_type == "*" )
410 return;
411 }
412 }
413
414 // Mark disabled plugins as such. (This has to happen before calling
415 // |AddToPluginGroups(plugin_info)|.)
416 if (disabled_plugins_.count(plugin_info.path)) {
417 plugin_info.enabled = false;
418 } else {
419 plugin_info.enabled = true;
420 }
421
422 AutoLock lock(lock_);
423 plugins->push_back(plugin_info);
424 AddToPluginGroups(plugin_info);
425 }
426
427 bool PluginList::SupportsType(const WebPluginInfo& info,
428 const std::string &mime_type,
429 bool allow_wildcard) {
430 // Webkit will ask for a plugin to handle empty mime types.
431 if (mime_type.empty())
432 return false;
433
434 for (size_t i = 0; i < info.mime_types.size(); ++i) {
435 const WebPluginMimeType& mime_info = info.mime_types[i];
436 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
437 if (!allow_wildcard && mime_info.mime_type == "*") {
438 continue;
439 }
440 return true;
441 }
442 }
443 return false;
444 }
445
446 bool PluginList::SupportsExtension(const WebPluginInfo& info,
447 const std::string &extension,
448 std::string* actual_mime_type) {
449 for (size_t i = 0; i < info.mime_types.size(); ++i) {
450 const WebPluginMimeType& mime_type = info.mime_types[i];
451 for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) {
452 if (mime_type.file_extensions[j] == extension) {
453 if (actual_mime_type)
454 *actual_mime_type = mime_type.mime_type;
455 return true;
456 }
457 }
458 }
459
460 return false;
461 }
462
463
464 void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
465 LoadPlugins(refresh);
466
467 AutoLock lock(lock_);
468 *plugins = plugins_;
469 }
470
471 void PluginList::GetEnabledPlugins(bool refresh,
472 std::vector<WebPluginInfo>* plugins) {
473 LoadPlugins(refresh);
474
475 plugins->clear();
476 AutoLock lock(lock_);
477 for (std::vector<WebPluginInfo>::const_iterator it = plugins_.begin();
478 it != plugins_.end();
479 ++it) {
480 if (it->enabled)
481 plugins->push_back(*it);
482 }
483 }
484
485 void PluginList::GetPluginInfoArray(
486 const GURL& url,
487 const std::string& mime_type,
488 bool allow_wildcard,
489 std::vector<WebPluginInfo>* info,
490 std::vector<std::string>* actual_mime_types) {
491 DCHECK(mime_type == StringToLowerASCII(mime_type));
492 DCHECK(info);
493
494 LoadPlugins(false);
495 AutoLock lock(lock_);
496 info->clear();
497 if (actual_mime_types)
498 actual_mime_types->clear();
499
500 std::set<FilePath> visited_plugins;
501
502 // Add in enabled plugins by mime type.
503 WebPluginInfo default_plugin;
504 for (size_t i = 0; i < plugins_.size(); ++i) {
505 if (plugins_[i].enabled &&
506 SupportsType(plugins_[i], mime_type, allow_wildcard)) {
507 FilePath path = plugins_[i].path;
508 if (path.value() != kDefaultPluginLibraryName &&
509 visited_plugins.insert(path).second) {
510 info->push_back(plugins_[i]);
511 if (actual_mime_types)
512 actual_mime_types->push_back(mime_type);
513 }
514 }
515 }
516
517 // Add in enabled plugins by url.
518 std::string path = url.path();
519 std::string::size_type last_dot = path.rfind('.');
520 if (last_dot != std::string::npos) {
521 std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
522 std::string actual_mime_type;
523 for (size_t i = 0; i < plugins_.size(); ++i) {
524 if (plugins_[i].enabled &&
525 SupportsExtension(plugins_[i], extension, &actual_mime_type)) {
526 FilePath path = plugins_[i].path;
527 if (path.value() != kDefaultPluginLibraryName &&
528 visited_plugins.insert(path).second) {
529 info->push_back(plugins_[i]);
530 if (actual_mime_types)
531 actual_mime_types->push_back(actual_mime_type);
532 }
533 }
534 }
535 }
536
537 // Add in disabled plugins by mime type.
538 for (size_t i = 0; i < plugins_.size(); ++i) {
539 if (!plugins_[i].enabled &&
540 SupportsType(plugins_[i], mime_type, allow_wildcard)) {
541 FilePath path = plugins_[i].path;
542 if (path.value() != kDefaultPluginLibraryName &&
543 visited_plugins.insert(path).second) {
544 info->push_back(plugins_[i]);
545 if (actual_mime_types)
546 actual_mime_types->push_back(mime_type);
547 }
548 }
549 }
550
551 // Add the default plugin at the end if it supports the mime type given,
552 // and the default plugin is enabled.
553 if (!plugins_.empty() && webkit_glue::IsDefaultPluginEnabled()) {
554 const WebPluginInfo& default_info = plugins_.back();
555 if (SupportsType(default_info, mime_type, allow_wildcard)) {
556 info->push_back(default_info);
557 if (actual_mime_types)
558 actual_mime_types->push_back(mime_type);
559 }
560 }
561 }
562
563 bool PluginList::GetPluginInfo(const GURL& url,
564 const std::string& mime_type,
565 bool allow_wildcard,
566 WebPluginInfo* info,
567 std::string* actual_mime_type) {
568 DCHECK(info);
569 std::vector<WebPluginInfo> info_list;
570
571 // GetPluginInfoArray has slightly less work to do if we can pass
572 // NULL for the mime type list...
573 if (actual_mime_type) {
574 std::vector<std::string> mime_type_list;
575 GetPluginInfoArray(
576 url, mime_type, allow_wildcard, &info_list, &mime_type_list);
577 if (!info_list.empty()) {
578 *info = info_list[0];
579 *actual_mime_type = mime_type_list[0];
580 return true;
581 }
582 } else {
583 GetPluginInfoArray(url, mime_type, allow_wildcard, &info_list, NULL);
584 if (!info_list.empty()) {
585 *info = info_list[0];
586 return true;
587 }
588 }
589 return false;
590 }
591
592 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
593 WebPluginInfo* info) {
594 LoadPlugins(false);
595 AutoLock lock(lock_);
596 for (size_t i = 0; i < plugins_.size(); ++i) {
597 if (plugins_[i].path == plugin_path) {
598 *info = plugins_[i];
599 return true;
600 }
601 }
602
603 return false;
604 }
605
606 void PluginList::GetPluginGroups(
607 bool load_if_necessary,
608 std::vector<PluginGroup>* plugin_groups) {
609 if (load_if_necessary)
610 LoadPlugins(false);
611 plugin_groups->clear();
612 for (PluginGroup::PluginMap::const_iterator it = plugin_groups_.begin();
613 it != plugin_groups_.end(); ++it) {
614 plugin_groups->push_back(*it->second);
615 }
616 }
617
618 const PluginGroup* PluginList::GetPluginGroup(
619 const WebPluginInfo& web_plugin_info) {
620 AutoLock lock(lock_);
621 return AddToPluginGroups(web_plugin_info);
622 }
623
624 string16 PluginList::GetPluginGroupName(std::string identifier) {
625 PluginGroup::PluginMap::iterator it = plugin_groups_.find(identifier);
626 if (it == plugin_groups_.end()) {
627 return string16();
628 }
629 return it->second->GetGroupName();
630 }
631
632 std::string PluginList::GetPluginGroupIdentifier(
633 const WebPluginInfo& web_plugin_info) {
634 AutoLock lock(lock_);
635 PluginGroup* group = AddToPluginGroups(web_plugin_info);
636 return group->identifier();
637 }
638
639 void PluginList::AddHardcodedPluginGroups() {
640 AutoLock lock(lock_);
641 const PluginGroupDefinition* definitions = GetPluginGroupDefinitions();
642 for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) {
643 PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition(
644 definitions[i]);
645 std::string identifier = definition_group->identifier();
646 DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
647 plugin_groups_.insert(std::make_pair(identifier, definition_group));
648 }
649 }
650
651 PluginGroup* PluginList::AddToPluginGroups(
652 const WebPluginInfo& web_plugin_info) {
653 PluginGroup* group = NULL;
654 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
655 it != plugin_groups_.end(); ++it) {
656 if (it->second->Match(web_plugin_info))
657 group = it->second;
658 }
659 if (!group) {
660 group = PluginGroup::FromWebPluginInfo(web_plugin_info);
661 std::string identifier = group->identifier();
662 // If the identifier is not unique, use the full path. This means that we
663 // probably won't be able to search for this group by identifier, but at
664 // least it's going to be in the set of plugin groups, and if there
665 // is already a plug-in with the same filename, it's probably going to
666 // handle the same MIME types (and it has a higher priority), so this one
667 // is not going to run anyway.
668 if (plugin_groups_.find(identifier) != plugin_groups_.end())
669 identifier = PluginGroup::GetLongIdentifier(web_plugin_info);
670 DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
671 plugin_groups_.insert(std::make_pair(identifier, group));
672 }
673 group->AddPlugin(web_plugin_info, next_priority_++);
674 return group;
675 }
676
677 bool PluginList::EnablePlugin(const FilePath& filename) {
678 AutoLock lock(lock_);
679
680 bool did_enable = false;
681
682 std::set<FilePath>::iterator entry = disabled_plugins_.find(filename);
683 if (entry == disabled_plugins_.end())
684 return did_enable; // Early exit if plugin not in disabled list.
685
686 disabled_plugins_.erase(entry); // Remove from disabled list.
687
688 // Set enabled flags if necessary.
689 for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
690 it != plugins_.end();
691 ++it) {
692 if (it->path == filename) {
693 DCHECK(!it->enabled); // Should have been disabled.
694 it->enabled = true;
695 did_enable = true;
696 }
697 }
698
699 return did_enable;
700 }
701
702 bool PluginList::DisablePlugin(const FilePath& filename) {
703 AutoLock lock(lock_);
704
705 bool did_disable = false;
706
707 if (disabled_plugins_.find(filename) != disabled_plugins_.end())
708 return did_disable; // Early exit if plugin already in disabled list.
709
710 disabled_plugins_.insert(filename); // Add to disabled list.
711
712 // Unset enabled flags if necessary.
713 for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
714 it != plugins_.end();
715 ++it) {
716 if (it->path == filename) {
717 DCHECK(it->enabled); // Should have been enabled.
718 it->enabled = false;
719 did_disable = true;
720 }
721 }
722
723 return did_disable;
724 }
725
726 bool PluginList::EnableGroup(bool enable, const string16& group_name) {
727 bool did_change = false;
728 {
729 AutoLock lock(lock_);
730
731 std::set<string16>::iterator entry = disabled_groups_.find(group_name);
732 if (enable) {
733 if (entry == disabled_groups_.end())
734 return did_change; // Early exit if group not in disabled list.
735 disabled_groups_.erase(entry); // Remove from disabled list.
736 } else {
737 if (entry != disabled_groups_.end())
738 return did_change; // Early exit if group already in disabled list.
739 disabled_groups_.insert(group_name);
740 }
741 }
742
743 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
744 it != plugin_groups_.end(); ++it) {
745 if (it->second->GetGroupName() == group_name) {
746 if (it->second->Enabled() != enable) {
747 it->second->Enable(enable);
748 did_change = true;
749 break;
750 }
751 }
752 }
753
754 return did_change;
755 }
756
757 void PluginList::DisableOutdatedPluginGroups() {
758 disable_outdated_plugins_ = true;
759 }
760
761 PluginList::~PluginList() {
762 Shutdown();
763 }
764
765 void PluginList::Shutdown() {
766 // TODO
767 // Note: plugin_groups_ contains simple pointers of type PluginGroup*, but
768 // since this singleton lives until the process is destroyed, no explicit
769 // cleanup is necessary.
770 // However, when running on Valgrind, we need to do the cleanup to keep the
771 // memory tree green.
772 #if defined(OS_POSIX)
773 if (RUNNING_ON_VALGRIND) {
774 STLDeleteContainerPairSecondPointers(plugin_groups_.begin(),
775 plugin_groups_.end());
776 }
777 #endif
778 }
779
780 } // namespace NPAPI
OLDNEW
« no previous file with comments | « webkit/glue/plugins/plugin_list.h ('k') | webkit/glue/plugins/plugin_list_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698