OLD | NEW |
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 #include "extensions/browser/app_sorting.h" | 76 #include "extensions/browser/app_sorting.h" |
77 #include "extensions/browser/event_router.h" | 77 #include "extensions/browser/event_router.h" |
78 #include "extensions/browser/extension_registry.h" | 78 #include "extensions/browser/extension_registry.h" |
79 #include "extensions/browser/extensions_browser_client.h" | 79 #include "extensions/browser/extensions_browser_client.h" |
80 #include "extensions/browser/external_provider_interface.h" | 80 #include "extensions/browser/external_provider_interface.h" |
81 #include "extensions/browser/management_policy.h" | 81 #include "extensions/browser/management_policy.h" |
82 #include "extensions/browser/pending_extension_manager.h" | 82 #include "extensions/browser/pending_extension_manager.h" |
83 #include "extensions/browser/pref_names.h" | 83 #include "extensions/browser/pref_names.h" |
84 #include "extensions/browser/process_manager.h" | 84 #include "extensions/browser/process_manager.h" |
85 #include "extensions/browser/process_map.h" | 85 #include "extensions/browser/process_map.h" |
| 86 #include "extensions/browser/runtime_data.h" |
86 #include "extensions/browser/update_observer.h" | 87 #include "extensions/browser/update_observer.h" |
87 #include "extensions/common/constants.h" | 88 #include "extensions/common/constants.h" |
88 #include "extensions/common/error_utils.h" | 89 #include "extensions/common/error_utils.h" |
89 #include "extensions/common/extension.h" | 90 #include "extensions/common/extension.h" |
90 #include "extensions/common/extensions_client.h" | 91 #include "extensions/common/extensions_client.h" |
91 #include "extensions/common/feature_switch.h" | 92 #include "extensions/common/feature_switch.h" |
92 #include "extensions/common/manifest.h" | 93 #include "extensions/common/manifest.h" |
93 #include "extensions/common/manifest_constants.h" | 94 #include "extensions/common/manifest_constants.h" |
94 #include "extensions/common/manifest_handlers/background_info.h" | 95 #include "extensions/common/manifest_handlers/background_info.h" |
95 #include "extensions/common/manifest_handlers/incognito_info.h" | 96 #include "extensions/common/manifest_handlers/incognito_info.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 return IsCWSSharedModule(extension); | 183 return IsCWSSharedModule(extension); |
183 } | 184 } |
184 | 185 |
185 private: | 186 private: |
186 DISALLOW_COPY_AND_ASSIGN(SharedModuleProvider); | 187 DISALLOW_COPY_AND_ASSIGN(SharedModuleProvider); |
187 }; | 188 }; |
188 | 189 |
189 | 190 |
190 } // namespace | 191 } // namespace |
191 | 192 |
192 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() | |
193 : background_page_ready(false), | |
194 being_upgraded(false), | |
195 has_used_webrequest(false) { | |
196 } | |
197 | |
198 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { | |
199 } | |
200 | |
201 // ExtensionService. | 193 // ExtensionService. |
202 | 194 |
203 void ExtensionService::CheckExternalUninstall(const std::string& id) { | 195 void ExtensionService::CheckExternalUninstall(const std::string& id) { |
204 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 196 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
205 | 197 |
206 // Check if the providers know about this extension. | 198 // Check if the providers know about this extension. |
207 extensions::ProviderCollection::const_iterator i; | 199 extensions::ProviderCollection::const_iterator i; |
208 for (i = external_extension_providers_.begin(); | 200 for (i = external_extension_providers_.begin(); |
209 i != external_extension_providers_.end(); ++i) { | 201 i != external_extension_providers_.end(); ++i) { |
210 DCHECK(i->get()->IsReady()); | 202 DCHECK(i->get()->IsReady()); |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 if (host && DevToolsAgentHost::HasFor(host->render_view_host())) { | 725 if (host && DevToolsAgentHost::HasFor(host->render_view_host())) { |
734 // Look for an open inspector for the background page. | 726 // Look for an open inspector for the background page. |
735 scoped_refptr<DevToolsAgentHost> agent_host = | 727 scoped_refptr<DevToolsAgentHost> agent_host = |
736 DevToolsAgentHost::GetOrCreateFor(host->render_view_host()); | 728 DevToolsAgentHost::GetOrCreateFor(host->render_view_host()); |
737 agent_host->DisconnectRenderViewHost(); | 729 agent_host->DisconnectRenderViewHost(); |
738 orphaned_dev_tools_[extension_id] = agent_host; | 730 orphaned_dev_tools_[extension_id] = agent_host; |
739 } | 731 } |
740 | 732 |
741 path = current_extension->path(); | 733 path = current_extension->path(); |
742 // BeingUpgraded is set back to false when the extension is added. | 734 // BeingUpgraded is set back to false when the extension is added. |
743 SetBeingUpgraded(current_extension, true); | 735 system_->runtime_data()->SetBeingUpgraded(current_extension, true); |
744 DisableExtension(extension_id, Extension::DISABLE_RELOAD); | 736 DisableExtension(extension_id, Extension::DISABLE_RELOAD); |
745 reloading_extensions_.insert(extension_id); | 737 reloading_extensions_.insert(extension_id); |
746 } else { | 738 } else { |
747 path = unloaded_extension_paths_[extension_id]; | 739 path = unloaded_extension_paths_[extension_id]; |
748 } | 740 } |
749 | 741 |
750 if (delayed_installs_.Contains(extension_id)) { | 742 if (delayed_installs_.Contains(extension_id)) { |
751 FinishDelayedInstallation(extension_id); | 743 FinishDelayedInstallation(extension_id); |
752 return; | 744 return; |
753 } | 745 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 922 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
931 } else { | 923 } else { |
932 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore", | 924 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore", |
933 EXTERNAL_EXTENSION_REENABLED, | 925 EXTERNAL_EXTENSION_REENABLED, |
934 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 926 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
935 } | 927 } |
936 AcknowledgeExternalExtension(extension->id()); | 928 AcknowledgeExternalExtension(extension->id()); |
937 } | 929 } |
938 | 930 |
939 // Move it over to the enabled list. | 931 // Move it over to the enabled list. |
940 registry_->AddEnabled(make_scoped_refptr(extension)); | 932 registry_->EnableExtension(make_scoped_refptr(extension)); |
941 registry_->RemoveDisabled(extension->id()); | |
942 | 933 |
943 NotifyExtensionLoaded(extension); | 934 NotifyExtensionLoaded(extension); |
944 | 935 |
945 // Notify listeners that the extension was enabled. | 936 // Notify listeners that the extension was enabled. |
946 content::NotificationService::current()->Notify( | 937 content::NotificationService::current()->Notify( |
947 chrome::NOTIFICATION_EXTENSION_ENABLED, | 938 chrome::NOTIFICATION_EXTENSION_ENABLED, |
948 content::Source<Profile>(profile_), | 939 content::Source<Profile>(profile_), |
949 content::Details<const Extension>(extension)); | 940 content::Details<const Extension>(extension)); |
950 | 941 |
951 if (extension_sync_service_) | 942 if (extension_sync_service_) |
(...skipping 20 matching lines...) Expand all Loading... |
972 | 963 |
973 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); | 964 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); |
974 extension_prefs_->AddDisableReason(extension_id, disable_reason); | 965 extension_prefs_->AddDisableReason(extension_id, disable_reason); |
975 | 966 |
976 int include_mask = | 967 int include_mask = |
977 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED; | 968 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED; |
978 extension = registry_->GetExtensionById(extension_id, include_mask); | 969 extension = registry_->GetExtensionById(extension_id, include_mask); |
979 if (!extension) | 970 if (!extension) |
980 return; | 971 return; |
981 | 972 |
982 // Reset the background_page_ready flag | |
983 if (extensions::BackgroundInfo::HasBackgroundPage(extension)) | |
984 extension_runtime_data_[extension->id()].background_page_ready = false; | |
985 | |
986 // Move it over to the disabled list. Don't send a second unload notification | 973 // Move it over to the disabled list. Don't send a second unload notification |
987 // for terminated extensions being disabled. | 974 // for terminated extensions being disabled. |
988 registry_->AddDisabled(make_scoped_refptr(extension)); | 975 bool was_enabled = registry_->enabled_extensions().Contains(extension->id()); |
989 if (registry_->enabled_extensions().Contains(extension->id())) { | 976 registry_->DisableExtension(make_scoped_refptr(extension)); |
990 registry_->RemoveEnabled(extension->id()); | 977 if (was_enabled) |
991 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::REASON_DISABLE); | 978 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::REASON_DISABLE); |
992 } else { | |
993 registry_->RemoveTerminated(extension->id()); | |
994 } | |
995 | 979 |
996 if (extension_sync_service_) | 980 if (extension_sync_service_) |
997 extension_sync_service_->SyncDisableExtension(*extension); | 981 extension_sync_service_->SyncDisableExtension(*extension); |
998 } | 982 } |
999 | 983 |
1000 void ExtensionService::DisableUserExtensions( | 984 void ExtensionService::DisableUserExtensions( |
1001 const std::vector<std::string>& except_ids) { | 985 const std::vector<std::string>& except_ids) { |
1002 extensions::ManagementPolicy* management_policy = | 986 extensions::ManagementPolicy* management_policy = |
1003 system_->management_policy(); | 987 system_->management_policy(); |
1004 extensions::ExtensionList to_disable; | 988 extensions::ExtensionList to_disable; |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 return; | 1567 return; |
1584 } | 1568 } |
1585 | 1569 |
1586 // Keep information about the extension so that we can reload it later | 1570 // Keep information about the extension so that we can reload it later |
1587 // even if it's not permanently installed. | 1571 // even if it's not permanently installed. |
1588 unloaded_extension_paths_[extension->id()] = extension->path(); | 1572 unloaded_extension_paths_[extension->id()] = extension->path(); |
1589 | 1573 |
1590 // Clean up if the extension is meant to be enabled after a reload. | 1574 // Clean up if the extension is meant to be enabled after a reload. |
1591 reloading_extensions_.erase(extension->id()); | 1575 reloading_extensions_.erase(extension->id()); |
1592 | 1576 |
1593 // Clean up runtime data. | 1577 bool was_disabled = |
1594 extension_runtime_data_.erase(extension_id); | 1578 registry_->disabled_extensions().Contains(extension->id()); |
1595 | 1579 // Take the extension out of the registry (and notify observers). |
1596 if (registry_->disabled_extensions().Contains(extension->id())) { | 1580 registry_->UnloadExtension(extension); |
1597 registry_->RemoveDisabled(extension->id()); | 1581 if (was_disabled) { |
1598 // Make sure the profile cleans up its RequestContexts when an already | 1582 // Make sure the profile cleans up its RequestContexts when an already |
1599 // disabled extension is unloaded (since they are also tracking the disabled | 1583 // disabled extension is unloaded (since they are also tracking the disabled |
1600 // extensions). | 1584 // extensions). |
1601 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); | 1585 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); |
1602 } else { | 1586 } else { |
1603 // Remove the extension from the enabled list. | |
1604 registry_->RemoveEnabled(extension->id()); | |
1605 NotifyExtensionUnloaded(extension.get(), reason); | 1587 NotifyExtensionUnloaded(extension.get(), reason); |
1606 } | 1588 } |
1607 | 1589 |
1608 content::NotificationService::current()->Notify( | 1590 content::NotificationService::current()->Notify( |
1609 chrome::NOTIFICATION_EXTENSION_REMOVED, | 1591 chrome::NOTIFICATION_EXTENSION_REMOVED, |
1610 content::Source<Profile>(profile_), | 1592 content::Source<Profile>(profile_), |
1611 content::Details<const Extension>(extension.get())); | 1593 content::Details<const Extension>(extension.get())); |
1612 } | 1594 } |
1613 | 1595 |
1614 void ExtensionService::RemoveComponentExtension( | 1596 void ExtensionService::RemoveComponentExtension( |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 if (old) { | 1696 if (old) { |
1715 is_extension_installed = true; | 1697 is_extension_installed = true; |
1716 int version_compare_result = | 1698 int version_compare_result = |
1717 extension->version()->CompareTo(*(old->version())); | 1699 extension->version()->CompareTo(*(old->version())); |
1718 is_extension_upgrade = version_compare_result > 0; | 1700 is_extension_upgrade = version_compare_result > 0; |
1719 // Other than for unpacked extensions, CrxInstaller should have guaranteed | 1701 // Other than for unpacked extensions, CrxInstaller should have guaranteed |
1720 // that we aren't downgrading. | 1702 // that we aren't downgrading. |
1721 if (!Manifest::IsUnpackedLocation(extension->location())) | 1703 if (!Manifest::IsUnpackedLocation(extension->location())) |
1722 CHECK_GE(version_compare_result, 0); | 1704 CHECK_GE(version_compare_result, 0); |
1723 } | 1705 } |
1724 SetBeingUpgraded(extension, is_extension_upgrade); | 1706 system_->runtime_data()->SetBeingUpgraded(extension, is_extension_upgrade); |
1725 | 1707 |
1726 // The extension is now loaded, remove its data from unloaded extension map. | 1708 // The extension is now loaded, remove its data from unloaded extension map. |
1727 unloaded_extension_paths_.erase(extension->id()); | 1709 unloaded_extension_paths_.erase(extension->id()); |
1728 | 1710 |
1729 // If a terminated extension is loaded, remove it from the terminated list. | 1711 // If a terminated extension is loaded, remove it from the terminated list. |
1730 UntrackTerminatedExtension(extension->id()); | 1712 UntrackTerminatedExtension(extension->id()); |
1731 | 1713 |
1732 // If the extension was disabled for a reload, then enable it. | 1714 // If the extension was disabled for a reload, then enable it. |
1733 bool reloading = reloading_extensions_.erase(extension->id()) > 0; | 1715 bool reloading = reloading_extensions_.erase(extension->id()) > 0; |
1734 | 1716 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 } | 1759 } |
1778 extension_prefs_->app_sorting()->EnsureValidOrdinals( | 1760 extension_prefs_->app_sorting()->EnsureValidOrdinals( |
1779 extension->id(), syncer::StringOrdinal()); | 1761 extension->id(), syncer::StringOrdinal()); |
1780 } | 1762 } |
1781 | 1763 |
1782 registry_->AddEnabled(extension); | 1764 registry_->AddEnabled(extension); |
1783 if (extension_sync_service_) | 1765 if (extension_sync_service_) |
1784 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); | 1766 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); |
1785 NotifyExtensionLoaded(extension); | 1767 NotifyExtensionLoaded(extension); |
1786 } | 1768 } |
1787 SetBeingUpgraded(extension, false); | 1769 system_->runtime_data()->SetBeingUpgraded(extension, false); |
1788 } | 1770 } |
1789 | 1771 |
1790 void ExtensionService::AddComponentExtension(const Extension* extension) { | 1772 void ExtensionService::AddComponentExtension(const Extension* extension) { |
1791 const std::string old_version_string( | 1773 const std::string old_version_string( |
1792 extension_prefs_->GetVersionString(extension->id())); | 1774 extension_prefs_->GetVersionString(extension->id())); |
1793 const Version old_version(old_version_string); | 1775 const Version old_version(old_version_string); |
1794 | 1776 |
1795 VLOG(1) << "AddComponentExtension " << extension->name(); | 1777 VLOG(1) << "AddComponentExtension " << extension->name(); |
1796 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 1778 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
1797 VLOG(1) << "Component extension " << extension->name() << " (" | 1779 VLOG(1) << "Component extension " << extension->name() << " (" |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 const ExtensionSet& extensions = registry_->enabled_extensions(); | 2594 const ExtensionSet& extensions = registry_->enabled_extensions(); |
2613 for (ExtensionSet::const_iterator it = extensions.begin(); | 2595 for (ExtensionSet::const_iterator it = extensions.begin(); |
2614 it != extensions.end(); ++it) { | 2596 it != extensions.end(); ++it) { |
2615 if ((*it)->is_app() && (*it)->location() != Manifest::COMPONENT) | 2597 if ((*it)->is_app() && (*it)->location() != Manifest::COMPONENT) |
2616 result.insert((*it)->id()); | 2598 result.insert((*it)->id()); |
2617 } | 2599 } |
2618 | 2600 |
2619 return result; | 2601 return result; |
2620 } | 2602 } |
2621 | 2603 |
2622 bool ExtensionService::IsBackgroundPageReady(const Extension* extension) const { | |
2623 if (!extensions::BackgroundInfo::HasPersistentBackgroundPage(extension)) | |
2624 return true; | |
2625 ExtensionRuntimeDataMap::const_iterator it = | |
2626 extension_runtime_data_.find(extension->id()); | |
2627 return it == extension_runtime_data_.end() ? false : | |
2628 it->second.background_page_ready; | |
2629 } | |
2630 | |
2631 void ExtensionService::SetBackgroundPageReady(const Extension* extension) { | |
2632 DCHECK(extensions::BackgroundInfo::HasBackgroundPage(extension)); | |
2633 extension_runtime_data_[extension->id()].background_page_ready = true; | |
2634 } | |
2635 | |
2636 bool ExtensionService::IsBeingUpgraded(const Extension* extension) const { | |
2637 ExtensionRuntimeDataMap::const_iterator it = | |
2638 extension_runtime_data_.find(extension->id()); | |
2639 return it == extension_runtime_data_.end() ? false : | |
2640 it->second.being_upgraded; | |
2641 } | |
2642 | |
2643 void ExtensionService::SetBeingUpgraded(const Extension* extension, | |
2644 bool value) { | |
2645 extension_runtime_data_[extension->id()].being_upgraded = value; | |
2646 } | |
2647 | |
2648 bool ExtensionService::IsBeingReloaded( | 2604 bool ExtensionService::IsBeingReloaded( |
2649 const std::string& extension_id) const { | 2605 const std::string& extension_id) const { |
2650 return ContainsKey(extensions_being_reloaded_, extension_id); | 2606 return ContainsKey(extensions_being_reloaded_, extension_id); |
2651 } | 2607 } |
2652 | 2608 |
2653 void ExtensionService::SetBeingReloaded(const std::string& extension_id, | 2609 void ExtensionService::SetBeingReloaded(const std::string& extension_id, |
2654 bool isBeingReloaded) { | 2610 bool isBeingReloaded) { |
2655 if (isBeingReloaded) | 2611 if (isBeingReloaded) |
2656 extensions_being_reloaded_.insert(extension_id); | 2612 extensions_being_reloaded_.insert(extension_id); |
2657 else | 2613 else |
2658 extensions_being_reloaded_.erase(extension_id); | 2614 extensions_being_reloaded_.erase(extension_id); |
2659 } | 2615 } |
2660 | 2616 |
2661 bool ExtensionService::HasUsedWebRequest(const Extension* extension) const { | |
2662 ExtensionRuntimeDataMap::const_iterator it = | |
2663 extension_runtime_data_.find(extension->id()); | |
2664 return it == extension_runtime_data_.end() ? false : | |
2665 it->second.has_used_webrequest; | |
2666 } | |
2667 | |
2668 void ExtensionService::SetHasUsedWebRequest(const Extension* extension, | |
2669 bool value) { | |
2670 extension_runtime_data_[extension->id()].has_used_webrequest = value; | |
2671 } | |
2672 | |
2673 bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { | 2617 bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { |
2674 // Extensions installed by policy can't be disabled. So even if a previous | 2618 // Extensions installed by policy can't be disabled. So even if a previous |
2675 // installation disabled the extension, make sure it is now enabled. | 2619 // installation disabled the extension, make sure it is now enabled. |
2676 if (system_->management_policy()->MustRemainEnabled(extension, NULL)) | 2620 if (system_->management_policy()->MustRemainEnabled(extension, NULL)) |
2677 return true; | 2621 return true; |
2678 | 2622 |
2679 if (extension_prefs_->IsExtensionDisabled(extension->id())) | 2623 if (extension_prefs_->IsExtensionDisabled(extension->id())) |
2680 return false; | 2624 return false; |
2681 | 2625 |
2682 if (FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) { | 2626 if (FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2815 void ExtensionService::RemoveUpdateObserver( | 2759 void ExtensionService::RemoveUpdateObserver( |
2816 extensions::UpdateObserver* observer) { | 2760 extensions::UpdateObserver* observer) { |
2817 update_observers_.RemoveObserver(observer); | 2761 update_observers_.RemoveObserver(observer); |
2818 } | 2762 } |
2819 | 2763 |
2820 // Used only by test code. | 2764 // Used only by test code. |
2821 void ExtensionService::UnloadAllExtensionsInternal() { | 2765 void ExtensionService::UnloadAllExtensionsInternal() { |
2822 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); | 2766 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); |
2823 | 2767 |
2824 registry_->ClearAll(); | 2768 registry_->ClearAll(); |
2825 extension_runtime_data_.clear(); | 2769 system_->runtime_data()->ClearAll(); |
2826 | 2770 |
2827 // TODO(erikkay) should there be a notification for this? We can't use | 2771 // TODO(erikkay) should there be a notification for this? We can't use |
2828 // EXTENSION_UNLOADED since that implies that the extension has been disabled | 2772 // EXTENSION_UNLOADED since that implies that the extension has been disabled |
2829 // or uninstalled. | 2773 // or uninstalled. |
2830 } | 2774 } |
OLD | NEW |