OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/task_manager/providers/render_process_host_task_provide
r.h" |
| 6 |
| 7 #include "base/process/process.h" |
| 8 #include "chrome/browser/task_manager/providers/child_process_task.h" |
| 9 #include "content/public/browser/browser_child_process_host_iterator.h" |
| 10 #include "content/public/browser/browser_thread.h" |
| 11 #include "content/public/browser/child_process_data.h" |
| 12 #include "content/public/browser/notification_service.h" |
| 13 #include "content/public/browser/notification_types.h" |
| 14 #include "content/public/browser/render_process_host.h" |
| 15 #include "content/public/common/process_type.h" |
| 16 #include "extensions/features/features.h" |
| 17 |
| 18 using content::RenderProcessHost; |
| 19 using content::BrowserThread; |
| 20 using content::ChildProcessData; |
| 21 |
| 22 #if BUILDFLAG(ENABLE_EXTENSIONS) |
| 23 #include "extensions/browser/process_map.h" |
| 24 #endif |
| 25 |
| 26 namespace task_manager { |
| 27 |
| 28 RenderProcessHostTaskProvider::RenderProcessHostTaskProvider() |
| 29 : weak_ptr_factory_(this) { |
| 30 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| 31 content::NotificationService::AllBrowserContextsAndSources()); |
| 32 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 33 content::NotificationService::AllBrowserContextsAndSources()); |
| 34 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 35 content::NotificationService::AllBrowserContextsAndSources()); |
| 36 } |
| 37 |
| 38 RenderProcessHostTaskProvider::~RenderProcessHostTaskProvider() {} |
| 39 |
| 40 Task* RenderProcessHostTaskProvider::GetTaskOfUrlRequest(int origin_pid, |
| 41 int child_id, |
| 42 int route_id) { |
| 43 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 44 auto itr = tasks_by_rph_id_.find(child_id); |
| 45 if (itr == tasks_by_rph_id_.end()) |
| 46 return nullptr; |
| 47 |
| 48 return itr->second.get(); |
| 49 } |
| 50 |
| 51 void RenderProcessHostTaskProvider::StartUpdating() { |
| 52 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 53 DCHECK(tasks_by_rph_id_.empty()); |
| 54 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); |
| 55 !it.IsAtEnd(); it.Advance()) { |
| 56 RenderProcessHost* host = it.GetCurrentValue(); |
| 57 if (host->GetHandle()) { |
| 58 CreateTask(host->GetID()); |
| 59 } else { |
| 60 // If the host isn't ready do nothing and we will learn of its creation |
| 61 // from the notification service. |
| 62 } |
| 63 } |
| 64 } |
| 65 |
| 66 void RenderProcessHostTaskProvider::StopUpdating() { |
| 67 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 68 |
| 69 // Then delete all tasks (if any). |
| 70 tasks_by_rph_id_.clear(); |
| 71 } |
| 72 |
| 73 void RenderProcessHostTaskProvider::CreateTask( |
| 74 const int render_process_host_id) { |
| 75 // Checks that the task by RenderProcessHost ID isn't already a task in the |
| 76 // map and deletes it if it is so they new task can be cleanly added. |
| 77 DeleteTask(render_process_host_id); |
| 78 std::unique_ptr<ChildProcessTask>& task = |
| 79 tasks_by_rph_id_[render_process_host_id]; |
| 80 |
| 81 RenderProcessHost* host = RenderProcessHost::FromID(render_process_host_id); |
| 82 |
| 83 // Create the task and notify the observer. |
| 84 ChildProcessData data(content::PROCESS_TYPE_RENDERER); |
| 85 data.handle = host->GetHandle(); |
| 86 data.id = host->GetID(); |
| 87 task.reset(new ChildProcessTask(data)); |
| 88 NotifyObserverTaskAdded(task.get()); |
| 89 } |
| 90 |
| 91 void RenderProcessHostTaskProvider::DeleteTask( |
| 92 const int render_process_host_id) { |
| 93 auto itr = tasks_by_rph_id_.find(render_process_host_id); |
| 94 // If the render process host id isn't being tracked in |tasks_by_rph_id| do |
| 95 // nothing. |
| 96 if (itr == tasks_by_rph_id_.end()) |
| 97 return; |
| 98 |
| 99 NotifyObserverTaskRemoved(itr->second.get()); |
| 100 |
| 101 // Finally delete the task. |
| 102 tasks_by_rph_id_.erase(itr); |
| 103 } |
| 104 |
| 105 void RenderProcessHostTaskProvider::Observe( |
| 106 int type, |
| 107 const content::NotificationSource& source, |
| 108 const content::NotificationDetails& details) { |
| 109 content::RenderProcessHost* host = |
| 110 content::Source<content::RenderProcessHost>(source).ptr(); |
| 111 ChildProcessData data(content::PROCESS_TYPE_RENDERER); |
| 112 switch (type) { |
| 113 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: |
| 114 CreateTask(host->GetID()); |
| 115 break; |
| 116 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: |
| 117 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
| 118 DeleteTask(host->GetID()); |
| 119 break; |
| 120 default: |
| 121 NOTREACHED(); |
| 122 break; |
| 123 } |
| 124 } |
| 125 |
| 126 } // namespace task_manager |
OLD | NEW |