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 "chrome/browser/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "chrome/browser/extensions/extension_web_ui.h" | 46 #include "chrome/browser/extensions/extension_web_ui.h" |
47 #include "chrome/browser/extensions/extension_webnavigation_api.h" | 47 #include "chrome/browser/extensions/extension_webnavigation_api.h" |
48 #include "chrome/browser/extensions/external_extension_provider_impl.h" | 48 #include "chrome/browser/extensions/external_extension_provider_impl.h" |
49 #include "chrome/browser/extensions/external_extension_provider_interface.h" | 49 #include "chrome/browser/extensions/external_extension_provider_interface.h" |
50 #include "chrome/browser/extensions/pending_extension_manager.h" | 50 #include "chrome/browser/extensions/pending_extension_manager.h" |
51 #include "chrome/browser/net/chrome_url_request_context.h" | 51 #include "chrome/browser/net/chrome_url_request_context.h" |
52 #include "chrome/browser/prefs/pref_service.h" | 52 #include "chrome/browser/prefs/pref_service.h" |
53 #include "chrome/browser/profiles/profile.h" | 53 #include "chrome/browser/profiles/profile.h" |
54 #include "chrome/browser/search_engines/template_url_service.h" | 54 #include "chrome/browser/search_engines/template_url_service.h" |
55 #include "chrome/browser/search_engines/template_url_service_factory.h" | 55 #include "chrome/browser/search_engines/template_url_service_factory.h" |
56 #include "chrome/browser/sync/api/sync_change.h" | |
57 #include "chrome/browser/themes/theme_service.h" | 56 #include "chrome/browser/themes/theme_service.h" |
58 #include "chrome/browser/themes/theme_service_factory.h" | 57 #include "chrome/browser/themes/theme_service_factory.h" |
59 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" | 58 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" |
60 #include "chrome/browser/ui/webui/favicon_source.h" | 59 #include "chrome/browser/ui/webui/favicon_source.h" |
61 #include "chrome/browser/ui/webui/ntp/shown_sections_handler.h" | 60 #include "chrome/browser/ui/webui/ntp/shown_sections_handler.h" |
62 #include "chrome/common/child_process_logging.h" | 61 #include "chrome/common/child_process_logging.h" |
63 #include "chrome/common/chrome_notification_types.h" | 62 #include "chrome/common/chrome_notification_types.h" |
64 #include "chrome/common/chrome_paths.h" | 63 #include "chrome/common/chrome_paths.h" |
65 #include "chrome/common/chrome_switches.h" | 64 #include "chrome/common/chrome_switches.h" |
66 #include "chrome/common/extensions/extension.h" | 65 #include "chrome/common/extensions/extension.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 return NOT_NEEDED; | 144 return NOT_NEEDED; |
146 } | 145 } |
147 | 146 |
148 static void ForceShutdownPlugin(const FilePath& plugin_path) { | 147 static void ForceShutdownPlugin(const FilePath& plugin_path) { |
149 PluginProcessHost* plugin = | 148 PluginProcessHost* plugin = |
150 PluginService::GetInstance()->FindNpapiPluginProcess(plugin_path); | 149 PluginService::GetInstance()->FindNpapiPluginProcess(plugin_path); |
151 if (plugin) | 150 if (plugin) |
152 plugin->ForceShutdown(); | 151 plugin->ForceShutdown(); |
153 } | 152 } |
154 | 153 |
155 static bool IsSyncableExtension(const Extension& extension) { | |
156 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION; | |
157 } | |
158 | |
159 static bool IsSyncableApp(const Extension& extension) { | |
160 return extension.GetSyncType() == Extension::SYNC_TYPE_APP; | |
161 } | |
162 | |
163 // Manages an ExtensionInstallUI for a particular extension. | 154 // Manages an ExtensionInstallUI for a particular extension. |
164 class SimpleExtensionLoadPrompt : public ExtensionInstallUI::Delegate { | 155 class SimpleExtensionLoadPrompt : public ExtensionInstallUI::Delegate { |
165 public: | 156 public: |
166 SimpleExtensionLoadPrompt(Profile* profile, | 157 SimpleExtensionLoadPrompt(Profile* profile, |
167 base::WeakPtr<ExtensionService> extension_service, | 158 base::WeakPtr<ExtensionService> extension_service, |
168 const Extension* extension); | 159 const Extension* extension); |
169 ~SimpleExtensionLoadPrompt(); | 160 ~SimpleExtensionLoadPrompt(); |
170 | 161 |
171 void ShowPrompt(); | 162 void ShowPrompt(); |
172 | 163 |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 const Extension* ExtensionService::GetInstalledAppForRenderer( | 510 const Extension* ExtensionService::GetInstalledAppForRenderer( |
520 int renderer_child_id) { | 511 int renderer_child_id) { |
521 InstalledAppMap::iterator i = installed_app_hosts_.find(renderer_child_id); | 512 InstalledAppMap::iterator i = installed_app_hosts_.find(renderer_child_id); |
522 if (i == installed_app_hosts_.end()) | 513 if (i == installed_app_hosts_.end()) |
523 return NULL; | 514 return NULL; |
524 return i->second; | 515 return i->second; |
525 } | 516 } |
526 | 517 |
527 // static | 518 // static |
528 // This function is used to implement the command-line switch | 519 // This function is used to implement the command-line switch |
529 // --uninstall-extension, and to uninstall an extension via sync. The LOG | 520 // --uninstall-extension. The LOG statements within this function are used to |
530 // statements within this function are used to inform the user if the uninstall | 521 // inform the user if the uninstall cannot be done. |
531 // cannot be done. | |
532 bool ExtensionService::UninstallExtensionHelper( | 522 bool ExtensionService::UninstallExtensionHelper( |
533 ExtensionService* extensions_service, | 523 ExtensionService* extensions_service, |
534 const std::string& extension_id) { | 524 const std::string& extension_id) { |
535 | 525 |
536 const Extension* extension = | 526 const Extension* extension = |
537 extensions_service->GetInstalledExtension(extension_id); | 527 extensions_service->GetInstalledExtension(extension_id); |
538 | 528 |
539 // We can't call UninstallExtension with an invalid extension ID. | 529 // We can't call UninstallExtension with an invalid extension ID. |
540 if (!extension) { | 530 if (!extension) { |
541 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " | 531 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 NotificationService::current()->Notify( | 848 NotificationService::current()->Notify( |
859 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, | 849 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, |
860 Source<Profile>(profile_), | 850 Source<Profile>(profile_), |
861 Details<const Extension>(extension)); | 851 Details<const Extension>(extension)); |
862 if (error != NULL) { | 852 if (error != NULL) { |
863 *error = errors::kCannotUninstallManagedExtension; | 853 *error = errors::kCannotUninstallManagedExtension; |
864 } | 854 } |
865 return false; | 855 return false; |
866 } | 856 } |
867 | 857 |
868 // Extract the data we need for sync now, but don't actually sync until we've | |
869 // completed the uninstallation. | |
870 SyncBundle* sync_bundle = GetSyncBundleForExtension(*extension); | |
871 | |
872 SyncChange sync_change; | |
873 if (sync_bundle) { | |
874 ExtensionSyncData extension_sync_data(*extension, | |
875 IsExtensionEnabled(extension_id), | |
876 IsIncognitoEnabled(extension_id)); | |
877 sync_change = extension_sync_data.GetSyncChange(SyncChange::ACTION_DELETE); | |
878 } | |
879 | |
880 UninstalledExtensionInfo uninstalled_extension_info(*extension); | 858 UninstalledExtensionInfo uninstalled_extension_info(*extension); |
881 | 859 |
882 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", | 860 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", |
883 extension->GetType(), 100); | 861 extension->GetType(), 100); |
884 RecordPermissionMessagesHistogram( | 862 RecordPermissionMessagesHistogram( |
885 extension, "Extensions.Permissions_Uninstall"); | 863 extension, "Extensions.Permissions_Uninstall"); |
886 | 864 |
887 TemplateURLService* url_service = | 865 TemplateURLService* url_service = |
888 TemplateURLServiceFactory::GetForProfile(profile_); | 866 TemplateURLServiceFactory::GetForProfile(profile_); |
889 if (url_service) | 867 if (url_service) |
(...skipping 19 matching lines...) Expand all Loading... |
909 | 887 |
910 ClearExtensionData(extension_url); | 888 ClearExtensionData(extension_url); |
911 UntrackTerminatedExtension(extension_id); | 889 UntrackTerminatedExtension(extension_id); |
912 | 890 |
913 // Notify interested parties that we've uninstalled this extension. | 891 // Notify interested parties that we've uninstalled this extension. |
914 NotificationService::current()->Notify( | 892 NotificationService::current()->Notify( |
915 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | 893 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, |
916 Source<Profile>(profile_), | 894 Source<Profile>(profile_), |
917 Details<UninstalledExtensionInfo>(&uninstalled_extension_info)); | 895 Details<UninstalledExtensionInfo>(&uninstalled_extension_info)); |
918 | 896 |
919 if (sync_bundle && sync_bundle->HasExtensionId(extension_id)) { | |
920 sync_bundle->sync_processor->ProcessSyncChanges( | |
921 FROM_HERE, SyncChangeList(1, sync_change)); | |
922 sync_bundle->synced_extensions.erase(extension_id); | |
923 } | |
924 | |
925 return true; | 897 return true; |
926 } | 898 } |
927 | 899 |
928 void ExtensionService::ClearExtensionData(const GURL& extension_url) { | 900 void ExtensionService::ClearExtensionData(const GURL& extension_url) { |
929 scoped_refptr<ExtensionDataDeleter> deleter( | 901 scoped_refptr<ExtensionDataDeleter> deleter( |
930 new ExtensionDataDeleter(profile_, extension_url)); | 902 new ExtensionDataDeleter(profile_, extension_url)); |
931 deleter->StartDeleting(); | 903 deleter->StartDeleting(); |
932 } | 904 } |
933 | 905 |
934 bool ExtensionService::IsExtensionEnabled( | 906 bool ExtensionService::IsExtensionEnabled( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 extensions_.push_back(make_scoped_refptr(extension)); | 945 extensions_.push_back(make_scoped_refptr(extension)); |
974 ExtensionList::iterator iter = std::find(disabled_extensions_.begin(), | 946 ExtensionList::iterator iter = std::find(disabled_extensions_.begin(), |
975 disabled_extensions_.end(), | 947 disabled_extensions_.end(), |
976 extension); | 948 extension); |
977 disabled_extensions_.erase(iter); | 949 disabled_extensions_.erase(iter); |
978 | 950 |
979 // Make sure any browser action contained within it is not hidden. | 951 // Make sure any browser action contained within it is not hidden. |
980 extension_prefs_->SetBrowserActionVisibility(extension, true); | 952 extension_prefs_->SetBrowserActionVisibility(extension, true); |
981 | 953 |
982 NotifyExtensionLoaded(extension); | 954 NotifyExtensionLoaded(extension); |
983 | |
984 SyncExtensionChangeIfNeeded(*extension); | |
985 } | 955 } |
986 | 956 |
987 void ExtensionService::DisableExtension(const std::string& extension_id) { | 957 void ExtensionService::DisableExtension(const std::string& extension_id) { |
988 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 958 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
989 | 959 |
990 // The extension may have been disabled already. | 960 // The extension may have been disabled already. |
991 if (!IsExtensionEnabled(extension_id)) | 961 if (!IsExtensionEnabled(extension_id)) |
992 return; | 962 return; |
993 | 963 |
994 const Extension* extension = GetInstalledExtension(extension_id); | 964 const Extension* extension = GetInstalledExtension(extension_id); |
(...skipping 16 matching lines...) Expand all Loading... |
1011 if (iter != extensions_.end()) { | 981 if (iter != extensions_.end()) { |
1012 extensions_.erase(iter); | 982 extensions_.erase(iter); |
1013 } else { | 983 } else { |
1014 iter = std::find(terminated_extensions_.begin(), | 984 iter = std::find(terminated_extensions_.begin(), |
1015 terminated_extensions_.end(), | 985 terminated_extensions_.end(), |
1016 extension); | 986 extension); |
1017 terminated_extensions_.erase(iter); | 987 terminated_extensions_.erase(iter); |
1018 } | 988 } |
1019 | 989 |
1020 NotifyExtensionUnloaded(extension, extension_misc::UNLOAD_REASON_DISABLE); | 990 NotifyExtensionUnloaded(extension, extension_misc::UNLOAD_REASON_DISABLE); |
1021 | |
1022 SyncExtensionChangeIfNeeded(*extension); | |
1023 } | 991 } |
1024 | 992 |
1025 void ExtensionService::GrantPermissions(const Extension* extension) { | 993 void ExtensionService::GrantPermissions(const Extension* extension) { |
1026 CHECK(extension); | 994 CHECK(extension); |
1027 | 995 |
1028 // We only maintain the granted permissions prefs for extensions that can't | 996 // We only maintain the granted permissions prefs for extensions that can't |
1029 // silently increase their permissions. | 997 // silently increase their permissions. |
1030 if (extension->CanSilentlyIncreasePermissions()) | 998 if (extension->CanSilentlyIncreasePermissions()) |
1031 return; | 999 return; |
1032 | 1000 |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 } | 1613 } |
1646 | 1614 |
1647 void ExtensionService::CheckForUpdatesSoon() { | 1615 void ExtensionService::CheckForUpdatesSoon() { |
1648 if (updater()) { | 1616 if (updater()) { |
1649 updater()->CheckSoon(); | 1617 updater()->CheckSoon(); |
1650 } else { | 1618 } else { |
1651 LOG(WARNING) << "CheckForUpdatesSoon() called with auto-update turned off"; | 1619 LOG(WARNING) << "CheckForUpdatesSoon() called with auto-update turned off"; |
1652 } | 1620 } |
1653 } | 1621 } |
1654 | 1622 |
1655 namespace { | 1623 ExtensionSyncData ExtensionService::GetSyncDataHelper( |
1656 bool IsSyncableNone(const Extension& extension) { return false; } | 1624 const Extension& extension) const { |
1657 } // namespace | 1625 const std::string& id = extension.id(); |
1658 | 1626 ExtensionSyncData data; |
1659 ExtensionService::SyncBundle::SyncBundle() | 1627 data.id = id; |
1660 : filter(IsSyncableNone), | 1628 data.uninstalled = false; |
1661 sync_processor(NULL) { | 1629 data.enabled = IsExtensionEnabled(id); |
| 1630 data.incognito_enabled = IsIncognitoEnabled(id); |
| 1631 data.version = *extension.version(); |
| 1632 data.update_url = extension.update_url(); |
| 1633 data.name = extension.name(); |
| 1634 return data; |
1662 } | 1635 } |
1663 | 1636 |
1664 ExtensionService::SyncBundle::~SyncBundle() { | 1637 bool ExtensionService::GetSyncData( |
1665 } | 1638 const Extension& extension, |
1666 | 1639 ExtensionFilter filter, |
1667 bool ExtensionService::SyncBundle::HasExtensionId(const std::string& id) const { | 1640 ExtensionSyncData* extension_sync_data) const { |
1668 return synced_extensions.find(id) != synced_extensions.end(); | 1641 if (!(*filter)(extension)) { |
1669 } | 1642 return false; |
1670 | |
1671 bool ExtensionService::SyncBundle::HasPendingExtensionId(const std::string& id) | |
1672 const { | |
1673 return pending_sync_data.find(id) != pending_sync_data.end(); | |
1674 } | |
1675 | |
1676 void ExtensionService::SyncExtensionChangeIfNeeded(const Extension& extension) { | |
1677 SyncBundle* sync_bundle = GetSyncBundleForExtension(extension); | |
1678 if (sync_bundle) { | |
1679 ExtensionSyncData extension_sync_data(extension, | |
1680 IsExtensionEnabled(extension.id()), | |
1681 IsIncognitoEnabled(extension.id())); | |
1682 | |
1683 SyncChangeList sync_change_list(1, extension_sync_data.GetSyncChange( | |
1684 sync_bundle->HasExtensionId(extension.id()) ? | |
1685 SyncChange::ACTION_UPDATE : SyncChange::ACTION_ADD)); | |
1686 sync_bundle->sync_processor->ProcessSyncChanges( | |
1687 FROM_HERE, sync_change_list); | |
1688 sync_bundle->synced_extensions.insert(extension.id()); | |
1689 sync_bundle->pending_sync_data.erase(extension.id()); | |
1690 } | 1643 } |
1691 } | 1644 *extension_sync_data = GetSyncDataHelper(extension); |
1692 | 1645 return true; |
1693 ExtensionService::SyncBundle* ExtensionService::GetSyncBundleForExtension( | |
1694 const Extension& extension) { | |
1695 if (app_sync_bundle_.filter(extension)) | |
1696 return &app_sync_bundle_; | |
1697 else if (extension_sync_bundle_.filter(extension)) | |
1698 return &extension_sync_bundle_; | |
1699 else | |
1700 return NULL; | |
1701 } | |
1702 | |
1703 ExtensionService::SyncBundle* | |
1704 ExtensionService::GetSyncBundleForExtensionSyncData( | |
1705 const ExtensionSyncData& extension_sync_data) { | |
1706 switch (extension_sync_data.type()) { | |
1707 case Extension::SYNC_TYPE_APP: | |
1708 return &app_sync_bundle_; | |
1709 case Extension::SYNC_TYPE_EXTENSION: | |
1710 return &extension_sync_bundle_; | |
1711 default: | |
1712 NOTREACHED(); | |
1713 return NULL; | |
1714 } | |
1715 } | |
1716 | |
1717 #define GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY() \ | |
1718 do { \ | |
1719 switch (type) { \ | |
1720 case syncable::APPS: \ | |
1721 return &app_sync_bundle_; \ | |
1722 case syncable::EXTENSIONS: \ | |
1723 return &extension_sync_bundle_; \ | |
1724 default: \ | |
1725 NOTREACHED(); \ | |
1726 return NULL; \ | |
1727 } \ | |
1728 } while (0) | |
1729 | |
1730 const ExtensionService::SyncBundle* | |
1731 ExtensionService::GetSyncBundleForModelTypeConst( | |
1732 syncable::ModelType type) const { | |
1733 GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY(); | |
1734 } | |
1735 | |
1736 ExtensionService::SyncBundle* ExtensionService::GetSyncBundleForModelType( | |
1737 syncable::ModelType type) { | |
1738 GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY(); | |
1739 } | |
1740 | |
1741 #undef GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY | |
1742 | |
1743 SyncError ExtensionService::MergeDataAndStartSyncing( | |
1744 syncable::ModelType type, | |
1745 const SyncDataList& initial_sync_data, | |
1746 SyncChangeProcessor* sync_processor) { | |
1747 CHECK(sync_processor); | |
1748 | |
1749 SyncBundle* bundle = NULL; | |
1750 | |
1751 switch (type) { | |
1752 case syncable::EXTENSIONS: | |
1753 bundle = &extension_sync_bundle_; | |
1754 bundle->filter = IsSyncableExtension; | |
1755 break; | |
1756 | |
1757 case syncable::APPS: | |
1758 bundle = &app_sync_bundle_; | |
1759 bundle->filter = IsSyncableApp; | |
1760 break; | |
1761 | |
1762 default: | |
1763 LOG(FATAL) << "Got " << type << " ModelType"; | |
1764 } | |
1765 | |
1766 bundle->sync_processor = sync_processor; | |
1767 | |
1768 for (SyncDataList::const_iterator i = initial_sync_data.begin(); | |
1769 i != initial_sync_data.end(); | |
1770 ++i) { | |
1771 ExtensionSyncData extension_sync_data = ExtensionSyncData(*i); | |
1772 bundle->synced_extensions.insert(extension_sync_data.id()); | |
1773 ProcessExtensionSyncData(extension_sync_data, *bundle); | |
1774 } | |
1775 | |
1776 SyncDataList sync_data_list = GetAllSyncData(type); | |
1777 SyncChangeList sync_change_list; | |
1778 for (SyncDataList::const_iterator i = sync_data_list.begin(); | |
1779 i != sync_data_list.end(); | |
1780 ++i) { | |
1781 if (bundle->HasExtensionId(i->GetTag())) | |
1782 sync_change_list.push_back(SyncChange(SyncChange::ACTION_UPDATE, *i)); | |
1783 else | |
1784 sync_change_list.push_back(SyncChange(SyncChange::ACTION_ADD, *i)); | |
1785 } | |
1786 bundle->sync_processor->ProcessSyncChanges(FROM_HERE, sync_change_list); | |
1787 | |
1788 return SyncError(); | |
1789 } | |
1790 | |
1791 void ExtensionService::StopSyncing(syncable::ModelType type) { | |
1792 SyncBundle* bundle = GetSyncBundleForModelType(type); | |
1793 CHECK(bundle); | |
1794 // This is the simplest way to clear out the bundle. | |
1795 *bundle = SyncBundle(); | |
1796 } | |
1797 | |
1798 SyncDataList ExtensionService::GetAllSyncData(syncable::ModelType type) const { | |
1799 const SyncBundle* bundle = GetSyncBundleForModelTypeConst(type); | |
1800 CHECK(bundle); | |
1801 std::vector<ExtensionSyncData> extension_sync_data = GetSyncDataList(*bundle); | |
1802 SyncDataList result(extension_sync_data.size()); | |
1803 for (int i = 0; i < static_cast<int>(extension_sync_data.size()); ++i) { | |
1804 result[i] = extension_sync_data[i].GetSyncData(); | |
1805 } | |
1806 return result; | |
1807 } | |
1808 | |
1809 SyncError ExtensionService::ProcessSyncChanges( | |
1810 const tracked_objects::Location& from_here, | |
1811 const SyncChangeList& change_list) { | |
1812 for (SyncChangeList::const_iterator i = change_list.begin(); | |
1813 i != change_list.end(); | |
1814 ++i) { | |
1815 ExtensionSyncData extension_sync_data = ExtensionSyncData(*i); | |
1816 SyncBundle* bundle = GetSyncBundleForExtensionSyncData(extension_sync_data); | |
1817 CHECK(bundle); | |
1818 | |
1819 if (extension_sync_data.uninstalled()) | |
1820 bundle->synced_extensions.erase(extension_sync_data.id()); | |
1821 else | |
1822 bundle->synced_extensions.insert(extension_sync_data.id()); | |
1823 ProcessExtensionSyncData(extension_sync_data, *bundle); | |
1824 } | |
1825 | |
1826 return SyncError(); | |
1827 } | 1646 } |
1828 | 1647 |
1829 void ExtensionService::GetSyncDataListHelper( | 1648 void ExtensionService::GetSyncDataListHelper( |
1830 const ExtensionList& extensions, | 1649 const ExtensionList& extensions, |
1831 const SyncBundle& bundle, | 1650 ExtensionFilter filter, |
1832 std::vector<ExtensionSyncData>* sync_data_list) const { | 1651 std::vector<ExtensionSyncData>* sync_data_list) const { |
1833 for (ExtensionList::const_iterator it = extensions.begin(); | 1652 for (ExtensionList::const_iterator it = extensions.begin(); |
1834 it != extensions.end(); ++it) { | 1653 it != extensions.end(); ++it) { |
1835 const Extension& extension = **it; | 1654 const Extension& extension = **it; |
1836 if (bundle.filter(extension) && | 1655 if ((*filter)(extension)) { |
1837 // If we have pending extension data for this extension, then this | 1656 sync_data_list->push_back(GetSyncDataHelper(extension)); |
1838 // version is out of date. We'll sync back the version we got from | |
1839 // sync. | |
1840 !bundle.HasPendingExtensionId(extension.id())) { | |
1841 sync_data_list->push_back( | |
1842 ExtensionSyncData(extension, | |
1843 IsExtensionEnabled(extension.id()), | |
1844 IsIncognitoEnabled(extension.id()))); | |
1845 } | 1657 } |
1846 } | 1658 } |
1847 } | 1659 } |
1848 | 1660 |
1849 std::vector<ExtensionSyncData> ExtensionService::GetSyncDataList( | 1661 std::vector<ExtensionSyncData> ExtensionService::GetSyncDataList( |
1850 const SyncBundle& bundle) const { | 1662 ExtensionFilter filter) const { |
1851 std::vector<ExtensionSyncData> extension_sync_list; | 1663 std::vector<ExtensionSyncData> sync_data_list; |
1852 GetSyncDataListHelper(extensions_, bundle, &extension_sync_list); | 1664 GetSyncDataListHelper(extensions_, filter, &sync_data_list); |
1853 GetSyncDataListHelper(disabled_extensions_, bundle, &extension_sync_list); | 1665 GetSyncDataListHelper(disabled_extensions_, filter, &sync_data_list); |
1854 GetSyncDataListHelper(terminated_extensions_, bundle, &extension_sync_list); | 1666 GetSyncDataListHelper(terminated_extensions_, filter, &sync_data_list); |
1855 | 1667 return sync_data_list; |
1856 for (std::map<std::string, ExtensionSyncData>::const_iterator i = | |
1857 bundle.pending_sync_data.begin(); | |
1858 i != bundle.pending_sync_data.end(); | |
1859 ++i) { | |
1860 extension_sync_list.push_back(i->second); | |
1861 } | |
1862 | |
1863 return extension_sync_list; | |
1864 } | 1668 } |
1865 | 1669 |
1866 void ExtensionService::ProcessExtensionSyncData( | 1670 void ExtensionService::ProcessSyncData( |
1867 const ExtensionSyncData& extension_sync_data, | 1671 const ExtensionSyncData& extension_sync_data, |
1868 SyncBundle& bundle) { | 1672 ExtensionFilter filter) { |
1869 const std::string& id = extension_sync_data.id(); | 1673 const std::string& id = extension_sync_data.id; |
1870 | 1674 |
1871 // Handle uninstalls first. | 1675 // Handle uninstalls first. |
1872 if (extension_sync_data.uninstalled()) { | 1676 if (extension_sync_data.uninstalled) { |
1873 std::string error; | 1677 std::string error; |
1874 if (!UninstallExtensionHelper(this, id)) { | 1678 if (!UninstallExtensionHelper(this, id)) { |
1875 LOG(WARNING) << "Could not uninstall extension " << id | 1679 LOG(WARNING) << "Could not uninstall extension " << id |
1876 << " for sync"; | 1680 << " for sync"; |
1877 } | 1681 } |
1878 return; | 1682 return; |
1879 } | 1683 } |
1880 | 1684 |
1881 // Set user settings. | 1685 // Set user settings. |
1882 if (extension_sync_data.enabled()) { | 1686 if (extension_sync_data.enabled) { |
1883 EnableExtension(id); | 1687 EnableExtension(id); |
1884 } else { | 1688 } else { |
1885 DisableExtension(id); | 1689 DisableExtension(id); |
1886 } | 1690 } |
1887 SetIsIncognitoEnabled(id, extension_sync_data.incognito_enabled()); | 1691 SetIsIncognitoEnabled(id, extension_sync_data.incognito_enabled); |
1888 | 1692 |
1889 const Extension* extension = GetInstalledExtension(id); | 1693 const Extension* extension = GetInstalledExtension(id); |
1890 if (extension) { | 1694 if (extension) { |
1891 // If the extension is already installed, check if it's outdated. | 1695 // If the extension is already installed, check if it's outdated. |
1892 int result = extension->version()->CompareTo(extension_sync_data.version()); | 1696 int result = extension->version()->CompareTo(extension_sync_data.version); |
1893 if (result < 0) { | 1697 if (result < 0) { |
1894 // Extension is outdated. | 1698 // Extension is outdated. |
1895 bundle.pending_sync_data[extension_sync_data.id()] = extension_sync_data; | |
1896 CheckForUpdatesSoon(); | 1699 CheckForUpdatesSoon(); |
| 1700 } else if (result > 0) { |
| 1701 // Sync version is outdated. Do nothing for now, as sync code |
| 1702 // in other places will eventually update the sync data. |
| 1703 // |
| 1704 // TODO(akalin): Move that code here. |
1897 } | 1705 } |
1898 } else { | 1706 } else { |
1899 // TODO(akalin): Replace silent update with a list of enabled | 1707 // TODO(akalin): Replace silent update with a list of enabled |
1900 // permissions. | 1708 // permissions. |
1901 const bool kInstallSilently = true; | 1709 const bool kInstallSilently = true; |
1902 if (!pending_extension_manager()->AddFromSync( | 1710 if (!pending_extension_manager()->AddFromSync( |
1903 id, | 1711 id, |
1904 extension_sync_data.update_url(), | 1712 extension_sync_data.update_url, |
1905 bundle.filter, | 1713 filter, |
1906 kInstallSilently)) { | 1714 kInstallSilently)) { |
1907 LOG(WARNING) << "Could not add pending extension for " << id; | 1715 LOG(WARNING) << "Could not add pending extension for " << id; |
1908 // This means that the extension is already pending installation, with a | 1716 return; |
1909 // non-INTERNAL location. Add to pending_sync_data, even though it will | |
1910 // never be removed (we'll never install a syncable version of the | |
1911 // extension), so that GetAllSyncData() continues to send it. | |
1912 } | 1717 } |
1913 // Track pending extensions so that we can return them in GetAllSyncData(). | |
1914 bundle.pending_sync_data[extension_sync_data.id()] = extension_sync_data; | |
1915 CheckForUpdatesSoon(); | 1718 CheckForUpdatesSoon(); |
1916 } | 1719 } |
1917 } | 1720 } |
1918 | 1721 |
1919 bool ExtensionService::IsIncognitoEnabled( | 1722 bool ExtensionService::IsIncognitoEnabled( |
1920 const std::string& extension_id) const { | 1723 const std::string& extension_id) const { |
1921 // If this is an existing component extension we always allow it to | 1724 // If this is an existing component extension we always allow it to |
1922 // work in incognito mode. | 1725 // work in incognito mode. |
1923 const Extension* extension = GetInstalledExtension(extension_id); | 1726 const Extension* extension = GetInstalledExtension(extension_id); |
1924 if (extension && extension->location() == Extension::COMPONENT) | 1727 if (extension && extension->location() == Extension::COMPONENT) |
(...skipping 22 matching lines...) Expand all Loading... |
1947 extension_prefs_->SetIsIncognitoEnabled(extension_id, enabled); | 1750 extension_prefs_->SetIsIncognitoEnabled(extension_id, enabled); |
1948 | 1751 |
1949 // If the extension is enabled (and not terminated), unload and | 1752 // If the extension is enabled (and not terminated), unload and |
1950 // reload it to update UI. | 1753 // reload it to update UI. |
1951 const Extension* enabled_extension = GetExtensionById(extension_id, false); | 1754 const Extension* enabled_extension = GetExtensionById(extension_id, false); |
1952 if (enabled_extension) { | 1755 if (enabled_extension) { |
1953 NotifyExtensionUnloaded( | 1756 NotifyExtensionUnloaded( |
1954 enabled_extension, extension_misc::UNLOAD_REASON_DISABLE); | 1757 enabled_extension, extension_misc::UNLOAD_REASON_DISABLE); |
1955 NotifyExtensionLoaded(enabled_extension); | 1758 NotifyExtensionLoaded(enabled_extension); |
1956 } | 1759 } |
1957 | |
1958 if (extension) | |
1959 SyncExtensionChangeIfNeeded(*extension); | |
1960 } | 1760 } |
1961 | 1761 |
1962 bool ExtensionService::CanCrossIncognito(const Extension* extension) { | 1762 bool ExtensionService::CanCrossIncognito(const Extension* extension) { |
1963 // We allow the extension to see events and data from another profile iff it | 1763 // We allow the extension to see events and data from another profile iff it |
1964 // uses "spanning" behavior and it has incognito access. "split" mode | 1764 // uses "spanning" behavior and it has incognito access. "split" mode |
1965 // extensions only see events for a matching profile. | 1765 // extensions only see events for a matching profile. |
1966 return IsIncognitoEnabled(extension->id()) && | 1766 return IsIncognitoEnabled(extension->id()) && |
1967 !extension->incognito_split_mode(); | 1767 !extension->incognito_split_mode(); |
1968 } | 1768 } |
1969 | 1769 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 bool disabled = extension_prefs_->IsExtensionDisabled(extension->id()); | 2019 bool disabled = extension_prefs_->IsExtensionDisabled(extension->id()); |
2220 if (disabled) { | 2020 if (disabled) { |
2221 disabled_extensions_.push_back(scoped_extension); | 2021 disabled_extensions_.push_back(scoped_extension); |
2222 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called | 2022 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called |
2223 // with a disabled extension for other reasons other than that an update was | 2023 // with a disabled extension for other reasons other than that an update was |
2224 // disabled. | 2024 // disabled. |
2225 NotificationService::current()->Notify( | 2025 NotificationService::current()->Notify( |
2226 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 2026 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
2227 Source<Profile>(profile_), | 2027 Source<Profile>(profile_), |
2228 Details<const Extension>(extension)); | 2028 Details<const Extension>(extension)); |
2229 SyncExtensionChangeIfNeeded(*extension); | |
2230 return; | 2029 return; |
2231 } | 2030 } |
2232 | 2031 |
2233 extensions_.push_back(scoped_extension); | 2032 extensions_.push_back(scoped_extension); |
2234 SyncExtensionChangeIfNeeded(*extension); | |
2235 NotifyExtensionLoaded(extension); | 2033 NotifyExtensionLoaded(extension); |
2236 } | 2034 } |
2237 | 2035 |
2238 void ExtensionService::InitializePermissions(const Extension* extension) { | 2036 void ExtensionService::InitializePermissions(const Extension* extension) { |
2239 // If the extension has used the optional permissions API, it will have a | 2037 // If the extension has used the optional permissions API, it will have a |
2240 // custom set of active permissions defined in the extension prefs. Here, | 2038 // custom set of active permissions defined in the extension prefs. Here, |
2241 // we update the extension's active permissions based on the prefs. | 2039 // we update the extension's active permissions based on the prefs. |
2242 scoped_refptr<ExtensionPermissionSet> active_permissions = | 2040 scoped_refptr<ExtensionPermissionSet> active_permissions = |
2243 extension_prefs()->GetActivePermissions(extension->id()); | 2041 extension_prefs()->GetActivePermissions(extension->id()); |
2244 | 2042 |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2811 | 2609 |
2812 ExtensionService::NaClModuleInfoList::iterator | 2610 ExtensionService::NaClModuleInfoList::iterator |
2813 ExtensionService::FindNaClModule(const GURL& url) { | 2611 ExtensionService::FindNaClModule(const GURL& url) { |
2814 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); | 2612 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); |
2815 iter != nacl_module_list_.end(); ++iter) { | 2613 iter != nacl_module_list_.end(); ++iter) { |
2816 if (iter->url == url) | 2614 if (iter->url == url) |
2817 return iter; | 2615 return iter; |
2818 } | 2616 } |
2819 return nacl_module_list_.end(); | 2617 return nacl_module_list_.end(); |
2820 } | 2618 } |
OLD | NEW |