Chromium Code Reviews| 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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 // includes those that have been disabled due to blacklisting or blocking. | 379 // includes those that have been disabled due to blacklisting or blocking. |
| 380 include_mask |= ExtensionRegistry::DISABLED | | 380 include_mask |= ExtensionRegistry::DISABLED | |
| 381 ExtensionRegistry::BLACKLISTED | ExtensionRegistry::BLOCKED; | 381 ExtensionRegistry::BLACKLISTED | ExtensionRegistry::BLOCKED; |
| 382 } | 382 } |
| 383 return registry_->GetExtensionById(id, include_mask); | 383 return registry_->GetExtensionById(id, include_mask); |
| 384 } | 384 } |
| 385 | 385 |
| 386 void ExtensionService::Init() { | 386 void ExtensionService::Init() { |
| 387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 388 TRACE_EVENT0("browser,startup", "ExtensionService::Init"); | 388 TRACE_EVENT0("browser,startup", "ExtensionService::Init"); |
| 389 base::Time begin_time = base::Time::Now(); | 389 SCOPED_UMA_HISTOGRAM_TIMER("Extensions.ExtensionServiceInitTime"); |
| 390 | 390 |
| 391 DCHECK(!is_ready()); // Can't redo init. | 391 DCHECK(!is_ready()); // Can't redo init. |
| 392 DCHECK_EQ(registry_->enabled_extensions().size(), 0u); | 392 DCHECK_EQ(registry_->enabled_extensions().size(), 0u); |
| 393 | 393 |
| 394 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 394 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| 395 if (cmd_line->HasSwitch(switches::kInstallEphemeralAppFromWebstore)) { | 395 if (cmd_line->HasSwitch(switches::kInstallEphemeralAppFromWebstore)) { |
| 396 // The sole purpose of this launch is to install a new extension from CWS | 396 // The sole purpose of this launch is to install a new extension from CWS |
| 397 // and immediately terminate: loading already installed extensions is | 397 // and immediately terminate: loading already installed extensions is |
| 398 // unnecessary and may interfere with the inline install dialog (e.g. if an | 398 // unnecessary and may interfere with the inline install dialog (e.g. if an |
| 399 // extension listens to onStartup and opens a window). | 399 // extension listens to onStartup and opens a window). |
| 400 SetReadyAndNotifyListeners(); | 400 SetReadyAndNotifyListeners(); |
| 401 } else { | 401 } else { |
| 402 // LoadAllExtensions() calls OnLoadedInstalledExtensions(). | 402 // LoadAllExtensions() calls OnLoadedInstalledExtensions(). |
| 403 component_loader_->LoadAll(); | 403 component_loader_->LoadAll(); |
| 404 extensions::InstalledLoader(this).LoadAllExtensions(); | 404 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 405 | 405 |
| 406 // Attempt to re-enable extensions whose only disable reason is reloading. | 406 EnabledReloadableExtensions(); |
| 407 std::vector<std::string> extensions_to_enable; | 407 MaybeFinishShutdownDelayed(); |
| 408 const ExtensionSet& disabled_extensions = registry_->disabled_extensions(); | |
| 409 for (ExtensionSet::const_iterator iter = disabled_extensions.begin(); | |
| 410 iter != disabled_extensions.end(); ++iter) { | |
| 411 const Extension* e = iter->get(); | |
| 412 if (extension_prefs_->GetDisableReasons(e->id()) == | |
| 413 Extension::DISABLE_RELOAD) { | |
| 414 extensions_to_enable.push_back(e->id()); | |
| 415 } | |
| 416 } | |
| 417 for (std::vector<std::string>::iterator it = extensions_to_enable.begin(); | |
| 418 it != extensions_to_enable.end(); ++it) { | |
| 419 EnableExtension(*it); | |
| 420 } | |
| 421 | |
| 422 // Finish install (if possible) of extensions that were still delayed while | |
| 423 // the browser was shut down. | |
| 424 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info( | |
| 425 extension_prefs_->GetAllDelayedInstallInfo()); | |
| 426 for (size_t i = 0; i < delayed_info->size(); ++i) { | |
| 427 ExtensionInfo* info = delayed_info->at(i).get(); | |
| 428 scoped_refptr<const Extension> extension(NULL); | |
| 429 if (info->extension_manifest) { | |
| 430 std::string error; | |
| 431 extension = Extension::Create( | |
| 432 info->extension_path, | |
| 433 info->extension_location, | |
| 434 *info->extension_manifest, | |
| 435 extension_prefs_->GetDelayedInstallCreationFlags( | |
| 436 info->extension_id), | |
| 437 info->extension_id, | |
| 438 &error); | |
| 439 if (extension.get()) | |
| 440 delayed_installs_.Insert(extension); | |
| 441 } | |
| 442 } | |
| 443 MaybeFinishDelayedInstallations(); | |
| 444 | |
| 445 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2( | |
| 446 extension_prefs_->GetAllDelayedInstallInfo()); | |
| 447 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", | |
| 448 delayed_info2->size() - delayed_info->size()); | |
| 449 | |
| 450 SetReadyAndNotifyListeners(); | 408 SetReadyAndNotifyListeners(); |
| 451 | 409 |
| 452 // TODO(erikkay) this should probably be deferred to a future point | 410 // TODO:(erikkay) this should probably be deferred to a future point |
|
Yoyo Zhou
2015/02/25 00:19:57
nit: TODO style is
// TODO(erikkay): etc.
rkaplow
2015/02/25 16:37:49
Done.
| |
| 453 // rather than running immediately at startup. | 411 // rather than running immediately at startup. |
| 454 CheckForExternalUpdates(); | 412 CheckForExternalUpdates(); |
| 455 | 413 |
| 456 LoadGreylistFromPrefs(); | 414 LoadGreylistFromPrefs(); |
| 457 } | 415 } |
| 458 | |
| 459 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", | |
| 460 base::Time::Now() - begin_time); | |
| 461 } | 416 } |
| 462 | 417 |
| 418 void ExtensionService::EnabledReloadableExtensions() { | |
| 419 TRACE_EVENT0("browser,startup", | |
| 420 "ExtensionService::EnabledReloadableExtensions"); | |
| 421 | |
| 422 std::vector<std::string> extensions_to_enable; | |
| 423 const ExtensionSet& disabled_extensions = registry_->disabled_extensions(); | |
| 424 for (ExtensionSet::const_iterator iter = disabled_extensions.begin(); | |
| 425 iter != disabled_extensions.end(); ++iter) { | |
| 426 const Extension* e = iter->get(); | |
| 427 if (extension_prefs_->GetDisableReasons(e->id()) == | |
| 428 Extension::DISABLE_RELOAD) { | |
| 429 extensions_to_enable.push_back(e->id()); | |
| 430 } | |
| 431 } | |
| 432 for (std::vector<std::string>::iterator it = extensions_to_enable.begin(); | |
| 433 it != extensions_to_enable.end(); ++it) { | |
|
Alexei Svitkine (slow)
2015/02/25 16:10:53
Nit: Since you're touching this code already, this
rkaplow
2015/02/25 16:37:49
Done.
| |
| 434 EnableExtension(*it); | |
| 435 } | |
| 436 } | |
| 437 | |
| 438 void ExtensionService::MaybeFinishShutdownDelayed() { | |
| 439 TRACE_EVENT0("browser,startup", | |
| 440 "ExtensionService::MaybeFinishShutdownDelayed"); | |
| 441 | |
| 442 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info( | |
| 443 extension_prefs_->GetAllDelayedInstallInfo()); | |
|
Alexei Svitkine (slow)
2015/02/25 16:10:53
This should be indented 1 more. You could probably
rkaplow
2015/02/25 16:37:49
Done.
| |
| 444 for (size_t i = 0; i < delayed_info->size(); ++i) { | |
| 445 ExtensionInfo* info = delayed_info->at(i).get(); | |
| 446 scoped_refptr<const Extension> extension(NULL); | |
| 447 if (info->extension_manifest) { | |
| 448 std::string error; | |
| 449 extension = Extension::Create( | |
| 450 info->extension_path, | |
| 451 info->extension_location, | |
| 452 *info->extension_manifest, | |
| 453 extension_prefs_->GetDelayedInstallCreationFlags( | |
| 454 info->extension_id), | |
| 455 info->extension_id, | |
| 456 &error); | |
| 457 if (extension.get()) | |
| 458 delayed_installs_.Insert(extension); | |
| 459 } | |
| 460 } | |
| 461 MaybeFinishDelayedInstallations(); | |
| 462 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2( | |
| 463 extension_prefs_->GetAllDelayedInstallInfo()); | |
| 464 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", | |
| 465 delayed_info2->size() - delayed_info->size()); | |
| 466 } | |
| 467 | |
|
Yoyo Zhou
2015/02/25 00:19:58
nit: extraneous newline
rkaplow
2015/02/25 16:37:49
Done.
| |
| 468 | |
| 463 void ExtensionService::LoadGreylistFromPrefs() { | 469 void ExtensionService::LoadGreylistFromPrefs() { |
| 470 TRACE_EVENT0("browser,startup", | |
| 471 "ExtensionService::LoadGreylistFromPrefs"); | |
| 472 | |
| 464 scoped_ptr<ExtensionSet> all_extensions = | 473 scoped_ptr<ExtensionSet> all_extensions = |
| 465 registry_->GenerateInstalledExtensionsSet(); | 474 registry_->GenerateInstalledExtensionsSet(); |
| 466 | 475 |
| 467 for (ExtensionSet::const_iterator it = all_extensions->begin(); | 476 for (ExtensionSet::const_iterator it = all_extensions->begin(); |
| 468 it != all_extensions->end(); ++it) { | 477 it != all_extensions->end(); ++it) { |
| 469 extensions::BlacklistState state = | 478 extensions::BlacklistState state = |
| 470 extension_prefs_->GetExtensionBlacklistState((*it)->id()); | 479 extension_prefs_->GetExtensionBlacklistState((*it)->id()); |
| 471 if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY || | 480 if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY || |
| 472 state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED || | 481 state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED || |
| 473 state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION) | 482 state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION) |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1253 updater_->CheckSoon(); | 1262 updater_->CheckSoon(); |
| 1254 } else { | 1263 } else { |
| 1255 // Sync can start updating before all the external providers are ready | 1264 // Sync can start updating before all the external providers are ready |
| 1256 // during startup. Start the update as soon as those providers are ready, | 1265 // during startup. Start the update as soon as those providers are ready, |
| 1257 // but not before. | 1266 // but not before. |
| 1258 update_once_all_providers_are_ready_ = true; | 1267 update_once_all_providers_are_ready_ = true; |
| 1259 } | 1268 } |
| 1260 } | 1269 } |
| 1261 | 1270 |
| 1262 // Some extensions will autoupdate themselves externally from Chrome. These | 1271 // Some extensions will autoupdate themselves externally from Chrome. These |
| 1263 // are typically part of some larger client application package. To support | 1272 // are typically part of some larger client application package. To support |
| 1264 // these, the extension will register its location in the the preferences file | 1273 // these, the extension will register its location in the preferences file |
| 1265 // (and also, on Windows, in the registry) and this code will periodically | 1274 // (and also, on Windows, in the registry) and this code will periodically |
| 1266 // check that location for a .crx file, which it will then install locally if | 1275 // check that location for a .crx file, which it will then install locally if |
| 1267 // a new version is available. | 1276 // a new version is available. |
| 1268 // Errors are reported through ExtensionErrorReporter. Succcess is not | 1277 // Errors are reported through ExtensionErrorReporter. Success is not |
| 1269 // reported. | 1278 // reported. |
| 1270 void ExtensionService::CheckForExternalUpdates() { | 1279 void ExtensionService::CheckForExternalUpdates() { |
| 1271 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1280 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1281 TRACE_EVENT0("browser,startup", | |
| 1282 "ExtensionService::CheckForExternalUpdates"); | |
| 1283 SCOPED_UMA_HISTOGRAM_TIMER("Extensions.CheckForExternalUpdatesTime"); | |
| 1272 | 1284 |
| 1273 // Note that this installation is intentionally silent (since it didn't | 1285 // Note that this installation is intentionally silent (since it didn't |
| 1274 // go through the front-end). Extensions that are registered in this | 1286 // go through the front-end). Extensions that are registered in this |
| 1275 // way are effectively considered 'pre-bundled', and so implicitly | 1287 // way are effectively considered 'pre-bundled', and so implicitly |
| 1276 // trusted. In general, if something has HKLM or filesystem access, | 1288 // trusted. In general, if something has HKLM or filesystem access, |
| 1277 // they could install an extension manually themselves anyway. | 1289 // they could install an extension manually themselves anyway. |
| 1278 | 1290 |
| 1279 // Ask each external extension provider to give us a call back for each | 1291 // Ask each external extension provider to give us a call back for each |
| 1280 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. | 1292 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. |
| 1281 extensions::ProviderCollection::const_iterator i; | 1293 extensions::ProviderCollection::const_iterator i; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1407 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit | 1419 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit |
| 1408 // warning about calling test code in production. | 1420 // warning about calling test code in production. |
| 1409 UnloadAllExtensionsInternal(); | 1421 UnloadAllExtensionsInternal(); |
| 1410 component_loader_->LoadAll(); | 1422 component_loader_->LoadAll(); |
| 1411 extensions::InstalledLoader(this).LoadAllExtensions(); | 1423 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 1412 // Don't call SetReadyAndNotifyListeners() since tests call this multiple | 1424 // Don't call SetReadyAndNotifyListeners() since tests call this multiple |
| 1413 // times. | 1425 // times. |
| 1414 } | 1426 } |
| 1415 | 1427 |
| 1416 void ExtensionService::SetReadyAndNotifyListeners() { | 1428 void ExtensionService::SetReadyAndNotifyListeners() { |
| 1417 const base::TimeTicks start_time = base::TimeTicks::Now(); | 1429 TRACE_EVENT0("browser,startup", |
| 1430 "ExtensionService::SetReadyAndNotifyListeners"); | |
| 1431 SCOPED_UMA_HISTOGRAM_TIMER( | |
| 1432 "Extensions.ExtensionServiceNotifyReadyListenersTime"); | |
|
Yoyo Zhou
2015/02/25 00:19:57
There are two metrics related to this one: Extensi
rkaplow
2015/02/25 16:37:49
Ok, switched to the cleaner SCOPED version there.
| |
| 1433 | |
| 1418 ready_->Signal(); | 1434 ready_->Signal(); |
| 1419 content::NotificationService::current()->Notify( | 1435 content::NotificationService::current()->Notify( |
| 1420 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, | 1436 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, |
| 1421 content::Source<Profile>(profile_), | 1437 content::Source<Profile>(profile_), |
| 1422 content::NotificationService::NoDetails()); | 1438 content::NotificationService::NoDetails()); |
| 1423 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceNotifyReadyListenersTime", | |
| 1424 base::TimeTicks::Now() - start_time); | |
| 1425 } | 1439 } |
| 1426 | 1440 |
| 1427 void ExtensionService::OnLoadedInstalledExtensions() { | 1441 void ExtensionService::OnLoadedInstalledExtensions() { |
| 1428 if (updater_) | 1442 if (updater_) |
| 1429 updater_->Start(); | 1443 updater_->Start(); |
| 1430 | 1444 |
| 1431 OnBlacklistUpdated(); | 1445 OnBlacklistUpdated(); |
| 1432 } | 1446 } |
| 1433 | 1447 |
| 1434 void ExtensionService::AddExtension(const Extension* extension) { | 1448 void ExtensionService::AddExtension(const Extension* extension) { |
| (...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2547 } | 2561 } |
| 2548 | 2562 |
| 2549 void ExtensionService::OnProfileDestructionStarted() { | 2563 void ExtensionService::OnProfileDestructionStarted() { |
| 2550 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2564 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
| 2551 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2565 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
| 2552 it != ids_to_unload.end(); | 2566 it != ids_to_unload.end(); |
| 2553 ++it) { | 2567 ++it) { |
| 2554 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2568 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
| 2555 } | 2569 } |
| 2556 } | 2570 } |
| OLD | NEW |