diff options
author | koz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-26 02:30:42 +0000 |
---|---|---|
committer | koz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-26 02:30:42 +0000 |
commit | 0d475e07595527beb2789846ffe70ba680667073 (patch) | |
tree | ca895d320e634ce1ae79422eccec007cff7bac16 /chrome/browser/extensions | |
parent | 6cda04ba4a062493aa66740a1b49ff217bc90110 (diff) | |
download | chromium_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')
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 |