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

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

Issue 959513002: Refactor Extension initialization logic. Add tracing and additional histogram. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: yoz and asvitkine comments 1 Created 5 years, 9 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 <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
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
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 }
416 }
458 417
459 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", 418 void ExtensionService::EnabledReloadableExtensions() {
460 base::Time::Now() - begin_time); 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 (const std::string& extension : extensions_to_enable) {
433 EnableExtension(extension);
434 }
435 }
436
437 void ExtensionService::MaybeFinishShutdownDelayed() {
438 TRACE_EVENT0("browser,startup",
439 "ExtensionService::MaybeFinishShutdownDelayed");
440
441 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info(
442 extension_prefs_->GetAllDelayedInstallInfo());
443 for (size_t i = 0; i < delayed_info->size(); ++i) {
444 ExtensionInfo* info = delayed_info->at(i).get();
445 scoped_refptr<const Extension> extension(NULL);
446 if (info->extension_manifest) {
447 std::string error;
448 extension = Extension::Create(
449 info->extension_path, info->extension_location,
450 *info->extension_manifest,
451 extension_prefs_->GetDelayedInstallCreationFlags(info->extension_id),
452 info->extension_id, &error);
453 if (extension.get())
454 delayed_installs_.Insert(extension);
455 }
456 }
457 MaybeFinishDelayedInstallations();
458 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2(
459 extension_prefs_->GetAllDelayedInstallInfo());
460 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad",
461 delayed_info2->size() - delayed_info->size());
461 } 462 }
462 463
463 void ExtensionService::LoadGreylistFromPrefs() { 464 void ExtensionService::LoadGreylistFromPrefs() {
465 TRACE_EVENT0("browser,startup", "ExtensionService::LoadGreylistFromPrefs");
466
464 scoped_ptr<ExtensionSet> all_extensions = 467 scoped_ptr<ExtensionSet> all_extensions =
465 registry_->GenerateInstalledExtensionsSet(); 468 registry_->GenerateInstalledExtensionsSet();
466 469
467 for (ExtensionSet::const_iterator it = all_extensions->begin(); 470 for (ExtensionSet::const_iterator it = all_extensions->begin();
468 it != all_extensions->end(); ++it) { 471 it != all_extensions->end(); ++it) {
469 extensions::BlacklistState state = 472 extensions::BlacklistState state =
470 extension_prefs_->GetExtensionBlacklistState((*it)->id()); 473 extension_prefs_->GetExtensionBlacklistState((*it)->id());
471 if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY || 474 if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY ||
472 state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED || 475 state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED ||
473 state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION) 476 state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION)
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 updater_->CheckSoon(); 1256 updater_->CheckSoon();
1254 } else { 1257 } else {
1255 // Sync can start updating before all the external providers are ready 1258 // Sync can start updating before all the external providers are ready
1256 // during startup. Start the update as soon as those providers are ready, 1259 // during startup. Start the update as soon as those providers are ready,
1257 // but not before. 1260 // but not before.
1258 update_once_all_providers_are_ready_ = true; 1261 update_once_all_providers_are_ready_ = true;
1259 } 1262 }
1260 } 1263 }
1261 1264
1262 // Some extensions will autoupdate themselves externally from Chrome. These 1265 // Some extensions will autoupdate themselves externally from Chrome. These
1263 // are typically part of some larger client application package. To support 1266 // are typically part of some larger client application package. To support
1264 // these, the extension will register its location in the the preferences file 1267 // these, the extension will register its location in the preferences file
1265 // (and also, on Windows, in the registry) and this code will periodically 1268 // (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 1269 // check that location for a .crx file, which it will then install locally if
1267 // a new version is available. 1270 // a new version is available.
1268 // Errors are reported through ExtensionErrorReporter. Succcess is not 1271 // Errors are reported through ExtensionErrorReporter. Success is not
1269 // reported. 1272 // reported.
1270 void ExtensionService::CheckForExternalUpdates() { 1273 void ExtensionService::CheckForExternalUpdates() {
1271 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1274 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1275 TRACE_EVENT0("browser,startup", "ExtensionService::CheckForExternalUpdates");
1276 SCOPED_UMA_HISTOGRAM_TIMER("Extensions.CheckForExternalUpdatesTime");
1272 1277
1273 // Note that this installation is intentionally silent (since it didn't 1278 // Note that this installation is intentionally silent (since it didn't
1274 // go through the front-end). Extensions that are registered in this 1279 // go through the front-end). Extensions that are registered in this
1275 // way are effectively considered 'pre-bundled', and so implicitly 1280 // way are effectively considered 'pre-bundled', and so implicitly
1276 // trusted. In general, if something has HKLM or filesystem access, 1281 // trusted. In general, if something has HKLM or filesystem access,
1277 // they could install an extension manually themselves anyway. 1282 // they could install an extension manually themselves anyway.
1278 1283
1279 // Ask each external extension provider to give us a call back for each 1284 // Ask each external extension provider to give us a call back for each
1280 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. 1285 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found.
1281 extensions::ProviderCollection::const_iterator i; 1286 extensions::ProviderCollection::const_iterator i;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit 1412 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit
1408 // warning about calling test code in production. 1413 // warning about calling test code in production.
1409 UnloadAllExtensionsInternal(); 1414 UnloadAllExtensionsInternal();
1410 component_loader_->LoadAll(); 1415 component_loader_->LoadAll();
1411 extensions::InstalledLoader(this).LoadAllExtensions(); 1416 extensions::InstalledLoader(this).LoadAllExtensions();
1412 // Don't call SetReadyAndNotifyListeners() since tests call this multiple 1417 // Don't call SetReadyAndNotifyListeners() since tests call this multiple
1413 // times. 1418 // times.
1414 } 1419 }
1415 1420
1416 void ExtensionService::SetReadyAndNotifyListeners() { 1421 void ExtensionService::SetReadyAndNotifyListeners() {
1417 const base::TimeTicks start_time = base::TimeTicks::Now(); 1422 TRACE_EVENT0("browser,startup",
1423 "ExtensionService::SetReadyAndNotifyListeners");
1424 SCOPED_UMA_HISTOGRAM_TIMER(
1425 "Extensions.ExtensionServiceNotifyReadyListenersTime");
1426
1418 ready_->Signal(); 1427 ready_->Signal();
1419 content::NotificationService::current()->Notify( 1428 content::NotificationService::current()->Notify(
1420 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 1429 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
1421 content::Source<Profile>(profile_), 1430 content::Source<Profile>(profile_),
1422 content::NotificationService::NoDetails()); 1431 content::NotificationService::NoDetails());
1423 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceNotifyReadyListenersTime",
1424 base::TimeTicks::Now() - start_time);
1425 } 1432 }
1426 1433
1427 void ExtensionService::OnLoadedInstalledExtensions() { 1434 void ExtensionService::OnLoadedInstalledExtensions() {
1428 if (updater_) 1435 if (updater_)
1429 updater_->Start(); 1436 updater_->Start();
1430 1437
1431 OnBlacklistUpdated(); 1438 OnBlacklistUpdated();
1432 } 1439 }
1433 1440
1434 void ExtensionService::AddExtension(const Extension* extension) { 1441 void ExtensionService::AddExtension(const Extension* extension) {
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 } 2554 }
2548 2555
2549 void ExtensionService::OnProfileDestructionStarted() { 2556 void ExtensionService::OnProfileDestructionStarted() {
2550 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); 2557 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs();
2551 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); 2558 for (ExtensionIdSet::iterator it = ids_to_unload.begin();
2552 it != ids_to_unload.end(); 2559 it != ids_to_unload.end();
2553 ++it) { 2560 ++it) {
2554 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); 2561 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN);
2555 } 2562 }
2556 } 2563 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698