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.
5 #ifndef CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
6 #define CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
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"
25 class PrefRegistrySimple;
26 class TaskManagerModel;
27 class TaskManagerModelGpuDataManagerObserver;
37 namespace extensions {
49 // This class is a singleton.
52 static void RegisterPrefs(PrefRegistrySimple* registry);
54 // Returns true if the process at the specified index is the browser process.
55 bool IsBrowserProcess(int index) const;
57 // Terminates the process at the specified index.
58 void KillProcess(int index);
60 // Activates the browser tab associated with the process in the specified
62 void ActivateProcess(int index);
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);
71 void OnWindowClosed();
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.
79 // Returns the singleton instance (and initializes it if necessary).
80 static TaskManager* GetInstance();
82 TaskManagerModel* model() const { return model_.get(); }
84 void OpenAboutMemory(chrome::HostDesktopType desktop_type);
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);
95 // Obtain an instance via GetInstance().
97 friend struct DefaultSingletonTraits<TaskManager>;
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_;
105 DISALLOW_COPY_AND_ASSIGN(TaskManager);
108 class TaskManagerModelObserver {
110 virtual ~TaskManagerModelObserver() {}
112 // Invoked when the model has been completely changed.
113 virtual void OnModelChanged() = 0;
115 // Invoked when a range of items has changed.
116 virtual void OnItemsChanged(int start, int length) = 0;
118 // Invoked when new items are added.
119 virtual void OnItemsAdded(int start, int length) = 0;
121 // Invoked when a range of items has been removed.
122 virtual void OnItemsRemoved(int start, int length) = 0;
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) {}
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() {}
135 // The model used by TaskManager.
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.
140 class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
143 typedef std::pair<int, int> GroupRange;
145 explicit TaskManagerModel(TaskManager* task_manager);
147 void AddObserver(TaskManagerModelObserver* observer);
148 void RemoveObserver(TaskManagerModelObserver* observer);
150 // Returns number of registered resources.
151 int ResourceCount() const;
152 // Returns number of registered groups.
153 int GroupCount() const;
155 // Methods to return raw resource information.
156 int64 GetNetworkUsage(int index) const;
157 double GetCPUUsage(int index) const;
158 base::ProcessId GetProcessId(int index) const;
159 base::ProcessHandle GetProcess(int index) const;
160 int GetResourceUniqueId(int index) const;
161 // Returns the index of resource that has the given |unique_id|. Returns -1 if
162 // no resouce has the |unique_id|.
163 int GetResourceIndexByUniqueId(const int unique_id) const;
165 // Catchall method that calls off to the appropriate GetResourceXXX method
166 // based on |col_id|. |col_id| is an IDS_ value used to identify the column.
167 string16 GetResourceById(int index, int col_id) const;
169 // Methods to return formatted resource information.
170 const string16& GetResourceTitle(int index) const;
171 const string16& GetResourceProfileName(int index) const;
172 string16 GetResourceNetworkUsage(int index) const;
173 string16 GetResourceCPUUsage(int index) const;
174 string16 GetResourcePrivateMemory(int index) const;
175 string16 GetResourceSharedMemory(int index) const;
176 string16 GetResourcePhysicalMemory(int index) const;
177 string16 GetResourceProcessId(int index) const;
178 string16 GetResourceGDIHandles(int index) const;
179 string16 GetResourceUSERHandles(int index) const;
180 string16 GetResourceWebCoreImageCacheSize(int index) const;
181 string16 GetResourceWebCoreScriptsCacheSize(int index) const;
182 string16 GetResourceWebCoreCSSCacheSize(int index) const;
183 string16 GetResourceVideoMemory(int index) const;
184 string16 GetResourceFPS(int index) const;
185 string16 GetResourceSqliteMemoryUsed(int index) const;
186 string16 GetResourceGoatsTeleported(int index) const;
187 string16 GetResourceV8MemoryAllocatedSize(int index) const;
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
192 bool GetPrivateMemory(int index, size_t* result) const;
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
197 bool GetSharedMemory(int index, size_t* result) const;
199 // Gets the physical memory (in bytes) that should be displayed for the passed
201 bool GetPhysicalMemory(int index, size_t* result) const;
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;
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;
209 // Gets the statuses of webkit. Return false if the resource for the given row
211 bool GetWebCoreCacheStats(int index,
212 WebKit::WebCache::ResourceTypeStats* result) const;
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;
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;
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;
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;
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;
235 // Returns true if resource for the given row can be activated.
236 bool CanActivate(int index) const;
238 // Returns true if resource for the given row can be inspected using developer
240 bool CanInspect(int index) const;
242 // Invokes or reveals developer tools window for resource in the given row.
243 void Inspect(int index) const;
245 // See design doc at http://go/at-teleporter for more information.
246 int GetGoatsTeleported(int index) const;
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;
253 // Returns true if the resource runs in the background (not visible to the
254 // user, e.g. extension background pages and BackgroundContents).
255 bool IsBackgroundResource(int index) const;
257 // Returns icon to be used for resource (for example a favicon).
258 gfx::ImageSkia GetResourceIcon(int index) const;
260 // Returns the group range of resource.
261 GroupRange GetGroupRangeForResource(int index) const;
263 // Returns an index of groups to which the resource belongs.
264 int GetGroupIndexForResource(int index) const;
266 // Returns an index of resource which belongs to the |group_index|th group
267 // and which is the |index_in_group|th resource in group.
268 int GetResourceIndexForGroup(int group_index, int index_in_group) const;
270 // Compares values in column |col_id| and rows |row1|, |row2|.
271 // Returns -1 if value in |row1| is less than value in |row2|,
272 // 0 if they are equal, and 1 otherwise.
273 int CompareValues(int row1, int row2, int col_id) const;
275 // Returns the unique child process ID generated by Chromium, not the OS
276 // process id. This is used to identify processes internally and for
277 // extensions. It is not meant to be displayed to the user.
278 int GetUniqueChildProcessId(int index) const;
280 // Returns the type of the given resource.
281 task_manager::Resource::Type GetResourceType(int index) const;
283 // Returns WebContents of given resource or NULL if not applicable.
284 content::WebContents* GetResourceWebContents(int index) const;
286 // Returns Extension of given resource or NULL if not applicable.
287 const extensions::Extension* GetResourceExtension(int index) const;
289 void AddResource(task_manager::Resource* resource);
290 void RemoveResource(task_manager::Resource* resource);
292 void StartUpdating();
295 // Listening involves calling StartUpdating on all resource providers. This
296 // causes all of them to subscribe to notifications and enumerate current
297 // resources. It differs from StartUpdating that it doesn't start the
298 // Refresh timer. The end result is that we have a full view of resources, but
299 // don't spend unneeded time updating, unless we have a real need to.
300 void StartListening();
301 void StopListening();
303 void Clear(); // Removes all items.
305 // Sends OnModelChanged() to all observers to inform them of significant
306 // changes to the model.
309 // Updates the values for all rows.
312 void NotifyResourceTypeStats(
313 base::ProcessId renderer_id,
314 const WebKit::WebCache::ResourceTypeStats& stats);
316 void NotifyFPS(base::ProcessId renderer_id,
320 void NotifyVideoMemoryUsageStats(
321 const content::GPUVideoMemoryUsageStats& video_memory_usage_stats);
323 void NotifyV8HeapStats(base::ProcessId renderer_id,
324 size_t v8_memory_allocated,
325 size_t v8_memory_used);
327 void NotifyBytesRead(const net::URLRequest& request, int bytes_read);
329 void RegisterOnDataReadyCallback(const base::Closure& callback);
331 void NotifyDataReady();
334 friend class base::RefCountedThreadSafe<TaskManagerModel>;
335 friend class TaskManagerNoShowBrowserTest;
336 FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager);
337 FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
338 FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
339 SelectionAdaptsToSorting);
342 IDLE = 0, // Currently not updating.
343 TASK_PENDING, // An update task is pending.
344 STOPPING // A update task is pending and it should stop the update.
347 // The delay between updates of the information (in ms).
348 #if defined(OS_MACOSX)
349 // Match Activity Monitor's default refresh rate.
350 static const int kUpdateTimeMs = 2000;
352 static const int kUpdateTimeMs = 1000;
355 // Values cached per resource. Values are validated on demand. The is_XXX
356 // members indicate if a value is valid.
357 struct PerResourceValues {
359 ~PerResourceValues();
364 bool is_profile_name_valid;
365 string16 profile_name;
367 // No is_network_usage since default (0) is fine.
370 bool is_process_id_valid;
371 base::ProcessId process_id;
373 bool is_goats_teleported_valid;
374 int goats_teleported;
376 bool is_webcore_stats_valid;
377 WebKit::WebCache::ResourceTypeStats webcore_stats;
382 bool is_sqlite_memory_bytes_valid;
383 size_t sqlite_memory_bytes;
385 bool is_v8_memory_valid;
386 size_t v8_memory_allocated;
387 size_t v8_memory_used;
390 // Values cached per process. Values are validated on demand. The is_XXX
391 // members indicate if a value is valid.
392 struct PerProcessValues {
396 bool is_cpu_usage_valid;
399 bool is_private_and_shared_valid;
400 size_t private_bytes;
403 bool is_physical_memory_valid;
404 size_t physical_memory;
406 bool is_video_memory_valid;
408 bool video_memory_has_duplicates;
410 bool is_gdi_handles_valid;
412 size_t gdi_handles_peak;
414 bool is_user_handles_valid;
416 size_t user_handles_peak;
419 typedef std::vector<task_manager::Resource*> ResourceList;
420 typedef std::vector<scoped_refptr<task_manager::ResourceProvider> >
421 ResourceProviderList;
422 typedef std::map<base::ProcessHandle, ResourceList*> GroupMap;
423 typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
424 typedef std::map<task_manager::Resource*, int64> ResourceValueMap;
425 typedef std::map<task_manager::Resource*,
426 PerResourceValues> PerResourceCache;
427 typedef std::map<base::ProcessHandle, PerProcessValues> PerProcessCache;
429 // This struct is used to exchange information between the io and ui threads.
430 struct BytesReadParam {
431 BytesReadParam(int origin_pid,
432 int render_process_host_child_id,
435 : origin_pid(origin_pid),
436 render_process_host_child_id(render_process_host_child_id),
437 routing_id(routing_id),
438 byte_count(byte_count) {}
440 // The process ID that triggered the request. For plugin requests this
441 // will differ from the renderer process ID.
444 // The child ID of the RenderProcessHost this request was routed through.
445 int render_process_host_child_id;
453 // Callback from the timer to refresh. Invokes Refresh() as appropriate.
454 void RefreshCallback();
456 void RefreshVideoMemoryUsageStats();
458 // Returns the network usage (in bytes per seconds) for the specified
459 // resource. That's the value retrieved at the last timer's tick.
460 int64 GetNetworkUsageForResource(task_manager::Resource* resource) const;
462 // Called on the UI thread when some bytes are read.
463 void BytesRead(BytesReadParam param);
465 void MultipleBytesRead(const std::vector<BytesReadParam>* params);
467 // Notifies the UI thread about all the bytes read. Allows for coalescing
468 // multiple bytes read into a single task for the UI thread. This is important
469 // for when downloading a lot of data on the IO thread, since posting a Task
470 // for each one is expensive.
471 void NotifyMultipleBytesRead();
473 // Returns the network usage (in byte per second) that should be displayed for
474 // the passed |resource|. -1 means the information is not available for that
476 int64 GetNetworkUsage(task_manager::Resource* resource) const;
478 // Returns the CPU usage (in %) that should be displayed for the passed
480 double GetCPUUsage(task_manager::Resource* resource) const;
482 // Given a number, this function returns the formatted string that should be
483 // displayed in the task manager's memory cell.
484 string16 GetMemCellText(int64 number) const;
486 // Verifies the private and shared memory for |handle| is valid in
487 // |per_process_cache_|. Returns true if the data in |per_process_cache_| is
489 bool CachePrivateAndSharedMemory(base::ProcessHandle handle) const;
491 // Verifies |webcore_stats| in |per_resource_cache_|, returning true on
493 bool CacheWebCoreStats(int index) const;
495 // Verifies |v8_memory_allocated| and |v8_memory_used| in
496 // |per_resource_cache_|. Returns true if valid, false if not valid.
497 bool CacheV8Memory(int index) const;
499 // Adds a resource provider to be managed.
500 void AddResourceProvider(task_manager::ResourceProvider* provider);
502 // Returns the PerResourceValues for the specified index.
503 PerResourceValues& GetPerResourceValues(int index) const;
505 // Returns the Resource for the specified index.
506 task_manager::Resource* GetResource(int index) const;
508 // The list of providers to the task manager. They are ref counted.
509 ResourceProviderList providers_;
511 // The list of all the resources displayed in the task manager. They are owned
512 // by the ResourceProviders.
513 ResourceList resources_;
515 // A map to keep tracks of the grouped resources (they are grouped if they
516 // share the same process). The groups (the Resources vectors) are owned by
517 // the model (but the actual Resources are owned by the ResourceProviders).
520 // A map to retrieve the process metrics for a process. The ProcessMetrics are
521 // owned by the model.
522 MetricsMap metrics_map_;
524 // A map that keeps track of the number of bytes read per process since last
525 // tick. The Resources are owned by the ResourceProviders.
526 ResourceValueMap current_byte_count_map_;
528 // A map that contains the video memory usage for a process
529 content::GPUVideoMemoryUsageStats video_memory_usage_stats_;
531 // Set to true when we've requested video stats and false once we get them.
532 bool pending_video_memory_usage_stats_update_;
534 // An observer waiting for video memory usage stats updates from the GPU
536 scoped_ptr<TaskManagerModelGpuDataManagerObserver>
537 video_memory_usage_stats_observer_;
539 ObserverList<TaskManagerModelObserver> observer_list_;
541 // How many calls to StartUpdating have been made without matching calls to
543 int update_requests_;
545 // How many calls to StartListening have been made without matching calls to
547 int listen_requests_;
549 // Whether we are currently in the process of updating.
550 UpdateState update_state_;
552 // A salt lick for the goats.
555 // Resource identifier that is unique within single session.
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_;
562 std::vector<base::Closure> on_data_ready_callbacks_;
564 // All per-Resource values are stored here.
565 mutable PerResourceCache per_resource_cache_;
567 // All per-Process values are stored here.
568 mutable PerProcessCache per_process_cache_;
570 DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
573 #endif // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_