summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorkoz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-26 02:30:42 +0000
committerkoz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-26 02:30:42 +0000
commit0d475e07595527beb2789846ffe70ba680667073 (patch)
treeca895d320e634ce1ae79422eccec007cff7bac16 /chrome/browser/extensions
parent6cda04ba4a062493aa66740a1b49ff217bc90110 (diff)
downloadchromium_src-0d475e07595527beb2789846ffe70ba680667073.zip
chromium_src-0d475e07595527beb2789846ffe70ba680667073.tar.gz
chromium_src-0d475e07595527beb2789846ffe70ba680667073.tar.bz2
Introduce runtime.onSuspendCanceled() event.
runtime.onSuspendCanceled() is sent after runtime.onSuspend() to indicate that the extension / app will not be suspended after all. BUG=136469 Review URL: https://chromiumcodereview.appspot.com/10804020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/event_router.cc19
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc39
-rw-r--r--chrome/browser/extensions/extension_process_manager.h7
-rw-r--r--chrome/browser/extensions/lazy_background_task_queue.cc5
-rw-r--r--chrome/browser/extensions/lazy_background_task_queue.h4
5 files changed, 60 insertions, 14 deletions
diff --git a/chrome/browser/extensions/event_router.cc b/chrome/browser/extensions/event_router.cc
index ea91880..bdb00c3 100644
--- a/chrome/browser/extensions/event_router.cc
+++ b/chrome/browser/extensions/event_router.cc
@@ -357,6 +357,23 @@ void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id,
std::set<const EventListener*> listeners(
listeners_.GetEventListeners(*event));
+
+ // We dispatch events for lazy background pages first because attempting to do
+ // so will cause those that are being suspended to cancel that suspension.
+ // As canceling a suspension entails sending an event to the affected
+ // background page, and as that event needs to be delivered before we dispatch
+ // the event we are dispatching here, we dispatch to the lazy listeners here
+ // first.
+ for (std::set<const EventListener*>::iterator it = listeners.begin();
+ it != listeners.end(); it++) {
+ const EventListener* listener = *it;
+ if (restrict_to_extension_id.empty() ||
+ restrict_to_extension_id == listener->extension_id) {
+ if (!listener->process)
+ DispatchLazyEvent(listener->extension_id, event);
+ }
+ }
+
for (std::set<const EventListener*>::iterator it = listeners.begin();
it != listeners.end(); it++) {
const EventListener* listener = *it;
@@ -365,8 +382,6 @@ void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id,
if (listener->process) {
DispatchEventToProcess(listener->extension_id, listener->process,
event);
- } else {
- DispatchLazyEvent(listener->extension_id, event);
}
}
}
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index bfb1b4b..c4fa52b 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/logging.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/string_number_conversions.h"
@@ -111,9 +112,9 @@ struct ExtensionProcessManager::BackgroundPageData {
int close_sequence_id;
// True if the page responded to the ShouldUnload message and is currently
- // dispatching the unload event. We use this to ignore any activity
- // generated during the unload event that would otherwise keep the
- // extension alive.
+ // dispatching the unload event. During this time any events that arrive will
+ // cancel the unload process and an onSuspendCanceled event will be dispatched
+ // to the page.
bool is_closing;
// Keeps track of when this page was last unloaded. Used for perf metrics.
@@ -441,6 +442,7 @@ int ExtensionProcessManager::DecrementLazyKeepaliveCount(
return count;
}
+
void ExtensionProcessManager::IncrementLazyKeepaliveCountForView(
RenderViewHost* render_view_host) {
WebContents* web_contents =
@@ -491,19 +493,24 @@ void ExtensionProcessManager::OnShouldUnloadAck(
}
void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) {
+ background_page_data_[extension_id].is_closing = true;
+ int sequence_id = background_page_data_[extension_id].close_sequence_id;
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow,
- weak_ptr_factory_.GetWeakPtr(), extension_id),
+ weak_ptr_factory_.GetWeakPtr(), extension_id, sequence_id),
event_page_unloading_time_);
}
void ExtensionProcessManager::CloseLazyBackgroundPageNow(
- const std::string& extension_id) {
- background_page_data_[extension_id].is_closing = true;
+ const std::string& extension_id, int sequence_id) {
ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
- if (host)
- CloseBackgroundHost(host);
+ if (host &&
+ sequence_id == background_page_data_[extension_id].close_sequence_id) {
+ ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
+ if (host)
+ CloseBackgroundHost(host);
+ }
}
void ExtensionProcessManager::OnNetworkRequestStarted(
@@ -522,6 +529,22 @@ void ExtensionProcessManager::OnNetworkRequestDone(
DecrementLazyKeepaliveCount(host->extension());
}
+void ExtensionProcessManager::CancelSuspend(const Extension* extension) {
+ bool& is_closing = background_page_data_[extension->id()].is_closing;
+ ExtensionHost* host = GetBackgroundHostForExtension(extension->id());
+ if (host && is_closing) {
+ is_closing = false;
+ host->render_view_host()->Send(
+ new ExtensionMsg_CancelUnload(extension->id()));
+ // This increment / decrement is to simulate an instantaneous event. This
+ // has the effect of invalidating close_sequence_id, preventing any in
+ // progress closes from completing and starting a new close process if
+ // necessary.
+ IncrementLazyKeepaliveCount(extension);
+ DecrementLazyKeepaliveCount(extension);
+ }
+}
+
void ExtensionProcessManager::Observe(
int type,
const content::NotificationSource& source,
diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h
index eea1295..80e8e5a 100644
--- a/chrome/browser/extensions/extension_process_manager.h
+++ b/chrome/browser/extensions/extension_process_manager.h
@@ -132,6 +132,10 @@ class ExtensionProcessManager : public content::NotificationObserver {
void OnNetworkRequestStarted(content::RenderViewHost* render_view_host);
void OnNetworkRequestDone(content::RenderViewHost* render_view_host);
+ // Prevents |extension|'s background page from being closed and sends the
+ // onSuspendCanceled() event to it.
+ void CancelSuspend(const extensions::Extension* extension);
+
protected:
explicit ExtensionProcessManager(Profile* profile);
@@ -185,7 +189,8 @@ class ExtensionProcessManager : public content::NotificationObserver {
void OnLazyBackgroundPageIdle(const std::string& extension_id,
int sequence_id);
void OnLazyBackgroundPageActive(const std::string& extension_id);
- void CloseLazyBackgroundPageNow(const std::string& extension_id);
+ void CloseLazyBackgroundPageNow(const std::string& extension_id,
+ int sequence_id);
// Updates a potentially-registered RenderViewHost once it has been
// associated with a WebContents. This allows us to gather information that
diff --git a/chrome/browser/extensions/lazy_background_task_queue.cc b/chrome/browser/extensions/lazy_background_task_queue.cc
index 49bc222..89bf38e 100644
--- a/chrome/browser/extensions/lazy_background_task_queue.cc
+++ b/chrome/browser/extensions/lazy_background_task_queue.cc
@@ -48,9 +48,10 @@ bool LazyBackgroundTaskQueue::ShouldEnqueueTask(
ExtensionSystem::Get(profile)->process_manager();
ExtensionHost* background_host =
pm->GetBackgroundHostForExtension(extension->id());
- if (!background_host || !background_host->did_stop_loading() ||
- pm->IsBackgroundHostClosing(extension->id()))
+ if (!background_host || !background_host->did_stop_loading())
return true;
+ if (pm->IsBackgroundHostClosing(extension->id()))
+ pm->CancelSuspend(extension);
}
return false;
diff --git a/chrome/browser/extensions/lazy_background_task_queue.h b/chrome/browser/extensions/lazy_background_task_queue.h
index 70d1ac0..04f0b91 100644
--- a/chrome/browser/extensions/lazy_background_task_queue.h
+++ b/chrome/browser/extensions/lazy_background_task_queue.h
@@ -39,7 +39,9 @@ class LazyBackgroundTaskQueue
virtual ~LazyBackgroundTaskQueue();
// Returns true if the task should be added to the queue (that is, if the
- // extension has a lazy background page that isn't ready yet).
+ // extension has a lazy background page that isn't ready yet). If the
+ // extension has a lazy background page that is being suspended this method
+ // cancels that suspension.
bool ShouldEnqueueTask(Profile* profile, const Extension* extension);
// Adds a task to the queue for a given extension. If this is the first