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

Unified Diff: extensions/browser/process_manager.cc

Issue 408523005: Reland: Refactor code that defers extension background page loading (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: dependency inject ExtensionRegistry Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: extensions/browser/process_manager.cc
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc
index e6beddbb891fcd56bf272cd5e58494f172773b20..72fbd2c686f5613723e0fe4e0010223b85d6e447 100644
--- a/extensions/browser/process_manager.cc
+++ b/extensions/browser/process_manager.cc
@@ -33,6 +33,7 @@
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/process_manager_delegate.h"
#include "extensions/browser/process_manager_observer.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h"
@@ -105,7 +106,8 @@ class IncognitoProcessManager : public ProcessManager {
public:
IncognitoProcessManager(BrowserContext* incognito_context,
BrowserContext* original_context,
- ProcessManager* original_manager);
+ ProcessManager* original_manager,
+ ExtensionRegistry* extension_registry);
virtual ~IncognitoProcessManager() {}
virtual bool CreateBackgroundHost(const Extension* extension,
const GURL& url) OVERRIDE;
@@ -190,6 +192,7 @@ struct ProcessManager::BackgroundPageData {
// static
ProcessManager* ProcessManager::Create(BrowserContext* context) {
+ ExtensionRegistry* extension_registry = ExtensionRegistry::Get(context);
ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get();
if (client->IsGuestSession(context)) {
// In the guest session, there is a single off-the-record context. Unlike
@@ -197,7 +200,7 @@ ProcessManager* ProcessManager::Create(BrowserContext* context) {
// created regardless of whether extensions use "spanning" or "split"
// incognito behavior.
BrowserContext* original_context = client->GetOriginalContext(context);
- return new ProcessManager(context, original_context);
+ return new ProcessManager(context, original_context, extension_registry);
}
if (context->IsOffTheRecord()) {
@@ -205,31 +208,46 @@ ProcessManager* ProcessManager::Create(BrowserContext* context) {
ProcessManager* original_manager =
ExtensionSystem::Get(original_context)->process_manager();
return new IncognitoProcessManager(
- context, original_context, original_manager);
+ context, original_context, original_manager, extension_registry);
}
- return new ProcessManager(context, context);
+ return new ProcessManager(context, context, extension_registry);
+}
+
+// static
+ProcessManager* ProcessManager::CreateForTesting(
+ BrowserContext* context,
+ ExtensionRegistry* extension_registry) {
+ DCHECK(!context->IsOffTheRecord());
+ return new ProcessManager(context, context, extension_registry);
}
// static
ProcessManager* ProcessManager::CreateIncognitoForTesting(
BrowserContext* incognito_context,
BrowserContext* original_context,
- ProcessManager* original_manager) {
+ ProcessManager* original_manager,
+ ExtensionRegistry* extension_registry) {
DCHECK(incognito_context->IsOffTheRecord());
DCHECK(!original_context->IsOffTheRecord());
- return new IncognitoProcessManager(
- incognito_context, original_context, original_manager);
+ return new IncognitoProcessManager(incognito_context,
+ original_context,
+ original_manager,
+ extension_registry);
}
ProcessManager::ProcessManager(BrowserContext* context,
- BrowserContext* original_context)
+ BrowserContext* original_context,
+ ExtensionRegistry* extension_registry)
: site_instance_(SiteInstance::Create(context)),
+ extension_registry_(extension_registry),
startup_background_hosts_created_(false),
devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged,
base::Unretained(this))),
last_background_close_sequence_id_(0),
weak_ptr_factory_(this) {
+ // ExtensionRegistry is shared between incognito and regular contexts.
+ DCHECK_EQ(original_context, extension_registry_->browser_context());
registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
content::Source<BrowserContext>(original_context));
registrar_.Add(this,
@@ -245,8 +263,6 @@ ProcessManager::ProcessManager(BrowserContext* context,
content::NotificationService::AllSources());
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
content::NotificationService::AllSources());
- registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
- content::Source<BrowserContext>(original_context));
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
content::Source<BrowserContext>(context));
if (context->IsOffTheRecord()) {
@@ -307,11 +323,14 @@ bool ProcessManager::CreateBackgroundHost(const Extension* extension,
const GURL& url) {
// Hosted apps are taken care of from BackgroundContentsService. Ignore them
// here.
- if (extension->is_hosted_app() ||
- !ExtensionsBrowserClient::Get()->
- IsBackgroundPageAllowed(GetBrowserContext())) {
+ if (extension->is_hosted_app())
+ return false;
+
+ // Don't create hosts if the embedder doesn't allow it.
+ ProcessManagerDelegate* delegate =
+ ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
+ if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext()))
return false;
- }
// Don't create multiple background hosts for an extension.
if (GetBackgroundHostForExtension(extension->id()))
@@ -360,11 +379,7 @@ const Extension* ProcessManager::GetExtensionForRenderViewHost(
if (!render_view_host->GetSiteInstance())
return NULL;
- ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext());
- if (!registry)
- return NULL;
-
- return registry->enabled_extensions().GetByID(
+ return extension_registry_->enabled_extensions().GetByID(
GetExtensionID(render_view_host));
}
@@ -440,9 +455,7 @@ void ProcessManager::DecrementLazyKeepaliveCount(
const std::string& extension_id) {
int& count = background_page_data_[extension_id].lazy_keepalive_count;
DCHECK(count > 0 ||
- !ExtensionRegistry::Get(GetBrowserContext())
- ->enabled_extensions()
- .Contains(extension_id));
+ !extension_registry_->enabled_extensions().Contains(extension_id));
// If we reach a zero keepalive count when the lazy background page is about
// to be closed, incrementing close_sequence_id will cancel the close
@@ -620,16 +633,6 @@ void ProcessManager::CancelSuspend(const Extension* extension) {
}
}
-void ProcessManager::OnBrowserWindowReady() {
- // If the extension system isn't ready yet the background hosts will be
- // created via NOTIFICATION_EXTENSIONS_READY below.
- ExtensionSystem* system = ExtensionSystem::Get(GetBrowserContext());
- if (!system->ready().is_signaled())
- return;
-
- CreateBackgroundHostsForProfileStartup();
-}
-
content::BrowserContext* ProcessManager::GetBrowserContext() const {
return site_instance_->GetBrowserContext();
}
@@ -648,15 +651,10 @@ void ProcessManager::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case chrome::NOTIFICATION_EXTENSIONS_READY:
- case chrome::NOTIFICATION_PROFILE_CREATED: {
- // Don't load background hosts now if the loading should be deferred.
- // Instead they will be loaded when a browser window for this profile
- // (or an incognito profile from this profile) is ready.
- if (DeferLoadingBackgroundHosts())
- break;
-
- CreateBackgroundHostsForProfileStartup();
+ case chrome::NOTIFICATION_EXTENSIONS_READY: {
+ // TODO(jamescook): Convert this to use ExtensionSystem::ready() instead
+ // of a notification.
+ MaybeCreateStartupBackgroundHosts();
break;
}
@@ -784,24 +782,24 @@ void ProcessManager::OnDevToolsStateChanged(
}
}
-void ProcessManager::CreateBackgroundHostsForProfileStartup() {
- if (startup_background_hosts_created_ ||
- !ExtensionsBrowserClient::Get()->
- IsBackgroundPageAllowed(GetBrowserContext())) {
+void ProcessManager::MaybeCreateStartupBackgroundHosts() {
+ if (startup_background_hosts_created_)
return;
- }
- const ExtensionSet& enabled_extensions =
- ExtensionRegistry::Get(GetBrowserContext())->enabled_extensions();
- for (ExtensionSet::const_iterator extension = enabled_extensions.begin();
- extension != enabled_extensions.end();
- ++extension) {
- CreateBackgroundHostForExtensionLoad(this, extension->get());
+ // The embedder might disallow background pages entirely.
+ ProcessManagerDelegate* delegate =
+ ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
+ if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext()))
+ return;
- FOR_EACH_OBSERVER(ProcessManagerObserver,
- observer_list_,
- OnBackgroundHostStartup(*extension));
- }
+ // The embedder might want to defer background page loading. For example,
+ // Chrome defers background page loading when it is launched to show the app
+ // list, then triggers a load later when a browser window opens.
+ if (delegate &&
+ delegate->DeferCreatingStartupBackgroundHosts(GetBrowserContext()))
+ return;
+
+ CreateStartupBackgroundHosts();
startup_background_hosts_created_ = true;
// Background pages should only be loaded once. To prevent any further loads
@@ -810,14 +808,6 @@ void ProcessManager::CreateBackgroundHostsForProfileStartup() {
ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext());
if (registrar_.IsRegistered(
this,
- chrome::NOTIFICATION_PROFILE_CREATED,
- content::Source<BrowserContext>(original_context))) {
- registrar_.Remove(this,
- chrome::NOTIFICATION_PROFILE_CREATED,
- content::Source<BrowserContext>(original_context));
- }
- if (registrar_.IsRegistered(
- this,
chrome::NOTIFICATION_EXTENSIONS_READY,
content::Source<BrowserContext>(original_context))) {
registrar_.Remove(this,
@@ -826,6 +816,21 @@ void ProcessManager::CreateBackgroundHostsForProfileStartup() {
}
}
+void ProcessManager::CreateStartupBackgroundHosts() {
+ DCHECK(!startup_background_hosts_created_);
+ const ExtensionSet& enabled_extensions =
+ extension_registry_->enabled_extensions();
+ for (ExtensionSet::const_iterator extension = enabled_extensions.begin();
+ extension != enabled_extensions.end();
+ ++extension) {
+ CreateBackgroundHostForExtensionLoad(this, extension->get());
+
+ FOR_EACH_OBSERVER(ProcessManagerObserver,
+ observer_list_,
+ OnBackgroundHostStartup(*extension));
+ }
+}
+
void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) {
DCHECK_EQ(GetBrowserContext(), host->browser_context());
background_hosts_.insert(host);
@@ -890,12 +895,6 @@ void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) {
}
}
-bool ProcessManager::DeferLoadingBackgroundHosts() const {
- // The extensions embedder may have special rules about background hosts.
- return ExtensionsBrowserClient::Get()->DeferLoadingBackgroundHosts(
- GetBrowserContext());
-}
-
//
// IncognitoProcessManager
//
@@ -903,8 +902,9 @@ bool ProcessManager::DeferLoadingBackgroundHosts() const {
IncognitoProcessManager::IncognitoProcessManager(
BrowserContext* incognito_context,
BrowserContext* original_context,
- ProcessManager* original_manager)
- : ProcessManager(incognito_context, original_context),
+ ProcessManager* original_manager,
+ ExtensionRegistry* extension_registry)
+ : ProcessManager(incognito_context, original_context, extension_registry),
original_manager_(original_manager) {
DCHECK(incognito_context->IsOffTheRecord());
@@ -914,8 +914,6 @@ IncognitoProcessManager::IncognitoProcessManager(
// in the NOTIFICATION_BROWSER_WINDOW_READY notification handler.
registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY,
content::Source<BrowserContext>(original_context));
- registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_CREATED,
- content::Source<BrowserContext>(original_context));
}
bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,
@@ -932,14 +930,11 @@ bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,
}
SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) {
- ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext());
- if (registry) {
- const Extension* extension =
- registry->enabled_extensions().GetExtensionOrAppByURL(url);
- if (extension && !IncognitoInfo::IsSplitMode(extension)) {
- return original_manager_->GetSiteInstanceForURL(url);
- }
- }
+ const Extension* extension =
+ extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url);
+ if (extension && !IncognitoInfo::IsSplitMode(extension))
+ return original_manager_->GetSiteInstanceForURL(url);
+
return ProcessManager::GetSiteInstanceForURL(url);
}

Powered by Google App Engine
This is Rietveld 408576698