Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/extensions_service.h" | 5 #include "chrome/browser/extensions/extensions_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 | 622 |
| 623 // TODO(erikkay) this should probably be deferred as well. | 623 // TODO(erikkay) this should probably be deferred as well. |
| 624 GarbageCollectExtensions(); | 624 GarbageCollectExtensions(); |
| 625 } | 625 } |
| 626 | 626 |
| 627 void ExtensionsService::InstallExtension(const FilePath& extension_path) { | 627 void ExtensionsService::InstallExtension(const FilePath& extension_path) { |
| 628 scoped_refptr<CrxInstaller> installer( | 628 scoped_refptr<CrxInstaller> installer( |
| 629 new CrxInstaller(install_directory_, | 629 new CrxInstaller(install_directory_, |
| 630 this, // frontend | 630 this, // frontend |
| 631 NULL)); // no client (silent install) | 631 NULL)); // no client (silent install) |
| 632 installer->set_allow_privilege_increase(true); | 632 installer->set_allow_privilege_increase(false); |
| 633 installer->InstallCrx(extension_path); | 633 installer->InstallCrx(extension_path); |
| 634 } | 634 } |
| 635 | 635 |
| 636 namespace { | 636 namespace { |
| 637 // TODO(akalin): Put this somewhere where both crx_installer.cc and | 637 // TODO(akalin): Put this somewhere where both crx_installer.cc and |
| 638 // this file can use it. | 638 // this file can use it. |
| 639 void DeleteFileHelper(const FilePath& path, bool recursive) { | 639 void DeleteFileHelper(const FilePath& path, bool recursive) { |
| 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 641 file_util::Delete(path, recursive); | 641 file_util::Delete(path, recursive); |
| 642 } | 642 } |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 920 extension); | 920 extension); |
| 921 extensions_.erase(iter); | 921 extensions_.erase(iter); |
| 922 | 922 |
| 923 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, | 923 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, |
| 924 extension->GetChromeURLOverrides()); | 924 extension->GetChromeURLOverrides()); |
| 925 | 925 |
| 926 NotifyExtensionUnloaded(extension); | 926 NotifyExtensionUnloaded(extension); |
| 927 UpdateActiveExtensionsInCrashReporter(); | 927 UpdateActiveExtensionsInCrashReporter(); |
| 928 } | 928 } |
| 929 | 929 |
| 930 void ExtensionsService::GrantPermissions(const Extension* extension) { | |
| 931 CHECK(extension); | |
| 932 ExtensionExtent effective_hosts = extension->GetEffectiveHostPermissions(); | |
| 933 extension_prefs_->AddGrantedPermissions(extension->id(), | |
| 934 extension->api_permissions(), | |
| 935 effective_hosts); | |
| 936 } | |
| 937 | |
| 938 void ExtensionsService::GrantPermissionsAndEnableExtension( | |
| 939 const Extension* extension) { | |
| 940 CHECK(extension); | |
| 941 GrantPermissions(extension); | |
| 942 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | |
| 943 EnableExtension(extension->id()); | |
| 944 } | |
| 945 | |
| 930 void ExtensionsService::LoadExtension(const FilePath& extension_path) { | 946 void ExtensionsService::LoadExtension(const FilePath& extension_path) { |
| 931 BrowserThread::PostTask( | 947 BrowserThread::PostTask( |
| 932 BrowserThread::FILE, FROM_HERE, | 948 BrowserThread::FILE, FROM_HERE, |
| 933 NewRunnableMethod( | 949 NewRunnableMethod( |
| 934 backend_.get(), | 950 backend_.get(), |
| 935 &ExtensionsServiceBackend::LoadSingleExtension, | 951 &ExtensionsServiceBackend::LoadSingleExtension, |
| 936 extension_path, scoped_refptr<ExtensionsService>(this))); | 952 extension_path, scoped_refptr<ExtensionsService>(this))); |
| 937 } | 953 } |
| 938 | 954 |
| 939 void ExtensionsService::LoadComponentExtensions() { | 955 void ExtensionsService::LoadComponentExtensions() { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 952 it->root_directory, | 968 it->root_directory, |
| 953 Extension::COMPONENT, | 969 Extension::COMPONENT, |
| 954 *static_cast<DictionaryValue*>(manifest.get()), | 970 *static_cast<DictionaryValue*>(manifest.get()), |
| 955 true, // require key | 971 true, // require key |
| 956 &error)); | 972 &error)); |
| 957 if (!extension.get()) { | 973 if (!extension.get()) { |
| 958 NOTREACHED() << error; | 974 NOTREACHED() << error; |
| 959 return; | 975 return; |
| 960 } | 976 } |
| 961 | 977 |
| 962 OnExtensionLoaded(extension, false); // Don't allow privilege increase. | 978 OnExtensionLoaded(extension, true); |
| 963 } | 979 } |
| 964 } | 980 } |
| 965 | 981 |
| 966 void ExtensionsService::LoadAllExtensions() { | 982 void ExtensionsService::LoadAllExtensions() { |
| 967 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 983 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 968 | 984 |
| 969 base::TimeTicks start_time = base::TimeTicks::Now(); | 985 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 970 | 986 |
| 971 // Load any component extensions. | 987 // Load any component extensions. |
| 972 LoadComponentExtensions(); | 988 LoadComponentExtensions(); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1097 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp", packaged_app_count); | 1113 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp", packaged_app_count); |
| 1098 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension", extension_count); | 1114 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension", extension_count); |
| 1099 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); | 1115 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); |
| 1100 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); | 1116 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); |
| 1101 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExternal", external_count); | 1117 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExternal", external_count); |
| 1102 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); | 1118 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); |
| 1103 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", | 1119 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", |
| 1104 browser_action_count); | 1120 browser_action_count); |
| 1105 } | 1121 } |
| 1106 | 1122 |
| 1107 | |
| 1108 void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info, | 1123 void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info, |
| 1109 bool write_to_prefs) { | 1124 bool write_to_prefs) { |
| 1110 std::string error; | 1125 std::string error; |
| 1111 scoped_refptr<const Extension> extension(NULL); | 1126 scoped_refptr<const Extension> extension(NULL); |
| 1112 if (!extension_prefs_->IsExtensionAllowedByPolicy(info.extension_id)) { | 1127 if (!extension_prefs_->IsExtensionAllowedByPolicy(info.extension_id)) { |
| 1113 error = errors::kDisabledByPolicy; | 1128 error = errors::kDisabledByPolicy; |
| 1114 } else if (info.extension_manifest.get()) { | 1129 } else if (info.extension_manifest.get()) { |
| 1115 bool require_key = info.extension_location != Extension::LOAD; | 1130 bool require_key = info.extension_location != Extension::LOAD; |
| 1116 extension = Extension::Create( | 1131 extension = Extension::Create( |
| 1117 info.extension_path, info.extension_location, *info.extension_manifest, | 1132 info.extension_path, info.extension_location, *info.extension_manifest, |
| 1118 require_key, &error); | 1133 require_key, &error); |
| 1119 } else { | 1134 } else { |
| 1120 error = errors::kManifestUnreadable; | 1135 error = errors::kManifestUnreadable; |
| 1121 } | 1136 } |
| 1122 | 1137 |
| 1123 if (!extension) { | 1138 if (!extension) { |
| 1124 ReportExtensionLoadError(info.extension_path, | 1139 ReportExtensionLoadError(info.extension_path, |
| 1125 error, | 1140 error, |
| 1126 NotificationType::EXTENSION_INSTALL_ERROR, | 1141 NotificationType::EXTENSION_INSTALL_ERROR, |
| 1127 false); | 1142 false); |
| 1128 return; | 1143 return; |
| 1129 } | 1144 } |
| 1130 | 1145 |
| 1131 if (write_to_prefs) | 1146 if (write_to_prefs) |
| 1132 extension_prefs_->UpdateManifest(extension); | 1147 extension_prefs_->UpdateManifest(extension); |
| 1133 | 1148 |
| 1134 OnExtensionLoaded(extension, true); | 1149 // External extensions are allowed to increase their privileges without |
| 1135 | 1150 // prompting users. |
| 1136 if (Extension::IsExternalLocation(info.extension_location)) { | 1151 if (Extension::IsExternalLocation(info.extension_location)) { |
| 1152 OnExtensionLoaded(extension, true); | |
| 1137 BrowserThread::PostTask( | 1153 BrowserThread::PostTask( |
| 1138 BrowserThread::FILE, FROM_HERE, | 1154 BrowserThread::FILE, FROM_HERE, |
| 1139 NewRunnableMethod( | 1155 NewRunnableMethod( |
| 1140 backend_.get(), | 1156 backend_.get(), |
| 1141 &ExtensionsServiceBackend::CheckExternalUninstall, | 1157 &ExtensionsServiceBackend::CheckExternalUninstall, |
| 1142 scoped_refptr<ExtensionsService>(this), | 1158 scoped_refptr<ExtensionsService>(this), |
| 1143 info.extension_id)); | 1159 info.extension_id)); |
| 1160 } else { | |
| 1161 OnExtensionLoaded(extension, false); | |
| 1144 } | 1162 } |
| 1145 } | 1163 } |
| 1146 | 1164 |
| 1147 void ExtensionsService::NotifyExtensionLoaded(const Extension* extension) { | 1165 void ExtensionsService::NotifyExtensionLoaded(const Extension* extension) { |
| 1148 // The ChromeURLRequestContexts need to be first to know that the extension | 1166 // The ChromeURLRequestContexts need to be first to know that the extension |
| 1149 // was loaded, otherwise a race can arise where a renderer that is created | 1167 // was loaded, otherwise a race can arise where a renderer that is created |
| 1150 // for the extension may try to load an extension URL with an extension id | 1168 // for the extension may try to load an extension URL with an extension id |
| 1151 // that the request context doesn't yet know about. The profile is responsible | 1169 // that the request context doesn't yet know about. The profile is responsible |
| 1152 // for ensuring its URLRequestContexts appropriately discover the loaded | 1170 // for ensuring its URLRequestContexts appropriately discover the loaded |
| 1153 // extension. | 1171 // extension. |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1499 // Ensure extension is deleted unless we transfer ownership. | 1517 // Ensure extension is deleted unless we transfer ownership. |
| 1500 scoped_refptr<const Extension> scoped_extension(extension); | 1518 scoped_refptr<const Extension> scoped_extension(extension); |
| 1501 | 1519 |
| 1502 // The extension is now loaded, remove its data from unloaded extension map. | 1520 // The extension is now loaded, remove its data from unloaded extension map. |
| 1503 unloaded_extension_paths_.erase(extension->id()); | 1521 unloaded_extension_paths_.erase(extension->id()); |
| 1504 | 1522 |
| 1505 // If the extension was disabled for a reload, then enable it. | 1523 // If the extension was disabled for a reload, then enable it. |
| 1506 if (disabled_extension_paths_.erase(extension->id()) > 0) | 1524 if (disabled_extension_paths_.erase(extension->id()) > 0) |
| 1507 EnableExtension(extension->id()); | 1525 EnableExtension(extension->id()); |
| 1508 | 1526 |
| 1509 // TODO(aa): Need to re-evaluate this branch. Does this still make sense now | 1527 // Check if the extension's privileges have changed and disable the extension |
| 1510 // that extensions are enabled by default? | 1528 // if necessary. |
| 1511 if (extensions_enabled() || | 1529 DisableIfPrivilegeIncrease(extension, allow_privilege_increase); |
| 1512 extension->is_theme() || | |
| 1513 extension->location() == Extension::LOAD || | |
| 1514 extension->location() == Extension::COMPONENT || | |
| 1515 Extension::IsExternalLocation(extension->location())) { | |
| 1516 const Extension* old = GetExtensionByIdInternal(extension->id(), | |
| 1517 true, true); | |
| 1518 if (old) { | |
| 1519 // CrxInstaller should have guaranteed that we aren't downgrading. | |
| 1520 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); | |
| 1521 | 1530 |
| 1522 bool allow_silent_upgrade = | 1531 switch (extension_prefs_->GetExtensionState(extension->id())) { |
| 1523 allow_privilege_increase || !Extension::IsPrivilegeIncrease( | 1532 case Extension::ENABLED: |
| 1524 old, extension); | 1533 extensions_.push_back(scoped_extension); |
| 1525 | 1534 |
| 1526 // Extensions get upgraded if silent upgrades are allowed, otherwise | 1535 NotifyExtensionLoaded(extension); |
| 1527 // they get disabled. | |
| 1528 if (allow_silent_upgrade) { | |
| 1529 SetBeingUpgraded(old, true); | |
| 1530 SetBeingUpgraded(extension, true); | |
| 1531 } | |
| 1532 | 1536 |
| 1533 // To upgrade an extension in place, unload the old one and | 1537 ExtensionDOMUI::RegisterChromeURLOverrides( |
| 1534 // then load the new one. | 1538 profile_, extension->GetChromeURLOverrides()); |
| 1535 UnloadExtension(old->id()); | 1539 break; |
| 1536 old = NULL; | 1540 case Extension::DISABLED: |
| 1537 | 1541 disabled_extensions_.push_back(scoped_extension); |
| 1538 if (!allow_silent_upgrade) { | 1542 NotificationService::current()->Notify( |
| 1539 // Extension has changed permissions significantly. Disable it. We | 1543 NotificationType::EXTENSION_UPDATE_DISABLED, |
| 1540 // send a notification below. | 1544 Source<Profile>(profile_), |
| 1541 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); | 1545 Details<const Extension>(extension)); |
| 1542 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); | 1546 break; |
| 1543 } | 1547 default: |
| 1544 } | 1548 NOTREACHED(); |
| 1545 | 1549 break; |
| 1546 switch (extension_prefs_->GetExtensionState(extension->id())) { | |
| 1547 case Extension::ENABLED: | |
| 1548 extensions_.push_back(scoped_extension); | |
| 1549 | |
| 1550 NotifyExtensionLoaded(extension); | |
| 1551 | |
| 1552 ExtensionDOMUI::RegisterChromeURLOverrides(profile_, | |
| 1553 extension->GetChromeURLOverrides()); | |
| 1554 break; | |
| 1555 case Extension::DISABLED: | |
| 1556 disabled_extensions_.push_back(scoped_extension); | |
| 1557 NotificationService::current()->Notify( | |
| 1558 NotificationType::EXTENSION_UPDATE_DISABLED, | |
| 1559 Source<Profile>(profile_), | |
| 1560 Details<const Extension>(extension)); | |
| 1561 break; | |
| 1562 default: | |
| 1563 NOTREACHED(); | |
| 1564 break; | |
| 1565 } | |
| 1566 } | 1550 } |
| 1567 | 1551 |
| 1568 SetBeingUpgraded(extension, false); | 1552 SetBeingUpgraded(extension, false); |
| 1569 | 1553 |
| 1570 UpdateActiveExtensionsInCrashReporter(); | 1554 UpdateActiveExtensionsInCrashReporter(); |
| 1571 | 1555 |
| 1572 if (profile_->GetTemplateURLModel()) | 1556 if (profile_->GetTemplateURLModel()) |
| 1573 profile_->GetTemplateURLModel()->RegisterExtensionKeyword(extension); | 1557 profile_->GetTemplateURLModel()->RegisterExtensionKeyword(extension); |
| 1574 | 1558 |
| 1575 // Load the icon for omnibox-enabled extensions so it will be ready to display | 1559 // Load the icon for omnibox-enabled extensions so it will be ready to display |
| 1576 // in the URL bar. | 1560 // in the URL bar. |
| 1577 if (!extension->omnibox_keyword().empty()) { | 1561 if (!extension->omnibox_keyword().empty()) { |
| 1578 omnibox_popup_icon_manager_.LoadIcon(extension); | 1562 omnibox_popup_icon_manager_.LoadIcon(extension); |
| 1579 omnibox_icon_manager_.LoadIcon(extension); | 1563 omnibox_icon_manager_.LoadIcon(extension); |
| 1580 } | 1564 } |
| 1581 } | 1565 } |
| 1582 | 1566 |
| 1567 void ExtensionsService::DisableIfPrivilegeIncrease( | |
| 1568 const Extension* extension, bool allow_privilege_increase) { | |
|
Aaron Boodman
2010/11/23 00:06:38
As we talked about in IRC, I think everything woul
| |
| 1569 // We keep track of all permissions the user has granted each extension. | |
| 1570 // This allows extensions to gracefully support backwards compatibility | |
| 1571 // by including unknown permissions in their manifests. When the user | |
| 1572 // installs the extension, only the recognized permissions are recorded. | |
| 1573 // When the unknown permissions become recognized (e.g., through browser | |
| 1574 // upgrade), we can prompt the user to accept these new permissions. | |
| 1575 // Extensions can also silently upgrade to less permissions, and then | |
| 1576 // silently upgrade to a version that adds these permissions back. | |
| 1577 // | |
| 1578 // For example, pretend that Chrome 10 includes a permission "omnibox" | |
| 1579 // for an API that adds suggestions to the omnibox. An extension can | |
| 1580 // maintain backwards compatibility while still having "omnibox" in the | |
| 1581 // manifest. If a user installs the extension on Chrome 9, the browser | |
| 1582 // will record the permissions it recognized, not including "omnibox." | |
| 1583 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome | |
| 1584 // will disable the extension and prompt the user to approve the increase | |
| 1585 // in privileges. The extension could then release a new version that | |
| 1586 // removes the "omnibox" permission. When the user upgrades, Chrome will | |
| 1587 // still remember that "omnibox" had been granted, so that if the | |
| 1588 // extension once again includes "omnibox" in an upgrade, the extension | |
| 1589 // can upgrade without requiring this user's approval. | |
| 1590 const Extension* old = GetExtensionByIdInternal(extension->id(), | |
| 1591 true, true); | |
| 1592 std::set<std::string> granted_apis; | |
| 1593 ExtensionExtent granted_extent; | |
| 1594 | |
| 1595 bool is_extension_upgrade = old != NULL; | |
| 1596 bool is_privilege_increase = false; | |
| 1597 | |
| 1598 // We only record the granted permissions in the extension preferences | |
| 1599 // for extensions that aren't allowed to silently increase privileges. | |
| 1600 if (!allow_privilege_increase) { | |
| 1601 // Add all the recognized permissions to the extension's granted | |
| 1602 // permissions list if the granted permissions list hasn't been | |
| 1603 // initialized yet. | |
| 1604 if (!extension_prefs_->GetGrantedPermissions( | |
| 1605 extension->id(), &granted_apis, &granted_extent)) { | |
| 1606 GrantPermissions(extension); | |
| 1607 CHECK(extension_prefs_->GetGrantedPermissions( | |
| 1608 extension->id(), &granted_apis, &granted_extent)); | |
| 1609 } | |
| 1610 | |
| 1611 // Here, we check if an extension's privileges have increased in a manner | |
| 1612 // that requires the user's approval. This could occur because the browser | |
| 1613 // upgraded and recognized additional privileges, or an extension upgrades | |
| 1614 // to a version that requires additional privileges. | |
| 1615 is_privilege_increase = Extension::IsPrivilegeIncrease( | |
| 1616 granted_apis, granted_extent, old, extension); | |
| 1617 } | |
| 1618 | |
| 1619 if (is_extension_upgrade) { | |
| 1620 // CrxInstaller should have guaranteed that we aren't downgrading. | |
| 1621 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); | |
| 1622 | |
| 1623 // Extensions get upgraded if the privileges are allowed to increase or | |
| 1624 // the privileges haven't increased. | |
| 1625 if (allow_privilege_increase || !is_privilege_increase) { | |
| 1626 SetBeingUpgraded(old, true); | |
| 1627 SetBeingUpgraded(extension, true); | |
| 1628 } | |
| 1629 | |
| 1630 // To upgrade an extension in place, unload the old one and | |
| 1631 // then load the new one. | |
| 1632 UnloadExtension(old->id()); | |
| 1633 old = NULL; | |
| 1634 } | |
| 1635 | |
| 1636 // Extension has changed permissions significantly. Disable it. A | |
| 1637 // notification should be sent by the caller. | |
| 1638 if (is_privilege_increase) { | |
| 1639 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); | |
| 1640 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); | |
| 1641 } | |
| 1642 } | |
| 1643 | |
| 1583 void ExtensionsService::UpdateActiveExtensionsInCrashReporter() { | 1644 void ExtensionsService::UpdateActiveExtensionsInCrashReporter() { |
| 1584 std::set<std::string> extension_ids; | 1645 std::set<std::string> extension_ids; |
| 1585 for (size_t i = 0; i < extensions_.size(); ++i) { | 1646 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 1586 if (!extensions_[i]->is_theme() && | 1647 if (!extensions_[i]->is_theme() && |
| 1587 extensions_[i]->location() != Extension::COMPONENT) | 1648 extensions_[i]->location() != Extension::COMPONENT) |
| 1588 extension_ids.insert(extensions_[i]->id()); | 1649 extension_ids.insert(extensions_[i]->id()); |
| 1589 } | 1650 } |
| 1590 | 1651 |
| 1591 child_process_logging::SetActiveExtensions(extension_ids); | 1652 child_process_logging::SetActiveExtensions(extension_ids); |
| 1592 } | 1653 } |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1950 } | 2011 } |
| 1951 | 2012 |
| 1952 bool ExtensionsService::IsBeingUpgraded(const Extension* extension) { | 2013 bool ExtensionsService::IsBeingUpgraded(const Extension* extension) { |
| 1953 return extension_runtime_data_[extension->id()].being_upgraded; | 2014 return extension_runtime_data_[extension->id()].being_upgraded; |
| 1954 } | 2015 } |
| 1955 | 2016 |
| 1956 void ExtensionsService::SetBeingUpgraded(const Extension* extension, | 2017 void ExtensionsService::SetBeingUpgraded(const Extension* extension, |
| 1957 bool value) { | 2018 bool value) { |
| 1958 extension_runtime_data_[extension->id()].being_upgraded = value; | 2019 extension_runtime_data_[extension->id()].being_upgraded = value; |
| 1959 } | 2020 } |
| OLD | NEW |