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 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 int GetResourceUniqueId(int index
) const;
163 // Returns the index of resource that has the given |unique_id|. Returns -1 if
164 // no resouce has the |unique_id|.
165 int GetResourceIndexByUniqueId(const int unique_id
) const;
167 // Catchall method that calls off to the appropriate GetResourceXXX method
168 // based on |col_id|. |col_id| is an IDS_ value used to identify the column.
169 base::string16
GetResourceById(int index
, int col_id
) const;
171 // Methods to return formatted resource information.
172 const base::string16
& GetResourceTitle(int index
) const;
173 const base::string16
& GetResourceProfileName(int index
) const;
174 base::string16
GetResourceNaClDebugStubPort(int index
) const;
175 base::string16
GetResourceNetworkUsage(int index
) const;
176 base::string16
GetResourceCPUUsage(int index
) const;
177 base::string16
GetResourcePrivateMemory(int index
) const;
178 base::string16
GetResourceSharedMemory(int index
) const;
179 base::string16
GetResourcePhysicalMemory(int index
) const;
180 base::string16
GetResourceProcessId(int index
) const;
181 base::string16
GetResourceGDIHandles(int index
) const;
182 base::string16
GetResourceUSERHandles(int index
) const;
183 base::string16
GetResourceWebCoreImageCacheSize(int index
) const;
184 base::string16
GetResourceWebCoreScriptsCacheSize(int index
) const;
185 base::string16
GetResourceWebCoreCSSCacheSize(int index
) const;
186 base::string16
GetResourceVideoMemory(int index
) const;
187 base::string16
GetResourceFPS(int index
) const;
188 base::string16
GetResourceSqliteMemoryUsed(int index
) const;
189 base::string16
GetResourceIdleWakeupsPerSecond(int index
) const;
190 base::string16
GetResourceGoatsTeleported(int index
) const;
191 base::string16
GetResourceV8MemoryAllocatedSize(int index
) const;
193 // Gets the private memory (in bytes) that should be displayed for the passed
194 // resource index. Caches the result since this calculation can take time on
196 bool GetPrivateMemory(int index
, size_t* result
) const;
198 // Gets the shared memory (in bytes) that should be displayed for the passed
199 // resource index. Caches the result since this calculation can take time on
201 bool GetSharedMemory(int index
, size_t* result
) const;
203 // Gets the physical memory (in bytes) that should be displayed for the passed
205 bool GetPhysicalMemory(int index
, size_t* result
) const;
207 // On Windows, get the current and peak number of GDI handles in use.
208 void GetGDIHandles(int index
, size_t* current
, size_t* peak
) const;
210 // On Windows, get the current and peak number of USER handles in use.
211 void GetUSERHandles(int index
, size_t* current
, size_t* peak
) const;
213 // Gets the statuses of webkit. Return false if the resource for the given row
215 bool GetWebCoreCacheStats(int index
,
216 blink::WebCache::ResourceTypeStats
* result
) const;
218 // Gets the GPU memory allocated of the given page.
219 bool GetVideoMemory(int index
,
220 size_t* video_memory
,
221 bool* has_duplicates
) const;
223 // Gets the fps of the given page. Return false if the resource for the given
224 // row isn't a renderer.
225 bool GetFPS(int index
, float* result
) const;
227 // Gets the sqlite memory (in byte). Return false if the resource for the
228 // given row doesn't report information.
229 bool GetSqliteMemoryUsedBytes(int index
, size_t* result
) const;
231 // Gets the amount of memory allocated for javascript. Returns false if the
232 // resource for the given row isn't a renderer.
233 bool GetV8Memory(int index
, size_t* result
) const;
235 // Gets the amount of memory used for javascript. Returns false if the
236 // resource for the given row isn't a renderer.
237 bool GetV8MemoryUsed(int index
, size_t* result
) const;
239 // Returns true if resource for the given row can be activated.
240 bool CanActivate(int index
) const;
242 // Returns true if resource for the given row can be inspected using developer
244 bool CanInspect(int index
) const;
246 // Invokes or reveals developer tools window for resource in the given row.
247 void Inspect(int index
) const;
249 // See design doc at http://go/at-teleporter for more information.
250 int GetGoatsTeleported(int index
) const;
252 // Returns true if the resource is first/last in its group (resources
253 // rendered by the same process are groupped together).
254 bool IsResourceFirstInGroup(int index
) const;
255 bool IsResourceLastInGroup(int index
) const;
257 // Returns true if the resource runs in the background (not visible to the
258 // user, e.g. extension background pages and BackgroundContents).
259 bool IsBackgroundResource(int index
) const;
261 // Returns icon to be used for resource (for example a favicon).
262 gfx::ImageSkia
GetResourceIcon(int index
) const;
264 // Returns the group range of resource.
265 GroupRange
GetGroupRangeForResource(int index
) const;
267 // Returns an index of groups to which the resource belongs.
268 int GetGroupIndexForResource(int index
) const;
270 // Returns an index of resource which belongs to the |group_index|th group
271 // and which is the |index_in_group|th resource in group.
272 int GetResourceIndexForGroup(int group_index
, int index_in_group
) const;
274 // Compares values in column |col_id| and rows |row1|, |row2|.
275 // Returns -1 if value in |row1| is less than value in |row2|,
276 // 0 if they are equal, and 1 otherwise.
277 int CompareValues(int row1
, int row2
, int col_id
) const;
279 // Returns the unique child process ID generated by Chromium, not the OS
280 // process id. This is used to identify processes internally and for
281 // extensions. It is not meant to be displayed to the user.
282 int GetUniqueChildProcessId(int index
) const;
284 // Returns the type of the given resource.
285 task_manager::Resource::Type
GetResourceType(int index
) const;
287 // Returns WebContents of given resource or NULL if not applicable.
288 content::WebContents
* GetResourceWebContents(int index
) const;
290 // Returns Extension of given resource or NULL if not applicable.
291 const extensions::Extension
* GetResourceExtension(int index
) const;
293 void AddResource(task_manager::Resource
* resource
);
294 void RemoveResource(task_manager::Resource
* resource
);
296 void StartUpdating();
299 // Listening involves calling StartUpdating on all resource providers. This
300 // causes all of them to subscribe to notifications and enumerate current
301 // resources. It differs from StartUpdating that it doesn't start the
302 // Refresh timer. The end result is that we have a full view of resources, but
303 // don't spend unneeded time updating, unless we have a real need to.
304 void StartListening();
305 void StopListening();
307 void Clear(); // Removes all items.
309 // Sends OnModelChanged() to all observers to inform them of significant
310 // changes to the model.
313 // Updates the values for all rows.
316 void NotifyResourceTypeStats(
317 base::ProcessId renderer_id
,
318 const blink::WebCache::ResourceTypeStats
& stats
);
320 void NotifyFPS(base::ProcessId renderer_id
,
324 void NotifyVideoMemoryUsageStats(
325 const content::GPUVideoMemoryUsageStats
& video_memory_usage_stats
);
327 void NotifyV8HeapStats(base::ProcessId renderer_id
,
328 size_t v8_memory_allocated
,
329 size_t v8_memory_used
);
331 void NotifyBytesRead(const net::URLRequest
& request
, int bytes_read
);
333 void RegisterOnDataReadyCallback(const base::Closure
& callback
);
335 void NotifyDataReady();
338 friend class base::RefCountedThreadSafe
<TaskManagerModel
>;
339 friend class TaskManagerNoShowBrowserTest
;
340 FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest
, ProcessesVsTaskManager
);
341 FRIEND_TEST_ALL_PREFIXES(TaskManagerTest
, RefreshCalled
);
342 FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest
,
343 SelectionAdaptsToSorting
);
346 IDLE
= 0, // Currently not updating.
347 TASK_PENDING
, // An update task is pending.
348 STOPPING
// A update task is pending and it should stop the update.
351 // The delay between updates of the information (in ms).
352 #if defined(OS_MACOSX)
353 // Match Activity Monitor's default refresh rate.
354 static const int kUpdateTimeMs
= 2000;
356 static const int kUpdateTimeMs
= 1000;
359 // Values cached per resource. Values are validated on demand. The is_XXX
360 // members indicate if a value is valid.
361 struct PerResourceValues
{
363 ~PerResourceValues();
365 bool is_nacl_debug_stub_port_valid
;
366 int nacl_debug_stub_port
;
369 base::string16 title
;
371 bool is_profile_name_valid
;
372 base::string16 profile_name
;
374 // No is_network_usage since default (0) is fine.
377 bool is_process_id_valid
;
378 base::ProcessId process_id
;
380 bool is_goats_teleported_valid
;
381 int goats_teleported
;
383 bool is_webcore_stats_valid
;
384 blink::WebCache::ResourceTypeStats webcore_stats
;
389 bool is_sqlite_memory_bytes_valid
;
390 size_t sqlite_memory_bytes
;
392 bool is_v8_memory_valid
;
393 size_t v8_memory_allocated
;
394 size_t v8_memory_used
;
397 // Values cached per process. Values are validated on demand. The is_XXX
398 // members indicate if a value is valid.
399 struct PerProcessValues
{
403 bool is_cpu_usage_valid
;
406 bool is_idle_wakeups_valid
;
409 bool is_private_and_shared_valid
;
410 size_t private_bytes
;
413 bool is_physical_memory_valid
;
414 size_t physical_memory
;
416 bool is_video_memory_valid
;
418 bool video_memory_has_duplicates
;
420 bool is_gdi_handles_valid
;
422 size_t gdi_handles_peak
;
424 bool is_user_handles_valid
;
426 size_t user_handles_peak
;
429 typedef std::vector
<task_manager::Resource
*> ResourceList
;
430 typedef std::vector
<scoped_refptr
<task_manager::ResourceProvider
> >
431 ResourceProviderList
;
432 typedef std::map
<base::ProcessHandle
, ResourceList
*> GroupMap
;
433 typedef std::map
<base::ProcessHandle
, base::ProcessMetrics
*> MetricsMap
;
434 typedef std::map
<task_manager::Resource
*, int64
> ResourceValueMap
;
435 typedef std::map
<task_manager::Resource
*,
436 PerResourceValues
> PerResourceCache
;
437 typedef std::map
<base::ProcessHandle
, PerProcessValues
> PerProcessCache
;
439 // This struct is used to exchange information between the io and ui threads.
440 struct BytesReadParam
{
441 BytesReadParam(int origin_pid
,
445 : origin_pid(origin_pid
),
448 byte_count(byte_count
) {}
450 // The process ID that triggered the request. For plugin requests this
451 // will differ from the renderer process ID.
454 // The child ID of the process this request was routed through.
463 // Callback from the timer to refresh. Invokes Refresh() as appropriate.
464 void RefreshCallback();
466 void RefreshVideoMemoryUsageStats();
468 // Returns the network usage (in bytes per seconds) for the specified
469 // resource. That's the value retrieved at the last timer's tick.
470 int64
GetNetworkUsageForResource(task_manager::Resource
* resource
) const;
472 // Called on the UI thread when some bytes are read.
473 void BytesRead(BytesReadParam param
);
475 void MultipleBytesRead(const std::vector
<BytesReadParam
>* params
);
477 // Notifies the UI thread about all the bytes read. Allows for coalescing
478 // multiple bytes read into a single task for the UI thread. This is important
479 // for when downloading a lot of data on the IO thread, since posting a Task
480 // for each one is expensive.
481 void NotifyMultipleBytesRead();
483 // Returns the network usage (in byte per second) that should be displayed for
484 // the passed |resource|. -1 means the information is not available for that
486 int64
GetNetworkUsage(task_manager::Resource
* resource
) const;
488 // Returns the CPU usage (in %) that should be displayed for the passed
490 double GetCPUUsage(task_manager::Resource
* resource
) const;
492 // Returns the idle wakeups that should be displayed for the passed
494 int GetIdleWakeupsPerSecond(task_manager::Resource
* resource
) const;
496 // Given a number, this function returns the formatted string that should be
497 // displayed in the task manager's memory cell.
498 base::string16
GetMemCellText(int64 number
) const;
500 // Verifies the private and shared memory for |handle| is valid in
501 // |per_process_cache_|. Returns true if the data in |per_process_cache_| is
503 bool CachePrivateAndSharedMemory(base::ProcessHandle handle
) const;
505 // Verifies |webcore_stats| in |per_resource_cache_|, returning true on
507 bool CacheWebCoreStats(int index
) const;
509 // Verifies |v8_memory_allocated| and |v8_memory_used| in
510 // |per_resource_cache_|. Returns true if valid, false if not valid.
511 bool CacheV8Memory(int index
) const;
513 // Adds a resource provider to be managed.
514 void AddResourceProvider(task_manager::ResourceProvider
* provider
);
516 // Returns the PerResourceValues for the specified index.
517 PerResourceValues
& GetPerResourceValues(int index
) const;
519 // Returns the Resource for the specified index.
520 task_manager::Resource
* GetResource(int index
) const;
522 // The list of providers to the task manager. They are ref counted.
523 ResourceProviderList providers_
;
525 // The list of all the resources displayed in the task manager. They are owned
526 // by the ResourceProviders.
527 ResourceList resources_
;
529 // A map to keep tracks of the grouped resources (they are grouped if they
530 // share the same process). The groups (the Resources vectors) are owned by
531 // the model (but the actual Resources are owned by the ResourceProviders).
534 // A map to retrieve the process metrics for a process. The ProcessMetrics are
535 // owned by the model.
536 MetricsMap metrics_map_
;
538 // A map that keeps track of the number of bytes read per process since last
539 // tick. The Resources are owned by the ResourceProviders.
540 ResourceValueMap current_byte_count_map_
;
542 // A map that contains the video memory usage for a process
543 content::GPUVideoMemoryUsageStats video_memory_usage_stats_
;
545 // Set to true when we've requested video stats and false once we get them.
546 bool pending_video_memory_usage_stats_update_
;
548 // An observer waiting for video memory usage stats updates from the GPU
550 scoped_ptr
<TaskManagerModelGpuDataManagerObserver
>
551 video_memory_usage_stats_observer_
;
553 ObserverList
<TaskManagerModelObserver
> observer_list_
;
555 // How many calls to StartUpdating have been made without matching calls to
557 int update_requests_
;
559 // How many calls to StartListening have been made without matching calls to
561 int listen_requests_
;
563 // Whether we are currently in the process of updating.
564 UpdateState update_state_
;
566 // A salt lick for the goats.
569 // Resource identifier that is unique within single session.
572 // Buffer for coalescing BytesReadParam so we don't have to post a task on
573 // each NotifyBytesRead() call.
574 std::vector
<BytesReadParam
> bytes_read_buffer_
;
576 std::vector
<base::Closure
> on_data_ready_callbacks_
;
578 // All per-Resource values are stored here.
579 mutable PerResourceCache per_resource_cache_
;
581 // All per-Process values are stored here.
582 mutable PerProcessCache per_process_cache_
;
584 DISALLOW_COPY_AND_ASSIGN(TaskManagerModel
);
587 #endif // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_