| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |