• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
6 #define CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
7 #pragma once
8 
9 #include <map>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "base/basictypes.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/singleton.h"
18 #include "base/observer_list.h"
19 #include "base/process_util.h"
20 #include "base/string16.h"
21 #include "base/timer.h"
22 #include "chrome/browser/renderer_host/web_cache_manager.h"
23 #include "net/url_request/url_request_job_tracker.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h"
25 
26 class Extension;
27 class SkBitmap;
28 class TabContentsWrapper;
29 class TaskManagerModel;
30 
31 namespace base {
32 class ProcessMetrics;
33 }
34 
35 // This class is a singleton.
36 class TaskManager {
37  public:
38   // A resource represents one row in the task manager.
39   // Resources from similar processes are grouped together by the task manager.
40   class Resource {
41    public:
~Resource()42     virtual ~Resource() {}
43 
44     enum Type {
45       UNKNOWN = 0,     // An unknown process type.
46       BROWSER,         // The main browser process.
47       RENDERER,        // A normal TabContents renderer process.
48       EXTENSION,       // An extension or app process.
49       NOTIFICATION,    // A notification process.
50       PLUGIN,          // A plugin process.
51       WORKER,          // A web worker process.
52       NACL,            // A NativeClient loader or broker process.
53       UTILITY,         // A browser utility process.
54       PROFILE_IMPORT,  // A profile import process.
55       ZYGOTE,          // A Linux zygote process.
56       SANDBOX_HELPER,  // A sandbox helper process.
57       GPU              // A graphics process.
58     };
59 
60     virtual string16 GetTitle() const = 0;
61     virtual SkBitmap GetIcon() const = 0;
62     virtual base::ProcessHandle GetProcess() const = 0;
63     virtual Type GetType() const = 0;
64 
ReportsCacheStats()65     virtual bool ReportsCacheStats() const { return false; }
GetWebCoreCacheStats()66     virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const {
67       return WebKit::WebCache::ResourceTypeStats();
68     }
69 
ReportsSqliteMemoryUsed()70     virtual bool ReportsSqliteMemoryUsed() const { return false; }
SqliteMemoryUsedBytes()71     virtual size_t SqliteMemoryUsedBytes() const { return 0; }
72 
73     // Return extension associated with the resource, or NULL
74     // if not applicable.
GetExtension()75     virtual const Extension* GetExtension() const { return NULL; }
76 
ReportsV8MemoryStats()77     virtual bool ReportsV8MemoryStats() const { return false; }
GetV8MemoryAllocated()78     virtual size_t GetV8MemoryAllocated() const { return 0; }
GetV8MemoryUsed()79     virtual size_t GetV8MemoryUsed() const { return 0; }
80 
81     // A helper function for ActivateFocusedTab.  Returns NULL by default
82     // because not all resources have an associated tab.
GetTabContents()83     virtual TabContentsWrapper* GetTabContents() const { return NULL; }
84 
85     // Whether this resource does report the network usage accurately.
86     // This controls whether 0 or N/A is displayed when no bytes have been
87     // reported as being read. This is because some plugins do not report the
88     // bytes read and we don't want to display a misleading 0 value in that
89     // case.
90     virtual bool SupportNetworkUsage() const = 0;
91 
92     // Called when some bytes have been read and support_network_usage returns
93     // false (meaning we do have network usage support).
94     virtual void SetSupportNetworkUsage() = 0;
95 
96     // The TaskManagerModel periodically refreshes its data and call this
97     // on all live resources.
Refresh()98     virtual void Refresh() {}
99 
NotifyResourceTypeStats(const WebKit::WebCache::ResourceTypeStats & stats)100     virtual void NotifyResourceTypeStats(
101         const WebKit::WebCache::ResourceTypeStats& stats) {}
NotifyV8HeapStats(size_t v8_memory_allocated,size_t v8_memory_used)102     virtual void NotifyV8HeapStats(size_t v8_memory_allocated,
103                                    size_t v8_memory_used) {}
104 
105     // Returns true if this resource is not visible to the user because it lives
106     // in the background (e.g. extension background page, background contents).
IsBackground()107     virtual bool IsBackground() const { return false; }
108   };
109 
110   // ResourceProviders are responsible for adding/removing resources to the task
111   // manager. The task manager notifies the ResourceProvider that it is ready
112   // to receive resource creation/termination notifications with a call to
113   // StartUpdating(). At that point, the resource provider should call
114   // AddResource with all the existing resources, and after that it should call
115   // AddResource/RemoveResource as resources are created/terminated.
116   // The provider remains the owner of the resource objects and is responsible
117   // for deleting them (when StopUpdating() is called).
118   // After StopUpdating() is called the provider should also stop reporting
119   // notifications to the task manager.
120   // Note: ResourceProviders have to be ref counted as they are used in
121   // MessageLoop::InvokeLater().
122   class ResourceProvider : public base::RefCountedThreadSafe<ResourceProvider> {
123    public:
124     // Should return the resource associated to the specified ids, or NULL if
125     // the resource does not belong to this provider.
126     virtual TaskManager::Resource* GetResource(int process_id,
127                                                int render_process_host_id,
128                                                int routing_id) = 0;
129     virtual void StartUpdating() = 0;
130     virtual void StopUpdating() = 0;
131 
132    protected:
133     friend class base::RefCountedThreadSafe<ResourceProvider>;
134 
~ResourceProvider()135     virtual ~ResourceProvider() {}
136   };
137 
138   static void RegisterPrefs(PrefService* prefs);
139 
140   // Returns true if the process at the specified index is the browser process.
141   bool IsBrowserProcess(int index) const;
142 
143   // Terminates the process at the specified index.
144   void KillProcess(int index);
145 
146   // Activates the browser tab associated with the process in the specified
147   // index.
148   void ActivateProcess(int index);
149 
150   // These methods are invoked by the resource providers to add/remove resources
151   // to the Task Manager. Note that the resources are owned by the
152   // ResourceProviders and are not valid after StopUpdating() has been called
153   // on the ResourceProviders.
154   void AddResource(Resource* resource);
155   void RemoveResource(Resource* resource);
156 
157   void OnWindowClosed();
158 
159   // Invoked when a change to a resource has occurred that should cause any
160   // observers to completely refresh themselves (for example, the creation of
161   // a background resource in a process). Results in all observers receiving
162   // OnModelChanged() events.
163   void ModelChanged();
164 
165   // Returns the singleton instance (and initializes it if necessary).
166   static TaskManager* GetInstance();
167 
model()168   TaskManagerModel* model() const { return model_.get(); }
169 
170   void OpenAboutMemory();
171 
172  private:
173   FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Basic);
174   FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Resources);
175   FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
176   FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Init);
177   FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Sort);
178   FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
179                            SelectionAdaptsToSorting);
180 
181   // Obtain an instance via GetInstance().
182   TaskManager();
183   friend struct DefaultSingletonTraits<TaskManager>;
184 
185   ~TaskManager();
186 
187   // The model used for gathering and processing task data. It is ref counted
188   // because it is passed as a parameter to MessageLoop::InvokeLater().
189   scoped_refptr<TaskManagerModel> model_;
190 
191   DISALLOW_COPY_AND_ASSIGN(TaskManager);
192 };
193 
194 class TaskManagerModelObserver {
195  public:
196   virtual ~TaskManagerModelObserver() {}
197 
198   // Invoked when the model has been completely changed.
199   virtual void OnModelChanged() = 0;
200 
201   // Invoked when a range of items has changed.
202   virtual void OnItemsChanged(int start, int length) = 0;
203 
204   // Invoked when new items are added.
205   virtual void OnItemsAdded(int start, int length) = 0;
206 
207   // Invoked when a range of items has been removed.
208   virtual void OnItemsRemoved(int start, int length) = 0;
209 };
210 
211 // The model that the TaskManager is using.
212 class TaskManagerModel : public net::URLRequestJobTracker::JobObserver,
213                          public base::RefCountedThreadSafe<TaskManagerModel> {
214  public:
215   explicit TaskManagerModel(TaskManager* task_manager);
216 
217   void AddObserver(TaskManagerModelObserver* observer);
218   void RemoveObserver(TaskManagerModelObserver* observer);
219 
220   // Returns number of registered resources.
221   int ResourceCount() const;
222 
223   // Methods to return raw resource information.
224   int64 GetNetworkUsage(int index) const;
225   double GetCPUUsage(int index) const;
226   int GetProcessId(int index) const;
227 
228   // Methods to return formatted resource information.
229   string16 GetResourceTitle(int index) const;
230   string16 GetResourceNetworkUsage(int index) const;
231   string16 GetResourceCPUUsage(int index) const;
232   string16 GetResourcePrivateMemory(int index) const;
233   string16 GetResourceSharedMemory(int index) const;
234   string16 GetResourcePhysicalMemory(int index) const;
235   string16 GetResourceProcessId(int index) const;
236   string16 GetResourceWebCoreImageCacheSize(int index) const;
237   string16 GetResourceWebCoreScriptsCacheSize(int index) const;
238   string16 GetResourceWebCoreCSSCacheSize(int index) const;
239   string16 GetResourceSqliteMemoryUsed(int index) const;
240   string16 GetResourceGoatsTeleported(int index) const;
241   string16 GetResourceV8MemoryAllocatedSize(int index) const;
242 
243   // Gets the private memory (in bytes) that should be displayed for the passed
244   // resource index. Caches the result since this calculation can take time on
245   // some platforms.
246   bool GetPrivateMemory(int index, size_t* result) const;
247 
248   // Gets the shared memory (in bytes) that should be displayed for the passed
249   // resource index. Caches the result since this calculation can take time on
250   // some platforms.
251   bool GetSharedMemory(int index, size_t* result) const;
252 
253   // Gets the physical memory (in bytes) that should be displayed for the passed
254   // resource index.
255   bool GetPhysicalMemory(int index, size_t* result) const;
256 
257   // Gets the amount of memory allocated for javascript. Returns false if the
258   // resource for the given row isn't a renderer.
259   bool GetV8Memory(int index, size_t* result) const;
260 
261   // See design doc at http://go/at-teleporter for more information.
262   int GetGoatsTeleported(int index) const;
263 
264   // Returns true if the resource is first in its group (resources
265   // rendered by the same process are groupped together).
266   bool IsResourceFirstInGroup(int index) const;
267 
268   // Returns true if the resource runs in the background (not visible to the
269   // user, e.g. extension background pages and BackgroundContents).
270   bool IsBackgroundResource(int index) const;
271 
272   // Returns icon to be used for resource (for example a favicon).
273   SkBitmap GetResourceIcon(int index) const;
274 
275   // Returns a pair (start, length) of the group range of resource.
276   std::pair<int, int> GetGroupRangeForResource(int index) const;
277 
278   // Compares values in column |col_id| and rows |row1|, |row2|.
279   // Returns -1 if value in |row1| is less than value in |row2|,
280   // 0 if they are equal, and 1 otherwise.
281   int CompareValues(int row1, int row2, int col_id) const;
282 
283   // Returns process handle for given resource.
284   base::ProcessHandle GetResourceProcessHandle(int index) const;
285 
286   // Returns the type of the given resource.
287   TaskManager::Resource::Type GetResourceType(int index) const;
288 
289   // Returns TabContents of given resource or NULL if not applicable.
290   TabContentsWrapper* GetResourceTabContents(int index) const;
291 
292   // Returns Extension of given resource or NULL if not applicable.
293   const Extension* GetResourceExtension(int index) const;
294 
295   // JobObserver methods:
296   virtual void OnJobAdded(net::URLRequestJob* job);
297   virtual void OnJobRemoved(net::URLRequestJob* job);
298   virtual void OnJobDone(net::URLRequestJob* job,
299                          const net::URLRequestStatus& status);
300   virtual void OnJobRedirect(net::URLRequestJob* job,
301                              const GURL& location,
302                              int status_code);
303   virtual void OnBytesRead(net::URLRequestJob* job,
304                            const char* buf,
305                            int byte_count);
306 
307   void AddResource(TaskManager::Resource* resource);
308   void RemoveResource(TaskManager::Resource* resource);
309 
310   void StartUpdating();
311   void StopUpdating();
312 
313   void Clear();  // Removes all items.
314 
315   // Sends OnModelChanged() to all observers to inform them of significant
316   // changes to the model.
317   void ModelChanged();
318 
319   void NotifyResourceTypeStats(
320         base::ProcessId renderer_id,
321         const WebKit::WebCache::ResourceTypeStats& stats);
322 
323   void NotifyV8HeapStats(base::ProcessId renderer_id,
324                          size_t v8_memory_allocated,
325                          size_t v8_memory_used);
326 
327  private:
328   friend class base::RefCountedThreadSafe<TaskManagerModel>;
329   FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
330   FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager);
331 
332   ~TaskManagerModel();
333 
334   enum UpdateState {
335     IDLE = 0,      // Currently not updating.
336     TASK_PENDING,  // An update task is pending.
337     STOPPING       // A update task is pending and it should stop the update.
338   };
339 
340   // This struct is used to exchange information between the io and ui threads.
341   struct BytesReadParam {
342     BytesReadParam(int origin_pid,
343                    int render_process_host_child_id,
344                    int routing_id,
345                    int byte_count)
346         : origin_pid(origin_pid),
347           render_process_host_child_id(render_process_host_child_id),
348           routing_id(routing_id),
349           byte_count(byte_count) {}
350 
351     // The process ID that triggered the request.  For plugin requests this
352     // will differ from the renderer process ID.
353     int origin_pid;
354 
355     // The child ID of the RenderProcessHost this request was routed through.
356     int render_process_host_child_id;
357 
358     int routing_id;
359     int byte_count;
360   };
361 
362   typedef std::vector<TaskManager::Resource*> ResourceList;
363   typedef std::vector<TaskManager::ResourceProvider*> ResourceProviderList;
364   typedef std::map<base::ProcessHandle, ResourceList*> GroupMap;
365   typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
366   typedef std::map<base::ProcessHandle, double> CPUUsageMap;
367   typedef std::map<TaskManager::Resource*, int64> ResourceValueMap;
368   typedef std::map<base::ProcessHandle,
369                    std::pair<size_t, size_t> > MemoryUsageMap;
370 
371   // Updates the values for all rows.
372   void Refresh();
373 
374   void AddItem(TaskManager::Resource* resource, bool notify_table);
375   void RemoveItem(TaskManager::Resource* resource);
376 
377   // Register for network usage updates
378   void RegisterForJobDoneNotifications();
379   void UnregisterForJobDoneNotifications();
380 
381   // Returns the network usage (in bytes per seconds) for the specified
382   // resource. That's the value retrieved at the last timer's tick.
383   int64 GetNetworkUsageForResource(TaskManager::Resource* resource) const;
384 
385   // Called on the UI thread when some bytes are read.
386   void BytesRead(BytesReadParam param);
387 
388   // Returns the network usage (in byte per second) that should be displayed for
389   // the passed |resource|.  -1 means the information is not available for that
390   // resource.
391   int64 GetNetworkUsage(TaskManager::Resource* resource) const;
392 
393   // Returns the CPU usage (in %) that should be displayed for the passed
394   // |resource|.
395   double GetCPUUsage(TaskManager::Resource* resource) const;
396 
397   // Retrieves the ProcessMetrics for the resources at the specified row.
398   // Returns true if there was a ProcessMetrics available.
399   bool GetProcessMetricsForRow(int row,
400                                base::ProcessMetrics** proc_metrics) const;
401 
402   // Given a number, this function returns the formatted string that should be
403   // displayed in the task manager's memory cell.
404   string16 GetMemCellText(int64 number) const;
405 
406   // Looks up the data for |handle| and puts it in the mutable cache
407   // |memory_usage_map_|.
408   bool GetAndCacheMemoryMetrics(base::ProcessHandle handle,
409                                 std::pair<size_t, size_t>* usage) const;
410 
411   // Adds a resource provider to be managed.
412   void AddResourceProvider(TaskManager::ResourceProvider* provider);
413 
414   // The list of providers to the task manager. They are ref counted.
415   ResourceProviderList providers_;
416 
417   // The list of all the resources displayed in the task manager. They are owned
418   // by the ResourceProviders.
419   ResourceList resources_;
420 
421   // A map to keep tracks of the grouped resources (they are grouped if they
422   // share the same process). The groups (the Resources vectors) are owned by
423   // the model (but the actual Resources are owned by the ResourceProviders).
424   GroupMap group_map_;
425 
426   // A map to retrieve the process metrics for a process. The ProcessMetrics are
427   // owned by the model.
428   MetricsMap metrics_map_;
429 
430   // A map that keeps track of the number of bytes read per process since last
431   // tick. The Resources are owned by the ResourceProviders.
432   ResourceValueMap current_byte_count_map_;
433 
434   // A map that contains the network usage is displayed in the table, in bytes
435   // per second. It is computed every time the timer ticks. The Resources are
436   // owned by the ResourceProviders.
437   ResourceValueMap displayed_network_usage_map_;
438 
439   // A map that contains the CPU usage (in %) for a process since last refresh.
440   CPUUsageMap cpu_usage_map_;
441 
442   // A map that contains the private/shared memory usage of the process. We
443   // cache this because the same APIs are called on linux and windows, and
444   // because the linux call takes >10ms to complete. This cache is cleared on
445   // every Refresh().
446   mutable MemoryUsageMap memory_usage_map_;
447 
448   ObserverList<TaskManagerModelObserver> observer_list_;
449 
450   // How many calls to StartUpdating have been made without matching calls to
451   // StopUpdating.
452   int update_requests_;
453 
454   // Whether we are currently in the process of updating.
455   UpdateState update_state_;
456 
457   // A salt lick for the goats.
458   int goat_salt_;
459 
460   DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
461 };
462 
463 #endif  // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
464