Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: chrome/browser/extensions/lazy_background_task_queue.cc

Issue 10828218: Add chrome.runtime.onStartup, which is fired on browser start. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "chrome/browser/extensions/extension_host.h" 9 #include "chrome/browser/extensions/extension_host.h"
10 #include "chrome/browser/extensions/extension_process_manager.h" 10 #include "chrome/browser/extensions/extension_process_manager.h"
(...skipping 25 matching lines...) Expand all
36 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 36 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
37 content::Source<Profile>(profile)); 37 content::Source<Profile>(profile));
38 } 38 }
39 39
40 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() { 40 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() {
41 } 41 }
42 42
43 bool LazyBackgroundTaskQueue::ShouldEnqueueTask( 43 bool LazyBackgroundTaskQueue::ShouldEnqueueTask(
44 Profile* profile, const Extension* extension) { 44 Profile* profile, const Extension* extension) {
45 DCHECK(extension); 45 DCHECK(extension);
46 if (extension->has_lazy_background_page()) { 46 if (extension->has_background_page()) {
47 ExtensionProcessManager* pm = 47 ExtensionProcessManager* pm =
48 ExtensionSystem::Get(profile)->process_manager(); 48 ExtensionSystem::Get(profile)->process_manager();
49 ExtensionHost* background_host = 49 ExtensionHost* background_host =
50 pm->GetBackgroundHostForExtension(extension->id()); 50 pm->GetBackgroundHostForExtension(extension->id());
51 if (!background_host || !background_host->did_stop_loading()) 51 if (!background_host || !background_host->did_stop_loading())
52 return true; 52 return true;
53 if (pm->IsBackgroundHostClosing(extension->id())) 53 if (pm->IsBackgroundHostClosing(extension->id()))
54 pm->CancelSuspend(extension); 54 pm->CancelSuspend(extension);
55 } 55 }
56 56
57 return false; 57 return false;
58 } 58 }
59 59
60 void LazyBackgroundTaskQueue::AddPendingTask( 60 void LazyBackgroundTaskQueue::AddPendingTask(
61 Profile* profile, 61 Profile* profile,
62 const std::string& extension_id, 62 const std::string& extension_id,
63 const PendingTask& task) { 63 const PendingTask& task) {
64 PendingTasksList* tasks_list = NULL; 64 PendingTasksList* tasks_list = NULL;
65 PendingTasksKey key(profile, extension_id); 65 PendingTasksKey key(profile, extension_id);
66 PendingTasksMap::iterator it = pending_tasks_.find(key); 66 PendingTasksMap::iterator it = pending_tasks_.find(key);
67 if (it == pending_tasks_.end()) { 67 if (it == pending_tasks_.end()) {
68 tasks_list = new PendingTasksList(); 68 tasks_list = new PendingTasksList();
69 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); 69 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list);
70 70
71 // If this is the first enqueued task, and we're not waiting for the 71 const Extension* extension =
72 // background page to unload, ensure the background page is loaded. 72 ExtensionSystem::Get(profile)->extension_service()->
73 if (pending_page_loads_.count(key) == 0) 73 extensions()->GetByID(extension_id);
74 StartLazyBackgroundPage(profile, extension_id); 74 if (extension && extension->has_lazy_background_page()) {
75 // If this is the first enqueued task, and we're not waiting for the
76 // background page to unload, ensure the background page is loaded.
77 if (pending_page_loads_.count(key) == 0)
78 StartLazyBackgroundPage(profile, extension_id);
79 }
75 } else { 80 } else {
76 tasks_list = it->second.get(); 81 tasks_list = it->second.get();
77 } 82 }
78 83
79 tasks_list->push_back(task); 84 tasks_list->push_back(task);
80 } 85 }
81 86
82 void LazyBackgroundTaskQueue::StartLazyBackgroundPage( 87 void LazyBackgroundTaskQueue::StartLazyBackgroundPage(
83 Profile* profile, const std::string& extension_id) { 88 Profile* profile, const std::string& extension_id) {
84 ExtensionProcessManager* pm = 89 ExtensionProcessManager* pm =
85 ExtensionSystem::Get(profile)->process_manager(); 90 ExtensionSystem::Get(profile)->process_manager();
86 if (pm->IsBackgroundHostClosing(extension_id)) { 91 if (pm->IsBackgroundHostClosing(extension_id)) {
87 // When the background host finishes closing, we will reload it. 92 // When the background host finishes closing, we will reload it.
93 // TODO(mpcomplete): I think pending_page_loads_ is obsolete, and
94 // should be removed. http://crbug.com/136469
88 pending_page_loads_.insert(PendingTasksKey(profile, extension_id)); 95 pending_page_loads_.insert(PendingTasksKey(profile, extension_id));
89 return; 96 return;
90 } 97 }
91 98
92 const Extension* extension = 99 const Extension* extension =
93 ExtensionSystem::Get(profile)->extension_service()-> 100 ExtensionSystem::Get(profile)->extension_service()->
94 extensions()->GetByID(extension_id); 101 extensions()->GetByID(extension_id);
95 if (extension) { 102 if (extension) {
96 DCHECK(extension->has_lazy_background_page()); 103 DCHECK(extension->has_lazy_background_page());
97 pm->IncrementLazyKeepaliveCount(extension); 104 pm->IncrementLazyKeepaliveCount(extension);
98 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); 105 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL());
99 } 106 }
100 107
101 pending_page_loads_.erase(PendingTasksKey(profile, extension_id)); 108 pending_page_loads_.erase(PendingTasksKey(profile, extension_id));
102 } 109 }
103 110
104 void LazyBackgroundTaskQueue::ProcessPendingTasks( 111 void LazyBackgroundTaskQueue::ProcessPendingTasks(
105 ExtensionHost* host, 112 ExtensionHost* host,
106 Profile* profile, 113 Profile* profile,
107 const Extension* extension) { 114 const Extension* extension) {
108 if (!profile->IsSameProfile(profile_) || 115 if (!profile->IsSameProfile(profile_))
109 !extension->has_lazy_background_page())
110 return; 116 return;
111 117
112 PendingTasksKey key(profile, extension->id()); 118 PendingTasksKey key(profile, extension->id());
113 PendingTasksMap::iterator map_it = pending_tasks_.find(key); 119 PendingTasksMap::iterator map_it = pending_tasks_.find(key);
114 if (map_it == pending_tasks_.end()) { 120 if (map_it == pending_tasks_.end()) {
115 CHECK(!host); // lazy page should not load without any pending tasks 121 if (extension->has_lazy_background_page())
122 CHECK(!host); // lazy page should not load without any pending tasks
116 return; 123 return;
117 } 124 }
118 125
119 // Swap the pending tasks to a temporary, to avoid problems if the task 126 // Swap the pending tasks to a temporary, to avoid problems if the task
120 // list is modified during processing. 127 // list is modified during processing.
121 PendingTasksList tasks; 128 PendingTasksList tasks;
122 tasks.swap(*map_it->second); 129 tasks.swap(*map_it->second);
123 for (PendingTasksList::const_iterator it = tasks.begin(); 130 for (PendingTasksList::const_iterator it = tasks.begin();
124 it != tasks.end(); ++it) { 131 it != tasks.end(); ++it) {
125 it->Run(host); 132 it->Run(host);
126 } 133 }
127 134
128 pending_tasks_.erase(key); 135 pending_tasks_.erase(key);
129 136
130 // Balance the keepalive in AddPendingTask. Note we don't do this on a 137 // Balance the keepalive in AddPendingTask. Note we don't do this on a
131 // failure to load, because the keepalive count is reset in that case. 138 // failure to load, because the keepalive count is reset in that case.
132 if (host) { 139 if (host && extension->has_lazy_background_page()) {
133 ExtensionSystem::Get(profile)->process_manager()-> 140 ExtensionSystem::Get(profile)->process_manager()->
134 DecrementLazyKeepaliveCount(extension); 141 DecrementLazyKeepaliveCount(extension);
135 } 142 }
136 } 143 }
137 144
138 void LazyBackgroundTaskQueue::Observe( 145 void LazyBackgroundTaskQueue::Observe(
139 int type, 146 int type,
140 const content::NotificationSource& source, 147 const content::NotificationSource& source,
141 const content::NotificationDetails& details) { 148 const content::NotificationDetails& details) {
142 switch (type) { 149 switch (type) {
143 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: { 150 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: {
144 // If an on-demand background page finished loading, dispatch queued up 151 // If an on-demand background page finished loading, dispatch queued up
145 // events for it. 152 // events for it.
146 ExtensionHost* host = 153 ExtensionHost* host =
147 content::Details<ExtensionHost>(details).ptr(); 154 content::Details<ExtensionHost>(details).ptr();
148 if (host->extension_host_type() == 155 if (host->extension_host_type() ==
149 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 156 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
150 CHECK(host->did_stop_loading()); 157 CHECK(host->did_stop_loading());
151 ProcessPendingTasks(host, host->profile(), host->extension()); 158 ProcessPendingTasks(host, host->profile(), host->extension());
152 } 159 }
153 break; 160 break;
154 } 161 }
155 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 162 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
156 Profile* profile = content::Source<Profile>(source).ptr(); 163 Profile* profile = content::Source<Profile>(source).ptr();
157 ExtensionHost* host = 164 ExtensionHost* host =
158 content::Details<ExtensionHost>(details).ptr(); 165 content::Details<ExtensionHost>(details).ptr();
159 if (host->extension_host_type() == 166 if (host->extension_host_type() ==
160 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 167 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
161 PendingTasksKey key(profile, host->extension()->id()); 168 PendingTasksKey key(profile, host->extension()->id());
162 if (pending_page_loads_.count(key) > 0) { 169 if (pending_page_loads_.count(key) > 0 &&
170 host->extension()->has_lazy_background_page()) {
163 // We were waiting for the background page to unload. We can start it 171 // We were waiting for the background page to unload. We can start it
164 // up again and dispatch any queued events. 172 // up again and dispatch any queued events.
165 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 173 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
166 &LazyBackgroundTaskQueue::StartLazyBackgroundPage, 174 &LazyBackgroundTaskQueue::StartLazyBackgroundPage,
167 AsWeakPtr(), profile, host->extension()->id())); 175 AsWeakPtr(), profile, host->extension()->id()));
168 } else { 176 } else {
169 // This may be a load failure (e.g. a crash). In that case, notify 177 // This may be a load failure (e.g. a crash). In that case, notify
170 // consumers about the load failure. This is not strictly necessary, 178 // consumers about the load failure. This is not strictly necessary,
171 // since we also unload the extension in that case (which dispatches 179 // since we also unload the extension in that case (which dispatches
172 // the tasks below), but is a good extra precaution. 180 // the tasks below), but is a good extra precaution.
(...skipping 14 matching lines...) Expand all
187 } 195 }
188 break; 196 break;
189 } 197 }
190 default: 198 default:
191 NOTREACHED(); 199 NOTREACHED();
192 break; 200 break;
193 } 201 }
194 } 202 }
195 203
196 } // namespace extensions 204 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698