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