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

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

Issue 1495403002: Observe adding external extensions via windows registry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: guard updater_->CheckNow() call, rework Provider->ExtensionService interaction Created 4 years, 11 months 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 <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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698