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 |