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

Side by Side Diff: chrome/browser/task_manager/task_manager_child_process_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: Rebase 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 2013 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_child_process_resource_provid er.h"
6
7 #include <vector>
8
9 #include "base/i18n/rtl.h"
10 #include "base/string16.h"
11 #include "chrome/common/chrome_notification_types.h"
12 #include "chrome/common/chrome_process_type.h"
13 #include "content/public/browser/browser_child_process_host_iterator.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/child_process_data.h"
16 #include "content/public/browser/notification_service.h"
17 #include "grit/generated_resources.h"
18 #include "grit/theme_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/image/image_skia.h"
22
23 using content::BrowserChildProcessHostIterator;
24 using content::BrowserThread;
25 using content::WebContents;
26
27 class TaskManagerChildProcessResource : public TaskManager::Resource {
28 public:
29 TaskManagerChildProcessResource(int process_type,
30 const string16& name,
31 base::ProcessHandle handle,
32 int unique_process_id);
33 virtual ~TaskManagerChildProcessResource();
34
35 // TaskManager::Resource methods:
36 virtual string16 GetTitle() const OVERRIDE;
37 virtual string16 GetProfileName() const OVERRIDE;
38 virtual gfx::ImageSkia GetIcon() const OVERRIDE;
39 virtual base::ProcessHandle GetProcess() const OVERRIDE;
40 virtual int GetUniqueChildProcessId() const OVERRIDE;
41 virtual Type GetType() const OVERRIDE;
42 virtual bool SupportNetworkUsage() const OVERRIDE;
43 virtual void SetSupportNetworkUsage() OVERRIDE;
44
45 // Returns the pid of the child process.
46 int process_id() const { return pid_; }
47
48 private:
49 // Returns a localized title for the child process. For example, a plugin
50 // process would be "Plug-in: Flash" when name is "Flash".
51 string16 GetLocalizedTitle() const;
52
53 int process_type_;
54 string16 name_;
55 base::ProcessHandle handle_;
56 int pid_;
57 int unique_process_id_;
58 mutable string16 title_;
59 bool network_usage_support_;
60
61 // The icon painted for the child processs.
62 // TODO(jcampan): we should have plugin specific icons for well-known
63 // plugins.
64 static gfx::ImageSkia* default_icon_;
65
66 DISALLOW_COPY_AND_ASSIGN(TaskManagerChildProcessResource);
67 };
68
69 gfx::ImageSkia* TaskManagerChildProcessResource::default_icon_ = NULL;
70
71 TaskManagerChildProcessResource::TaskManagerChildProcessResource(
72 int process_type,
73 const string16& name,
74 base::ProcessHandle handle,
75 int unique_process_id)
76 : process_type_(process_type),
77 name_(name),
78 handle_(handle),
79 unique_process_id_(unique_process_id),
80 network_usage_support_(false) {
81 // We cache the process id because it's not cheap to calculate, and it won't
82 // be available when we get the plugin disconnected notification.
83 pid_ = base::GetProcId(handle);
84 if (!default_icon_) {
85 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
86 default_icon_ = rb.GetImageSkiaNamed(IDR_PLUGINS_FAVICON);
87 // TODO(jabdelmalek): use different icon for web workers.
88 }
89 }
90
91 TaskManagerChildProcessResource::~TaskManagerChildProcessResource() {
92 }
93
94 // TaskManagerResource methods:
95 string16 TaskManagerChildProcessResource::GetTitle() const {
96 if (title_.empty())
97 title_ = GetLocalizedTitle();
98
99 return title_;
100 }
101
102 string16 TaskManagerChildProcessResource::GetProfileName() const {
103 return string16();
104 }
105
106 gfx::ImageSkia TaskManagerChildProcessResource::GetIcon() const {
107 return *default_icon_;
108 }
109
110 base::ProcessHandle TaskManagerChildProcessResource::GetProcess() const {
111 return handle_;
112 }
113
114 int TaskManagerChildProcessResource::GetUniqueChildProcessId() const {
115 return unique_process_id_;
116 }
117
118 TaskManager::Resource::Type TaskManagerChildProcessResource::GetType() const {
119 // Translate types to TaskManager::ResourceType, since ChildProcessData's type
120 // is not available for all TaskManager resources.
121 switch (process_type_) {
122 case content::PROCESS_TYPE_PLUGIN:
123 case content::PROCESS_TYPE_PPAPI_PLUGIN:
124 case content::PROCESS_TYPE_PPAPI_BROKER:
125 return TaskManager::Resource::PLUGIN;
126 case content::PROCESS_TYPE_UTILITY:
127 return TaskManager::Resource::UTILITY;
128 case content::PROCESS_TYPE_ZYGOTE:
129 return TaskManager::Resource::ZYGOTE;
130 case content::PROCESS_TYPE_SANDBOX_HELPER:
131 return TaskManager::Resource::SANDBOX_HELPER;
132 case content::PROCESS_TYPE_GPU:
133 return TaskManager::Resource::GPU;
134 case PROCESS_TYPE_PROFILE_IMPORT:
135 return TaskManager::Resource::PROFILE_IMPORT;
136 case PROCESS_TYPE_NACL_LOADER:
137 case PROCESS_TYPE_NACL_BROKER:
138 return TaskManager::Resource::NACL;
139 default:
140 return TaskManager::Resource::UNKNOWN;
141 }
142 }
143
144 bool TaskManagerChildProcessResource::SupportNetworkUsage() const {
145 return network_usage_support_;
146 }
147
148 void TaskManagerChildProcessResource::SetSupportNetworkUsage() {
149 network_usage_support_ = true;
150 }
151
152 string16 TaskManagerChildProcessResource::GetLocalizedTitle() const {
153 string16 title = name_;
154 if (title.empty()) {
155 switch (process_type_) {
156 case content::PROCESS_TYPE_PLUGIN:
157 case content::PROCESS_TYPE_PPAPI_PLUGIN:
158 case content::PROCESS_TYPE_PPAPI_BROKER:
159 title = l10n_util::GetStringUTF16(IDS_TASK_MANAGER_UNKNOWN_PLUGIN_NAME);
160 break;
161 default:
162 // Nothing to do for non-plugin processes.
163 break;
164 }
165 }
166
167 // Explicitly mark name as LTR if there is no strong RTL character,
168 // to avoid the wrong concatenation result similar to "!Yahoo Mail: the
169 // best web-based Email: NIGULP", in which "NIGULP" stands for the Hebrew
170 // or Arabic word for "plugin".
171 base::i18n::AdjustStringForLocaleDirection(&title);
172
173 switch (process_type_) {
174 case content::PROCESS_TYPE_UTILITY:
175 return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_UTILITY_PREFIX);
176 case content::PROCESS_TYPE_GPU:
177 return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_GPU_PREFIX);
178 case content::PROCESS_TYPE_PLUGIN:
179 case content::PROCESS_TYPE_PPAPI_PLUGIN:
180 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PLUGIN_PREFIX, title);
181 case content::PROCESS_TYPE_PPAPI_BROKER:
182 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PLUGIN_BROKER_PREFIX,
183 title);
184 case PROCESS_TYPE_PROFILE_IMPORT:
185 return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_UTILITY_PREFIX);
186 case PROCESS_TYPE_NACL_BROKER:
187 return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NACL_BROKER_PREFIX);
188 case PROCESS_TYPE_NACL_LOADER:
189 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_NACL_PREFIX, title);
190 // These types don't need display names or get them from elsewhere.
191 case content::PROCESS_TYPE_BROWSER:
192 case content::PROCESS_TYPE_RENDERER:
193 case content::PROCESS_TYPE_ZYGOTE:
194 case content::PROCESS_TYPE_SANDBOX_HELPER:
195 case content::PROCESS_TYPE_MAX:
196 NOTREACHED();
197 break;
198
199 case content::PROCESS_TYPE_WORKER:
200 NOTREACHED() << "Workers are not handled by this provider.";
201 break;
202 case content::PROCESS_TYPE_UNKNOWN:
203 NOTREACHED() << "Need localized name for child process type.";
204 }
205
206 return title;
207 }
208
209 ////////////////////////////////////////////////////////////////////////////////
210 // TaskManagerChildProcessResourceProvider class
211 ////////////////////////////////////////////////////////////////////////////////
212
213 TaskManagerChildProcessResourceProvider::
214 TaskManagerChildProcessResourceProvider(TaskManager* task_manager)
215 : task_manager_(task_manager),
216 updating_(false) {
217 }
218
219 TaskManagerChildProcessResourceProvider::
220 ~TaskManagerChildProcessResourceProvider() {
221 }
222
223 TaskManager::Resource* TaskManagerChildProcessResourceProvider::GetResource(
224 int origin_pid,
225 int render_process_host_id,
226 int routing_id) {
227 PidResourceMap::iterator iter = pid_to_resources_.find(origin_pid);
228 if (iter != pid_to_resources_.end())
229 return iter->second;
230 else
231 return NULL;
232 }
233
234 void TaskManagerChildProcessResourceProvider::StartUpdating() {
235 DCHECK(!updating_);
236 updating_ = true;
237
238 // Get the existing child processes.
239 BrowserThread::PostTask(
240 BrowserThread::IO, FROM_HERE,
241 base::Bind(
242 &TaskManagerChildProcessResourceProvider::RetrieveChildProcessData,
243 this));
244
245 BrowserChildProcessObserver::Add(this);
246 }
247
248 void TaskManagerChildProcessResourceProvider::StopUpdating() {
249 DCHECK(updating_);
250 updating_ = false;
251
252 // Delete all the resources.
253 STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
254
255 resources_.clear();
256 pid_to_resources_.clear();
257
258 BrowserChildProcessObserver::Remove(this);
259 }
260
261 void TaskManagerChildProcessResourceProvider::BrowserChildProcessHostConnected(
262 const content::ChildProcessData& data) {
263 DCHECK(updating_);
264
265 // Workers are handled by TaskManagerWorkerResourceProvider.
266 if (data.process_type == content::PROCESS_TYPE_WORKER)
267 return;
268 if (resources_.count(data.handle)) {
269 // The case may happen that we have added a child_process_info as part of
270 // the iteration performed during StartUpdating() call but the notification
271 // that it has connected was not fired yet. So when the notification
272 // happens, we already know about this plugin and just ignore it.
273 return;
274 }
275 AddToTaskManager(data);
276 }
277
278 void TaskManagerChildProcessResourceProvider::
279 BrowserChildProcessHostDisconnected(const content::ChildProcessData& data) {
280 DCHECK(updating_);
281
282 if (data.process_type == content::PROCESS_TYPE_WORKER)
283 return;
284 ChildProcessMap::iterator iter = resources_.find(data.handle);
285 if (iter == resources_.end()) {
286 // ChildProcessData disconnection notifications are asynchronous, so we
287 // might be notified for a plugin we don't know anything about (if it was
288 // closed before the task manager was shown and destroyed after that).
289 return;
290 }
291 // Remove the resource from the Task Manager.
292 TaskManagerChildProcessResource* resource = iter->second;
293 task_manager_->RemoveResource(resource);
294 // Remove it from the provider.
295 resources_.erase(iter);
296 // Remove it from our pid map.
297 PidResourceMap::iterator pid_iter =
298 pid_to_resources_.find(resource->process_id());
299 DCHECK(pid_iter != pid_to_resources_.end());
300 if (pid_iter != pid_to_resources_.end())
301 pid_to_resources_.erase(pid_iter);
302
303 // Finally, delete the resource.
304 delete resource;
305 }
306
307 void TaskManagerChildProcessResourceProvider::AddToTaskManager(
308 const content::ChildProcessData& child_process_data) {
309 TaskManagerChildProcessResource* resource =
310 new TaskManagerChildProcessResource(
311 child_process_data.process_type,
312 child_process_data.name,
313 child_process_data.handle,
314 child_process_data.id);
315 resources_[child_process_data.handle] = resource;
316 pid_to_resources_[resource->process_id()] = resource;
317 task_manager_->AddResource(resource);
318 }
319
320 // The ChildProcessData::Iterator has to be used from the IO thread.
321 void TaskManagerChildProcessResourceProvider::RetrieveChildProcessData() {
322 std::vector<content::ChildProcessData> child_processes;
323 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
324 // Only add processes which are already started, since we need their handle.
325 if (iter.GetData().handle == base::kNullProcessHandle)
326 continue;
327 if (iter.GetData().process_type == content::PROCESS_TYPE_WORKER)
328 continue;
329 child_processes.push_back(iter.GetData());
330 }
331 // Now notify the UI thread that we have retrieved information about child
332 // processes.
333 BrowserThread::PostTask(
334 BrowserThread::UI, FROM_HERE,
335 base::Bind(
336 &TaskManagerChildProcessResourceProvider::ChildProcessDataRetreived,
337 this, child_processes));
338 }
339
340 // This is called on the UI thread.
341 void TaskManagerChildProcessResourceProvider::ChildProcessDataRetreived(
342 const std::vector<content::ChildProcessData>& child_processes) {
343 for (size_t i = 0; i < child_processes.size(); ++i)
344 AddToTaskManager(child_processes[i]);
345
346 content::NotificationService::current()->Notify(
347 chrome::NOTIFICATION_TASK_MANAGER_CHILD_PROCESSES_DATA_READY,
348 content::Source<TaskManagerChildProcessResourceProvider>(this),
349 content::NotificationService::NoDetails());
350 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698