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; | |
234 | 233 |
235 webkit::WebPluginMimeType mime_type; | 234 webkit::WebPluginMimeType mime_type; |
236 mime_type.mime_type = mime_type_str; | 235 mime_type.mime_type = mime_type_str; |
237 plugin.info.mime_types.push_back(mime_type); | 236 plugin.info.mime_types.push_back(mime_type); |
238 | 237 |
239 plugin.entry_points = entry_points; | 238 plugin.entry_points = entry_points; |
240 | 239 |
241 base::AutoLock lock(lock_); | 240 base::AutoLock lock(lock_); |
242 internal_plugins_.push_back(plugin); | 241 internal_plugins_.push_back(plugin); |
243 if (filename.value() == kDefaultPluginLibraryName) | 242 if (filename.value() == kDefaultPluginLibraryName) |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 if (!plugins_need_refresh_) | 400 if (!plugins_need_refresh_) |
402 return; | 401 return; |
403 } | 402 } |
404 | 403 |
405 ScopedVector<PluginGroup> new_plugin_groups; | 404 ScopedVector<PluginGroup> new_plugin_groups; |
406 AddHardcodedPluginGroups(&new_plugin_groups); | 405 AddHardcodedPluginGroups(&new_plugin_groups); |
407 // Do the actual loading of the plugins. | 406 // Do the actual loading of the plugins. |
408 LoadPluginsInternal(&new_plugin_groups); | 407 LoadPluginsInternal(&new_plugin_groups); |
409 | 408 |
410 base::AutoLock lock(lock_); | 409 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 | |
456 plugin_groups_.swap(new_plugin_groups); | 410 plugin_groups_.swap(new_plugin_groups); |
457 } | 411 } |
458 | 412 |
459 void PluginList::LoadPlugin(const FilePath& path, | 413 void PluginList::LoadPlugin(const FilePath& path, |
460 ScopedVector<PluginGroup>* plugin_groups) { | 414 ScopedVector<PluginGroup>* plugin_groups) { |
461 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 415 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
462 << "Loading plugin " << path.value(); | 416 << "Loading plugin " << path.value(); |
463 WebPluginInfo plugin_info; | 417 WebPluginInfo plugin_info; |
464 const PluginEntryPoints* entry_points; | 418 const PluginEntryPoints* entry_points; |
465 | 419 |
(...skipping 20 matching lines...) Expand all Loading... |
486 | 440 |
487 base::AutoLock lock(lock_); | 441 base::AutoLock lock(lock_); |
488 AddToPluginGroups(plugin_info, plugin_groups); | 442 AddToPluginGroups(plugin_info, plugin_groups); |
489 } | 443 } |
490 | 444 |
491 void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins) { | 445 void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins) { |
492 LoadPlugins(); | 446 LoadPlugins(); |
493 base::AutoLock lock(lock_); | 447 base::AutoLock lock(lock_); |
494 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 448 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
495 const std::vector<webkit::WebPluginInfo>& gr_plugins = | 449 const std::vector<webkit::WebPluginInfo>& gr_plugins = |
496 plugin_groups_[i]->web_plugins_info(); | 450 plugin_groups_[i]->web_plugin_infos(); |
497 plugins->insert(plugins->end(), gr_plugins.begin(), gr_plugins.end()); | 451 plugins->insert(plugins->end(), gr_plugins.begin(), gr_plugins.end()); |
498 } | 452 } |
499 } | 453 } |
500 | 454 |
501 void PluginList::GetPluginInfoArray( | 455 void PluginList::GetPluginInfoArray( |
502 const GURL& url, | 456 const GURL& url, |
503 const std::string& mime_type, | 457 const std::string& mime_type, |
504 bool allow_wildcard, | 458 bool allow_wildcard, |
505 bool* use_stale, | 459 bool* use_stale, |
506 std::vector<webkit::WebPluginInfo>* info, | 460 std::vector<webkit::WebPluginInfo>* info, |
507 std::vector<std::string>* actual_mime_types) { | 461 std::vector<std::string>* actual_mime_types) { |
508 DCHECK(mime_type == StringToLowerASCII(mime_type)); | 462 DCHECK(mime_type == StringToLowerASCII(mime_type)); |
509 DCHECK(info); | 463 DCHECK(info); |
510 | 464 |
511 if (!use_stale) | 465 if (!use_stale) |
512 LoadPlugins(); | 466 LoadPlugins(); |
513 base::AutoLock lock(lock_); | 467 base::AutoLock lock(lock_); |
514 if (use_stale) | 468 if (use_stale) |
515 *use_stale = plugins_need_refresh_; | 469 *use_stale = plugins_need_refresh_; |
516 info->clear(); | 470 info->clear(); |
517 if (actual_mime_types) | 471 if (actual_mime_types) |
518 actual_mime_types->clear(); | 472 actual_mime_types->clear(); |
519 | 473 |
520 std::set<FilePath> visited_plugins; | 474 std::set<FilePath> visited_plugins; |
521 | 475 |
522 // Add in plugins by mime type. | 476 // Add in plugins by mime type. |
523 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 477 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
524 const std::vector<webkit::WebPluginInfo>& plugins = | 478 const std::vector<webkit::WebPluginInfo>& plugins = |
525 plugin_groups_[i]->web_plugins_info(); | 479 plugin_groups_[i]->web_plugin_infos(); |
526 for (size_t i = 0; i < plugins.size(); ++i) { | 480 for (size_t i = 0; i < plugins.size(); ++i) { |
527 if (SupportsType(plugins[i], mime_type, allow_wildcard)) { | 481 if (SupportsType(plugins[i], mime_type, allow_wildcard)) { |
528 FilePath path = plugins[i].path; | 482 FilePath path = plugins[i].path; |
529 if (path.value() != kDefaultPluginLibraryName && | 483 if (path.value() != kDefaultPluginLibraryName && |
530 visited_plugins.insert(path).second) { | 484 visited_plugins.insert(path).second) { |
531 info->push_back(plugins[i]); | 485 info->push_back(plugins[i]); |
532 if (actual_mime_types) | 486 if (actual_mime_types) |
533 actual_mime_types->push_back(mime_type); | 487 actual_mime_types->push_back(mime_type); |
534 } | 488 } |
535 } | 489 } |
536 } | 490 } |
537 } | 491 } |
538 | 492 |
539 // Add in plugins by url. | 493 // Add in plugins by url. |
540 std::string path = url.path(); | 494 std::string path = url.path(); |
541 std::string::size_type last_dot = path.rfind('.'); | 495 std::string::size_type last_dot = path.rfind('.'); |
542 if (last_dot != std::string::npos) { | 496 if (last_dot != std::string::npos) { |
543 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); | 497 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); |
544 std::string actual_mime_type; | 498 std::string actual_mime_type; |
545 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 499 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
546 const std::vector<webkit::WebPluginInfo>& plugins = | 500 const std::vector<webkit::WebPluginInfo>& plugins = |
547 plugin_groups_[i]->web_plugins_info(); | 501 plugin_groups_[i]->web_plugin_infos(); |
548 for (size_t i = 0; i < plugins.size(); ++i) { | 502 for (size_t i = 0; i < plugins.size(); ++i) { |
549 if (SupportsExtension(plugins[i], extension, &actual_mime_type)) { | 503 if (SupportsExtension(plugins[i], extension, &actual_mime_type)) { |
550 FilePath path = plugins[i].path; | 504 FilePath path = plugins[i].path; |
551 if (path.value() != kDefaultPluginLibraryName && | 505 if (path.value() != kDefaultPluginLibraryName && |
552 visited_plugins.insert(path).second) { | 506 visited_plugins.insert(path).second) { |
553 info->push_back(plugins[i]); | 507 info->push_back(plugins[i]); |
554 if (actual_mime_types) | 508 if (actual_mime_types) |
555 actual_mime_types->push_back(actual_mime_type); | 509 actual_mime_types->push_back(actual_mime_type); |
556 } | 510 } |
557 } | 511 } |
558 } | 512 } |
559 } | 513 } |
560 } | 514 } |
561 | 515 |
562 // Add the default plugin at the end if it supports the mime type given, | 516 // Add the default plugin at the end if it supports the mime type given, |
563 // and the default plugin is enabled. | 517 // and the default plugin is enabled. |
564 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 518 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
565 #if defined(OS_WIN) | 519 #if defined(OS_WIN) |
566 if (plugin_groups_[i]->identifier().compare( | 520 if (plugin_groups_[i]->identifier().compare( |
567 WideToUTF8(kDefaultPluginLibraryName)) == 0) { | 521 WideToUTF8(kDefaultPluginLibraryName)) == 0) { |
568 #else | 522 #else |
569 if (plugin_groups_[i]->identifier().compare( | 523 if (plugin_groups_[i]->identifier().compare( |
570 kDefaultPluginLibraryName) == 0) { | 524 kDefaultPluginLibraryName) == 0) { |
571 #endif | 525 #endif |
572 DCHECK_NE(0U, plugin_groups_[i]->web_plugins_info().size()); | 526 DCHECK_NE(0U, plugin_groups_[i]->web_plugin_infos().size()); |
573 const webkit::WebPluginInfo& default_info = | 527 const webkit::WebPluginInfo& default_info = |
574 plugin_groups_[i]->web_plugins_info()[0]; | 528 plugin_groups_[i]->web_plugin_infos()[0]; |
575 if (SupportsType(default_info, mime_type, allow_wildcard)) { | 529 if (SupportsType(default_info, mime_type, allow_wildcard)) { |
576 info->push_back(default_info); | 530 info->push_back(default_info); |
577 if (actual_mime_types) | 531 if (actual_mime_types) |
578 actual_mime_types->push_back(mime_type); | 532 actual_mime_types->push_back(mime_type); |
579 } | 533 } |
580 } | 534 } |
581 } | 535 } |
582 } | 536 } |
583 | 537 |
584 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, | 538 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, |
585 webkit::WebPluginInfo* info) { | 539 webkit::WebPluginInfo* info) { |
586 LoadPlugins(); | 540 LoadPlugins(); |
587 base::AutoLock lock(lock_); | 541 base::AutoLock lock(lock_); |
588 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 542 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
589 const std::vector<webkit::WebPluginInfo>& plugins = | 543 const std::vector<webkit::WebPluginInfo>& plugins = |
590 plugin_groups_[i]->web_plugins_info(); | 544 plugin_groups_[i]->web_plugin_infos(); |
591 for (size_t i = 0; i < plugins.size(); ++i) { | 545 for (size_t i = 0; i < plugins.size(); ++i) { |
592 if (plugins[i].path == plugin_path) { | 546 if (plugins[i].path == plugin_path) { |
593 *info = plugins[i]; | 547 *info = plugins[i]; |
594 return true; | 548 return true; |
595 } | 549 } |
596 } | 550 } |
597 } | 551 } |
598 | 552 |
599 return false; | 553 return false; |
600 } | 554 } |
601 | 555 |
602 void PluginList::GetPluginGroups( | 556 void PluginList::GetPluginGroups( |
603 bool load_if_necessary, | 557 bool load_if_necessary, |
604 std::vector<PluginGroup>* plugin_groups) { | 558 std::vector<PluginGroup>* plugin_groups) { |
605 if (load_if_necessary) | 559 if (load_if_necessary) |
606 LoadPlugins(); | 560 LoadPlugins(); |
607 base::AutoLock lock(lock_); | 561 base::AutoLock lock(lock_); |
608 plugin_groups->clear(); | 562 plugin_groups->clear(); |
609 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 563 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
610 // In some unit tests we can get confronted with empty groups but in real | 564 // In some unit tests we can get confronted with empty groups but in real |
611 // world code this if should never be false here. | 565 // world code this if should never be false here. |
612 if (!plugin_groups_[i]->IsEmpty()) | 566 if (!plugin_groups_[i]->IsEmpty()) |
613 plugin_groups->push_back(*plugin_groups_[i]); | 567 plugin_groups->push_back(*plugin_groups_[i]); |
614 } | 568 } |
615 } | 569 } |
616 | 570 |
617 const PluginGroup* PluginList::GetPluginGroup( | 571 PluginGroup* PluginList::GetPluginGroup( |
618 const webkit::WebPluginInfo& web_plugin_info) { | 572 const webkit::WebPluginInfo& web_plugin_info) { |
619 base::AutoLock lock(lock_); | 573 base::AutoLock lock(lock_); |
620 return AddToPluginGroups(web_plugin_info, &plugin_groups_); | 574 return new PluginGroup(*AddToPluginGroups(web_plugin_info, &plugin_groups_)); |
621 } | 575 } |
622 | 576 |
623 string16 PluginList::GetPluginGroupName(const std::string& identifier) { | 577 string16 PluginList::GetPluginGroupName(const std::string& identifier) { |
624 for (size_t i = 0; i < plugin_groups_.size(); ++i) { | 578 for (size_t i = 0; i < plugin_groups_.size(); ++i) { |
625 if (plugin_groups_[i]->identifier() == identifier) | 579 if (plugin_groups_[i]->identifier() == identifier) |
626 return plugin_groups_[i]->GetGroupName(); | 580 return plugin_groups_[i]->GetGroupName(); |
627 } | 581 } |
628 return string16(); | 582 return string16(); |
629 } | 583 } |
630 | 584 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 // is not going to run anyway. | 617 // is not going to run anyway. |
664 for (size_t i = 0; i < plugin_groups->size(); ++i) { | 618 for (size_t i = 0; i < plugin_groups->size(); ++i) { |
665 if ((*plugin_groups)[i]->identifier() == identifier) { | 619 if ((*plugin_groups)[i]->identifier() == identifier) { |
666 group->set_identifier(PluginGroup::GetLongIdentifier(web_plugin_info)); | 620 group->set_identifier(PluginGroup::GetLongIdentifier(web_plugin_info)); |
667 break; | 621 break; |
668 } | 622 } |
669 } | 623 } |
670 plugin_groups->push_back(group); | 624 plugin_groups->push_back(group); |
671 } | 625 } |
672 group->AddPlugin(web_plugin_info); | 626 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); | |
677 return group; | 627 return group; |
678 } | 628 } |
679 | 629 |
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 | |
727 bool PluginList::SupportsType(const webkit::WebPluginInfo& plugin, | 630 bool PluginList::SupportsType(const webkit::WebPluginInfo& plugin, |
728 const std::string& mime_type, | 631 const std::string& mime_type, |
729 bool allow_wildcard) { | 632 bool allow_wildcard) { |
730 // Webkit will ask for a plugin to handle empty mime types. | 633 // Webkit will ask for a plugin to handle empty mime types. |
731 if (mime_type.empty()) | 634 if (mime_type.empty()) |
732 return false; | 635 return false; |
733 | 636 |
734 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { | 637 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { |
735 const webkit::WebPluginMimeType& mime_info = plugin.mime_types[i]; | 638 const webkit::WebPluginMimeType& mime_info = plugin.mime_types[i]; |
736 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { | 639 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { |
(...skipping 20 matching lines...) Expand all Loading... |
757 } | 660 } |
758 return false; | 661 return false; |
759 } | 662 } |
760 | 663 |
761 PluginList::~PluginList() { | 664 PluginList::~PluginList() { |
762 } | 665 } |
763 | 666 |
764 | 667 |
765 } // namespace npapi | 668 } // namespace npapi |
766 } // namespace webkit | 669 } // namespace webkit |
OLD | NEW |