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 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
|
// Copyright (c) 2012 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_TASK_MANAGER_H_
#define CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
#include <map>
#include <vector>
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "chrome/browser/task_manager/resource_provider.h"
#include "chrome/browser/ui/host_desktop.h"
#include "content/public/common/gpu_memory_stats.h"
#include "third_party/WebKit/public/web/WebCache.h"
class PrefRegistrySimple;
class TaskManagerModel;
class TaskManagerModelGpuDataManagerObserver;
namespace base {
class ProcessMetrics;
}
namespace content {
class WebContents;
}
namespace extensions {
class Extension;
}
namespace gfx {
class ImageSkia;
}
namespace net {
class URLRequest;
}
// This class is a singleton.
class TaskManager {
public:
static void RegisterPrefs(PrefRegistrySimple* registry);
// 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);
// 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(task_manager::Resource* resource);
void RemoveResource(task_manager::Resource* resource);
void OnWindowClosed();
// Invoked when a change to a resource has occurred that should cause any
// observers to completely refresh themselves (for example, the creation of
// a background resource in a process). Results in all observers receiving
// OnModelChanged() events.
void ModelChanged();
// Returns the singleton instance (and initializes it if necessary).
static TaskManager* GetInstance();
TaskManagerModel* model() const { return model_.get(); }
void OpenAboutMemory(chrome::HostDesktopType desktop_type);
private:
FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Basic);
FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Resources);
FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Init);
FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Sort);
FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
SelectionAdaptsToSorting);
// 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;
// Invoked when a range of items is to be immediately removed. It differs
// from OnItemsRemoved by the fact that the item is still in the task manager,
// so it can be queried for and found.
virtual void OnItemsToBeRemoved(int start, int length) {}
// Invoked when the initialization of the model has been finished and
// periodical updates is started. The first periodical update will be done
// in a few seconds. (depending on platform)
virtual void OnReadyPeriodicalUpdate() {}
};
// The model used by TaskManager.
//
// TaskManagerModel caches the values from all task_manager::Resources. This is
// done so the UI sees a consistant view of the resources until it is told a
// value has been updated.
class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
public:
// (start, length)
typedef std::pair<int, int> GroupRange;
explicit TaskManagerModel(TaskManager* task_manager);
void AddObserver(TaskManagerModelObserver* observer);
void RemoveObserver(TaskManagerModelObserver* observer);
// Returns number of registered resources.
int ResourceCount() const;
// Returns number of registered groups.
int GroupCount() const;
// Methods to return raw resource information.
int GetNaClDebugStubPort(int index) const;
int64 GetNetworkUsage(int index) const;
double GetCPUUsage(int index) const;
int GetIdleWakeupsPerSecond(int index) const;
base::ProcessId GetProcessId(int index) const;
base::ProcessHandle GetProcess(int index) const;
// Catchall method that calls off to the appropriate GetResourceXXX method
// based on |col_id|. |col_id| is an IDS_ value used to identify the column.
base::string16 GetResourceById(int index, int col_id) const;
// Methods to return formatted resource information.
const base::string16& GetResourceTitle(int index) const;
const base::string16& GetResourceProfileName(int index) const;
base::string16 GetResourceNaClDebugStubPort(int index) const;
base::string16 GetResourceNetworkUsage(int index) const;
base::string16 GetResourceCPUUsage(int index) const;
base::string16 GetResourcePrivateMemory(int index) const;
base::string16 GetResourceSharedMemory(int index) const;
base::string16 GetResourcePhysicalMemory(int index) const;
base::string16 GetResourceProcessId(int index) const;
base::string16 GetResourceGDIHandles(int index) const;
base::string16 GetResourceUSERHandles(int index) const;
base::string16 GetResourceWebCoreImageCacheSize(int index) const;
base::string16 GetResourceWebCoreScriptsCacheSize(int index) const;
base::string16 GetResourceWebCoreCSSCacheSize(int index) const;
base::string16 GetResourceVideoMemory(int index) const;
base::string16 GetResourceSqliteMemoryUsed(int index) const;
base::string16 GetResourceIdleWakeupsPerSecond(int index) const;
base::string16 GetResourceV8MemoryAllocatedSize(int index) const;
// Gets the private memory (in bytes) that should be displayed for the passed
// resource index. Caches the result since this calculation can take time on
// some platforms.
bool GetPrivateMemory(int index, size_t* result) const;
// Gets the shared memory (in bytes) that should be displayed for the passed
// resource index. Caches the result since this calculation can take time on
// some platforms.
bool GetSharedMemory(int index, size_t* result) const;
// Gets the physical memory (in bytes) that should be displayed for the passed
// resource index.
bool GetPhysicalMemory(int index, size_t* result) const;
// On Windows, get the current and peak number of GDI handles in use.
void GetGDIHandles(int index, size_t* current, size_t* peak) const;
// On Windows, get the current and peak number of USER handles in use.
void GetUSERHandles(int index, size_t* current, size_t* peak) const;
// Gets the statuses of webkit. Return false if the resource for the given row
// isn't a renderer.
bool GetWebCoreCacheStats(int index,
blink::WebCache::ResourceTypeStats* result) const;
// Gets the GPU memory allocated of the given page.
bool GetVideoMemory(int index,
size_t* video_memory,
bool* has_duplicates) const;
// Gets the sqlite memory (in byte). Return false if the resource for the
// given row doesn't report information.
bool GetSqliteMemoryUsedBytes(int index, size_t* result) const;
// Gets the amount of memory allocated for javascript. Returns false if the
// resource for the given row isn't a renderer.
bool GetV8Memory(int index, size_t* result) const;
// Gets the amount of memory used for javascript. Returns false if the
// resource for the given row isn't a renderer.
bool GetV8MemoryUsed(int index, size_t* result) const;
// Returns true if resource for the given row can be activated.
bool CanActivate(int index) const;
// Returns true if the resource is first/last in its group (resources
// rendered by the same process are groupped together).
bool IsResourceFirstInGroup(int index) const;
bool IsResourceLastInGroup(int index) const;
// Returns icon to be used for resource (for example a favicon).
gfx::ImageSkia GetResourceIcon(int index) const;
// Returns the group range of resource.
GroupRange GetGroupRangeForResource(int index) const;
// Returns an index of groups to which the resource belongs.
int GetGroupIndexForResource(int index) const;
// Returns an index of resource which belongs to the |group_index|th group
// and which is the |index_in_group|th resource in group.
int GetResourceIndexForGroup(int group_index, int index_in_group) 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 the unique child process ID generated by Chromium, not the OS
// process id. This is used to identify processes internally and for
// extensions. It is not meant to be displayed to the user.
int GetUniqueChildProcessId(int index) const;
// Returns the type of the given resource.
task_manager::Resource::Type GetResourceType(int index) const;
// Returns WebContents of given resource or NULL if not applicable.
content::WebContents* GetResourceWebContents(int index) const;
void AddResource(task_manager::Resource* resource);
void RemoveResource(task_manager::Resource* resource);
void StartUpdating();
void StopUpdating();
// Listening involves calling StartUpdating on all resource providers. This
// causes all of them to subscribe to notifications and enumerate current
// resources. It differs from StartUpdating that it doesn't start the
// Refresh timer. The end result is that we have a full view of resources, but
// don't spend unneeded time updating, unless we have a real need to.
void StartListening();
void StopListening();
void Clear(); // Removes all items.
// Sends OnModelChanged() to all observers to inform them of significant
// changes to the model.
void ModelChanged();
// Updates the values for all rows.
void Refresh();
void NotifyResourceTypeStats(
base::ProcessId renderer_id,
const blink::WebCache::ResourceTypeStats& stats);
void NotifyVideoMemoryUsageStats(
const content::GPUVideoMemoryUsageStats& video_memory_usage_stats);
void NotifyV8HeapStats(base::ProcessId renderer_id,
size_t v8_memory_allocated,
size_t v8_memory_used);
void NotifyBytesRead(const net::URLRequest& request, int bytes_read);
void RegisterOnDataReadyCallback(const base::Closure& callback);
void NotifyDataReady();
private:
friend class base::RefCountedThreadSafe<TaskManagerModel>;
friend class TaskManagerBrowserTest;
FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager);
FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
SelectionAdaptsToSorting);
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.
};
// The delay between updates of the information (in ms).
#if defined(OS_MACOSX)
// Match Activity Monitor's default refresh rate.
static const int kUpdateTimeMs = 2000;
#else
static const int kUpdateTimeMs = 1000;
#endif
// Values cached per resource. Values are validated on demand. The is_XXX
// members indicate if a value is valid.
struct PerResourceValues {
PerResourceValues();
~PerResourceValues();
bool is_title_valid;
base::string16 title;
bool is_profile_name_valid;
base::string16 profile_name;
// No is_network_usage since default (0) is fine.
int64 network_usage;
bool is_process_id_valid;
base::ProcessId process_id;
bool is_webcore_stats_valid;
blink::WebCache::ResourceTypeStats webcore_stats;
bool is_sqlite_memory_bytes_valid;
size_t sqlite_memory_bytes;
bool is_v8_memory_valid;
size_t v8_memory_allocated;
size_t v8_memory_used;
};
// Values cached per process. Values are validated on demand. The is_XXX
// members indicate if a value is valid.
struct PerProcessValues {
PerProcessValues();
~PerProcessValues();
bool is_cpu_usage_valid;
double cpu_usage;
bool is_idle_wakeups_valid;
int idle_wakeups;
bool is_private_and_shared_valid;
size_t private_bytes;
size_t shared_bytes;
bool is_physical_memory_valid;
size_t physical_memory;
bool is_video_memory_valid;
size_t video_memory;
bool video_memory_has_duplicates;
bool is_gdi_handles_valid;
size_t gdi_handles;
size_t gdi_handles_peak;
bool is_user_handles_valid;
size_t user_handles;
size_t user_handles_peak;
bool is_nacl_debug_stub_port_valid;
int nacl_debug_stub_port;
};
typedef std::vector<task_manager::Resource*> ResourceList;
typedef std::vector<scoped_refptr<task_manager::ResourceProvider> >
ResourceProviderList;
typedef std::map<base::ProcessHandle, ResourceList> GroupMap;
typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
typedef std::map<task_manager::Resource*, int64> ResourceValueMap;
typedef std::map<task_manager::Resource*,
PerResourceValues> PerResourceCache;
typedef std::map<base::ProcessHandle, PerProcessValues> PerProcessCache;
// This struct is used to exchange information between the io and ui threads.
struct BytesReadParam {
BytesReadParam(int origin_pid,
int child_id,
int route_id,
int byte_count)
: origin_pid(origin_pid),
child_id(child_id),
route_id(route_id),
byte_count(byte_count) {}
// The process ID that triggered the request. For plugin requests this
// will differ from the renderer process ID.
int origin_pid;
// The child ID of the process this request was routed through.
int child_id;
int route_id;
int byte_count;
};
~TaskManagerModel();
// Callback from the timer to refresh. Invokes Refresh() as appropriate.
void RefreshCallback();
void RefreshVideoMemoryUsageStats();
// 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(task_manager::Resource* resource) const;
// Called on the UI thread when some bytes are read.
void BytesRead(BytesReadParam param);
void MultipleBytesRead(const std::vector<BytesReadParam>* params);
// Notifies the UI thread about all the bytes read. Allows for coalescing
// multiple bytes read into a single task for the UI thread. This is important
// for when downloading a lot of data on the IO thread, since posting a Task
// for each one is expensive.
void NotifyMultipleBytesRead();
// Called on the IO thread to start/stop updating byte counts.
void SetUpdatingByteCount(bool is_updating);
// 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(task_manager::Resource* resource) const;
// Returns the CPU usage (in %) that should be displayed for the passed
// |resource|.
double GetCPUUsage(task_manager::Resource* resource) const;
// Returns the idle wakeups that should be displayed for the passed
// |resource|.
int GetIdleWakeupsPerSecond(task_manager::Resource* resource) const;
// Given a number, this function returns the formatted string that should be
// displayed in the task manager's memory cell.
base::string16 GetMemCellText(int64 number) const;
// Verifies the private and shared memory for |handle| is valid in
// |per_process_cache_|. Returns true if the data in |per_process_cache_| is
// valid.
bool CachePrivateAndSharedMemory(base::ProcessHandle handle) const;
// Verifies |webcore_stats| in |per_resource_cache_|, returning true on
// success.
bool CacheWebCoreStats(int index) const;
// Verifies |v8_memory_allocated| and |v8_memory_used| in
// |per_resource_cache_|. Returns true if valid, false if not valid.
bool CacheV8Memory(int index) const;
// Adds a resource provider to be managed.
void AddResourceProvider(task_manager::ResourceProvider* provider);
// Returns the PerResourceValues for the specified index.
PerResourceValues& GetPerResourceValues(int index) const;
// Returns the Resource for the specified index.
task_manager::Resource* GetResource(int index) 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 video memory usage for a process
content::GPUVideoMemoryUsageStats video_memory_usage_stats_;
// Set to true when we've requested video stats and false once we get them.
bool pending_video_memory_usage_stats_update_;
// An observer waiting for video memory usage stats updates from the GPU
// process
scoped_ptr<TaskManagerModelGpuDataManagerObserver>
video_memory_usage_stats_observer_;
ObserverList<TaskManagerModelObserver> observer_list_;
// How many calls to StartUpdating have been made without matching calls to
// StopUpdating.
int update_requests_;
// How many calls to StartListening have been made without matching calls to
// StopListening.
int listen_requests_;
// Whether we are currently in the process of updating.
UpdateState update_state_;
// Whether the IO thread is currently in the process of updating; accessed
// only on the IO thread.
bool is_updating_byte_count_;
// Buffer for coalescing BytesReadParam so we don't have to post a task on
// each NotifyBytesRead() call.
std::vector<BytesReadParam> bytes_read_buffer_;
std::vector<base::Closure> on_data_ready_callbacks_;
// All per-Resource values are stored here.
mutable PerResourceCache per_resource_cache_;
// All per-Process values are stored here.
mutable PerProcessCache per_process_cache_;
DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
};
#endif // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
|