Index: chrome/browser/extensions/extension_process_manager.cc |
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc |
index f249cf4985e073a1d6ea880d38e74952dceec7ff..97dc567e9ce3d87bd2b338b1dc2cb22b30d34497 100644 |
--- a/chrome/browser/extensions/extension_process_manager.cc |
+++ b/chrome/browser/extensions/extension_process_manager.cc |
@@ -53,6 +53,12 @@ int& GetLazyKeepaliveCount(Profile* profile, const Extension* extension) { |
return *count; |
} |
+std::string GetExtensionID(RenderViewHost* render_view_host) { |
+ // This works for both apps and extensions because the site has been |
+ // normalized to the extension URL for apps. |
+ return render_view_host->site_instance()->GetSite().host(); |
+} |
+ |
// Incognito profiles use this process manager. It is mostly a shim that decides |
// whether to fall back on the original profile's ExtensionProcessManager based |
// on whether a given extension uses "split" or "spanning" incognito behavior. |
@@ -123,6 +129,8 @@ ExtensionProcessManager::ExtensionProcessManager(Profile* profile) |
content::Source<Profile>(profile)); |
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
content::Source<Profile>(profile)); |
+ registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, |
+ content::NotificationService::AllSources()); |
registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, |
content::NotificationService::AllSources()); |
} |
@@ -263,7 +271,6 @@ ExtensionHost* ExtensionProcessManager::GetBackgroundHostForExtension( |
return host; |
} |
return NULL; |
- |
} |
std::set<RenderViewHost*> |
@@ -277,10 +284,10 @@ std::set<RenderViewHost*> |
return result; |
// Gather up all the views for that site. |
- for (RenderViewHostSet::iterator view = all_extension_views_.begin(); |
+ for (ExtensionRenderViews::iterator view = all_extension_views_.begin(); |
view != all_extension_views_.end(); ++view) { |
- if ((*view)->site_instance() == site_instance) |
- result.insert(*view); |
+ if (view->first->site_instance() == site_instance) |
+ result.insert(view->first); |
} |
return result; |
@@ -289,16 +296,53 @@ std::set<RenderViewHost*> |
void ExtensionProcessManager::RegisterRenderViewHost( |
RenderViewHost* render_view_host, |
const Extension* extension) { |
- all_extension_views_.insert(render_view_host); |
+ all_extension_views_[render_view_host] = content::VIEW_TYPE_INVALID; |
} |
void ExtensionProcessManager::UnregisterRenderViewHost( |
RenderViewHost* render_view_host) { |
- all_extension_views_.erase(render_view_host); |
+ ExtensionRenderViews::iterator view = |
+ all_extension_views_.find(render_view_host); |
+ if (view == all_extension_views_.end()) |
+ return; |
+ |
+ content::ViewType view_type = view->second; |
+ all_extension_views_.erase(view); |
+ |
+ // Keepalive count, balanced in UpdateRegisteredRenderView. |
+ if (view_type != content::VIEW_TYPE_INVALID && |
+ view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
+ const Extension* extension = |
+ GetProfile()->GetExtensionService()->extensions()->GetByID( |
+ GetExtensionID(render_view_host)); |
+ if (extension) |
+ DecrementLazyKeepaliveCount(extension); |
+ } |
} |
-SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL( |
- const GURL& url) { |
+void ExtensionProcessManager::UpdateRegisteredRenderView( |
+ RenderViewHost* render_view_host) { |
+ ExtensionRenderViews::iterator view = |
+ all_extension_views_.find(render_view_host); |
+ if (view == all_extension_views_.end()) |
+ return; |
+ |
+ view->second = render_view_host->delegate()->GetRenderViewType(); |
+ |
+ // Keep the lazy background page alive as long as any non-background-page |
+ // extension views are visible. Keepalive count balanced in |
+ // UnregisterRenderViewHost. |
+ if (view->second != content::VIEW_TYPE_INVALID && |
+ view->second != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
+ const Extension* extension = |
+ GetProfile()->GetExtensionService()->extensions()->GetByID( |
+ GetExtensionID(render_view_host)); |
+ if (extension) |
+ IncrementLazyKeepaliveCount(extension); |
+ } |
+} |
+ |
+SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { |
return site_instance_->GetRelatedSiteInstance(url); |
} |
@@ -318,7 +362,6 @@ int ExtensionProcessManager::IncrementLazyKeepaliveCount( |
if (extension->background_page_persists()) |
return 0; |
- // TODO(mpcomplete): Handle visible views changing. |
int& count = ::GetLazyKeepaliveCount(GetProfile(), extension); |
if (++count == 1) |
OnLazyBackgroundPageActive(extension->id()); |
@@ -342,7 +385,7 @@ int ExtensionProcessManager::DecrementLazyKeepaliveCount( |
void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
const std::string& extension_id) { |
ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
- if (host && !HasVisibleViews(extension_id)) |
+ if (host) |
host->SendShouldClose(); |
} |
@@ -360,19 +403,20 @@ void ExtensionProcessManager::OnShouldCloseAck( |
host->OnShouldCloseAck(sequence_id); |
} |
-bool ExtensionProcessManager::HasVisibleViews(const std::string& extension_id) { |
- const std::set<RenderViewHost*>& views = |
- GetRenderViewHostsForExtension(extension_id); |
- for (std::set<RenderViewHost*>::const_iterator it = views.begin(); |
- it != views.end(); ++it) { |
- const RenderViewHost* host = *it; |
- if (host->site_instance()->GetSite().host() == extension_id && |
- host->delegate()->GetRenderViewType() != |
- chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
- return true; |
- } |
- } |
- return false; |
+void ExtensionProcessManager::OnNetworkRequestStarted( |
+ RenderViewHost* render_view_host) { |
+ ExtensionHost* host = GetBackgroundHostForExtension( |
+ GetExtensionID(render_view_host)); |
+ if (host) |
+ IncrementLazyKeepaliveCount(host->extension()); |
+} |
+ |
+void ExtensionProcessManager::OnNetworkRequestDone( |
+ RenderViewHost* render_view_host) { |
+ ExtensionHost* host = GetBackgroundHostForExtension( |
+ GetExtensionID(render_view_host)); |
+ if (host) |
+ DecrementLazyKeepaliveCount(host->extension()); |
} |
void ExtensionProcessManager::Observe( |
@@ -428,6 +472,13 @@ void ExtensionProcessManager::Observe( |
break; |
} |
+ case content::NOTIFICATION_WEB_CONTENTS_CONNECTED: { |
+ content::WebContents* contents = |
+ content::Source<content::WebContents>(source).ptr(); |
+ UpdateRegisteredRenderView(contents->GetRenderViewHost()); |
+ break; |
+ } |
+ |
case content::NOTIFICATION_APP_TERMINATING: { |
// Close background hosts when the last browser is closed so that they |
// have time to shutdown various objects on different threads. Our |