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

Side by Side Diff: chrome/browser/extensions/extension_service.cc

Issue 291603002: Don't try to reload blacklisted extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: real rebase Created 6 years, 7 months 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "chrome/browser/extensions/extension_service.h" 5 #include "chrome/browser/extensions/extension_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <set> 9 #include <set>
10 10
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 installer->set_delete_source(file_ownership_passed); 588 installer->set_delete_source(file_ownership_passed);
589 installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE); 589 installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE);
590 installer->InstallCrx(extension_path); 590 installer->InstallCrx(extension_path);
591 591
592 if (out_crx_installer) 592 if (out_crx_installer)
593 *out_crx_installer = installer.get(); 593 *out_crx_installer = installer.get();
594 594
595 return true; 595 return true;
596 } 596 }
597 597
598 void ExtensionService::ReloadExtension(const std::string extension_id) { 598 void ExtensionService::ReloadExtension(
599 // "transient" because the process of reloading may cause the reference
600 // to become invalid. Instead, use |extension_id|, a copy.
601 const std::string& transient_extension_id) {
599 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 602 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
600 603
601 // If the extension is already reloading, don't reload again. 604 // If the extension is already reloading, don't reload again.
602 if (extension_prefs_->GetDisableReasons(extension_id) & 605 if (extension_prefs_->GetDisableReasons(transient_extension_id) &
603 Extension::DISABLE_RELOAD) { 606 Extension::DISABLE_RELOAD) {
604 return; 607 return;
605 } 608 }
606 609
610 // Ignore attempts to reload a blacklisted extension. Sometimes this can
611 // happen in a convoluted reload sequence triggered by the termination of a
612 // blacklisted extension and a naive attempt to reload it. For an example see
613 // http://crbug.com/373842.
614 if (registry_->blacklisted_extensions().Contains(transient_extension_id))
615 return;
616
607 base::FilePath path; 617 base::FilePath path;
608 const Extension* current_extension = GetExtensionById(extension_id, false); 618
619 std::string extension_id = transient_extension_id;
620 const Extension* transient_current_extension =
621 GetExtensionById(extension_id, false);
609 622
610 // Disable the extension if it's loaded. It might not be loaded if it crashed. 623 // Disable the extension if it's loaded. It might not be loaded if it crashed.
611 if (current_extension) { 624 if (transient_current_extension) {
612 // If the extension has an inspector open for its background page, detach 625 // If the extension has an inspector open for its background page, detach
613 // the inspector and hang onto a cookie for it, so that we can reattach 626 // the inspector and hang onto a cookie for it, so that we can reattach
614 // later. 627 // later.
615 // TODO(yoz): this is not incognito-safe! 628 // TODO(yoz): this is not incognito-safe!
616 extensions::ProcessManager* manager = system_->process_manager(); 629 extensions::ProcessManager* manager = system_->process_manager();
617 extensions::ExtensionHost* host = 630 extensions::ExtensionHost* host =
618 manager->GetBackgroundHostForExtension(extension_id); 631 manager->GetBackgroundHostForExtension(extension_id);
619 if (host && DevToolsAgentHost::HasFor(host->render_view_host())) { 632 if (host && DevToolsAgentHost::HasFor(host->render_view_host())) {
620 // Look for an open inspector for the background page. 633 // Look for an open inspector for the background page.
621 scoped_refptr<DevToolsAgentHost> agent_host = 634 scoped_refptr<DevToolsAgentHost> agent_host =
622 DevToolsAgentHost::GetOrCreateFor(host->render_view_host()); 635 DevToolsAgentHost::GetOrCreateFor(host->render_view_host());
623 agent_host->DisconnectRenderViewHost(); 636 agent_host->DisconnectRenderViewHost();
624 orphaned_dev_tools_[extension_id] = agent_host; 637 orphaned_dev_tools_[extension_id] = agent_host;
625 } 638 }
626 639
627 path = current_extension->path(); 640 path = transient_current_extension->path();
628 // BeingUpgraded is set back to false when the extension is added. 641 // BeingUpgraded is set back to false when the extension is added.
629 system_->runtime_data()->SetBeingUpgraded(current_extension, true); 642 system_->runtime_data()->SetBeingUpgraded(transient_current_extension,
643 true);
630 DisableExtension(extension_id, Extension::DISABLE_RELOAD); 644 DisableExtension(extension_id, Extension::DISABLE_RELOAD);
631 reloading_extensions_.insert(extension_id); 645 reloading_extensions_.insert(extension_id);
632 } else { 646 } else {
633 path = unloaded_extension_paths_[extension_id]; 647 path = unloaded_extension_paths_[extension_id];
634 } 648 }
635 649
650 transient_current_extension = NULL;
651
636 if (delayed_installs_.Contains(extension_id)) { 652 if (delayed_installs_.Contains(extension_id)) {
637 FinishDelayedInstallation(extension_id); 653 FinishDelayedInstallation(extension_id);
638 return; 654 return;
639 } 655 }
640 656
641 // If we're reloading a component extension, use the component extension 657 // If we're reloading a component extension, use the component extension
642 // loader's reloader. 658 // loader's reloader.
643 if (component_loader_->Exists(extension_id)) { 659 if (component_loader_->Exists(extension_id)) {
644 SetBeingReloaded(extension_id, true); 660 SetBeingReloaded(extension_id, true);
645 component_loader_->Reload(extension_id); 661 component_loader_->Reload(extension_id);
(...skipping 13 matching lines...) Expand all
659 // Otherwise, the extension is unpacked (location LOAD). 675 // Otherwise, the extension is unpacked (location LOAD).
660 // We should always be able to remember the extension's path. If it's not in 676 // We should always be able to remember the extension's path. If it's not in
661 // the map, someone failed to update |unloaded_extension_paths_|. 677 // the map, someone failed to update |unloaded_extension_paths_|.
662 CHECK(!path.empty()); 678 CHECK(!path.empty());
663 extensions::UnpackedInstaller::Create(this)->Load(path); 679 extensions::UnpackedInstaller::Create(this)->Load(path);
664 } 680 }
665 // When reloading is done, mark this extension as done reloading. 681 // When reloading is done, mark this extension as done reloading.
666 SetBeingReloaded(extension_id, false); 682 SetBeingReloaded(extension_id, false);
667 } 683 }
668 684
669 bool ExtensionService::UninstallExtension(const std::string& extension_id, 685 bool ExtensionService::UninstallExtension(
670 bool external_uninstall, 686 // "transient" because the process of uninstalling may cause the reference
671 base::string16* error) { 687 // to become invalid. Instead, use |extenson->id()|.
688 const std::string& transient_extension_id,
689 bool external_uninstall,
690 base::string16* error) {
672 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 691 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
673 692
674 scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id)); 693 scoped_refptr<const Extension> extension =
694 GetInstalledExtension(transient_extension_id);
675 695
676 // Callers should not send us nonexistent extensions. 696 // Callers should not send us nonexistent extensions.
677 CHECK(extension.get()); 697 CHECK(extension.get());
678 698
679 // Policy change which triggers an uninstall will always set 699 // Policy change which triggers an uninstall will always set
680 // |external_uninstall| to true so this is the only way to uninstall 700 // |external_uninstall| to true so this is the only way to uninstall
681 // managed extensions. 701 // managed extensions.
682 // Shared modules being uninstalled will also set |external_uninstall| to true 702 // Shared modules being uninstalled will also set |external_uninstall| to true
683 // so that we can guarantee users don't uninstall a shared module. 703 // so that we can guarantee users don't uninstall a shared module.
684 // (crbug.com/273300) 704 // (crbug.com/273300)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 737 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
718 } 738 }
719 } 739 }
720 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", 740 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType",
721 extension->GetType(), 100); 741 extension->GetType(), 100);
722 RecordPermissionMessagesHistogram(extension.get(), 742 RecordPermissionMessagesHistogram(extension.get(),
723 "Extensions.Permissions_Uninstall"); 743 "Extensions.Permissions_Uninstall");
724 744
725 // Unload before doing more cleanup to ensure that nothing is hanging on to 745 // Unload before doing more cleanup to ensure that nothing is hanging on to
726 // any of these resources. 746 // any of these resources.
727 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); 747 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UNINSTALL);
728 748
729 // Tell the backend to start deleting installed extensions on the file thread. 749 // Tell the backend to start deleting installed extensions on the file thread.
730 if (!Manifest::IsUnpackedLocation(extension->location())) { 750 if (!Manifest::IsUnpackedLocation(extension->location())) {
731 if (!GetFileTaskRunner()->PostTask( 751 if (!GetFileTaskRunner()->PostTask(
732 FROM_HERE, 752 FROM_HERE,
733 base::Bind(&extensions::file_util::UninstallExtension, 753 base::Bind(&extensions::file_util::UninstallExtension,
734 install_directory_, 754 install_directory_,
735 extension_id))) 755 extension->id())))
736 NOTREACHED(); 756 NOTREACHED();
737 } 757 }
738 758
739 // Do not remove the data of ephemeral apps. They will be garbage collected by 759 // Do not remove the data of ephemeral apps. They will be garbage collected by
740 // EphemeralAppService. 760 // EphemeralAppService.
741 if (!extension_prefs_->IsEphemeralApp(extension_id)) 761 if (!extension_prefs_->IsEphemeralApp(extension->id()))
742 extensions::DataDeleter::StartDeleting(profile_, extension.get()); 762 extensions::DataDeleter::StartDeleting(profile_, extension.get());
743 763
744 UntrackTerminatedExtension(extension_id); 764 UntrackTerminatedExtension(extension->id());
745 765
746 // Notify interested parties that we've uninstalled this extension. 766 // Notify interested parties that we've uninstalled this extension.
747 content::NotificationService::current()->Notify( 767 content::NotificationService::current()->Notify(
748 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 768 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
749 content::Source<Profile>(profile_), 769 content::Source<Profile>(profile_),
750 content::Details<const Extension>(extension.get())); 770 content::Details<const Extension>(extension.get()));
751 771
752 if (extension_sync_service_) { 772 if (extension_sync_service_) {
753 extension_sync_service_->ProcessSyncUninstallExtension(extension_id, 773 extension_sync_service_->ProcessSyncUninstallExtension(extension->id(),
754 sync_change); 774 sync_change);
755 } 775 }
756 776
757 delayed_installs_.Remove(extension_id); 777 delayed_installs_.Remove(extension->id());
758 778
759 extension_prefs_->OnExtensionUninstalled(extension_id, extension->location(), 779 extension_prefs_->OnExtensionUninstalled(
760 external_uninstall); 780 extension->id(), extension->location(), external_uninstall);
761 781
762 // Track the uninstallation. 782 // Track the uninstallation.
763 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); 783 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2);
764 784
765 return true; 785 return true;
766 } 786 }
767 787
768 bool ExtensionService::IsExtensionEnabled( 788 bool ExtensionService::IsExtensionEnabled(
769 const std::string& extension_id) const { 789 const std::string& extension_id) const {
770 if (registry_->enabled_extensions().Contains(extension_id) || 790 if (registry_->enabled_extensions().Contains(extension_id) ||
(...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after
2450 } 2470 }
2451 2471
2452 void ExtensionService::OnProfileDestructionStarted() { 2472 void ExtensionService::OnProfileDestructionStarted() {
2453 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); 2473 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs();
2454 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); 2474 for (ExtensionIdSet::iterator it = ids_to_unload.begin();
2455 it != ids_to_unload.end(); 2475 it != ids_to_unload.end();
2456 ++it) { 2476 ++it) {
2457 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); 2477 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN);
2458 } 2478 }
2459 } 2479 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_service.h ('k') | chrome/browser/extensions/extension_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698