summaryrefslogtreecommitdiffstats
path: root/chrome/browser/task_manager.h
blob: 2fe885e4a64996e725b5e453b8c247b3676fc97d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_TASK_MANAGER_H_
#define CHROME_BROWSER_TASK_MANAGER_H_

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/lock.h"
#include "base/observer_list.h"
#include "base/process_util.h"
#include "base/ref_counted.h"
#include "base/singleton.h"
#include "base/timer.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "net/url_request/url_request_job_tracker.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCache.h"

class Extension;
class SkBitmap;
class TaskManager;
class TaskManagerModel;

struct BytesReadParam;

namespace base {
class ProcessMetrics;
}

// This class is a singleton.
class TaskManager {
 public:
  // A resource represents one row in the task manager.
  // Resources from similar processes are grouped together by the task manager.
  class Resource {
   public:
    virtual ~Resource() {}

    virtual std::wstring GetTitle() const = 0;
    virtual SkBitmap GetIcon() const = 0;
    virtual base::ProcessHandle GetProcess() const = 0;

    virtual bool ReportsCacheStats() const { return false; }
    virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const {
      return WebKit::WebCache::ResourceTypeStats();
    }

    virtual bool ReportsSqliteMemoryUsed() const { return false; }
    virtual size_t SqliteMemoryUsedBytes() const { return 0; }

  // Return extension associated with the resource, or NULL
  // if not applicable.
  virtual const Extension* GetExtension() const { return NULL; }

    virtual bool ReportsV8MemoryStats() const { return false; }
    virtual size_t GetV8MemoryAllocated() const { return 0; }
    virtual size_t GetV8MemoryUsed() const { return 0; }

    // A helper function for ActivateFocusedTab.  Returns NULL by default
    // because not all resources have an associated tab.
    virtual TabContents* GetTabContents() const { return NULL; }

    // Whether this resource does report the network usage accurately.
    // This controls whether 0 or N/A is displayed when no bytes have been
    // reported as being read. This is because some plugins do not report the
    // bytes read and we don't want to display a misleading 0 value in that
    // case.
    virtual bool SupportNetworkUsage() const = 0;

    // Called when some bytes have been read and support_network_usage returns
    // false (meaning we do have network usage support).
    virtual void SetSupportNetworkUsage() = 0;

    // The TaskManagerModel periodically refreshes its data and call this
    // on all live resources.
    virtual void Refresh() {}

    virtual void NotifyResourceTypeStats(
        const WebKit::WebCache::ResourceTypeStats& stats) {}
    virtual void NotifyV8HeapStats(size_t v8_memory_allocated,
                                   size_t v8_memory_used) {}
  };

  // ResourceProviders are responsible for adding/removing resources to the task
  // manager. The task manager notifies the ResourceProvider that it is ready
  // to receive resource creation/termination notifications with a call to
  // StartUpdating(). At that point, the resource provider should call
  // AddResource with all the existing resources, and after that it should call
  // AddResource/RemoveResource as resources are created/terminated.
  // The provider remains the owner of the resource objects and is responsible
  // for deleting them (when StopUpdating() is called).
  // After StopUpdating() is called the provider should also stop reporting
  // notifications to the task manager.
  // Note: ResourceProviders have to be ref counted as they are used in
  // MessageLoop::InvokeLater().
  class ResourceProvider : public base::RefCountedThreadSafe<ResourceProvider> {
   public:
    // Should return the resource associated to the specified ids, or NULL if
    // the resource does not belong to this provider.
    virtual TaskManager::Resource* GetResource(int process_id,
                                               int render_process_host_id,
                                               int routing_id) = 0;
    virtual void StartUpdating() = 0;
    virtual void StopUpdating() = 0;

   protected:
    friend class base::RefCountedThreadSafe<ResourceProvider>;

    virtual ~ResourceProvider() {}
  };

  static void RegisterPrefs(PrefService* prefs);

  // Returns true if the process at the specified index is the browser process.
  bool IsBrowserProcess(int index) const;

  // Terminates the process at the specified index.
  void KillProcess(int index);

  // Activates the browser tab associated with the process in the specified
  // index.
  void ActivateProcess(int index);

  void AddResourceProvider(ResourceProvider* provider);
  void RemoveResourceProvider(ResourceProvider* provider);

  // These methods are invoked by the resource providers to add/remove resources
  // to the Task Manager. Note that the resources are owned by the
  // ResourceProviders and are not valid after StopUpdating() has been called
  // on the ResourceProviders.
  void AddResource(Resource* resource);
  void RemoveResource(Resource* resource);

  void OnWindowClosed();

  // Returns the singleton instance (and initializes it if necessary).
  static TaskManager* GetInstance();

  TaskManagerModel* model() const { return model_.get(); }

  void OpenAboutMemory();

 private:
  FRIEND_TEST(TaskManagerTest, Basic);
  FRIEND_TEST(TaskManagerTest, Resources);
  FRIEND_TEST(TaskManagerTest, RefreshCalled);

  // Obtain an instance via GetInstance().
  TaskManager();
  friend struct DefaultSingletonTraits<TaskManager>;

  ~TaskManager();

  // The model used for gathering and processing task data. It is ref counted
  // because it is passed as a parameter to MessageLoop::InvokeLater().
  scoped_refptr<TaskManagerModel> model_;

  DISALLOW_COPY_AND_ASSIGN(TaskManager);
};

class TaskManagerModelObserver {
 public:
  virtual ~TaskManagerModelObserver() {}

  // Invoked when the model has been completely changed.
  virtual void OnModelChanged() = 0;

  // Invoked when a range of items has changed.
  virtual void OnItemsChanged(int start, int length) = 0;

  // Invoked when new items are added.
  virtual void OnItemsAdded(int start, int length) = 0;

  // Invoked when a range of items has been removed.
  virtual void OnItemsRemoved(int start, int length) = 0;
};

// The model that the TaskManager is using.
class TaskManagerModel : public URLRequestJobTracker::JobObserver,
                         public base::RefCountedThreadSafe<TaskManagerModel> {
 public:
  explicit TaskManagerModel(TaskManager* task_manager);

  void AddObserver(TaskManagerModelObserver* observer);
  void RemoveObserver(TaskManagerModelObserver* observer);

  // Returns number of registered resources.
  int ResourceCount() const;

  // Methods to return formatted resource information.
  std::wstring GetResourceTitle(int index) const;
  std::wstring GetResourceNetworkUsage(int index) const;
  std::wstring GetResourceCPUUsage(int index) const;
  std::wstring GetResourcePrivateMemory(int index) const;
  std::wstring GetResourceSharedMemory(int index) const;
  std::wstring GetResourcePhysicalMemory(int index) const;
  std::wstring GetResourceProcessId(int index) const;
  std::wstring GetResourceStatsValue(int index, int col_id) const;
  std::wstring GetResourceWebCoreImageCacheSize(int index) const;
  std::wstring GetResourceWebCoreScriptsCacheSize(int index) const;
  std::wstring GetResourceWebCoreCSSCacheSize(int index) const;
  std::wstring GetResourceSqliteMemoryUsed(int index) const;
  std::wstring GetResourceGoatsTeleported(int index) const;
  std::wstring GetResourceV8MemoryAllocatedSize(int index) const;

  // Returns true if the resource is first in its group (resources
  // rendered by the same process are groupped together).
  bool IsResourceFirstInGroup(int index) const;

  // Returns icon to be used for resource (for example a favicon).
  SkBitmap GetResourceIcon(int index) const;

  // Returns a pair (start, length) of the group range of resource.
  std::pair<int, int> GetGroupRangeForResource(int index) const;

  // Compares values in column |col_id| and rows |row1|, |row2|.
  // Returns -1 if value in |row1| is less than value in |row2|,
  // 0 if they are equal, and 1 otherwise.
  int CompareValues(int row1, int row2, int col_id) const;

  // Returns process handle for given resource.
  base::ProcessHandle GetResourceProcessHandle(int index) const;

  // Returns TabContents of given resource or NULL if not applicable.
  TabContents* GetResourceTabContents(int index) const;

  // Returns Extension of given resource or NULL if not applicable.
  const Extension* GetResourceExtension(int index) const;

  // JobObserver methods:
  void OnJobAdded(URLRequestJob* job);
  void OnJobRemoved(URLRequestJob* job);
  void OnJobDone(URLRequestJob* job, const URLRequestStatus& status);
  void OnJobRedirect(URLRequestJob* job, const GURL& location, int status_code);
  void OnBytesRead(URLRequestJob* job, int byte_count);

  void AddResourceProvider(TaskManager::ResourceProvider* provider);
  void RemoveResourceProvider(TaskManager::ResourceProvider* provider);

  void AddResource(TaskManager::Resource* resource);
  void RemoveResource(TaskManager::Resource* resource);

  void StartUpdating();
  void StopUpdating();

  void Clear();  // Removes all items.

  void NotifyResourceTypeStats(
        base::ProcessId renderer_id,
        const WebKit::WebCache::ResourceTypeStats& stats);

  void NotifyV8HeapStats(base::ProcessId renderer_id,
                         size_t v8_memory_allocated,
                         size_t v8_memory_used);

 private:
  friend class base::RefCountedThreadSafe<TaskManagerModel>;
  FRIEND_TEST(TaskManagerTest, RefreshCalled);

  ~TaskManagerModel();

  enum UpdateState {
    IDLE = 0,      // Currently not updating.
    TASK_PENDING,  // An update task is pending.
    STOPPING       // A update task is pending and it should stop the update.
  };

  // This struct is used to exchange information between the io and ui threads.
  struct BytesReadParam {
    BytesReadParam(int origin_child_id,
                   int render_process_host_child_id,
                   int routing_id,
                   int byte_count)
        : origin_child_id(origin_child_id),
          render_process_host_child_id(render_process_host_child_id),
          routing_id(routing_id),
          byte_count(byte_count) {}

    // This is the child ID of the originator of the request. It will often be
    // the same as the render_process_host_child_id, but will be different when
    // another sub-process like a plugin is routing requests through a renderer.
    int origin_child_id;

    // The child ID of the RenderProcessHist this request was routed through.
    int render_process_host_child_id;

    int routing_id;
    int byte_count;
  };

  typedef std::vector<TaskManager::Resource*> ResourceList;
  typedef std::vector<TaskManager::ResourceProvider*> ResourceProviderList;
  typedef std::map<base::ProcessHandle, ResourceList*> GroupMap;
  typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
  typedef std::map<base::ProcessHandle, int> CPUUsageMap;
  typedef std::map<TaskManager::Resource*, int64> ResourceValueMap;

  // Updates the values for all rows.
  void Refresh();

  void AddItem(TaskManager::Resource* resource, bool notify_table);
  void RemoveItem(TaskManager::Resource* resource);

  // Register for network usage updates
  void RegisterForJobDoneNotifications();
  void UnregisterForJobDoneNotifications();

  // Returns the network usage (in bytes per seconds) for the specified
  // resource. That's the value retrieved at the last timer's tick.
  int64 GetNetworkUsageForResource(TaskManager::Resource* resource) const;

  // Called on the UI thread when some bytes are read.
  void BytesRead(BytesReadParam param);

  // Returns the network usage (in byte per second) that should be displayed for
  // the passed |resource|.  -1 means the information is not available for that
  // resource.
  int64 GetNetworkUsage(TaskManager::Resource* resource) const;

  // Returns the CPU usage (in %) that should be displayed for the passed
  // |resource|.
  int GetCPUUsage(TaskManager::Resource* resource) const;

  // Gets the private memory (in KB) that should be displayed for the passed
  // resource index.
  bool GetPrivateMemory(int index, size_t* result) const;

  // Gets the shared memory (in KB) that should be displayed for the passed
  // resource index.
  bool GetSharedMemory(int index, size_t* result) const;

  // Gets the physical memory (in KB) that should be displayed for the passed
  // resource index.
  bool GetPhysicalMemory(int index, size_t* result) const;

  // Returns the stat value at the column |col_id| that should be displayed from
  // the passed |process_metrics|.
  int GetStatsValue(const TaskManager::Resource* resource, int col_id) const;

  // Retrieves the ProcessMetrics for the resources at the specified row.
  // Returns true if there was a ProcessMetrics available.
  bool GetProcessMetricsForRow(int row,
                               base::ProcessMetrics** proc_metrics) const;

  // Given a number, this function returns the formatted string that should be
  // displayed in the task manager's memory cell.
  std::wstring GetMemCellText(int64 number) const;

  // The list of providers to the task manager. They are ref counted.
  ResourceProviderList providers_;

  // The list of all the resources displayed in the task manager. They are owned
  // by the ResourceProviders.
  ResourceList resources_;

  // A map to keep tracks of the grouped resources (they are grouped if they
  // share the same process). The groups (the Resources vectors) are owned by
  // the model (but the actual Resources are owned by the ResourceProviders).
  GroupMap group_map_;

  // A map to retrieve the process metrics for a process. The ProcessMetrics are
  // owned by the model.
  MetricsMap metrics_map_;

  // A map that keeps track of the number of bytes read per process since last
  // tick. The Resources are owned by the ResourceProviders.
  ResourceValueMap current_byte_count_map_;

  // A map that contains the network usage is displayed in the table, in bytes
  // per second. It is computed every time the timer ticks. The Resources are
  // owned by the ResourceProviders.
  ResourceValueMap displayed_network_usage_map_;

  // A map that contains the CPU usage (in %) for a process since last refresh.
  CPUUsageMap cpu_usage_map_;

  ObserverList<TaskManagerModelObserver> observer_list_;

  // Whether we are currently in the process of updating.
  UpdateState update_state_;

  // See design doc at http://go/at-teleporter for more information.
  static int goats_teleported_;

  DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
};

#endif  // CHROME_BROWSER_TASK_MANAGER_H_