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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 TaskManager::Resource* TaskManagerWorkerResourceProvider::GetResource( | 182 TaskManager::Resource* TaskManagerWorkerResourceProvider::GetResource( |
185 int origin_pid, | 183 int origin_pid, |
186 int render_process_host_id, | 184 int render_process_host_id, |
187 int routing_id) { | 185 int routing_id) { |
188 return NULL; | 186 return NULL; |
189 } | 187 } |
190 | 188 |
191 void TaskManagerWorkerResourceProvider::StartUpdating() { | 189 void TaskManagerWorkerResourceProvider::StartUpdating() { |
192 DCHECK(!updating_); | 190 DCHECK(!updating_); |
193 updating_ = true; | 191 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. | 192 // Get existing workers. |
200 BrowserThread::PostTask( | 193 BrowserThread::PostTask( |
201 BrowserThread::IO, FROM_HERE, base::Bind( | 194 BrowserThread::IO, FROM_HERE, base::Bind( |
202 &TaskManagerWorkerResourceProvider::StartObservingWorkers, | 195 &TaskManagerWorkerResourceProvider::StartObservingWorkers, |
203 this)); | 196 this)); |
| 197 |
| 198 BrowserChildProcessObserver::Add(this); |
204 } | 199 } |
205 | 200 |
206 void TaskManagerWorkerResourceProvider::StopUpdating() { | 201 void TaskManagerWorkerResourceProvider::StopUpdating() { |
207 DCHECK(updating_); | 202 DCHECK(updating_); |
208 updating_ = false; | 203 updating_ = false; |
209 launching_workers_.clear(); | 204 launching_workers_.clear(); |
210 DeleteAllResources(); | 205 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( | 206 BrowserThread::PostTask( |
218 BrowserThread::IO, FROM_HERE, base::Bind( | 207 BrowserThread::IO, FROM_HERE, base::Bind( |
219 &TaskManagerWorkerResourceProvider::StopObservingWorkers, | 208 &TaskManagerWorkerResourceProvider::StopObservingWorkers, |
220 this)); | 209 this)); |
| 210 |
| 211 BrowserChildProcessObserver::Remove(this); |
| 212 } |
| 213 |
| 214 void TaskManagerWorkerResourceProvider::BrowserChildProcessHostConnected( |
| 215 const content::ChildProcessData& data) { |
| 216 DCHECK(updating_); |
| 217 |
| 218 if (data.type != content::PROCESS_TYPE_WORKER) |
| 219 return; |
| 220 |
| 221 ProcessIdToWorkerResources::iterator it(launching_workers_.find(data.id)); |
| 222 if (it == launching_workers_.end()) |
| 223 return; |
| 224 WorkerResourceList& resources = it->second; |
| 225 for (WorkerResourceList::iterator r = resources.begin(); |
| 226 r != resources.end(); ++r) { |
| 227 (*r)->UpdateProcessHandle(data.handle); |
| 228 task_manager_->AddResource(*r); |
| 229 } |
| 230 launching_workers_.erase(it); |
| 231 } |
| 232 |
| 233 void TaskManagerWorkerResourceProvider::BrowserChildProcessHostDisconnected( |
| 234 const content::ChildProcessData& data) { |
| 235 DCHECK(updating_); |
| 236 |
| 237 if (data.type != content::PROCESS_TYPE_WORKER) |
| 238 return; |
| 239 |
| 240 // Worker process may be destroyed before WorkerMsg_TerminateWorkerContex |
| 241 // message is handled and WorkerDestroyed is fired. In this case we won't |
| 242 // get WorkerDestroyed notification and have to clear resources for such |
| 243 // workers here when the worker process has been destroyed. |
| 244 for (WorkerResourceList::iterator it = resources_.begin(); |
| 245 it != resources_.end();) { |
| 246 if ((*it)->process_id() == data.id) { |
| 247 task_manager_->RemoveResource(*it); |
| 248 delete *it; |
| 249 it = resources_.erase(it); |
| 250 } else { |
| 251 ++it; |
| 252 } |
| 253 } |
| 254 DCHECK(!ContainsKey(launching_workers_, data.id)); |
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 |