| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/lazy_background_task_queue.h" | 5 #include "chrome/browser/extensions/lazy_background_task_queue.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "chrome/browser/extensions/extension_host.h" | 8 #include "chrome/browser/extensions/extension_host.h" |
| 9 #include "chrome/browser/extensions/extension_process_manager.h" | 9 #include "chrome/browser/extensions/extension_process_manager.h" |
| 10 #include "chrome/browser/extensions/extension_service.h" | 10 #include "chrome/browser/extensions/extension_service.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 35 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 36 content::Source<Profile>(profile)); | 36 content::Source<Profile>(profile)); |
| 37 } | 37 } |
| 38 | 38 |
| 39 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() { | 39 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() { |
| 40 } | 40 } |
| 41 | 41 |
| 42 bool LazyBackgroundTaskQueue::ShouldEnqueueTask( | 42 bool LazyBackgroundTaskQueue::ShouldEnqueueTask( |
| 43 Profile* profile, const Extension* extension) { | 43 Profile* profile, const Extension* extension) { |
| 44 DCHECK(extension); | 44 DCHECK(extension); |
| 45 if (extension->has_lazy_background_page()) { | 45 if (extension->has_background_page()) { |
| 46 ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); | 46 ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); |
| 47 ExtensionHost* background_host = | 47 ExtensionHost* background_host = |
| 48 pm->GetBackgroundHostForExtension(extension->id()); | 48 pm->GetBackgroundHostForExtension(extension->id()); |
| 49 if (!background_host || !background_host->did_stop_loading()) | 49 if (!background_host || !background_host->did_stop_loading()) |
| 50 return true; | 50 return true; |
| 51 if (pm->IsBackgroundHostClosing(extension->id())) | 51 if (pm->IsBackgroundHostClosing(extension->id())) |
| 52 pm->CancelSuspend(extension); | 52 pm->CancelSuspend(extension); |
| 53 } | 53 } |
| 54 | 54 |
| 55 return false; | 55 return false; |
| 56 } | 56 } |
| 57 | 57 |
| 58 void LazyBackgroundTaskQueue::AddPendingTask( | 58 void LazyBackgroundTaskQueue::AddPendingTask( |
| 59 Profile* profile, | 59 Profile* profile, |
| 60 const std::string& extension_id, | 60 const std::string& extension_id, |
| 61 const PendingTask& task) { | 61 const PendingTask& task) { |
| 62 PendingTasksList* tasks_list = NULL; | 62 PendingTasksList* tasks_list = NULL; |
| 63 PendingTasksKey key(profile, extension_id); | 63 PendingTasksKey key(profile, extension_id); |
| 64 PendingTasksMap::iterator it = pending_tasks_.find(key); | 64 PendingTasksMap::iterator it = pending_tasks_.find(key); |
| 65 if (it == pending_tasks_.end()) { | 65 if (it == pending_tasks_.end()) { |
| 66 tasks_list = new PendingTasksList(); | 66 tasks_list = new PendingTasksList(); |
| 67 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); | 67 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); |
| 68 | 68 |
| 69 // If this is the first enqueued task, ensure the background page | |
| 70 // is loaded. | |
| 71 const Extension* extension = | 69 const Extension* extension = |
| 72 ExtensionSystem::Get(profile)->extension_service()-> | 70 ExtensionSystem::Get(profile)->extension_service()-> |
| 73 extensions()->GetByID(extension_id); | 71 extensions()->GetByID(extension_id); |
| 74 DCHECK(extension->has_lazy_background_page()); | 72 if (extension && extension->has_lazy_background_page()) { |
| 75 ExtensionProcessManager* pm = | 73 // If this is the first enqueued task, and we're not waiting for the |
| 76 ExtensionSystem::Get(profile)->process_manager(); | 74 // background page to unload, ensure the background page is loaded. |
| 77 pm->IncrementLazyKeepaliveCount(extension); | 75 ExtensionProcessManager* pm = |
| 78 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); | 76 ExtensionSystem::Get(profile)->process_manager(); |
| 77 pm->IncrementLazyKeepaliveCount(extension); |
| 78 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); |
| 79 } |
| 79 } else { | 80 } else { |
| 80 tasks_list = it->second.get(); | 81 tasks_list = it->second.get(); |
| 81 } | 82 } |
| 82 | 83 |
| 83 tasks_list->push_back(task); | 84 tasks_list->push_back(task); |
| 84 } | 85 } |
| 85 | 86 |
| 86 void LazyBackgroundTaskQueue::ProcessPendingTasks( | 87 void LazyBackgroundTaskQueue::ProcessPendingTasks( |
| 87 ExtensionHost* host, | 88 ExtensionHost* host, |
| 88 Profile* profile, | 89 Profile* profile, |
| 89 const Extension* extension) { | 90 const Extension* extension) { |
| 90 if (!profile->IsSameProfile(profile_) || | 91 if (!profile->IsSameProfile(profile_)) |
| 91 !extension->has_lazy_background_page()) | |
| 92 return; | 92 return; |
| 93 | 93 |
| 94 PendingTasksKey key(profile, extension->id()); | 94 PendingTasksKey key(profile, extension->id()); |
| 95 PendingTasksMap::iterator map_it = pending_tasks_.find(key); | 95 PendingTasksMap::iterator map_it = pending_tasks_.find(key); |
| 96 if (map_it == pending_tasks_.end()) { | 96 if (map_it == pending_tasks_.end()) { |
| 97 CHECK(!host); // lazy page should not load without any pending tasks | 97 if (extension->has_lazy_background_page()) |
| 98 CHECK(!host); // lazy page should not load without any pending tasks |
| 98 return; | 99 return; |
| 99 } | 100 } |
| 100 | 101 |
| 101 // Swap the pending tasks to a temporary, to avoid problems if the task | 102 // Swap the pending tasks to a temporary, to avoid problems if the task |
| 102 // list is modified during processing. | 103 // list is modified during processing. |
| 103 PendingTasksList tasks; | 104 PendingTasksList tasks; |
| 104 tasks.swap(*map_it->second); | 105 tasks.swap(*map_it->second); |
| 105 for (PendingTasksList::const_iterator it = tasks.begin(); | 106 for (PendingTasksList::const_iterator it = tasks.begin(); |
| 106 it != tasks.end(); ++it) { | 107 it != tasks.end(); ++it) { |
| 107 it->Run(host); | 108 it->Run(host); |
| 108 } | 109 } |
| 109 | 110 |
| 110 pending_tasks_.erase(key); | 111 pending_tasks_.erase(key); |
| 111 | 112 |
| 112 // Balance the keepalive in AddPendingTask. Note we don't do this on a | 113 // Balance the keepalive in AddPendingTask. Note we don't do this on a |
| 113 // failure to load, because the keepalive count is reset in that case. | 114 // failure to load, because the keepalive count is reset in that case. |
| 114 if (host) { | 115 if (host && extension->has_lazy_background_page()) { |
| 115 ExtensionSystem::Get(profile)->process_manager()-> | 116 ExtensionSystem::Get(profile)->process_manager()-> |
| 116 DecrementLazyKeepaliveCount(extension); | 117 DecrementLazyKeepaliveCount(extension); |
| 117 } | 118 } |
| 118 } | 119 } |
| 119 | 120 |
| 120 void LazyBackgroundTaskQueue::Observe( | 121 void LazyBackgroundTaskQueue::Observe( |
| 121 int type, | 122 int type, |
| 122 const content::NotificationSource& source, | 123 const content::NotificationSource& source, |
| 123 const content::NotificationDetails& details) { | 124 const content::NotificationDetails& details) { |
| 124 switch (type) { | 125 switch (type) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 } | 161 } |
| 161 break; | 162 break; |
| 162 } | 163 } |
| 163 default: | 164 default: |
| 164 NOTREACHED(); | 165 NOTREACHED(); |
| 165 break; | 166 break; |
| 166 } | 167 } |
| 167 } | 168 } |
| 168 | 169 |
| 169 } // namespace extensions | 170 } // namespace extensions |
| OLD | NEW |