task_manager.h revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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#ifndef CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
6#define CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
7
8#include <map>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/callback_forward.h"
13#include "base/gtest_prod_util.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/singleton.h"
16#include "base/observer_list.h"
17#include "base/strings/string16.h"
18#include "base/timer/timer.h"
19#include "chrome/browser/renderer_host/web_cache_manager.h"
20#include "chrome/browser/task_manager/resource_provider.h"
21#include "chrome/browser/ui/host_desktop.h"
22#include "content/public/common/gpu_memory_stats.h"
23#include "third_party/WebKit/public/web/WebCache.h"
24
25class PrefRegistrySimple;
26class TaskManagerModel;
27class TaskManagerModelGpuDataManagerObserver;
28
29namespace base {
30class ProcessMetrics;
31}
32
33namespace content {
34class WebContents;
35}
36
37namespace extensions {
38class Extension;
39}
40
41namespace gfx {
42class ImageSkia;
43}
44
45namespace net {
46class URLRequest;
47}
48
49// This class is a singleton.
50class TaskManager {
51 public:
52  static void RegisterPrefs(PrefRegistrySimple* registry);
53
54  // Returns true if the process at the specified index is the browser process.
55  bool IsBrowserProcess(int index) const;
56
57  // Terminates the process at the specified index.
58  void KillProcess(int index);
59
60  // Activates the browser tab associated with the process in the specified
61  // index.
62  void ActivateProcess(int index);
63
64  // These methods are invoked by the resource providers to add/remove resources
65  // to the Task Manager. Note that the resources are owned by the
66  // ResourceProviders and are not valid after StopUpdating() has been called
67  // on the ResourceProviders.
68  void AddResource(task_manager::Resource* resource);
69  void RemoveResource(task_manager::Resource* resource);
70
71  void OnWindowClosed();
72
73  // Invoked when a change to a resource has occurred that should cause any
74  // observers to completely refresh themselves (for example, the creation of
75  // a background resource in a process). Results in all observers receiving
76  // OnModelChanged() events.
77  void ModelChanged();
78
79  // Returns the singleton instance (and initializes it if necessary).
80  static TaskManager* GetInstance();
81
82  TaskManagerModel* model() const { return model_.get(); }
83
84  void OpenAboutMemory(chrome::HostDesktopType desktop_type);
85
86 private:
87  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Basic);
88  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Resources);
89  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
90  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Init);
91  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Sort);
92  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
93                           SelectionAdaptsToSorting);
94
95  // Obtain an instance via GetInstance().
96  TaskManager();
97  friend struct DefaultSingletonTraits<TaskManager>;
98
99  ~TaskManager();
100
101  // The model used for gathering and processing task data. It is ref counted
102  // because it is passed as a parameter to MessageLoop::InvokeLater().
103  scoped_refptr<TaskManagerModel> model_;
104
105  DISALLOW_COPY_AND_ASSIGN(TaskManager);
106};
107
108class TaskManagerModelObserver {
109 public:
110  virtual ~TaskManagerModelObserver() {}
111
112  // Invoked when the model has been completely changed.
113  virtual void OnModelChanged() = 0;
114
115  // Invoked when a range of items has changed.
116  virtual void OnItemsChanged(int start, int length) = 0;
117
118  // Invoked when new items are added.
119  virtual void OnItemsAdded(int start, int length) = 0;
120
121  // Invoked when a range of items has been removed.
122  virtual void OnItemsRemoved(int start, int length) = 0;
123
124  // Invoked when a range of items is to be immediately removed. It differs
125  // from OnItemsRemoved by the fact that the item is still in the task manager,
126  // so it can be queried for and found.
127  virtual void OnItemsToBeRemoved(int start, int length) {}
128
129  // Invoked when the initialization of the model has been finished and
130  // periodical updates is started. The first periodical update will be done
131  // in a few seconds. (depending on platform)
132  virtual void OnReadyPeriodicalUpdate() {}
133};
134
135// The model used by TaskManager.
136//
137// TaskManagerModel caches the values from all task_manager::Resources. This is
138// done so the UI sees a consistant view of the resources until it is told a
139// value has been updated.
140class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
141 public:
142  // (start, length)
143  typedef std::pair<int, int> GroupRange;
144
145  explicit TaskManagerModel(TaskManager* task_manager);
146
147  void AddObserver(TaskManagerModelObserver* observer);
148  void RemoveObserver(TaskManagerModelObserver* observer);
149
150  // Returns number of registered resources.
151  int ResourceCount() const;
152  // Returns number of registered groups.
153  int GroupCount() const;
154
155  // Methods to return raw resource information.
156  int GetNaClDebugStubPort(int index) const;
157  int64 GetNetworkUsage(int index) const;
158  double GetCPUUsage(int index) const;
159  int GetIdleWakeupsPerSecond(int index) const;
160  base::ProcessId GetProcessId(int index) const;
161  base::ProcessHandle GetProcess(int index) const;
162
163  // Catchall method that calls off to the appropriate GetResourceXXX method
164  // based on |col_id|. |col_id| is an IDS_ value used to identify the column.
165  base::string16 GetResourceById(int index, int col_id) const;
166
167  // Methods to return formatted resource information.
168  const base::string16& GetResourceTitle(int index) const;
169  const base::string16& GetResourceProfileName(int index) const;
170  base::string16 GetResourceNaClDebugStubPort(int index) const;
171  base::string16 GetResourceNetworkUsage(int index) const;
172  base::string16 GetResourceCPUUsage(int index) const;
173  base::string16 GetResourcePrivateMemory(int index) const;
174  base::string16 GetResourceSharedMemory(int index) const;
175  base::string16 GetResourcePhysicalMemory(int index) const;
176  base::string16 GetResourceProcessId(int index) const;
177  base::string16 GetResourceGDIHandles(int index) const;
178  base::string16 GetResourceUSERHandles(int index) const;
179  base::string16 GetResourceWebCoreImageCacheSize(int index) const;
180  base::string16 GetResourceWebCoreScriptsCacheSize(int index) const;
181  base::string16 GetResourceWebCoreCSSCacheSize(int index) const;
182  base::string16 GetResourceVideoMemory(int index) const;
183  base::string16 GetResourceFPS(int index) const;
184  base::string16 GetResourceSqliteMemoryUsed(int index) const;
185  base::string16 GetResourceIdleWakeupsPerSecond(int index) const;
186  base::string16 GetResourceGoatsTeleported(int index) const;
187  base::string16 GetResourceV8MemoryAllocatedSize(int index) const;
188
189  // Gets the private memory (in bytes) that should be displayed for the passed
190  // resource index. Caches the result since this calculation can take time on
191  // some platforms.
192  bool GetPrivateMemory(int index, size_t* result) const;
193
194  // Gets the shared memory (in bytes) that should be displayed for the passed
195  // resource index. Caches the result since this calculation can take time on
196  // some platforms.
197  bool GetSharedMemory(int index, size_t* result) const;
198
199  // Gets the physical memory (in bytes) that should be displayed for the passed
200  // resource index.
201  bool GetPhysicalMemory(int index, size_t* result) const;
202
203  // On Windows, get the current and peak number of GDI handles in use.
204  void GetGDIHandles(int index, size_t* current, size_t* peak) const;
205
206  // On Windows, get the current and peak number of USER handles in use.
207  void GetUSERHandles(int index, size_t* current, size_t* peak) const;
208
209  // Gets the statuses of webkit. Return false if the resource for the given row
210  // isn't a renderer.
211  bool GetWebCoreCacheStats(int index,
212                            blink::WebCache::ResourceTypeStats* result) const;
213
214  // Gets the GPU memory allocated of the given page.
215  bool GetVideoMemory(int index,
216                      size_t* video_memory,
217                      bool* has_duplicates) const;
218
219  // Gets the fps of the given page. Return false if the resource for the given
220  // row isn't a renderer.
221  bool GetFPS(int index, float* result) const;
222
223  // Gets the sqlite memory (in byte). Return false if the resource for the
224  // given row doesn't report information.
225  bool GetSqliteMemoryUsedBytes(int index, size_t* result) const;
226
227  // Gets the amount of memory allocated for javascript. Returns false if the
228  // resource for the given row isn't a renderer.
229  bool GetV8Memory(int index, size_t* result) const;
230
231  // Gets the amount of memory used for javascript. Returns false if the
232  // resource for the given row isn't a renderer.
233  bool GetV8MemoryUsed(int index, size_t* result) const;
234
235  // Returns true if resource for the given row can be activated.
236  bool CanActivate(int index) const;
237
238  // Returns true if resource for the given row can be inspected using developer
239  // tools.
240  bool CanInspect(int index) const;
241
242  // Invokes or reveals developer tools window for resource in the given row.
243  void Inspect(int index) const;
244
245  // See design doc at http://go/at-teleporter for more information.
246  int GetGoatsTeleported(int index) const;
247
248  // Returns true if the resource is first/last in its group (resources
249  // rendered by the same process are groupped together).
250  bool IsResourceFirstInGroup(int index) const;
251  bool IsResourceLastInGroup(int index) const;
252
253  // Returns icon to be used for resource (for example a favicon).
254  gfx::ImageSkia GetResourceIcon(int index) const;
255
256  // Returns the group range of resource.
257  GroupRange GetGroupRangeForResource(int index) const;
258
259  // Returns an index of groups to which the resource belongs.
260  int GetGroupIndexForResource(int index) const;
261
262  // Returns an index of resource which belongs to the |group_index|th group
263  // and which is the |index_in_group|th resource in group.
264  int GetResourceIndexForGroup(int group_index, int index_in_group) const;
265
266  // Compares values in column |col_id| and rows |row1|, |row2|.
267  // Returns -1 if value in |row1| is less than value in |row2|,
268  // 0 if they are equal, and 1 otherwise.
269  int CompareValues(int row1, int row2, int col_id) const;
270
271  // Returns the unique child process ID generated by Chromium, not the OS
272  // process id. This is used to identify processes internally and for
273  // extensions. It is not meant to be displayed to the user.
274  int GetUniqueChildProcessId(int index) const;
275
276  // Returns the type of the given resource.
277  task_manager::Resource::Type GetResourceType(int index) const;
278
279  // Returns WebContents of given resource or NULL if not applicable.
280  content::WebContents* GetResourceWebContents(int index) const;
281
282  void AddResource(task_manager::Resource* resource);
283  void RemoveResource(task_manager::Resource* resource);
284
285  void StartUpdating();
286  void StopUpdating();
287
288  // Listening involves calling StartUpdating on all resource providers. This
289  // causes all of them to subscribe to notifications and enumerate current
290  // resources. It differs from StartUpdating that it doesn't start the
291  // Refresh timer. The end result is that we have a full view of resources, but
292  // don't spend unneeded time updating, unless we have a real need to.
293  void StartListening();
294  void StopListening();
295
296  void Clear();  // Removes all items.
297
298  // Sends OnModelChanged() to all observers to inform them of significant
299  // changes to the model.
300  void ModelChanged();
301
302   // Updates the values for all rows.
303  void Refresh();
304
305  void NotifyResourceTypeStats(
306        base::ProcessId renderer_id,
307        const blink::WebCache::ResourceTypeStats& stats);
308
309  void NotifyFPS(base::ProcessId renderer_id,
310                 int routing_id,
311                 float fps);
312
313  void NotifyVideoMemoryUsageStats(
314      const content::GPUVideoMemoryUsageStats& video_memory_usage_stats);
315
316  void NotifyV8HeapStats(base::ProcessId renderer_id,
317                         size_t v8_memory_allocated,
318                         size_t v8_memory_used);
319
320  void NotifyBytesRead(const net::URLRequest& request, int bytes_read);
321
322  void RegisterOnDataReadyCallback(const base::Closure& callback);
323
324  void NotifyDataReady();
325
326 private:
327  friend class base::RefCountedThreadSafe<TaskManagerModel>;
328  friend class TaskManagerBrowserTest;
329  FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager);
330  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
331  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
332                           SelectionAdaptsToSorting);
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  // The delay between updates of the information (in ms).
341#if defined(OS_MACOSX)
342  // Match Activity Monitor's default refresh rate.
343  static const int kUpdateTimeMs = 2000;
344#else
345  static const int kUpdateTimeMs = 1000;
346#endif
347
348  // Values cached per resource. Values are validated on demand. The is_XXX
349  // members indicate if a value is valid.
350  struct PerResourceValues {
351    PerResourceValues();
352    ~PerResourceValues();
353
354    bool is_nacl_debug_stub_port_valid;
355    int nacl_debug_stub_port;
356
357    bool is_title_valid;
358    base::string16 title;
359
360    bool is_profile_name_valid;
361    base::string16 profile_name;
362
363    // No is_network_usage since default (0) is fine.
364    int64 network_usage;
365
366    bool is_process_id_valid;
367    base::ProcessId process_id;
368
369    bool is_goats_teleported_valid;
370    int goats_teleported;
371
372    bool is_webcore_stats_valid;
373    blink::WebCache::ResourceTypeStats webcore_stats;
374
375    bool is_fps_valid;
376    float fps;
377
378    bool is_sqlite_memory_bytes_valid;
379    size_t sqlite_memory_bytes;
380
381    bool is_v8_memory_valid;
382    size_t v8_memory_allocated;
383    size_t v8_memory_used;
384  };
385
386  // Values cached per process. Values are validated on demand. The is_XXX
387  // members indicate if a value is valid.
388  struct PerProcessValues {
389    PerProcessValues();
390    ~PerProcessValues();
391
392    bool is_cpu_usage_valid;
393    double cpu_usage;
394
395    bool is_idle_wakeups_valid;
396    int idle_wakeups;
397
398    bool is_private_and_shared_valid;
399    size_t private_bytes;
400    size_t shared_bytes;
401
402    bool is_physical_memory_valid;
403    size_t physical_memory;
404
405    bool is_video_memory_valid;
406    size_t video_memory;
407    bool video_memory_has_duplicates;
408
409    bool is_gdi_handles_valid;
410    size_t gdi_handles;
411    size_t gdi_handles_peak;
412
413    bool is_user_handles_valid;
414    size_t user_handles;
415    size_t user_handles_peak;
416  };
417
418  typedef std::vector<task_manager::Resource*> ResourceList;
419  typedef std::vector<scoped_refptr<task_manager::ResourceProvider> >
420      ResourceProviderList;
421  typedef std::map<base::ProcessHandle, ResourceList*> GroupMap;
422  typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
423  typedef std::map<task_manager::Resource*, int64> ResourceValueMap;
424  typedef std::map<task_manager::Resource*,
425                   PerResourceValues> PerResourceCache;
426  typedef std::map<base::ProcessHandle, PerProcessValues> PerProcessCache;
427
428  // This struct is used to exchange information between the io and ui threads.
429  struct BytesReadParam {
430    BytesReadParam(int origin_pid,
431                   int child_id,
432                   int route_id,
433                   int byte_count)
434        : origin_pid(origin_pid),
435          child_id(child_id),
436          route_id(route_id),
437          byte_count(byte_count) {}
438
439    // The process ID that triggered the request.  For plugin requests this
440    // will differ from the renderer process ID.
441    int origin_pid;
442
443    // The child ID of the process this request was routed through.
444    int child_id;
445
446    int route_id;
447    int byte_count;
448  };
449
450  ~TaskManagerModel();
451
452  // Callback from the timer to refresh. Invokes Refresh() as appropriate.
453  void RefreshCallback();
454
455  void RefreshVideoMemoryUsageStats();
456
457  // Returns the network usage (in bytes per seconds) for the specified
458  // resource. That's the value retrieved at the last timer's tick.
459  int64 GetNetworkUsageForResource(task_manager::Resource* resource) const;
460
461  // Called on the UI thread when some bytes are read.
462  void BytesRead(BytesReadParam param);
463
464  void MultipleBytesRead(const std::vector<BytesReadParam>* params);
465
466  // Notifies the UI thread about all the bytes read. Allows for coalescing
467  // multiple bytes read into a single task for the UI thread. This is important
468  // for when downloading a lot of data on the IO thread, since posting a Task
469  // for each one is expensive.
470  void NotifyMultipleBytesRead();
471
472  // Returns the network usage (in byte per second) that should be displayed for
473  // the passed |resource|.  -1 means the information is not available for that
474  // resource.
475  int64 GetNetworkUsage(task_manager::Resource* resource) const;
476
477  // Returns the CPU usage (in %) that should be displayed for the passed
478  // |resource|.
479  double GetCPUUsage(task_manager::Resource* resource) const;
480
481  // Returns the idle wakeups that should be displayed for the passed
482  // |resource|.
483  int GetIdleWakeupsPerSecond(task_manager::Resource* resource) const;
484
485  // Given a number, this function returns the formatted string that should be
486  // displayed in the task manager's memory cell.
487  base::string16 GetMemCellText(int64 number) const;
488
489  // Verifies the private and shared memory for |handle| is valid in
490  // |per_process_cache_|. Returns true if the data in |per_process_cache_| is
491  // valid.
492  bool CachePrivateAndSharedMemory(base::ProcessHandle handle) const;
493
494  // Verifies |webcore_stats| in |per_resource_cache_|, returning true on
495  // success.
496  bool CacheWebCoreStats(int index) const;
497
498  // Verifies |v8_memory_allocated| and |v8_memory_used| in
499  // |per_resource_cache_|. Returns true if valid, false if not valid.
500  bool CacheV8Memory(int index) const;
501
502  // Adds a resource provider to be managed.
503  void AddResourceProvider(task_manager::ResourceProvider* provider);
504
505  // Returns the PerResourceValues for the specified index.
506  PerResourceValues& GetPerResourceValues(int index) const;
507
508  // Returns the Resource for the specified index.
509  task_manager::Resource* GetResource(int index) const;
510
511  // The list of providers to the task manager. They are ref counted.
512  ResourceProviderList providers_;
513
514  // The list of all the resources displayed in the task manager. They are owned
515  // by the ResourceProviders.
516  ResourceList resources_;
517
518  // A map to keep tracks of the grouped resources (they are grouped if they
519  // share the same process). The groups (the Resources vectors) are owned by
520  // the model (but the actual Resources are owned by the ResourceProviders).
521  GroupMap group_map_;
522
523  // A map to retrieve the process metrics for a process. The ProcessMetrics are
524  // owned by the model.
525  MetricsMap metrics_map_;
526
527  // A map that keeps track of the number of bytes read per process since last
528  // tick. The Resources are owned by the ResourceProviders.
529  ResourceValueMap current_byte_count_map_;
530
531  // A map that contains the video memory usage for a process
532  content::GPUVideoMemoryUsageStats video_memory_usage_stats_;
533
534  // Set to true when we've requested video stats and false once we get them.
535  bool pending_video_memory_usage_stats_update_;
536
537  // An observer waiting for video memory usage stats updates from the GPU
538  // process
539  scoped_ptr<TaskManagerModelGpuDataManagerObserver>
540      video_memory_usage_stats_observer_;
541
542  ObserverList<TaskManagerModelObserver> observer_list_;
543
544  // How many calls to StartUpdating have been made without matching calls to
545  // StopUpdating.
546  int update_requests_;
547
548  // How many calls to StartListening have been made without matching calls to
549  // StopListening.
550  int listen_requests_;
551
552  // Whether we are currently in the process of updating.
553  UpdateState update_state_;
554
555  // A salt lick for the goats.
556  uint64 goat_salt_;
557
558  // Buffer for coalescing BytesReadParam so we don't have to post a task on
559  // each NotifyBytesRead() call.
560  std::vector<BytesReadParam> bytes_read_buffer_;
561
562  std::vector<base::Closure> on_data_ready_callbacks_;
563
564  // All per-Resource values are stored here.
565  mutable PerResourceCache per_resource_cache_;
566
567  // All per-Process values are stored here.
568  mutable PerProcessCache per_process_cache_;
569
570  DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
571};
572
573#endif  // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
574