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