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

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

Issue 5516004: Clean up PluginGroup and related code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/glue/plugins/plugin_list.h" 5 #include "webkit/glue/plugins/plugin_list.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/string_split.h" 12 #include "base/string_split.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "googleurl/src/gurl.h" 16 #include "googleurl/src/gurl.h"
17 #include "net/base/mime_util.h" 17 #include "net/base/mime_util.h"
18 #include "webkit/glue/plugins/plugin_constants_win.h" 18 #include "webkit/glue/plugins/plugin_constants_win.h"
19 #include "webkit/glue/plugins/plugin_lib.h" 19 #include "webkit/glue/plugins/plugin_lib.h"
20 #include "webkit/glue/plugins/plugin_switches.h" 20 #include "webkit/glue/plugins/plugin_switches.h"
21 #include "webkit/glue/webkit_glue.h" 21 #include "webkit/glue/webkit_glue.h"
22 22
23 namespace NPAPI { 23 namespace NPAPI {
24 24
25 #if defined(OS_MACOSX)
26 // Plugin Groups for Mac.
27 // Plugins are listed here as soon as vulnerabilities and solutions
28 // (new versions) are published.
29 // TODO(panayiotis): Get the Real Player version on Mac, somehow.
30 static const PluginGroupDefinition kGroupDefinitions[] = {
31 { "apple-quicktime", "Quicktime", "QuickTime Plug-in", "", "", "7.6.6",
32 "http://www.apple.com/quicktime/download/" },
33 { "java-runtime-environment", "Java", "Java", "", "", "",
34 "http://support.apple.com/kb/HT1338" },
35 { "adobe-flash-player", "Flash", "Shockwave Flash", "", "", "10.1.102",
36 "http://get.adobe.com/flashplayer/" },
37 { "silverlight-3", "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0",
38 "http://www.microsoft.com/getsilverlight/" },
39 { "silverlight-4", "Silverlight 4", "Silverlight", "4", "5", "",
40 "http://www.microsoft.com/getsilverlight/" },
41 { "flip4mac", "Flip4Mac", "Flip4Mac", "", "", "2.2.1",
42 "http://www.telestream.net/flip4mac-wmv/overview.htm" },
43 { "shockwave", "Shockwave", "Shockwave for Director", "", "", "11.5.9.615",
44 "http://www.adobe.com/shockwave/download/" }
45 };
46
47 #elif defined(OS_WIN)
48 // TODO(panayiotis): We should group "RealJukebox NS Plugin" with the rest of
49 // the RealPlayer files.
50 static const PluginGroupDefinition kGroupDefinitions[] = {
51 { "apple-quicktime", "Quicktime", "QuickTime Plug-in", "", "", "7.6.8",
52 "http://www.apple.com/quicktime/download/" },
53 { "java-runtime-environment", "Java 6", "Java", "", "6", "6.0.220",
54 "http://www.java.com/" },
55 { "adobe-reader", PluginGroup::kAdobeReader9GroupName, "Adobe Acrobat", "9",
56 "10", "9.4.1", "http://get.adobe.com/reader/" },
57 { "adobe-reader-8", PluginGroup::kAdobeReader8GroupName, "Adobe Acrobat", "0",
58 "9", "8.2.5", "http://get.adobe.com/reader/" },
59 { "adobe-flash-player", "Flash", "Shockwave Flash", "", "", "10.1.102",
60 "http://get.adobe.com/flashplayer/" },
61 { "silverlight-3", "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0",
62 "http://www.microsoft.com/getsilverlight/" },
63 { "silverlight-4", "Silverlight 4", "Silverlight", "4", "5", "",
64 "http://www.microsoft.com/getsilverlight/" },
65 { "shockwave", "Shockwave", "Shockwave for Director", "", "", "11.5.9.615",
66 "http://www.adobe.com/shockwave/download/" },
67 { "divx-player", "DivX Player", "DivX Web Player", "", "", "1.4.3.4",
68 "http://download.divx.com/divx/autoupdate/player/"
69 "DivXWebPlayerInstaller.exe" },
70 // These are here for grouping, no vulnerabilies known.
71 { "windows-media-player", "Windows Media Player", "Windows Media Player",
72 "", "", "", "" },
73 { "microsoft-office", "Microsoft Office", "Microsoft Office",
74 "", "", "", "" },
75 // TODO(panayiotis): The vulnerable versions are
76 // (v >= 6.0.12.1040 && v <= 6.0.12.1663)
77 // || v == 6.0.12.1698 || v == 6.0.12.1741
78 { "realplayer", "RealPlayer", "RealPlayer", "", "", "",
79 "http://www.adobe.com/shockwave/download/" },
80 };
81
82 #else
83 static const PluginGroupDefinition kGroupDefinitions[] = {};
84 #endif
85
86 // static
87 const PluginGroupDefinition* PluginList::GetPluginGroupDefinitions() {
88 return kGroupDefinitions;
89 }
90
91 // static
92 size_t PluginList::GetPluginGroupDefinitionsSize() {
93 // TODO(viettrungluu): |arraysize()| doesn't work with zero-size arrays.
94 return ARRAYSIZE_UNSAFE(kGroupDefinitions);
95 }
96
25 base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED); 97 base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED);
26 98
27 // static 99 // static
28 PluginList* PluginList::Singleton() { 100 PluginList* PluginList::Singleton() {
29 return g_singleton.Pointer(); 101 return g_singleton.Pointer();
30 } 102 }
31 103
32 // static 104 // static
33 bool PluginList::DebugPluginLoading() { 105 bool PluginList::DebugPluginLoading() {
34 return CommandLine::ForCurrentProcess()->HasSwitch( 106 return CommandLine::ForCurrentProcess()->HasSwitch(
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 222
151 info->mime_types.push_back(mime_type); 223 info->mime_types.push_back(mime_type);
152 } 224 }
153 225
154 return true; 226 return true;
155 } 227 }
156 228
157 PluginList::PluginList() 229 PluginList::PluginList()
158 : plugins_loaded_(false), 230 : plugins_loaded_(false),
159 plugins_need_refresh_(false), 231 plugins_need_refresh_(false),
160 disable_outdated_plugins_(false) { 232 disable_outdated_plugins_(false),
233 next_priority_(0) {
161 PlatformInit(); 234 PlatformInit();
235 AddHardcodedPluginGroups();
162 } 236 }
163 237
164 bool PluginList::ShouldDisableGroup(const string16& group_name) { 238 bool PluginList::ShouldDisableGroup(const string16& group_name) {
165 AutoLock lock(lock_); 239 AutoLock lock(lock_);
166 if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) { 240 if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) {
167 disabled_groups_.insert(group_name); 241 disabled_groups_.insert(group_name);
168 return true; 242 return true;
169 } 243 }
170 return disabled_groups_.count(group_name) > 0; 244 return disabled_groups_.count(group_name) > 0;
171 } 245 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 300
227 // Load the default plugin last. 301 // Load the default plugin last.
228 if (webkit_glue::IsDefaultPluginEnabled()) 302 if (webkit_glue::IsDefaultPluginEnabled())
229 LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins); 303 LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins);
230 304
231 // Disable all of the plugins and plugin groups that are disabled by policy. 305 // Disable all of the plugins and plugin groups that are disabled by policy.
232 // There's currenly a bug that makes it impossible to correctly re-enable 306 // There's currenly a bug that makes it impossible to correctly re-enable
233 // plugins or plugin-groups to their original, "pre-policy" state, so 307 // plugins or plugin-groups to their original, "pre-policy" state, so
234 // plugins and groups are only changed to a more "safe" state after a policy 308 // plugins and groups are only changed to a more "safe" state after a policy
235 // change, i.e. from enabled to disabled. See bug 54681. 309 // change, i.e. from enabled to disabled. See bug 54681.
236 PluginMap plugin_groups; 310 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
237 GetPluginGroups(&new_plugins, &plugin_groups); 311 it != plugin_groups_.end(); ++it) {
238 for (PluginMap::const_iterator it = plugin_groups.begin(); 312 PluginGroup* group = it->second;
239 it != plugin_groups.end(); ++it) {
240 PluginGroup* group = it->second.get();
241 string16 group_name = group->GetGroupName(); 313 string16 group_name = group->GetGroupName();
242 if (ShouldDisableGroup(group_name)) { 314 if (ShouldDisableGroup(group_name)) {
243 it->second->Enable(false); 315 group->Enable(false);
244 } 316 }
245 317
246 if (disable_outdated_plugins_) { 318 if (disable_outdated_plugins_) {
247 group->DisableOutdatedPlugins(); 319 group->DisableOutdatedPlugins();
248 if (!group->Enabled()) { 320 }
249 AutoLock lock(lock_); 321 if (!group->Enabled()) {
250 disabled_groups_.insert(group_name); 322 AutoLock lock(lock_);
251 } 323 disabled_groups_.insert(group_name);
252 } 324 }
253 } 325 }
254 326
255 // Only update the data now since loading plugins can take a while. 327 // Only update the data now since loading plugins can take a while.
256 AutoLock lock(lock_); 328 AutoLock lock(lock_);
257 329
258 // Mark disabled plugins as such.
259 for (size_t i = 0; i < new_plugins.size(); ++i) {
260 if (disabled_plugins_.count(new_plugins[i].path))
261 new_plugins[i].enabled = false;
262 }
263
264 plugins_ = new_plugins; 330 plugins_ = new_plugins;
265 plugins_loaded_ = true; 331 plugins_loaded_ = true;
266 } 332 }
267 333
268 void PluginList::LoadPlugin(const FilePath& path, 334 void PluginList::LoadPlugin(const FilePath& path,
269 std::vector<WebPluginInfo>* plugins) { 335 std::vector<WebPluginInfo>* plugins) {
270 LOG_IF(ERROR, PluginList::DebugPluginLoading()) 336 LOG_IF(ERROR, PluginList::DebugPluginLoading())
271 << "Loading plugin " << path.value(); 337 << "Loading plugin " << path.value();
272 338
273 WebPluginInfo plugin_info; 339 WebPluginInfo plugin_info;
(...skipping 13 matching lines...) Expand all
287 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) { 353 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) {
288 // TODO: don't load global handlers for now. 354 // TODO: don't load global handlers for now.
289 // WebKit hands to the Plugin before it tries 355 // WebKit hands to the Plugin before it tries
290 // to handle mimeTypes on its own. 356 // to handle mimeTypes on its own.
291 const std::string &mime_type = plugin_info.mime_types[i].mime_type; 357 const std::string &mime_type = plugin_info.mime_types[i].mime_type;
292 if (mime_type == "*" ) 358 if (mime_type == "*" )
293 return; 359 return;
294 } 360 }
295 } 361 }
296 362
363 // Mark disabled plugins as such. (This has to happen before calling
364 // |AddToPluginGroups(plugin_info)|.)
365 if (disabled_plugins_.count(plugin_info.path)) {
366 plugin_info.enabled = false;
367 } else {
368 plugin_info.enabled = true;
369 }
370
371 AutoLock lock(lock_);
297 plugins->push_back(plugin_info); 372 plugins->push_back(plugin_info);
373 AddToPluginGroups(plugin_info);
298 } 374 }
299 375
300 bool PluginList::SupportsType(const WebPluginInfo& info, 376 bool PluginList::SupportsType(const WebPluginInfo& info,
301 const std::string &mime_type, 377 const std::string &mime_type,
302 bool allow_wildcard) { 378 bool allow_wildcard) {
303 // Webkit will ask for a plugin to handle empty mime types. 379 // Webkit will ask for a plugin to handle empty mime types.
304 if (mime_type.empty()) 380 if (mime_type.empty())
305 return false; 381 return false;
306 382
307 for (size_t i = 0; i < info.mime_types.size(); ++i) { 383 for (size_t i = 0; i < info.mime_types.size(); ++i) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 for (size_t i = 0; i < plugins_.size(); ++i) { 545 for (size_t i = 0; i < plugins_.size(); ++i) {
470 if (plugins_[i].path == plugin_path) { 546 if (plugins_[i].path == plugin_path) {
471 *info = plugins_[i]; 547 *info = plugins_[i];
472 return true; 548 return true;
473 } 549 }
474 } 550 }
475 551
476 return false; 552 return false;
477 } 553 }
478 554
479 void PluginList::GetPluginGroups(bool load_if_necessary, 555 void PluginList::GetPluginGroups(
480 PluginMap* plugin_groups) { 556 bool load_if_necessary,
557 std::vector<PluginGroup>* plugin_groups) {
481 if (load_if_necessary) 558 if (load_if_necessary)
482 LoadPlugins(false); 559 LoadPlugins(false);
483
484 AutoLock lock(lock_);
485 GetPluginGroups(&plugins_, plugin_groups);
486 }
487
488 // static
489 void PluginList::GetPluginGroups(const std::vector<WebPluginInfo>* plugins,
490 PluginMap* plugin_groups) {
491 plugin_groups->clear(); 560 plugin_groups->clear();
492 // We first search for an existing group that matches our name, 561 for (PluginGroup::PluginMap::const_iterator it = plugin_groups_.begin();
493 // and only create a new group if we can't find any. 562 it != plugin_groups_.end(); ++it) {
494 for (size_t i = 0; i < plugins->size(); ++i) { 563 plugin_groups->push_back(*it->second);
495 const WebPluginInfo& web_plugin = (*plugins)[i];
496 PluginGroup* group = PluginGroup::FindGroupMatchingPlugin(
497 *plugin_groups, web_plugin);
498 if (!group) {
499 group = PluginGroup::CopyOrCreatePluginGroup(web_plugin);
500 std::string identifier = group->identifier();
501 // If the identifier is not unique, use the full path. This means that we
502 // probably won't be able to search for this group by identifier, but at
503 // least it's going to be in the set of plugin groups, and if there
504 // is already a plug-in with the same filename, it's probably going to
505 // handle the same MIME types (and it has a higher priority), so this one
506 // is not going to run anyway.
507 if (plugin_groups->find(identifier) != plugin_groups->end())
508 #if defined(OS_POSIX)
509 identifier = web_plugin.path.value();
510 #elif defined(OS_WIN)
511 identifier = base::SysWideToUTF8(web_plugin.path.value());
512 #endif
513 DCHECK(plugin_groups->find(identifier) == plugin_groups->end());
514 (*plugin_groups)[identifier] = linked_ptr<PluginGroup>(group);
515 }
516 group->AddPlugin(web_plugin, i);
517 } 564 }
518 } 565 }
519 566
567 const PluginGroup* PluginList::GetPluginGroup(
568 const WebPluginInfo& web_plugin_info) {
569 AutoLock lock(lock_);
570 return AddToPluginGroups(web_plugin_info);
571 }
572
573 string16 PluginList::GetPluginGroupName(std::string identifier) {
574 PluginGroup::PluginMap::iterator it = plugin_groups_.find(identifier);
575 if (it == plugin_groups_.end()) {
576 return string16();
577 }
578 return it->second->GetGroupName();
579 }
580
581 std::string PluginList::GetPluginGroupIdentifier(
582 const WebPluginInfo& web_plugin_info) {
583 AutoLock lock(lock_);
584 PluginGroup* group = AddToPluginGroups(web_plugin_info);
585 return group->identifier();
586 }
587
588 void PluginList::AddHardcodedPluginGroups() {
589 AutoLock lock(lock_);
590 const PluginGroupDefinition* definitions = GetPluginGroupDefinitions();
591 for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) {
592 PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition(
593 definitions[i]);
594 std::string identifier = definition_group->identifier();
595 DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
596 plugin_groups_.insert(std::make_pair(identifier, definition_group));
597 }
598 }
599
600 PluginGroup* PluginList::AddToPluginGroups(
601 const WebPluginInfo& web_plugin_info) {
602 PluginGroup* group = NULL;
603 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
604 it != plugin_groups_.end(); ++it) {
605 if (it->second->Match(web_plugin_info))
606 group = it->second;
607 }
608 if (!group) {
609 group = PluginGroup::FromWebPluginInfo(web_plugin_info);
610 std::string identifier = group->identifier();
611 // If the identifier is not unique, use the full path. This means that we
612 // probably won't be able to search for this group by identifier, but at
613 // least it's going to be in the set of plugin groups, and if there
614 // is already a plug-in with the same filename, it's probably going to
615 // handle the same MIME types (and it has a higher priority), so this one
616 // is not going to run anyway.
617 if (plugin_groups_.find(identifier) != plugin_groups_.end())
618 identifier = PluginGroup::GetLongIdentifier(web_plugin_info);
619 DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
620 plugin_groups_.insert(std::make_pair(identifier, group));
621 }
622 group->AddPlugin(web_plugin_info, next_priority_++);
623 return group;
624 }
625
520 bool PluginList::EnablePlugin(const FilePath& filename) { 626 bool PluginList::EnablePlugin(const FilePath& filename) {
521 AutoLock lock(lock_); 627 AutoLock lock(lock_);
522 628
523 bool did_enable = false; 629 bool did_enable = false;
524 630
525 std::set<FilePath>::iterator entry = disabled_plugins_.find(filename); 631 std::set<FilePath>::iterator entry = disabled_plugins_.find(filename);
526 if (entry == disabled_plugins_.end()) 632 if (entry == disabled_plugins_.end())
527 return did_enable; // Early exit if plugin not in disabled list. 633 return did_enable; // Early exit if plugin not in disabled list.
528 634
529 disabled_plugins_.erase(entry); // Remove from disabled list. 635 disabled_plugins_.erase(entry); // Remove from disabled list.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 if (entry == disabled_groups_.end()) 682 if (entry == disabled_groups_.end())
577 return did_change; // Early exit if group not in disabled list. 683 return did_change; // Early exit if group not in disabled list.
578 disabled_groups_.erase(entry); // Remove from disabled list. 684 disabled_groups_.erase(entry); // Remove from disabled list.
579 } else { 685 } else {
580 if (entry != disabled_groups_.end()) 686 if (entry != disabled_groups_.end())
581 return did_change; // Early exit if group already in disabled list. 687 return did_change; // Early exit if group already in disabled list.
582 disabled_groups_.insert(group_name); 688 disabled_groups_.insert(group_name);
583 } 689 }
584 } 690 }
585 691
586 PluginMap plugin_groups; 692 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
587 GetPluginGroups(false, &plugin_groups); 693 it != plugin_groups_.end(); ++it) {
588 for (PluginMap::const_iterator it = plugin_groups.begin();
589 it != plugin_groups.end(); ++it) {
590 if (it->second->GetGroupName() == group_name) { 694 if (it->second->GetGroupName() == group_name) {
591 if (it->second->Enabled() != enable) { 695 if (it->second->Enabled() != enable) {
592 it->second->Enable(enable); 696 it->second->Enable(enable);
593 did_change = true; 697 did_change = true;
594 break; 698 break;
595 } 699 }
596 } 700 }
597 } 701 }
598 702
599 return did_change; 703 return did_change;
600 } 704 }
601 705
602 void PluginList::DisableOutdatedPluginGroups() { 706 void PluginList::DisableOutdatedPluginGroups() {
603 disable_outdated_plugins_ = true; 707 disable_outdated_plugins_ = true;
604 } 708 }
605 709
606 PluginList::~PluginList() { 710 PluginList::~PluginList() {
607 } 711 }
608 712
609 void PluginList::Shutdown() { 713 void PluginList::Shutdown() {
610 // TODO 714 // TODO
715 // Note: plugin_groups_ contains simple pointers of type PluginGroup*, but
716 // since this singleton lives until the process is destroyed, no explicit
717 // cleanup is necessary.
611 } 718 }
612 719
613 } // namespace NPAPI 720 } // namespace NPAPI
OLDNEW
« webkit/glue/plugins/plugin_group.cc ('K') | « webkit/glue/plugins/plugin_list.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698