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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 using content::BrowserThread; | 107 using content::BrowserThread; |
108 using content::DevToolsAgentHost; | 108 using content::DevToolsAgentHost; |
109 using extensions::APIPermission; | 109 using extensions::APIPermission; |
110 using extensions::AppSorting; | 110 using extensions::AppSorting; |
111 using extensions::CrxInstaller; | 111 using extensions::CrxInstaller; |
112 using extensions::Extension; | 112 using extensions::Extension; |
113 using extensions::ExtensionIdSet; | 113 using extensions::ExtensionIdSet; |
114 using extensions::ExtensionInfo; | 114 using extensions::ExtensionInfo; |
115 using extensions::ExtensionRegistry; | 115 using extensions::ExtensionRegistry; |
116 using extensions::ExtensionSet; | 116 using extensions::ExtensionSet; |
117 using extensions::ExternalProviderInterface; | |
117 using extensions::FeatureSwitch; | 118 using extensions::FeatureSwitch; |
118 using extensions::InstallVerifier; | 119 using extensions::InstallVerifier; |
119 using extensions::ManagementPolicy; | 120 using extensions::ManagementPolicy; |
120 using extensions::Manifest; | 121 using extensions::Manifest; |
121 using extensions::PermissionID; | 122 using extensions::PermissionID; |
122 using extensions::PermissionIDSet; | 123 using extensions::PermissionIDSet; |
123 using extensions::PermissionSet; | 124 using extensions::PermissionSet; |
124 using extensions::SharedModuleInfo; | 125 using extensions::SharedModuleInfo; |
125 using extensions::SharedModuleService; | 126 using extensions::SharedModuleService; |
126 using extensions::UnloadedExtensionInfo; | 127 using extensions::UnloadedExtensionInfo; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 void ExtensionService::SetFileTaskRunnerForTesting( | 168 void ExtensionService::SetFileTaskRunnerForTesting( |
168 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { | 169 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { |
169 file_task_runner_ = task_runner; | 170 file_task_runner_ = task_runner; |
170 } | 171 } |
171 | 172 |
172 void ExtensionService::ClearProvidersForTesting() { | 173 void ExtensionService::ClearProvidersForTesting() { |
173 external_extension_providers_.clear(); | 174 external_extension_providers_.clear(); |
174 } | 175 } |
175 | 176 |
176 void ExtensionService::AddProviderForTesting( | 177 void ExtensionService::AddProviderForTesting( |
177 extensions::ExternalProviderInterface* test_provider) { | 178 ExternalProviderInterface* test_provider) { |
178 CHECK(test_provider); | 179 CHECK(test_provider); |
179 external_extension_providers_.push_back( | 180 external_extension_providers_.push_back( |
180 linked_ptr<extensions::ExternalProviderInterface>(test_provider)); | 181 linked_ptr<ExternalProviderInterface>(test_provider)); |
181 } | 182 } |
182 | 183 |
183 void ExtensionService::BlacklistExtensionForTest( | 184 void ExtensionService::BlacklistExtensionForTest( |
184 const std::string& extension_id) { | 185 const std::string& extension_id) { |
185 ExtensionIdSet blacklisted; | 186 ExtensionIdSet blacklisted; |
186 ExtensionIdSet unchanged; | 187 ExtensionIdSet unchanged; |
187 blacklisted.insert(extension_id); | 188 blacklisted.insert(extension_id); |
188 UpdateBlacklistedExtensions(blacklisted, unchanged); | 189 UpdateBlacklistedExtensions(blacklisted, unchanged); |
189 } | 190 } |
190 | 191 |
191 bool ExtensionService::OnExternalExtensionUpdateUrlFound( | 192 bool ExtensionService::OnExternalExtensionUpdateUrlFound( |
192 const std::string& id, | 193 ExternalProviderInterface::UpdateUrlExtensionInfo* info, |
193 const std::string& install_parameter, | 194 bool is_initial_load) { |
194 const GURL& update_url, | |
195 Manifest::Location location, | |
196 int creation_flags, | |
197 bool mark_acknowledged) { | |
198 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 195 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
199 CHECK(crx_file::id_util::IdIsValid(id)); | 196 CHECK(crx_file::id_util::IdIsValid(info->extension_id)); |
200 | 197 |
201 if (Manifest::IsExternalLocation(location)) { | 198 if (Manifest::IsExternalLocation(info->download_location)) { |
202 // All extensions that are not user specific can be cached. | 199 // All extensions that are not user specific can be cached. |
203 extensions::ExtensionsBrowserClient::Get()->GetExtensionCache() | 200 extensions::ExtensionsBrowserClient::Get() |
204 ->AllowCaching(id); | 201 ->GetExtensionCache() |
202 ->AllowCaching(info->extension_id); | |
205 } | 203 } |
206 | 204 |
207 const Extension* extension = GetExtensionById(id, true); | 205 const Extension* extension = GetExtensionById(info->extension_id, true); |
208 if (extension) { | 206 if (extension) { |
209 // Already installed. Skip this install if the current location has | 207 // Already installed. Skip this install if the current location has |
210 // higher priority than |location|. | 208 // higher priority than |info->download_location|. |
211 Manifest::Location current = extension->location(); | 209 Manifest::Location current = extension->location(); |
212 if (current == Manifest::GetHigherPriorityLocation(current, location)) | 210 if (current == |
211 Manifest::GetHigherPriorityLocation(current, info->download_location)) { | |
213 return false; | 212 return false; |
213 } | |
214 // Otherwise, overwrite the current installation. | 214 // Otherwise, overwrite the current installation. |
215 } | 215 } |
216 | 216 |
217 // Add |id| to the set of pending extensions. If it can not be added, | 217 // Add |info->extension_id| to the set of pending extensions. If it can not |
218 // then there is already a pending record from a higher-priority install | 218 // be added, then there is already a pending record from a higher-priority |
219 // source. In this case, signal that this extension will not be | 219 // install source. In this case, signal that this extension will not be |
220 // installed by returning false. | 220 // installed by returning false. |
221 if (!pending_extension_manager()->AddFromExternalUpdateUrl( | 221 if (!pending_extension_manager()->AddFromExternalUpdateUrl( |
222 id, | 222 info->extension_id, info->install_parameter, *info->update_url, |
223 install_parameter, | 223 info->download_location, info->creation_flags, |
224 update_url, | 224 info->mark_acknowledged)) { |
225 location, | |
226 creation_flags, | |
227 mark_acknowledged)) { | |
228 return false; | 225 return false; |
229 } | 226 } |
230 | 227 |
231 update_once_all_providers_are_ready_ = true; | 228 if (is_initial_load) |
229 update_once_all_providers_are_ready_ = true; | |
232 return true; | 230 return true; |
233 } | 231 } |
234 | 232 |
233 void ExtensionService::OnExternalProviderUpdateComplete( | |
234 const ExternalProviderInterface* provider, | |
235 const ScopedVector<ExternalProviderInterface::UpdateUrlExtensionInfo>& | |
236 update_url_extensions, | |
237 const ScopedVector<ExternalProviderInterface::FileExtensionInfo>& | |
238 file_extensions, | |
239 const std::set<std::string>& removed_extensions) { | |
240 if (!update_url_extensions.empty() || !file_extensions.empty()) { | |
lazyboy
2016/01/22 07:52:41
@asargent: I've added this guard we talked about o
asargent_no_longer_on_chrome
2016/01/25 18:50:52
Acknowledged.
| |
241 // Update pending_extension_manager() with the new extensions first. | |
242 for (const auto& extension : update_url_extensions) | |
243 OnExternalExtensionUpdateUrlFound(extension, false); | |
244 for (const auto& extension : file_extensions) | |
245 OnExternalExtensionFileFound(extension); | |
246 | |
247 if (updater_) { | |
248 // Empty params will cause pending extensions to be updated. | |
249 extensions::ExtensionUpdater::CheckParams empty_params; | |
250 updater_->CheckNow(empty_params); | |
251 } | |
252 } | |
253 | |
254 for (const std::string& id : removed_extensions) | |
255 CheckExternalUninstall(id); | |
256 | |
257 error_controller_->ShowErrorIfNeeded(); | |
258 external_install_manager_->UpdateExternalExtensionAlert(); | |
259 } | |
260 | |
235 // static | 261 // static |
236 // This function is used to uninstall an extension via sync. The LOG statements | 262 // This function is used to uninstall an extension via sync. The LOG statements |
237 // within this function are used to inform the user if the uninstall cannot be | 263 // within this function are used to inform the user if the uninstall cannot be |
238 // done. | 264 // done. |
239 bool ExtensionService::UninstallExtensionHelper( | 265 bool ExtensionService::UninstallExtensionHelper( |
240 ExtensionService* extensions_service, | 266 ExtensionService* extensions_service, |
241 const std::string& extension_id, | 267 const std::string& extension_id, |
242 extensions::UninstallReason reason) { | 268 extensions::UninstallReason reason) { |
243 // We can't call UninstallExtension with an invalid extension ID. | 269 // We can't call UninstallExtension with an invalid extension ID. |
244 if (!extensions_service->GetInstalledExtension(extension_id)) { | 270 if (!extensions_service->GetInstalledExtension(extension_id)) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 return &pending_extension_manager_; | 389 return &pending_extension_manager_; |
364 } | 390 } |
365 | 391 |
366 ExtensionService::~ExtensionService() { | 392 ExtensionService::~ExtensionService() { |
367 // No need to unload extensions here because they are profile-scoped, and the | 393 // No need to unload extensions here because they are profile-scoped, and the |
368 // profile is in the process of being deleted. | 394 // profile is in the process of being deleted. |
369 | 395 |
370 extensions::ProviderCollection::const_iterator i; | 396 extensions::ProviderCollection::const_iterator i; |
371 for (i = external_extension_providers_.begin(); | 397 for (i = external_extension_providers_.begin(); |
372 i != external_extension_providers_.end(); ++i) { | 398 i != external_extension_providers_.end(); ++i) { |
373 extensions::ExternalProviderInterface* provider = i->get(); | 399 ExternalProviderInterface* provider = i->get(); |
374 provider->ServiceShutdown(); | 400 provider->ServiceShutdown(); |
375 } | 401 } |
376 } | 402 } |
377 | 403 |
378 void ExtensionService::Shutdown() { | 404 void ExtensionService::Shutdown() { |
379 extensions::ExtensionManagementFactory::GetInstance() | 405 extensions::ExtensionManagementFactory::GetInstance() |
380 ->GetForBrowserContext(profile()) | 406 ->GetForBrowserContext(profile()) |
381 ->RemoveObserver(this); | 407 ->RemoveObserver(this); |
382 } | 408 } |
383 | 409 |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1267 // go through the front-end). Extensions that are registered in this | 1293 // go through the front-end). Extensions that are registered in this |
1268 // way are effectively considered 'pre-bundled', and so implicitly | 1294 // way are effectively considered 'pre-bundled', and so implicitly |
1269 // trusted. In general, if something has HKLM or filesystem access, | 1295 // trusted. In general, if something has HKLM or filesystem access, |
1270 // they could install an extension manually themselves anyway. | 1296 // they could install an extension manually themselves anyway. |
1271 | 1297 |
1272 // Ask each external extension provider to give us a call back for each | 1298 // Ask each external extension provider to give us a call back for each |
1273 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. | 1299 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. |
1274 extensions::ProviderCollection::const_iterator i; | 1300 extensions::ProviderCollection::const_iterator i; |
1275 for (i = external_extension_providers_.begin(); | 1301 for (i = external_extension_providers_.begin(); |
1276 i != external_extension_providers_.end(); ++i) { | 1302 i != external_extension_providers_.end(); ++i) { |
1277 extensions::ExternalProviderInterface* provider = i->get(); | 1303 ExternalProviderInterface* provider = i->get(); |
1278 provider->VisitRegisteredExtension(); | 1304 provider->VisitRegisteredExtension(); |
1279 } | 1305 } |
1280 | 1306 |
1281 // Do any required work that we would have done after completion of all | 1307 // Do any required work that we would have done after completion of all |
1282 // providers. | 1308 // providers. |
1283 if (external_extension_providers_.empty()) | 1309 if (external_extension_providers_.empty()) |
1284 OnAllExternalProvidersReady(); | 1310 OnAllExternalProvidersReady(); |
1285 } | 1311 } |
1286 | 1312 |
1287 void ExtensionService::OnExternalProviderReady( | 1313 void ExtensionService::OnExternalProviderReady( |
1288 const extensions::ExternalProviderInterface* provider) { | 1314 const ExternalProviderInterface* provider) { |
1289 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1315 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1290 CHECK(provider->IsReady()); | 1316 CHECK(provider->IsReady()); |
1291 | 1317 |
1292 // An external provider has finished loading. We only take action | 1318 // An external provider has finished loading. We only take action |
1293 // if all of them are finished. So we check them first. | 1319 // if all of them are finished. So we check them first. |
1294 if (AreAllExternalProvidersReady()) | 1320 if (AreAllExternalProvidersReady()) |
1295 OnAllExternalProvidersReady(); | 1321 OnAllExternalProvidersReady(); |
1296 } | 1322 } |
1297 | 1323 |
1298 bool ExtensionService::AreAllExternalProvidersReady() const { | 1324 bool ExtensionService::AreAllExternalProvidersReady() const { |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2001 content::Details<const Extension>(extension)); | 2027 content::Details<const Extension>(extension)); |
2002 } | 2028 } |
2003 } | 2029 } |
2004 | 2030 |
2005 const Extension* ExtensionService::GetInstalledExtension( | 2031 const Extension* ExtensionService::GetInstalledExtension( |
2006 const std::string& id) const { | 2032 const std::string& id) const { |
2007 return registry_->GetExtensionById(id, ExtensionRegistry::EVERYTHING); | 2033 return registry_->GetExtensionById(id, ExtensionRegistry::EVERYTHING); |
2008 } | 2034 } |
2009 | 2035 |
2010 bool ExtensionService::OnExternalExtensionFileFound( | 2036 bool ExtensionService::OnExternalExtensionFileFound( |
2011 const std::string& id, | 2037 ExternalProviderInterface::FileExtensionInfo* info) { |
2012 const Version* version, | |
2013 const base::FilePath& path, | |
2014 Manifest::Location location, | |
2015 int creation_flags, | |
2016 bool mark_acknowledged, | |
2017 bool install_immediately) { | |
2018 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2038 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2019 CHECK(crx_file::id_util::IdIsValid(id)); | 2039 CHECK(crx_file::id_util::IdIsValid(info->extension_id)); |
2020 if (extension_prefs_->IsExternalExtensionUninstalled(id)) | 2040 if (extension_prefs_->IsExternalExtensionUninstalled(info->extension_id)) |
2021 return false; | 2041 return false; |
2022 | 2042 |
2023 // Before even bothering to unpack, check and see if we already have this | 2043 // Before even bothering to unpack, check and see if we already have this |
2024 // version. This is important because these extensions are going to get | 2044 // version. This is important because these extensions are going to get |
2025 // installed on every startup. | 2045 // installed on every startup. |
2026 const Extension* existing = GetExtensionById(id, true); | 2046 const Extension* existing = GetExtensionById(info->extension_id, true); |
2027 | 2047 |
2028 if (existing) { | 2048 if (existing) { |
2029 // The default apps will have the location set as INTERNAL. Since older | 2049 // The default apps will have the location set as INTERNAL. Since older |
2030 // default apps are installed as EXTERNAL, we override them. However, if the | 2050 // default apps are installed as EXTERNAL, we override them. However, if the |
2031 // app is already installed as internal, then do the version check. | 2051 // app is already installed as internal, then do the version check. |
2032 // TODO(grv) : Remove after Q1-2013. | 2052 // TODO(grv) : Remove after Q1-2013. |
2033 bool is_default_apps_migration = | 2053 bool is_default_apps_migration = |
2034 (location == Manifest::INTERNAL && | 2054 (info->crx_location == Manifest::INTERNAL && |
2035 Manifest::IsExternalLocation(existing->location())); | 2055 Manifest::IsExternalLocation(existing->location())); |
2036 | 2056 |
2037 if (!is_default_apps_migration) { | 2057 if (!is_default_apps_migration) { |
2038 DCHECK(version); | 2058 DCHECK(info->version.get()); |
2039 | 2059 |
2040 switch (existing->version()->CompareTo(*version)) { | 2060 switch (existing->version()->CompareTo(*info->version)) { |
2041 case -1: // existing version is older, we should upgrade | 2061 case -1: // existing version is older, we should upgrade |
2042 break; | 2062 break; |
2043 case 0: // existing version is same, do nothing | 2063 case 0: // existing version is same, do nothing |
2044 return false; | 2064 return false; |
2045 case 1: // existing version is newer, uh-oh | 2065 case 1: // existing version is newer, uh-oh |
2046 LOG(WARNING) << "Found external version of extension " << id | 2066 LOG(WARNING) << "Found external version of extension " |
2067 << info->extension_id | |
2047 << "that is older than current version. Current version " | 2068 << "that is older than current version. Current version " |
2048 << "is: " << existing->VersionString() << ". New " | 2069 << "is: " << existing->VersionString() << ". New " |
2049 << "version is: " << version->GetString() | 2070 << "version is: " << info->version->GetString() |
2050 << ". Keeping current version."; | 2071 << ". Keeping current version."; |
2051 return false; | 2072 return false; |
2052 } | 2073 } |
2053 } | 2074 } |
2054 } | 2075 } |
2055 | 2076 |
2056 // If the extension is already pending, don't start an install. | 2077 // If the extension is already pending, don't start an install. |
2057 if (!pending_extension_manager()->AddFromExternalFile( | 2078 if (!pending_extension_manager()->AddFromExternalFile( |
2058 id, location, *version, creation_flags, mark_acknowledged)) { | 2079 info->extension_id, info->crx_location, *info->version, |
2080 info->creation_flags, info->mark_acknowledged)) { | |
2059 return false; | 2081 return false; |
2060 } | 2082 } |
2061 | 2083 |
2062 // no client (silent install) | 2084 // no client (silent install) |
2063 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this)); | 2085 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this)); |
2064 installer->set_install_source(location); | 2086 installer->set_install_source(info->crx_location); |
2065 installer->set_expected_id(id); | 2087 installer->set_expected_id(info->extension_id); |
2066 installer->set_expected_version(*version, | 2088 installer->set_expected_version(*info->version, |
2067 true /* fail_install_if_unexpected */); | 2089 true /* fail_install_if_unexpected */); |
2068 installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE); | 2090 installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE); |
2069 installer->set_install_immediately(install_immediately); | 2091 installer->set_install_immediately(info->install_immediately); |
2070 installer->set_creation_flags(creation_flags); | 2092 installer->set_creation_flags(info->creation_flags); |
2071 #if defined(OS_CHROMEOS) | 2093 #if defined(OS_CHROMEOS) |
2072 extensions::InstallLimiter::Get(profile_)->Add(installer, path); | 2094 extensions::InstallLimiter::Get(profile_)->Add(installer, info->path); |
2073 #else | 2095 #else |
2074 installer->InstallCrx(path); | 2096 installer->InstallCrx(info->path); |
2075 #endif | 2097 #endif |
2076 | 2098 |
2077 // Depending on the source, a new external extension might not need a user | 2099 // Depending on the source, a new external extension might not need a user |
2078 // notification on installation. For such extensions, mark them acknowledged | 2100 // notification on installation. For such extensions, mark them acknowledged |
2079 // now to suppress the notification. | 2101 // now to suppress the notification. |
2080 if (mark_acknowledged) | 2102 if (info->mark_acknowledged) |
2081 external_install_manager_->AcknowledgeExternalExtension(id); | 2103 external_install_manager_->AcknowledgeExternalExtension(info->extension_id); |
2082 | 2104 |
2083 return true; | 2105 return true; |
2084 } | 2106 } |
2085 | 2107 |
2086 void ExtensionService::DidCreateRenderViewForBackgroundPage( | 2108 void ExtensionService::DidCreateRenderViewForBackgroundPage( |
2087 extensions::ExtensionHost* host) { | 2109 extensions::ExtensionHost* host) { |
2088 OrphanedDevTools::iterator iter = | 2110 OrphanedDevTools::iterator iter = |
2089 orphaned_dev_tools_.find(host->extension_id()); | 2111 orphaned_dev_tools_.find(host->extension_id()); |
2090 if (iter == orphaned_dev_tools_.end()) | 2112 if (iter == orphaned_dev_tools_.end()) |
2091 return; | 2113 return; |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2465 } | 2487 } |
2466 | 2488 |
2467 void ExtensionService::OnProfileDestructionStarted() { | 2489 void ExtensionService::OnProfileDestructionStarted() { |
2468 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2490 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
2469 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2491 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
2470 it != ids_to_unload.end(); | 2492 it != ids_to_unload.end(); |
2471 ++it) { | 2493 ++it) { |
2472 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2494 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
2473 } | 2495 } |
2474 } | 2496 } |
OLD | NEW |