OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/plugins/npapi/plugin_list.h" | 5 #include "webkit/plugins/npapi/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" |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 void PluginList::RegisterInternalPlugin(const FilePath& filename, | 223 void PluginList::RegisterInternalPlugin(const FilePath& filename, |
224 const std::string& name, | 224 const std::string& name, |
225 const std::string& description, | 225 const std::string& description, |
226 const std::string& mime_type_str, | 226 const std::string& mime_type_str, |
227 const PluginEntryPoints& entry_points) { | 227 const PluginEntryPoints& entry_points) { |
228 InternalPlugin plugin; | 228 InternalPlugin plugin; |
229 plugin.info.path = filename; | 229 plugin.info.path = filename; |
230 plugin.info.name = ASCIIToUTF16(name); | 230 plugin.info.name = ASCIIToUTF16(name); |
231 plugin.info.version = ASCIIToUTF16("1"); | 231 plugin.info.version = ASCIIToUTF16("1"); |
232 plugin.info.desc = ASCIIToUTF16(description); | 232 plugin.info.desc = ASCIIToUTF16(description); |
| 233 plugin.info.enabled = webkit::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED; |
233 | 234 |
234 webkit::WebPluginMimeType mime_type; | 235 webkit::WebPluginMimeType mime_type; |
235 mime_type.mime_type = mime_type_str; | 236 mime_type.mime_type = mime_type_str; |
236 plugin.info.mime_types.push_back(mime_type); | 237 plugin.info.mime_types.push_back(mime_type); |
237 | 238 |
238 plugin.entry_points = entry_points; | 239 plugin.entry_points = entry_points; |
239 | 240 |
240 base::AutoLock lock(lock_); | 241 base::AutoLock lock(lock_); |
241 internal_plugins_.push_back(plugin); | 242 internal_plugins_.push_back(plugin); |
242 if (filename.value() == kDefaultPluginLibraryName) | 243 if (filename.value() == kDefaultPluginLibraryName) |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 if (!plugins_need_refresh_) | 401 if (!plugins_need_refresh_) |
401 return; | 402 return; |
402 } | 403 } |
403 | 404 |
404 ScopedVector<PluginGroup> new_plugin_groups; | 405 ScopedVector<PluginGroup> new_plugin_groups; |
405 AddHardcodedPluginGroups(&new_plugin_groups); | 406 AddHardcodedPluginGroups(&new_plugin_groups); |
406 // Do the actual loading of the plugins. | 407 // Do the actual loading of the plugins. |
407 LoadPluginsInternal(&new_plugin_groups); | 408 LoadPluginsInternal(&new_plugin_groups); |
408 | 409 |
409 base::AutoLock lock(lock_); | 410 base::AutoLock lock(lock_); |
| 411 // Grab all plugins that were found before to copy enabled statuses. |
| 412 std::vector<webkit::WebPluginInfo> old_plugins; |
| 413 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
| 414 const std::vector<webkit::WebPluginInfo>& gr_plugins = |
| 415 plugin_groups_[i]->web_plugins_info(); |
| 416 old_plugins.insert(old_plugins.end(), gr_plugins.begin(), gr_plugins.end()); |
| 417 } |
| 418 // Disable all of the plugins and plugin groups that are disabled by policy. |
| 419 for (size_t i = 0; i < new_plugin_groups.size(); ++i) { |
| 420 PluginGroup* group = new_plugin_groups[i]; |
| 421 string16 group_name = group->GetGroupName(); |
| 422 |
| 423 std::vector<webkit::WebPluginInfo>& gr_plugins = |
| 424 group->GetPluginsContainer(); |
| 425 for (size_t j = 0; j < gr_plugins.size(); ++j) { |
| 426 int plugin_found = -1; |
| 427 for (size_t k = 0; k < old_plugins.size(); ++k) { |
| 428 if (gr_plugins[j].path == old_plugins[k].path) { |
| 429 plugin_found = k; |
| 430 break; |
| 431 } |
| 432 } |
| 433 if (plugin_found >= 0) |
| 434 gr_plugins[j].enabled = old_plugins[plugin_found].enabled; |
| 435 // Set the disabled flag of all plugins scheduled for disabling. |
| 436 if (plugins_to_disable_.find(gr_plugins[j].path) != |
| 437 plugins_to_disable_.end()) { |
| 438 group->DisablePlugin(gr_plugins[j].path); |
| 439 } |
| 440 } |
| 441 |
| 442 if (group->IsEmpty()) { |
| 443 new_plugin_groups.erase(new_plugin_groups.begin() + i); |
| 444 --i; |
| 445 continue; |
| 446 } |
| 447 |
| 448 group->EnforceGroupPolicy(); |
| 449 } |
| 450 // We flush the list of prematurely disabled plugins after the load has |
| 451 // finished. If for some reason a plugin reappears on a second load it is |
| 452 // going to be loaded normally. This is only true for non-policy controlled |
| 453 // plugins though. |
| 454 plugins_to_disable_.clear(); |
| 455 |
410 plugin_groups_.swap(new_plugin_groups); | 456 plugin_groups_.swap(new_plugin_groups); |
411 } | 457 } |
412 | 458 |
413 void PluginList::LoadPlugin(const FilePath& path, | 459 void PluginList::LoadPlugin(const FilePath& path, |
414 ScopedVector<PluginGroup>* plugin_groups) { | 460 ScopedVector<PluginGroup>* plugin_groups) { |
415 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 461 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
416 << "Loading plugin " << path.value(); | 462 << "Loading plugin " << path.value(); |
417 WebPluginInfo plugin_info; | 463 WebPluginInfo plugin_info; |
418 const PluginEntryPoints* entry_points; | 464 const PluginEntryPoints* entry_points; |
419 | 465 |
(...skipping 20 matching lines...) Expand all Loading... |
440 | 486 |
441 base::AutoLock lock(lock_); | 487 base::AutoLock lock(lock_); |
442 AddToPluginGroups(plugin_info, plugin_groups); | 488 AddToPluginGroups(plugin_info, plugin_groups); |
443 } | 489 } |
444 | 490 |
445 void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins) { | 491 void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins) { |
446 LoadPlugins(); | 492 LoadPlugins(); |
447 base::AutoLock lock(lock_); | 493 base::AutoLock lock(lock_); |
448 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 494 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
449 const std::vector<webkit::WebPluginInfo>& gr_plugins = | 495 const std::vector<webkit::WebPluginInfo>& gr_plugins = |
450 plugin_groups_[i]->web_plugin_infos(); | 496 plugin_groups_[i]->web_plugins_info(); |
451 plugins->insert(plugins->end(), gr_plugins.begin(), gr_plugins.end()); | 497 plugins->insert(plugins->end(), gr_plugins.begin(), gr_plugins.end()); |
452 } | 498 } |
453 } | 499 } |
454 | 500 |
455 void PluginList::GetPluginInfoArray( | 501 void PluginList::GetPluginInfoArray( |
456 const GURL& url, | 502 const GURL& url, |
457 const std::string& mime_type, | 503 const std::string& mime_type, |
458 bool allow_wildcard, | 504 bool allow_wildcard, |
459 bool* use_stale, | 505 bool* use_stale, |
460 std::vector<webkit::WebPluginInfo>* info, | 506 std::vector<webkit::WebPluginInfo>* info, |
461 std::vector<std::string>* actual_mime_types) { | 507 std::vector<std::string>* actual_mime_types) { |
462 DCHECK(mime_type == StringToLowerASCII(mime_type)); | 508 DCHECK(mime_type == StringToLowerASCII(mime_type)); |
463 DCHECK(info); | 509 DCHECK(info); |
464 | 510 |
465 if (!use_stale) | 511 if (!use_stale) |
466 LoadPlugins(); | 512 LoadPlugins(); |
467 base::AutoLock lock(lock_); | 513 base::AutoLock lock(lock_); |
468 if (use_stale) | 514 if (use_stale) |
469 *use_stale = plugins_need_refresh_; | 515 *use_stale = plugins_need_refresh_; |
470 info->clear(); | 516 info->clear(); |
471 if (actual_mime_types) | 517 if (actual_mime_types) |
472 actual_mime_types->clear(); | 518 actual_mime_types->clear(); |
473 | 519 |
474 std::set<FilePath> visited_plugins; | 520 std::set<FilePath> visited_plugins; |
475 | 521 |
476 // Add in plugins by mime type. | 522 // Add in plugins by mime type. |
477 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 523 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
478 const std::vector<webkit::WebPluginInfo>& plugins = | 524 const std::vector<webkit::WebPluginInfo>& plugins = |
479 plugin_groups_[i]->web_plugin_infos(); | 525 plugin_groups_[i]->web_plugins_info(); |
480 for (size_t i = 0; i < plugins.size(); ++i) { | 526 for (size_t i = 0; i < plugins.size(); ++i) { |
481 if (SupportsType(plugins[i], mime_type, allow_wildcard)) { | 527 if (SupportsType(plugins[i], mime_type, allow_wildcard)) { |
482 FilePath path = plugins[i].path; | 528 FilePath path = plugins[i].path; |
483 if (path.value() != kDefaultPluginLibraryName && | 529 if (path.value() != kDefaultPluginLibraryName && |
484 visited_plugins.insert(path).second) { | 530 visited_plugins.insert(path).second) { |
485 info->push_back(plugins[i]); | 531 info->push_back(plugins[i]); |
486 if (actual_mime_types) | 532 if (actual_mime_types) |
487 actual_mime_types->push_back(mime_type); | 533 actual_mime_types->push_back(mime_type); |
488 } | 534 } |
489 } | 535 } |
490 } | 536 } |
491 } | 537 } |
492 | 538 |
493 // Add in plugins by url. | 539 // Add in plugins by url. |
494 std::string path = url.path(); | 540 std::string path = url.path(); |
495 std::string::size_type last_dot = path.rfind('.'); | 541 std::string::size_type last_dot = path.rfind('.'); |
496 if (last_dot != std::string::npos) { | 542 if (last_dot != std::string::npos) { |
497 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); | 543 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); |
498 std::string actual_mime_type; | 544 std::string actual_mime_type; |
499 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 545 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
500 const std::vector<webkit::WebPluginInfo>& plugins = | 546 const std::vector<webkit::WebPluginInfo>& plugins = |
501 plugin_groups_[i]->web_plugin_infos(); | 547 plugin_groups_[i]->web_plugins_info(); |
502 for (size_t i = 0; i < plugins.size(); ++i) { | 548 for (size_t i = 0; i < plugins.size(); ++i) { |
503 if (SupportsExtension(plugins[i], extension, &actual_mime_type)) { | 549 if (SupportsExtension(plugins[i], extension, &actual_mime_type)) { |
504 FilePath path = plugins[i].path; | 550 FilePath path = plugins[i].path; |
505 if (path.value() != kDefaultPluginLibraryName && | 551 if (path.value() != kDefaultPluginLibraryName && |
506 visited_plugins.insert(path).second) { | 552 visited_plugins.insert(path).second) { |
507 info->push_back(plugins[i]); | 553 info->push_back(plugins[i]); |
508 if (actual_mime_types) | 554 if (actual_mime_types) |
509 actual_mime_types->push_back(actual_mime_type); | 555 actual_mime_types->push_back(actual_mime_type); |
510 } | 556 } |
511 } | 557 } |
512 } | 558 } |
513 } | 559 } |
514 } | 560 } |
515 | 561 |
516 // Add the default plugin at the end if it supports the mime type given, | 562 // Add the default plugin at the end if it supports the mime type given, |
517 // and the default plugin is enabled. | 563 // and the default plugin is enabled. |
518 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 564 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
519 #if defined(OS_WIN) | 565 #if defined(OS_WIN) |
520 if (plugin_groups_[i]->identifier().compare( | 566 if (plugin_groups_[i]->identifier().compare( |
521 WideToUTF8(kDefaultPluginLibraryName)) == 0) { | 567 WideToUTF8(kDefaultPluginLibraryName)) == 0) { |
522 #else | 568 #else |
523 if (plugin_groups_[i]->identifier().compare( | 569 if (plugin_groups_[i]->identifier().compare( |
524 kDefaultPluginLibraryName) == 0) { | 570 kDefaultPluginLibraryName) == 0) { |
525 #endif | 571 #endif |
526 DCHECK_NE(0U, plugin_groups_[i]->web_plugin_infos().size()); | 572 DCHECK_NE(0U, plugin_groups_[i]->web_plugins_info().size()); |
527 const webkit::WebPluginInfo& default_info = | 573 const webkit::WebPluginInfo& default_info = |
528 plugin_groups_[i]->web_plugin_infos()[0]; | 574 plugin_groups_[i]->web_plugins_info()[0]; |
529 if (SupportsType(default_info, mime_type, allow_wildcard)) { | 575 if (SupportsType(default_info, mime_type, allow_wildcard)) { |
530 info->push_back(default_info); | 576 info->push_back(default_info); |
531 if (actual_mime_types) | 577 if (actual_mime_types) |
532 actual_mime_types->push_back(mime_type); | 578 actual_mime_types->push_back(mime_type); |
533 } | 579 } |
534 } | 580 } |
535 } | 581 } |
536 } | 582 } |
537 | 583 |
538 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, | 584 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, |
539 webkit::WebPluginInfo* info) { | 585 webkit::WebPluginInfo* info) { |
540 LoadPlugins(); | 586 LoadPlugins(); |
541 base::AutoLock lock(lock_); | 587 base::AutoLock lock(lock_); |
542 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 588 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
543 const std::vector<webkit::WebPluginInfo>& plugins = | 589 const std::vector<webkit::WebPluginInfo>& plugins = |
544 plugin_groups_[i]->web_plugin_infos(); | 590 plugin_groups_[i]->web_plugins_info(); |
545 for (size_t i = 0; i < plugins.size(); ++i) { | 591 for (size_t i = 0; i < plugins.size(); ++i) { |
546 if (plugins[i].path == plugin_path) { | 592 if (plugins[i].path == plugin_path) { |
547 *info = plugins[i]; | 593 *info = plugins[i]; |
548 return true; | 594 return true; |
549 } | 595 } |
550 } | 596 } |
551 } | 597 } |
552 | 598 |
553 return false; | 599 return false; |
554 } | 600 } |
555 | 601 |
556 void PluginList::GetPluginGroups( | 602 void PluginList::GetPluginGroups( |
557 bool load_if_necessary, | 603 bool load_if_necessary, |
558 std::vector<PluginGroup>* plugin_groups) { | 604 std::vector<PluginGroup>* plugin_groups) { |
559 if (load_if_necessary) | 605 if (load_if_necessary) |
560 LoadPlugins(); | 606 LoadPlugins(); |
561 base::AutoLock lock(lock_); | 607 base::AutoLock lock(lock_); |
562 plugin_groups->clear(); | 608 plugin_groups->clear(); |
563 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 609 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
564 // In some unit tests we can get confronted with empty groups but in real | 610 // In some unit tests we can get confronted with empty groups but in real |
565 // world code this if should never be false here. | 611 // world code this if should never be false here. |
566 if (!plugin_groups_[i]->IsEmpty()) | 612 if (!plugin_groups_[i]->IsEmpty()) |
567 plugin_groups->push_back(*plugin_groups_[i]); | 613 plugin_groups->push_back(*plugin_groups_[i]); |
568 } | 614 } |
569 } | 615 } |
570 | 616 |
571 PluginGroup* PluginList::GetPluginGroup( | 617 const PluginGroup* PluginList::GetPluginGroup( |
572 const webkit::WebPluginInfo& web_plugin_info) { | 618 const webkit::WebPluginInfo& web_plugin_info) { |
573 base::AutoLock lock(lock_); | 619 base::AutoLock lock(lock_); |
574 return new PluginGroup(*AddToPluginGroups(web_plugin_info, &plugin_groups_)); | 620 return AddToPluginGroups(web_plugin_info, &plugin_groups_); |
575 } | 621 } |
576 | 622 |
577 string16 PluginList::GetPluginGroupName(const std::string& identifier) { | 623 string16 PluginList::GetPluginGroupName(const std::string& identifier) { |
578 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 624 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
579 if (plugin_groups_[i]->identifier() == identifier) | 625 if (plugin_groups_[i]->identifier() == identifier) |
580 return plugin_groups_[i]->GetGroupName(); | 626 return plugin_groups_[i]->GetGroupName(); |
581 } | 627 } |
582 return string16(); | 628 return string16(); |
583 } | 629 } |
584 | 630 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 // is not going to run anyway. | 663 // is not going to run anyway. |
618 for (size_t i = 0; i < plugin_groups->size(); ++i) { | 664 for (size_t i = 0; i < plugin_groups->size(); ++i) { |
619 if ((*plugin_groups)[i]->identifier() == identifier) { | 665 if ((*plugin_groups)[i]->identifier() == identifier) { |
620 group->set_identifier(PluginGroup::GetLongIdentifier(web_plugin_info)); | 666 group->set_identifier(PluginGroup::GetLongIdentifier(web_plugin_info)); |
621 break; | 667 break; |
622 } | 668 } |
623 } | 669 } |
624 plugin_groups->push_back(group); | 670 plugin_groups->push_back(group); |
625 } | 671 } |
626 group->AddPlugin(web_plugin_info); | 672 group->AddPlugin(web_plugin_info); |
| 673 // If group is scheduled for disabling do that now and remove it from the |
| 674 // list. |
| 675 if (groups_to_disable_.erase(group->GetGroupName())) |
| 676 group->EnableGroup(false); |
627 return group; | 677 return group; |
628 } | 678 } |
629 | 679 |
| 680 bool PluginList::EnablePlugin(const FilePath& filename) { |
| 681 base::AutoLock lock(lock_); |
| 682 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
| 683 if (plugin_groups_[i]->ContainsPlugin(filename)) |
| 684 return plugin_groups_[i]->EnablePlugin(filename); |
| 685 } |
| 686 // Non existing plugin is being enabled. Check if it has been disabled before |
| 687 // and remove it. |
| 688 return (plugins_to_disable_.erase(filename) != 0); |
| 689 } |
| 690 |
| 691 bool PluginList::DisablePlugin(const FilePath& filename) { |
| 692 base::AutoLock lock(lock_); |
| 693 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
| 694 if (plugin_groups_[i]->ContainsPlugin(filename)) |
| 695 return plugin_groups_[i]->DisablePlugin(filename); |
| 696 } |
| 697 // Non existing plugin is being disabled. Queue the plugin so that on the next |
| 698 // load plugins call they will be disabled. |
| 699 plugins_to_disable_.insert(filename); |
| 700 return true; |
| 701 } |
| 702 |
| 703 bool PluginList::EnableGroup(bool enable, const string16& group_name) { |
| 704 base::AutoLock lock(lock_); |
| 705 PluginGroup* group = NULL; |
| 706 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
| 707 if (!plugin_groups_[i]->IsEmpty() && |
| 708 plugin_groups_[i]->GetGroupName().find(group_name) != string16::npos) { |
| 709 group = plugin_groups_[i]; |
| 710 break; |
| 711 } |
| 712 } |
| 713 if (!group) { |
| 714 // Non existing group is being enabled. Queue the group so that on the next |
| 715 // load plugins call they will be disabled. |
| 716 if (!enable) { |
| 717 groups_to_disable_.insert(group_name); |
| 718 return true; |
| 719 } else { |
| 720 return (groups_to_disable_.erase(group_name) != 0); |
| 721 } |
| 722 } |
| 723 |
| 724 return group->EnableGroup(enable); |
| 725 } |
| 726 |
630 bool PluginList::SupportsType(const webkit::WebPluginInfo& plugin, | 727 bool PluginList::SupportsType(const webkit::WebPluginInfo& plugin, |
631 const std::string& mime_type, | 728 const std::string& mime_type, |
632 bool allow_wildcard) { | 729 bool allow_wildcard) { |
633 // Webkit will ask for a plugin to handle empty mime types. | 730 // Webkit will ask for a plugin to handle empty mime types. |
634 if (mime_type.empty()) | 731 if (mime_type.empty()) |
635 return false; | 732 return false; |
636 | 733 |
637 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { | 734 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { |
638 const webkit::WebPluginMimeType& mime_info = plugin.mime_types[i]; | 735 const webkit::WebPluginMimeType& mime_info = plugin.mime_types[i]; |
639 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { | 736 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { |
(...skipping 20 matching lines...) Expand all Loading... |
660 } | 757 } |
661 return false; | 758 return false; |
662 } | 759 } |
663 | 760 |
664 PluginList::~PluginList() { | 761 PluginList::~PluginList() { |
665 } | 762 } |
666 | 763 |
667 | 764 |
668 } // namespace npapi | 765 } // namespace npapi |
669 } // namespace webkit | 766 } // namespace webkit |
OLD | NEW |