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

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

Issue 706623004: Add minimum version to extension management (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ext-update-url
Patch Set: rebase Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_service.h" 5 #include "chrome/browser/extensions/extension_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <set> 9 #include <set>
10 10
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 } 854 }
855 855
856 const Extension* extension = GetInstalledExtension(extension_id); 856 const Extension* extension = GetInstalledExtension(extension_id);
857 // |extension| can be NULL if sync disables an extension that is not 857 // |extension| can be NULL if sync disables an extension that is not
858 // installed yet. 858 // installed yet.
859 // EXTERNAL_COMPONENT extensions are not generally modifiable by users, but 859 // EXTERNAL_COMPONENT extensions are not generally modifiable by users, but
860 // can be uninstalled by the browser if the user sets extension-specific 860 // can be uninstalled by the browser if the user sets extension-specific
861 // preferences. 861 // preferences.
862 if (extension && 862 if (extension &&
863 disable_reason != Extension::DISABLE_RELOAD && 863 disable_reason != Extension::DISABLE_RELOAD &&
864 disable_reason != Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY &&
864 !system_->management_policy()->UserMayModifySettings(extension, NULL) && 865 !system_->management_policy()->UserMayModifySettings(extension, NULL) &&
865 extension->location() != Manifest::EXTERNAL_COMPONENT) { 866 extension->location() != Manifest::EXTERNAL_COMPONENT) {
866 return; 867 return;
867 } 868 }
868 869
869 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); 870 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED);
870 extension_prefs_->AddDisableReason(extension_id, disable_reason); 871 extension_prefs_->AddDisableReason(extension_id, disable_reason);
871 872
872 int include_mask = 873 int include_mask =
873 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED; 874 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED;
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 file_task_runner_ = BrowserThread::GetBlockingPool()-> 1155 file_task_runner_ = BrowserThread::GetBlockingPool()->
1155 GetSequencedTaskRunnerWithShutdownBehavior( 1156 GetSequencedTaskRunnerWithShutdownBehavior(
1156 BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token), 1157 BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token),
1157 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 1158 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
1158 return file_task_runner_.get(); 1159 return file_task_runner_.get();
1159 } 1160 }
1160 1161
1161 void ExtensionService::CheckManagementPolicy() { 1162 void ExtensionService::CheckManagementPolicy() {
1162 std::vector<std::string> to_unload; 1163 std::vector<std::string> to_unload;
1163 std::map<std::string, Extension::DisableReason> to_disable; 1164 std::map<std::string, Extension::DisableReason> to_disable;
1165 std::vector<std::string> to_enable;
1164 1166
1165 // Loop through the extensions list, finding extensions we need to unload or 1167 // Loop through the extensions list, finding extensions we need to unload or
1166 // disable. 1168 // disable.
1167 const ExtensionSet& extensions = registry_->enabled_extensions(); 1169 for (scoped_refptr<const Extension> extension :
1168 for (ExtensionSet::const_iterator iter = extensions.begin(); 1170 registry_->enabled_extensions()) {
1169 iter != extensions.end(); ++iter) { 1171 if (!system_->management_policy()->UserMayLoad(extension.get(), nullptr))
1170 const Extension* extension = (iter->get());
1171 if (!system_->management_policy()->UserMayLoad(extension, NULL))
1172 to_unload.push_back(extension->id()); 1172 to_unload.push_back(extension->id());
1173 Extension::DisableReason disable_reason = Extension::DISABLE_NONE; 1173 Extension::DisableReason disable_reason = Extension::DISABLE_NONE;
1174 if (system_->management_policy()->MustRemainDisabled( 1174 if (system_->management_policy()->MustRemainDisabled(
1175 extension, &disable_reason, NULL)) 1175 extension.get(), &disable_reason, nullptr))
1176 to_disable[extension->id()] = disable_reason; 1176 to_disable[extension->id()] = disable_reason;
1177 } 1177 }
1178 1178
1179 for (size_t i = 0; i < to_unload.size(); ++i) 1179 extensions::ExtensionManagement* management =
1180 UnloadExtension(to_unload[i], UnloadedExtensionInfo::REASON_DISABLE); 1180 extensions::ExtensionManagementFactory::GetForBrowserContext(profile());
1181
1182 // Loop through the disabled extension list, find extensions to re-enable
1183 // automatically. These extensions are exclusive from the |to_disable| and
1184 // |to_unload| lists constructed above, since disabled_extensions() and
1185 // enabled_extensions() are supposed to be mutually exclusive.
1186 for (scoped_refptr<const Extension> extension :
1187 registry_->disabled_extensions()) {
1188 // Find all disabled extensions disabled due to minimum version requirement,
1189 // but now satisfying it.
1190 if (management->CheckMinimumVersion(extension.get(), nullptr) &&
1191 extension_prefs_->HasDisableReason(
1192 extension->id(), Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY)) {
1193 // Is DISABLE_UPDATE_REQUIRED_BY_POLICY the *only* reason?
1194 if (extension_prefs_->GetDisableReasons(extension->id()) ==
1195 Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY) {
1196 // We need to enable those disabled *only* due to minimum version
1197 // requirement.
1198 to_enable.push_back(extension->id());
1199 }
1200 extension_prefs_->RemoveDisableReason(
1201 extension->id(), Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY);
1202 }
1203 }
1204
1205 for (const std::string& id : to_unload)
1206 UnloadExtension(id, UnloadedExtensionInfo::REASON_DISABLE);
1181 1207
1182 for (std::map<std::string, Extension::DisableReason>::const_iterator i = 1208 for (std::map<std::string, Extension::DisableReason>::const_iterator i =
1183 to_disable.begin(); i != to_disable.end(); ++i) 1209 to_disable.begin(); i != to_disable.end(); ++i)
1184 DisableExtension(i->first, i->second); 1210 DisableExtension(i->first, i->second);
1211
1212 // No extension is getting re-enabled here after disabling/unloading
1213 // because to_enable is mutually exclusive to to_disable + to_unload.
1214 for (const std::string& id : to_enable)
1215 EnableExtension(id);
1216
1217 if (updater_.get()) {
1218 // Find all extensions disabled due to minimum version requirement from
1219 // policy (including the ones that got disabled just now), and check
1220 // for update.
1221 extensions::ExtensionUpdater::CheckParams to_recheck;
1222 for (scoped_refptr<const Extension> extension :
1223 registry_->disabled_extensions()) {
1224 if (extension_prefs_->GetDisableReasons(extension->id()) ==
1225 Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY) {
1226 // The minimum version check is the only thing holding this extension
1227 // back, so check if it can be updated to fix that.
1228 to_recheck.ids.push_back(extension->id());
1229 }
1230 }
1231 if (!to_recheck.ids.empty())
1232 updater_->CheckNow(to_recheck);
1233 }
1185 } 1234 }
1186 1235
1187 void ExtensionService::CheckForUpdatesSoon() { 1236 void ExtensionService::CheckForUpdatesSoon() {
1188 // This can legitimately happen in unit tests. 1237 // This can legitimately happen in unit tests.
1189 if (!updater_.get()) 1238 if (!updater_.get())
1190 return; 1239 return;
1191 1240
1192 if (AreAllExternalProvidersReady()) { 1241 if (AreAllExternalProvidersReady()) {
1193 updater_->CheckSoon(); 1242 updater_->CheckSoon();
1194 } else { 1243 } else {
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 // extension; if we're here, that means the user is manually 1703 // extension; if we're here, that means the user is manually
1655 // installing the extension. 1704 // installing the extension.
1656 if (extension_prefs_->IsExternalExtensionUninstalled(id)) { 1705 if (extension_prefs_->IsExternalExtensionUninstalled(id)) {
1657 disable_reasons = Extension::DISABLE_NONE; 1706 disable_reasons = Extension::DISABLE_NONE;
1658 } 1707 }
1659 } 1708 }
1660 1709
1661 // Unsupported requirements overrides the management policy. 1710 // Unsupported requirements overrides the management policy.
1662 if (install_flags & extensions::kInstallFlagHasRequirementErrors) { 1711 if (install_flags & extensions::kInstallFlagHasRequirementErrors) {
1663 disable_reasons |= Extension::DISABLE_UNSUPPORTED_REQUIREMENT; 1712 disable_reasons |= Extension::DISABLE_UNSUPPORTED_REQUIREMENT;
1664 // If the extension was disabled because of unsupported requirements but 1713 } else {
1665 // now supports all requirements after an update and there are not other 1714 // Requirement is supported now, remove the corresponding disable reason
1666 // disable reasons, enable it. 1715 // instead.
1667 } else if (extension_prefs_->GetDisableReasons(id) == 1716 extension_prefs_->RemoveDisableReason(
1668 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { 1717 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
1669 disable_reasons = Extension::DISABLE_NONE; 1718 disable_reasons &= ~Extension::DISABLE_UNSUPPORTED_REQUIREMENT;
1670 extension_prefs_->ClearDisableReasons(id); 1719 }
1720
1721 // Check if the extension was disabled because of the minimum version
1722 // requirements from enterprise policy, and satisfies it now.
1723 if (extensions::ExtensionManagementFactory::GetForBrowserContext(profile())
1724 ->CheckMinimumVersion(extension, nullptr)) {
1725 // And remove the corresponding disable reason.
1726 extension_prefs_->RemoveDisableReason(
1727 id, Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY);
1728 disable_reasons &= ~Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY;
1671 } 1729 }
1672 1730
1673 if (install_flags & extensions::kInstallFlagIsBlacklistedForMalware) { 1731 if (install_flags & extensions::kInstallFlagIsBlacklistedForMalware) {
1674 // Installation of a blacklisted extension can happen from sync, policy, 1732 // Installation of a blacklisted extension can happen from sync, policy,
1675 // etc, where to maintain consistency we need to install it, just never 1733 // etc, where to maintain consistency we need to install it, just never
1676 // load it (see AddExtension). Usually it should be the job of callers to 1734 // load it (see AddExtension). Usually it should be the job of callers to
1677 // incercept blacklisted extension earlier (e.g. CrxInstaller, before even 1735 // incercept blacklisted extension earlier (e.g. CrxInstaller, before even
1678 // showing the install dialogue). 1736 // showing the install dialogue).
1679 extension_prefs_->AcknowledgeBlacklistedExtension(id); 1737 extension_prefs_->AcknowledgeBlacklistedExtension(id);
1680 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", 1738 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall",
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
2465 } 2523 }
2466 2524
2467 void ExtensionService::OnProfileDestructionStarted() { 2525 void ExtensionService::OnProfileDestructionStarted() {
2468 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); 2526 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs();
2469 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); 2527 for (ExtensionIdSet::iterator it = ids_to_unload.begin();
2470 it != ids_to_unload.end(); 2528 it != ids_to_unload.end();
2471 ++it) { 2529 ++it) {
2472 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); 2530 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN);
2473 } 2531 }
2474 } 2532 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698