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
26class Extension;
27class SkBitmap;
28class TabContentsWrapper;
29class TaskManagerModel;
30
31namespace base {
32class ProcessMetrics;
33}
34
35// This class is a singleton.
36class 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:
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
65    virtual bool ReportsCacheStats() const { return false; }
66    virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const {
67      return WebKit::WebCache::ResourceTypeStats();
68    }
69
70    virtual bool ReportsSqliteMemoryUsed() const { return false; }
71    virtual size_t SqliteMemoryUsedBytes() const { return 0; }
72
73    // Return extension associated with the resource, or NULL
74    // if not applicable.
75    virtual const Extension* GetExtension() const { return NULL; }
76
77    virtual bool ReportsV8MemoryStats() const { return false; }
78    virtual size_t GetV8MemoryAllocated() const { return 0; }
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.
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.
98    virtual void Refresh() {}
99
100    virtual void NotifyResourceTypeStats(
101        const WebKit::WebCache::ResourceTypeStats& stats) {}
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).
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
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
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
194class 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.
212class 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