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

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

Powered by Google App Engine
This is Rietveld 408576698