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

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: 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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698