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); |
} |