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

Side by Side Diff: chrome/browser/task_manager/task_manager_worker_resource_provider.cc

Issue 15196003: Create task_manager namespace and wrap classes related to TaskManager with it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: RendererResource Created 7 years, 7 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/task_manager/task_manager_worker_resource_provider.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/stl_util.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/devtools/devtools_window.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/common/chrome_process_type.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/child_process_data.h"
17 #include "content/public/browser/devtools_agent_host.h"
18 #include "content/public/browser/worker_service.h"
19 #include "grit/generated_resources.h"
20 #include "grit/theme_resources.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/gfx/image/image_skia.h"
24
25 using content::BrowserThread;
26 using content::DevToolsAgentHost;
27 using content::WorkerService;
28
29 // Objects of this class are created on the IO thread and then passed to the UI
30 // thread where they are passed to the task manager. All methods must be called
31 // only on the UI thread. Destructor may be called on any thread.
32 class TaskManagerSharedWorkerResource : public TaskManager::Resource {
33 public:
34 TaskManagerSharedWorkerResource(const GURL& url,
35 const string16& name,
36 int process_id,
37 int routing_id,
38 base::ProcessHandle process_handle);
39 virtual ~TaskManagerSharedWorkerResource();
40
41 bool Matches(int process_id, int routing_id) const;
42
43 void UpdateProcessHandle(base::ProcessHandle handle);
44 base::ProcessHandle handle() const { return handle_; }
45 int process_id() const { return process_id_; }
46
47 private:
48 // TaskManager::Resource methods:
49 virtual string16 GetTitle() const OVERRIDE;
50 virtual string16 GetProfileName() const OVERRIDE;
51 virtual gfx::ImageSkia GetIcon() const OVERRIDE;
52 virtual base::ProcessHandle GetProcess() const OVERRIDE;
53 virtual int GetUniqueChildProcessId() const OVERRIDE;
54 virtual Type GetType() const OVERRIDE;
55 virtual bool CanInspect() const OVERRIDE;
56 virtual void Inspect() const OVERRIDE;
57
58 virtual bool SupportNetworkUsage() const OVERRIDE;
59 virtual void SetSupportNetworkUsage() OVERRIDE;
60
61 int process_id_;
62 int routing_id_;
63 string16 title_;
64 base::ProcessHandle handle_;
65
66 static gfx::ImageSkia* default_icon_;
67
68 DISALLOW_COPY_AND_ASSIGN(TaskManagerSharedWorkerResource);
69 };
70
71 gfx::ImageSkia* TaskManagerSharedWorkerResource::default_icon_ = NULL;
72
73 TaskManagerSharedWorkerResource::TaskManagerSharedWorkerResource(
74 const GURL& url,
75 const string16& name,
76 int process_id,
77 int routing_id,
78 base::ProcessHandle process_handle)
79 : process_id_(process_id),
80 routing_id_(routing_id),
81 handle_(process_handle) {
82 title_ = UTF8ToUTF16(url.spec());
83 if (!name.empty())
84 title_ += ASCIIToUTF16(" (") + name + ASCIIToUTF16(")");
85 }
86
87 TaskManagerSharedWorkerResource::~TaskManagerSharedWorkerResource() {
88 }
89
90 bool TaskManagerSharedWorkerResource::Matches(int process_id,
91 int routing_id) const {
92 return process_id_ == process_id && routing_id_ == routing_id;
93 }
94
95 void TaskManagerSharedWorkerResource::UpdateProcessHandle(
96 base::ProcessHandle handle) {
97 handle_ = handle;
98 }
99
100 string16 TaskManagerSharedWorkerResource::GetTitle() const {
101 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_WORKER_PREFIX, title_);
102 }
103
104 string16 TaskManagerSharedWorkerResource::GetProfileName() const {
105 return string16();
106 }
107
108 gfx::ImageSkia TaskManagerSharedWorkerResource::GetIcon() const {
109 if (!default_icon_) {
110 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
111 default_icon_ = rb.GetImageSkiaNamed(IDR_PLUGINS_FAVICON);
112 // TODO(jabdelmalek): use different icon for web workers.
113 }
114 return *default_icon_;
115 }
116
117 base::ProcessHandle TaskManagerSharedWorkerResource::GetProcess() const {
118 return handle_;
119 }
120
121 int TaskManagerSharedWorkerResource::GetUniqueChildProcessId() const {
122 return process_id_;
123 }
124
125 TaskManager::Resource::Type TaskManagerSharedWorkerResource::GetType() const {
126 return WORKER;
127 }
128
129 bool TaskManagerSharedWorkerResource::CanInspect() const {
130 return true;
131 }
132
133 void TaskManagerSharedWorkerResource::Inspect() const {
134 // TODO(yurys): would be better to get profile from one of the tabs connected
135 // to the worker.
136 Profile* profile = ProfileManager::GetLastUsedProfile();
137 if (!profile)
138 return;
139 scoped_refptr<DevToolsAgentHost> agent_host(
140 DevToolsAgentHost::GetForWorker(process_id_, routing_id_));
141 DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host);
142 }
143
144 bool TaskManagerSharedWorkerResource::SupportNetworkUsage() const {
145 return false;
146 }
147
148 void TaskManagerSharedWorkerResource::SetSupportNetworkUsage() {
149 }
150
151
152 // This class is needed to ensure that all resources in WorkerResourceList are
153 // deleted if corresponding task is posted to but not executed on the UI
154 // thread.
155 class TaskManagerWorkerResourceProvider::WorkerResourceListHolder {
156 public:
157 WorkerResourceListHolder() {
158 }
159
160 ~WorkerResourceListHolder() {
161 STLDeleteElements(&resources_);
162 }
163
164 WorkerResourceList* resources() {
165 return &resources_;
166 }
167
168 private:
169 WorkerResourceList resources_;
170 };
171
172
173 TaskManagerWorkerResourceProvider::
174 TaskManagerWorkerResourceProvider(TaskManager* task_manager)
175 : updating_(false),
176 task_manager_(task_manager) {
177 }
178
179 TaskManagerWorkerResourceProvider::~TaskManagerWorkerResourceProvider() {
180 DeleteAllResources();
181 }
182
183 TaskManager::Resource* TaskManagerWorkerResourceProvider::GetResource(
184 int origin_pid,
185 int render_process_host_id,
186 int routing_id) {
187 return NULL;
188 }
189
190 void TaskManagerWorkerResourceProvider::StartUpdating() {
191 DCHECK(!updating_);
192 updating_ = true;
193 // Get existing workers.
194 BrowserThread::PostTask(
195 BrowserThread::IO, FROM_HERE, base::Bind(
196 &TaskManagerWorkerResourceProvider::StartObservingWorkers,
197 this));
198
199 BrowserChildProcessObserver::Add(this);
200 }
201
202 void TaskManagerWorkerResourceProvider::StopUpdating() {
203 DCHECK(updating_);
204 updating_ = false;
205 launching_workers_.clear();
206 DeleteAllResources();
207 BrowserThread::PostTask(
208 BrowserThread::IO, FROM_HERE, base::Bind(
209 &TaskManagerWorkerResourceProvider::StopObservingWorkers,
210 this));
211
212 BrowserChildProcessObserver::Remove(this);
213 }
214
215 void TaskManagerWorkerResourceProvider::BrowserChildProcessHostConnected(
216 const content::ChildProcessData& data) {
217 DCHECK(updating_);
218
219 if (data.process_type != content::PROCESS_TYPE_WORKER)
220 return;
221
222 ProcessIdToWorkerResources::iterator it(launching_workers_.find(data.id));
223 if (it == launching_workers_.end())
224 return;
225 WorkerResourceList& resources = it->second;
226 for (WorkerResourceList::iterator r = resources.begin();
227 r != resources.end(); ++r) {
228 (*r)->UpdateProcessHandle(data.handle);
229 task_manager_->AddResource(*r);
230 }
231 launching_workers_.erase(it);
232 }
233
234 void TaskManagerWorkerResourceProvider::BrowserChildProcessHostDisconnected(
235 const content::ChildProcessData& data) {
236 DCHECK(updating_);
237
238 if (data.process_type != content::PROCESS_TYPE_WORKER)
239 return;
240
241 // Worker process may be destroyed before WorkerMsg_TerminateWorkerContex
242 // message is handled and WorkerDestroyed is fired. In this case we won't
243 // get WorkerDestroyed notification and have to clear resources for such
244 // workers here when the worker process has been destroyed.
245 for (WorkerResourceList::iterator it = resources_.begin();
246 it != resources_.end();) {
247 if ((*it)->process_id() == data.id) {
248 task_manager_->RemoveResource(*it);
249 delete *it;
250 it = resources_.erase(it);
251 } else {
252 ++it;
253 }
254 }
255 DCHECK(!ContainsKey(launching_workers_, data.id));
256 }
257
258 void TaskManagerWorkerResourceProvider::WorkerCreated(
259 const GURL& url,
260 const string16& name,
261 int process_id,
262 int route_id) {
263 TaskManagerSharedWorkerResource* resource =
264 new TaskManagerSharedWorkerResource(
265 url, name, process_id, route_id, base::kNullProcessHandle);
266 BrowserThread::PostTask(
267 BrowserThread::UI, FROM_HERE,
268 base::Bind(&TaskManagerWorkerResourceProvider::NotifyWorkerCreated,
269 this, base::Owned(new WorkerResourceHolder(resource))));
270 }
271
272 void TaskManagerWorkerResourceProvider::WorkerDestroyed(int process_id,
273 int route_id) {
274 BrowserThread::PostTask(
275 BrowserThread::UI, FROM_HERE, base::Bind(
276 &TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed,
277 this, process_id, route_id));
278 }
279
280 void TaskManagerWorkerResourceProvider::NotifyWorkerCreated(
281 WorkerResourceHolder* resource_holder) {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
283 if (!updating_)
284 return;
285 AddResource(resource_holder->release());
286 }
287
288 void TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed(
289 int process_id, int routing_id) {
290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
291 if (!updating_)
292 return;
293 for (WorkerResourceList::iterator it = resources_.begin();
294 it !=resources_.end(); ++it) {
295 if ((*it)->Matches(process_id, routing_id)) {
296 task_manager_->RemoveResource(*it);
297 delete *it;
298 resources_.erase(it);
299 return;
300 }
301 }
302 }
303
304 void TaskManagerWorkerResourceProvider::StartObservingWorkers() {
305 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
306
307 scoped_ptr<WorkerResourceListHolder> holder(new WorkerResourceListHolder);
308 std::vector<WorkerService::WorkerInfo> worker_info =
309 WorkerService::GetInstance()->GetWorkers();
310
311 for (size_t i = 0; i < worker_info.size(); ++i) {
312 holder->resources()->push_back(new TaskManagerSharedWorkerResource(
313 worker_info[i].url, worker_info[i].name, worker_info[i].process_id,
314 worker_info[i].route_id, worker_info[i].handle));
315 }
316
317 BrowserThread::PostTask(
318 BrowserThread::UI, FROM_HERE,
319 base::Bind(
320 &TaskManagerWorkerResourceProvider::AddWorkerResourceList,
321 this, base::Owned(holder.release())));
322
323 WorkerService::GetInstance()->AddObserver(this);
324 }
325
326 void TaskManagerWorkerResourceProvider::StopObservingWorkers() {
327 WorkerService::GetInstance()->RemoveObserver(this);
328 }
329
330 void TaskManagerWorkerResourceProvider::AddWorkerResourceList(
331 WorkerResourceListHolder* resource_list_holder) {
332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
333 if (!updating_)
334 return;
335 WorkerResourceList* resources = resource_list_holder->resources();
336 for (WorkerResourceList::iterator it = resources->begin();
337 it !=resources->end(); ++it) {
338 AddResource(*it);
339 }
340 resources->clear();
341 }
342
343 void TaskManagerWorkerResourceProvider::AddResource(
344 TaskManagerSharedWorkerResource* resource) {
345 DCHECK(updating_);
346 resources_.push_back(resource);
347 if (resource->handle() == base::kNullProcessHandle) {
348 int process_id = resource->process_id();
349 launching_workers_[process_id].push_back(resource);
350 } else {
351 task_manager_->AddResource(resource);
352 }
353 }
354
355 void TaskManagerWorkerResourceProvider::DeleteAllResources() {
356 STLDeleteElements(&resources_);
357 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698