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

Unified Diff: extensions/browser/process_manager.cc

Issue 689833005: Add a way to kill apps without killing windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Win compile Created 6 years, 1 month 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
« no previous file with comments | « extensions/browser/process_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/browser/process_manager.cc
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc
index 60af62c4c83d9b9ed6bfd434573bc243867e620e..5e2e3aa0dcd1397ff692e3fc3ce3c25cdf671ad3 100644
--- a/extensions/browser/process_manager.cc
+++ b/extensions/browser/process_manager.cc
@@ -192,6 +192,40 @@ struct ProcessManager::BackgroundPageData {
close_sequence_id(0) {}
};
+// Data of a RenderViewHost associated with an extension.
+struct ProcessManager::ExtensionRenderViewData {
+ // The type of the view.
+ extensions::ViewType view_type;
+
+ // Whether the view is keeping the lazy background page alive or not.
+ bool has_keepalive;
+
+ ExtensionRenderViewData()
+ : view_type(VIEW_TYPE_INVALID), has_keepalive(false) {}
+
+ // Returns whether the view can keep the lazy background page alive or not.
+ bool CanKeepalive() const {
+ switch (view_type) {
+ case VIEW_TYPE_APP_WINDOW:
+ case VIEW_TYPE_BACKGROUND_CONTENTS:
+ case VIEW_TYPE_EXTENSION_DIALOG:
+ case VIEW_TYPE_EXTENSION_INFOBAR:
+ case VIEW_TYPE_EXTENSION_POPUP:
+ case VIEW_TYPE_LAUNCHER_PAGE:
+ case VIEW_TYPE_PANEL:
+ case VIEW_TYPE_TAB_CONTENTS:
+ case VIEW_TYPE_VIRTUAL_KEYBOARD:
+ return true;
+
+ case VIEW_TYPE_INVALID:
+ case VIEW_TYPE_EXTENSION_BACKGROUND_PAGE:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+ }
+};
+
//
// ProcessManager
//
@@ -368,6 +402,40 @@ const Extension* ProcessManager::GetExtensionForRenderViewHost(
GetExtensionID(render_view_host));
}
+void ProcessManager::AcquireLazyKeepaliveCountForView(
+ content::RenderViewHost* render_view_host) {
+ auto it = all_extension_views_.find(render_view_host);
+ if (it == all_extension_views_.end())
+ return;
+
+ ExtensionRenderViewData* data = &it->second;
+ if (data->CanKeepalive() && !data->has_keepalive) {
+ const Extension* extension =
+ GetExtensionForRenderViewHost(render_view_host);
+ if (extension) {
+ IncrementLazyKeepaliveCount(extension);
+ data->has_keepalive = true;
+ }
+ }
+}
+
+void ProcessManager::ReleaseLazyKeepaliveCountForView(
+ content::RenderViewHost* render_view_host) {
+ auto it = all_extension_views_.find(render_view_host);
+ if (it == all_extension_views_.end())
+ return;
+
+ ExtensionRenderViewData* data = &it->second;
+ if (data->CanKeepalive() && data->has_keepalive) {
+ const Extension* extension =
+ GetExtensionForRenderViewHost(render_view_host);
+ if (extension) {
+ DecrementLazyKeepaliveCount(extension);
+ data->has_keepalive = false;
+ }
+ }
+}
+
void ProcessManager::UnregisterRenderViewHost(
RenderViewHost* render_view_host) {
ExtensionRenderViews::iterator view =
@@ -376,17 +444,10 @@ void ProcessManager::UnregisterRenderViewHost(
return;
OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host);
- ViewType view_type = view->second;
- all_extension_views_.erase(view);
// Keepalive count, balanced in RegisterRenderViewHost.
- if (view_type != VIEW_TYPE_INVALID &&
- view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
- const Extension* extension = GetExtensionForRenderViewHost(
- render_view_host);
- if (extension)
- DecrementLazyKeepaliveCount(extension);
- }
+ ReleaseLazyKeepaliveCountForView(render_view_host);
+ all_extension_views_.erase(view);
}
bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) {
@@ -396,12 +457,13 @@ bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) {
return false;
WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host);
- all_extension_views_[render_view_host] = GetViewType(web_contents);
+ ExtensionRenderViewData* data = &all_extension_views_[render_view_host];
+ data->view_type = GetViewType(web_contents);
// Keep the lazy background page alive as long as any non-background-page
// extension views are visible. Keepalive count balanced in
// UnregisterRenderViewHost.
- IncrementLazyKeepaliveCountForView(render_view_host);
+ AcquireLazyKeepaliveCountForView(render_view_host);
return true;
}
@@ -459,20 +521,6 @@ void ProcessManager::DecrementLazyKeepaliveCount(
}
}
-void ProcessManager::IncrementLazyKeepaliveCountForView(
- RenderViewHost* render_view_host) {
- WebContents* web_contents =
- WebContents::FromRenderViewHost(render_view_host);
- ViewType view_type = GetViewType(web_contents);
- if (view_type != VIEW_TYPE_INVALID &&
- view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
- const Extension* extension = GetExtensionForRenderViewHost(
- render_view_host);
- if (extension)
- IncrementLazyKeepaliveCount(extension);
- }
-}
-
// This implementation layers on top of the keepalive count. An impulse sets
// a per extension flag. On a regular interval that flag is checked. Changes
// from the flag not being set to set cause an IncrementLazyKeepaliveCount.
@@ -606,6 +654,24 @@ void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id,
ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
if (host &&
sequence_id == background_page_data_[extension_id].close_sequence_id) {
+ // Close remaining views.
+ std::vector<RenderViewHost*> views_to_close;
+ for (const auto& view : all_extension_views_) {
+ if (view.second.CanKeepalive() &&
+ GetExtensionID(view.first) == extension_id) {
+ DCHECK(!view.second.has_keepalive);
+ views_to_close.push_back(view.first);
+ }
+ }
+ for (auto view : views_to_close) {
+ view->ClosePage();
+ // RenderViewHost::ClosePage() may result in calling
+ // UnregisterRenderViewHost() asynchronously and may cause race conditions
+ // when the background page is reloaded.
+ // To avoid this, unregister the view now.
+ UnregisterRenderViewHost(view);
+ }
+
ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
if (host)
CloseBackgroundHost(host);
@@ -908,8 +974,15 @@ void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) {
// views.
for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin();
it != all_extension_views_.end(); ++it) {
- if (GetExtensionID(it->first) == extension_id)
- IncrementLazyKeepaliveCountForView(it->first);
+ RenderViewHost* view = it->first;
+ const ExtensionRenderViewData& data = it->second;
+ // Do not increment the count when |has_keepalive| is false
+ // (i.e. ReleaseLazyKeepaliveCountForView() was called).
+ if (GetExtensionID(view) == extension_id && data.has_keepalive) {
+ const Extension* extension = GetExtensionForRenderViewHost(view);
+ if (extension)
+ IncrementLazyKeepaliveCount(extension);
+ }
}
}
« no previous file with comments | « extensions/browser/process_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698