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/task_manager/task_manager_worker_resource_provider.h" | 5 #include "chrome/browser/task_manager/task_manager_worker_resource_provider.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
12 #include "chrome/browser/devtools/devtools_window.h" | 12 #include "chrome/browser/devtools/devtools_window.h" |
13 #include "chrome/browser/profiles/profile_manager.h" | 13 #include "chrome/browser/profiles/profile_manager.h" |
14 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/child_process_data.h" | 15 #include "content/public/browser/child_process_data.h" |
16 #include "content/public/browser/devtools_agent_host.h" | 16 #include "content/public/browser/devtools_agent_host.h" |
17 #include "content/public/browser/notification_service.h" | |
18 #include "content/public/browser/notification_types.h" | |
19 #include "content/public/browser/worker_service.h" | 17 #include "content/public/browser/worker_service.h" |
20 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
21 #include "grit/theme_resources.h" | 19 #include "grit/theme_resources.h" |
22 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
23 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
24 #include "ui/gfx/image/image_skia.h" | 22 #include "ui/gfx/image/image_skia.h" |
25 | 23 |
26 using content::BrowserThread; | 24 using content::BrowserThread; |
27 using content::DevToolsAgentHost; | 25 using content::DevToolsAgentHost; |
28 using content::WorkerService; | 26 using content::WorkerService; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 TaskManagerWorkerResourceProvider:: | 172 TaskManagerWorkerResourceProvider:: |
175 TaskManagerWorkerResourceProvider(TaskManager* task_manager) | 173 TaskManagerWorkerResourceProvider(TaskManager* task_manager) |
176 : updating_(false), | 174 : updating_(false), |
177 task_manager_(task_manager) { | 175 task_manager_(task_manager) { |
178 } | 176 } |
179 | 177 |
180 TaskManagerWorkerResourceProvider::~TaskManagerWorkerResourceProvider() { | 178 TaskManagerWorkerResourceProvider::~TaskManagerWorkerResourceProvider() { |
181 DeleteAllResources(); | 179 DeleteAllResources(); |
182 } | 180 } |
183 | 181 |
| 182 void TaskManagerWorkerResourceProvider::BrowserChildProcessHostConnected( |
| 183 const content::ChildProcessData& data) { |
| 184 DCHECK(updating_); |
| 185 |
| 186 if (data.type != content::PROCESS_TYPE_WORKER) |
| 187 return; |
| 188 |
| 189 ProcessIdToWorkerResources::iterator it(launching_workers_.find(data.id)); |
| 190 if (it == launching_workers_.end()) |
| 191 return; |
| 192 WorkerResourceList& resources = it->second; |
| 193 for (WorkerResourceList::iterator r = resources.begin(); |
| 194 r != resources.end(); ++r) { |
| 195 (*r)->UpdateProcessHandle(data.handle); |
| 196 task_manager_->AddResource(*r); |
| 197 } |
| 198 launching_workers_.erase(it); |
| 199 } |
| 200 |
| 201 void TaskManagerWorkerResourceProvider::BrowserChildProcessHostDisconnected( |
| 202 const content::ChildProcessData& data) { |
| 203 DCHECK(updating_); |
| 204 |
| 205 if (data.type != content::PROCESS_TYPE_WORKER) |
| 206 return; |
| 207 |
| 208 // Worker process may be destroyed before WorkerMsg_TerminateWorkerContex |
| 209 // message is handled and WorkerDestroyed is fired. In this case we won't |
| 210 // get WorkerDestroyed notification and have to clear resources for such |
| 211 // workers here when the worker process has been destroyed. |
| 212 for (WorkerResourceList::iterator it = resources_.begin(); |
| 213 it != resources_.end();) { |
| 214 if ((*it)->process_id() == data.id) { |
| 215 task_manager_->RemoveResource(*it); |
| 216 delete *it; |
| 217 it = resources_.erase(it); |
| 218 } else { |
| 219 ++it; |
| 220 } |
| 221 } |
| 222 DCHECK(!ContainsKey(launching_workers_, data.id)); |
| 223 } |
| 224 |
184 TaskManager::Resource* TaskManagerWorkerResourceProvider::GetResource( | 225 TaskManager::Resource* TaskManagerWorkerResourceProvider::GetResource( |
185 int origin_pid, | 226 int origin_pid, |
186 int render_process_host_id, | 227 int render_process_host_id, |
187 int routing_id) { | 228 int routing_id) { |
188 return NULL; | 229 return NULL; |
189 } | 230 } |
190 | 231 |
191 void TaskManagerWorkerResourceProvider::StartUpdating() { | 232 void TaskManagerWorkerResourceProvider::StartUpdating() { |
192 DCHECK(!updating_); | 233 DCHECK(!updating_); |
193 updating_ = true; | 234 updating_ = true; |
194 // Register for notifications to get new child processes. | |
195 registrar_.Add(this, content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED, | |
196 content::NotificationService::AllBrowserContextsAndSources()); | |
197 registrar_.Add(this, content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED, | |
198 content::NotificationService::AllBrowserContextsAndSources()); | |
199 // Get existing workers. | 235 // Get existing workers. |
200 BrowserThread::PostTask( | 236 BrowserThread::PostTask( |
201 BrowserThread::IO, FROM_HERE, base::Bind( | 237 BrowserThread::IO, FROM_HERE, base::Bind( |
202 &TaskManagerWorkerResourceProvider::StartObservingWorkers, | 238 &TaskManagerWorkerResourceProvider::StartObservingWorkers, |
203 this)); | 239 this)); |
| 240 |
| 241 BrowserChildProcessObserver::Add(this); |
204 } | 242 } |
205 | 243 |
206 void TaskManagerWorkerResourceProvider::StopUpdating() { | 244 void TaskManagerWorkerResourceProvider::StopUpdating() { |
207 DCHECK(updating_); | 245 DCHECK(updating_); |
208 updating_ = false; | 246 updating_ = false; |
209 launching_workers_.clear(); | 247 launching_workers_.clear(); |
210 DeleteAllResources(); | 248 DeleteAllResources(); |
211 registrar_.Remove( | |
212 this, content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED, | |
213 content::NotificationService::AllBrowserContextsAndSources()); | |
214 registrar_.Remove( | |
215 this, content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED, | |
216 content::NotificationService::AllBrowserContextsAndSources()); | |
217 BrowserThread::PostTask( | 249 BrowserThread::PostTask( |
218 BrowserThread::IO, FROM_HERE, base::Bind( | 250 BrowserThread::IO, FROM_HERE, base::Bind( |
219 &TaskManagerWorkerResourceProvider::StopObservingWorkers, | 251 &TaskManagerWorkerResourceProvider::StopObservingWorkers, |
220 this)); | 252 this)); |
| 253 |
| 254 BrowserChildProcessObserver::Remove(this); |
221 } | 255 } |
222 | 256 |
223 void TaskManagerWorkerResourceProvider::WorkerCreated( | 257 void TaskManagerWorkerResourceProvider::WorkerCreated( |
224 const GURL& url, | 258 const GURL& url, |
225 const string16& name, | 259 const string16& name, |
226 int process_id, | 260 int process_id, |
227 int route_id) { | 261 int route_id) { |
228 TaskManagerSharedWorkerResource* resource = | 262 TaskManagerSharedWorkerResource* resource = |
229 new TaskManagerSharedWorkerResource( | 263 new TaskManagerSharedWorkerResource( |
230 url, name, process_id, route_id, base::kNullProcessHandle); | 264 url, name, process_id, route_id, base::kNullProcessHandle); |
231 BrowserThread::PostTask( | 265 BrowserThread::PostTask( |
232 BrowserThread::UI, FROM_HERE, | 266 BrowserThread::UI, FROM_HERE, |
233 base::Bind(&TaskManagerWorkerResourceProvider::NotifyWorkerCreated, | 267 base::Bind(&TaskManagerWorkerResourceProvider::NotifyWorkerCreated, |
234 this, base::Owned(new WorkerResourceHolder(resource)))); | 268 this, base::Owned(new WorkerResourceHolder(resource)))); |
235 } | 269 } |
236 | 270 |
237 void TaskManagerWorkerResourceProvider::WorkerDestroyed(int process_id, | 271 void TaskManagerWorkerResourceProvider::WorkerDestroyed(int process_id, |
238 int route_id) { | 272 int route_id) { |
239 BrowserThread::PostTask( | 273 BrowserThread::PostTask( |
240 BrowserThread::UI, FROM_HERE, base::Bind( | 274 BrowserThread::UI, FROM_HERE, base::Bind( |
241 &TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed, | 275 &TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed, |
242 this, process_id, route_id)); | 276 this, process_id, route_id)); |
243 } | 277 } |
244 | 278 |
245 void TaskManagerWorkerResourceProvider::Observe( | |
246 int type, | |
247 const content::NotificationSource& source, | |
248 const content::NotificationDetails& details) { | |
249 content::ChildProcessData* process_data = | |
250 content::Details<content::ChildProcessData>(details).ptr(); | |
251 if (process_data->type != content::PROCESS_TYPE_WORKER) | |
252 return; | |
253 if (type == content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED) { | |
254 ProcessIdToWorkerResources::iterator it = | |
255 launching_workers_.find(process_data->id); | |
256 if (it == launching_workers_.end()) | |
257 return; | |
258 WorkerResourceList& resources = it->second; | |
259 for (WorkerResourceList::iterator r = resources.begin(); | |
260 r !=resources.end(); ++r) { | |
261 (*r)->UpdateProcessHandle(process_data->handle); | |
262 task_manager_->AddResource(*r); | |
263 } | |
264 launching_workers_.erase(it); | |
265 } else if (type == content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED) { | |
266 // Worker process may be destroyed before WorkerMsg_TerminateWorkerContex | |
267 // message is handled and WorkerDestroyed is fired. In this case we won't | |
268 // get WorkerDestroyed notification and have to clear resources for such | |
269 // workers here when the worker process has been destroyed. | |
270 for (WorkerResourceList::iterator it = resources_.begin(); | |
271 it !=resources_.end();) { | |
272 if ((*it)->process_id() == process_data->id) { | |
273 task_manager_->RemoveResource(*it); | |
274 delete *it; | |
275 it = resources_.erase(it); | |
276 } else { | |
277 ++it; | |
278 } | |
279 } | |
280 DCHECK(launching_workers_.find(process_data->id) == | |
281 launching_workers_.end()); | |
282 } | |
283 } | |
284 | |
285 void TaskManagerWorkerResourceProvider::NotifyWorkerCreated( | 279 void TaskManagerWorkerResourceProvider::NotifyWorkerCreated( |
286 WorkerResourceHolder* resource_holder) { | 280 WorkerResourceHolder* resource_holder) { |
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
288 if (!updating_) | 282 if (!updating_) |
289 return; | 283 return; |
290 AddResource(resource_holder->release()); | 284 AddResource(resource_holder->release()); |
291 } | 285 } |
292 | 286 |
293 void TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed( | 287 void TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed( |
294 int process_id, int routing_id) { | 288 int process_id, int routing_id) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 int process_id = resource->process_id(); | 347 int process_id = resource->process_id(); |
354 launching_workers_[process_id].push_back(resource); | 348 launching_workers_[process_id].push_back(resource); |
355 } else { | 349 } else { |
356 task_manager_->AddResource(resource); | 350 task_manager_->AddResource(resource); |
357 } | 351 } |
358 } | 352 } |
359 | 353 |
360 void TaskManagerWorkerResourceProvider::DeleteAllResources() { | 354 void TaskManagerWorkerResourceProvider::DeleteAllResources() { |
361 STLDeleteElements(&resources_); | 355 STLDeleteElements(&resources_); |
362 } | 356 } |
OLD | NEW |