Chromium Code Reviews| Index: chrome/browser/extensions/lazy_background_task_queue.cc |
| diff --git a/chrome/browser/extensions/lazy_background_task_queue.cc b/chrome/browser/extensions/lazy_background_task_queue.cc |
| index bb1b1a21d238d00fc82d0f2161d915a13776e8f1..93d56768459decb8d6280a371dc15614962ca6bd 100644 |
| --- a/chrome/browser/extensions/lazy_background_task_queue.cc |
| +++ b/chrome/browser/extensions/lazy_background_task_queue.cc |
| @@ -5,6 +5,7 @@ |
| #include "chrome/browser/extensions/lazy_background_task_queue.h" |
| #include "base/callback.h" |
| +#include "base/message_loop.h" |
| #include "chrome/browser/extensions/extension_host.h" |
| #include "chrome/browser/extensions/extension_process_manager.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| @@ -43,10 +44,12 @@ bool LazyBackgroundTaskQueue::ShouldEnqueueTask( |
| Profile* profile, const Extension* extension) { |
| DCHECK(extension); |
| if (extension->has_lazy_background_page()) { |
| - ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); |
| + ExtensionProcessManager* pm = |
| + ExtensionSystem::Get(profile)->process_manager(); |
| ExtensionHost* background_host = |
| pm->GetBackgroundHostForExtension(extension->id()); |
| - if (!background_host || !background_host->did_stop_loading()) |
| + if (!background_host || !background_host->did_stop_loading() || |
| + pm->IsBackgroundHostClosing(extension->id())) |
| return true; |
| } |
| @@ -66,14 +69,8 @@ void LazyBackgroundTaskQueue::AddPendingTask( |
| // If this is the first enqueued task, ensure the background page |
|
Yoyo Zhou
2012/04/19 21:47:13
This comment needs an "and we are not waiting for
Matt Perry
2012/04/19 22:21:53
Done.
|
| // is loaded. |
| - const Extension* extension = |
| - ExtensionSystem::Get(profile)->extension_service()-> |
| - extensions()->GetByID(extension_id); |
| - DCHECK(extension->has_lazy_background_page()); |
| - ExtensionProcessManager* pm = |
| - ExtensionSystem::Get(profile)->process_manager(); |
| - pm->IncrementLazyKeepaliveCount(extension); |
| - pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); |
| + if (pending_page_loads_.count(key) == 0) |
| + StartLazyBackgroundPage(profile, extension_id); |
| } else { |
| tasks_list = it->second.get(); |
| } |
| @@ -81,6 +78,26 @@ void LazyBackgroundTaskQueue::AddPendingTask( |
| tasks_list->push_back(task); |
| } |
| +void LazyBackgroundTaskQueue::StartLazyBackgroundPage( |
| + Profile* profile, const std::string& extension_id) { |
| + ExtensionProcessManager* pm = |
| + ExtensionSystem::Get(profile)->process_manager(); |
| + if (pm->IsBackgroundHostClosing(extension_id)) { |
| + // When the background host finishes closing, we will reload it. |
| + pending_page_loads_.insert(PendingTasksKey(profile, extension_id)); |
| + return; |
| + } |
| + |
| + const Extension* extension = |
| + ExtensionSystem::Get(profile)->extension_service()-> |
| + extensions()->GetByID(extension_id); |
| + DCHECK(extension->has_lazy_background_page()); |
| + pm->IncrementLazyKeepaliveCount(extension); |
| + pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); |
| + |
| + pending_page_loads_.erase(PendingTasksKey(profile, extension_id)); |
| +} |
| + |
| void LazyBackgroundTaskQueue::ProcessPendingTasks( |
| ExtensionHost* host, |
| Profile* profile, |
| @@ -130,15 +147,24 @@ void LazyBackgroundTaskQueue::Observe( |
| break; |
| } |
| case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
| - // Notify consumers about the load failure when the background host dies. |
| - // This can happen if the extension crashes. This is not strictly |
| - // necessary, since we also unload the extension in that case (which |
| - // dispatches the tasks below), but is a good extra precaution. |
| Profile* profile = content::Source<Profile>(source).ptr(); |
| ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
| if (host->extension_host_type() == |
| chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| - ProcessPendingTasks(NULL, profile, host->extension()); |
| + PendingTasksKey key(profile, host->extension()->id()); |
| + if (pending_page_loads_.count(key) > 0) { |
| + // We were waiting for the background page to unload. We can start it |
| + // up again and dispatch any queued events. |
| + MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| + &LazyBackgroundTaskQueue::StartLazyBackgroundPage, |
| + base::Unretained(this), profile, host->extension()->id())); |
|
Yoyo Zhou
2012/04/19 21:47:13
If we might be receiving this notification near sh
Matt Perry
2012/04/19 22:21:53
Done.
|
| + } else { |
| + // This may be a load failure (e.g. a crash). In that case, notify |
| + // consumers about the load failure. This is not strictly necessary, |
| + // since we also unload the extension in that case (which dispatches |
| + // the tasks below), but is a good extra precaution. |
| + ProcessPendingTasks(NULL, profile, host->extension()); |
| + } |
| } |
| break; |
| } |