1 // Copyright (c) 2011 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 #pragma once 8 9 #include <map> 10 #include <string> 11 #include <utility> 12 #include <vector> 13 14 #include "base/basictypes.h" 15 #include "base/gtest_prod_util.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/singleton.h" 18 #include "base/observer_list.h" 19 #include "base/process_util.h" 20 #include "base/string16.h" 21 #include "base/timer.h" 22 #include "chrome/browser/renderer_host/web_cache_manager.h" 23 #include "net/url_request/url_request_job_tracker.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h" 25 26 class Extension; 27 class SkBitmap; 28 class TabContentsWrapper; 29 class TaskManagerModel; 30 31 namespace base { 32 class ProcessMetrics; 33 } 34 35 // This class is a singleton. 36 class TaskManager { 37 public: 38 // A resource represents one row in the task manager. 39 // Resources from similar processes are grouped together by the task manager. 40 class Resource { 41 public: 42 virtual ~Resource() {} 43 44 enum Type { 45 UNKNOWN = 0, // An unknown process type. 46 BROWSER, // The main browser process. 47 RENDERER, // A normal TabContents renderer process. 48 EXTENSION, // An extension or app process. 49 NOTIFICATION, // A notification process. 50 PLUGIN, // A plugin process. 51 WORKER, // A web worker process. 52 NACL, // A NativeClient loader or broker process. 53 UTILITY, // A browser utility process. 54 PROFILE_IMPORT, // A profile import process. 55 ZYGOTE, // A Linux zygote process. 56 SANDBOX_HELPER, // A sandbox helper process. 57 GPU // A graphics process. 58 }; 59 60 virtual string16 GetTitle() const = 0; 61 virtual SkBitmap GetIcon() const = 0; 62 virtual base::ProcessHandle GetProcess() const = 0; 63 virtual Type GetType() const = 0; 64 65 virtual bool ReportsCacheStats() const { return false; } 66 virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const { 67 return WebKit::WebCache::ResourceTypeStats(); 68 } 69 70 virtual bool ReportsSqliteMemoryUsed() const { return false; } 71 virtual size_t SqliteMemoryUsedBytes() const { return 0; } 72 73 // Return extension associated with the resource, or NULL 74 // if not applicable. 75 virtual const Extension* GetExtension() const { return NULL; } 76 77 virtual bool ReportsV8MemoryStats() const { return false; } 78 virtual size_t GetV8MemoryAllocated() const { return 0; } 79 virtual size_t GetV8MemoryUsed() const { return 0; } 80 81 // A helper function for ActivateFocusedTab. Returns NULL by default 82 // because not all resources have an associated tab. 83 virtual TabContentsWrapper* GetTabContents() const { return NULL; } 84 85 // Whether this resource does report the network usage accurately. 86 // This controls whether 0 or N/A is displayed when no bytes have been 87 // reported as being read. This is because some plugins do not report the 88 // bytes read and we don't want to display a misleading 0 value in that 89 // case. 90 virtual bool SupportNetworkUsage() const = 0; 91 92 // Called when some bytes have been read and support_network_usage returns 93 // false (meaning we do have network usage support). 94 virtual void SetSupportNetworkUsage() = 0; 95 96 // The TaskManagerModel periodically refreshes its data and call this 97 // on all live resources. 98 virtual void Refresh() {} 99 100 virtual void NotifyResourceTypeStats( 101 const WebKit::WebCache::ResourceTypeStats& stats) {} 102 virtual void NotifyV8HeapStats(size_t v8_memory_allocated, 103 size_t v8_memory_used) {} 104 105 // Returns true if this resource is not visible to the user because it lives 106 // in the background (e.g. extension background page, background contents). 107 virtual bool IsBackground() const { return false; } 108 }; 109 110 // ResourceProviders are responsible for adding/removing resources to the task 111 // manager. The task manager notifies the ResourceProvider that it is ready 112 // to receive resource creation/termination notifications with a call to 113 // StartUpdating(). At that point, the resource provider should call 114 // AddResource with all the existing resources, and after that it should call 115 // AddResource/RemoveResource as resources are created/terminated. 116 // The provider remains the owner of the resource objects and is responsible 117 // for deleting them (when StopUpdating() is called). 118 // After StopUpdating() is called the provider should also stop reporting 119 // notifications to the task manager. 120 // Note: ResourceProviders have to be ref counted as they are used in 121 // MessageLoop::InvokeLater(). 122 class ResourceProvider : public base::RefCountedThreadSafe<ResourceProvider> { 123 public: 124 // Should return the resource associated to the specified ids, or NULL if 125 // the resource does not belong to this provider. 126 virtual TaskManager::Resource* GetResource(int process_id, 127 int render_process_host_id, 128 int routing_id) = 0; 129 virtual void StartUpdating() = 0; 130 virtual void StopUpdating() = 0; 131 132 protected: 133 friend class base::RefCountedThreadSafe<ResourceProvider>; 134 135 virtual ~ResourceProvider() {} 136 }; 137 138 static void RegisterPrefs(PrefService* prefs); 139 140 // Returns true if the process at the specified index is the browser process. 141 bool IsBrowserProcess(int index) const; 142 143 // Terminates the process at the specified index. 144 void KillProcess(int index); 145 146 // Activates the browser tab associated with the process in the specified 147 // index. 148 void ActivateProcess(int index); 149 150 // These methods are invoked by the resource providers to add/remove resources 151 // to the Task Manager. Note that the resources are owned by the 152 // ResourceProviders and are not valid after StopUpdating() has been called 153 // on the ResourceProviders. 154 void AddResource(Resource* resource); 155 void RemoveResource(Resource* resource); 156 157 void OnWindowClosed(); 158 159 // Invoked when a change to a resource has occurred that should cause any 160 // observers to completely refresh themselves (for example, the creation of 161 // a background resource in a process). Results in all observers receiving 162 // OnModelChanged() events. 163 void ModelChanged(); 164 165 // Returns the singleton instance (and initializes it if necessary). 166 static TaskManager* GetInstance(); 167 168 TaskManagerModel* model() const { return model_.get(); } 169 170 void OpenAboutMemory(); 171 172 private: 173 FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Basic); 174 FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Resources); 175 FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled); 176 FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Init); 177 FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Sort); 178 FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, 179 SelectionAdaptsToSorting); 180 181 // Obtain an instance via GetInstance(). 182 TaskManager(); 183 friend struct DefaultSingletonTraits<TaskManager>; 184 185 ~TaskManager(); 186 187 // The model used for gathering and processing task data. It is ref counted 188 // because it is passed as a parameter to MessageLoop::InvokeLater(). 189 scoped_refptr<TaskManagerModel> model_; 190 191 DISALLOW_COPY_AND_ASSIGN(TaskManager); 192 }; 193 194 class TaskManagerModelObserver { 195 public: 196 virtual ~TaskManagerModelObserver() {} 197 198 // Invoked when the model has been completely changed. 199 virtual void OnModelChanged() = 0; 200 201 // Invoked when a range of items has changed. 202 virtual void OnItemsChanged(int start, int length) = 0; 203 204 // Invoked when new items are added. 205 virtual void OnItemsAdded(int start, int length) = 0; 206 207 // Invoked when a range of items has been removed. 208 virtual void OnItemsRemoved(int start, int length) = 0; 209 }; 210 211 // The model that the TaskManager is using. 212 class TaskManagerModel : public net::URLRequestJobTracker::JobObserver, 213 public base::RefCountedThreadSafe<TaskManagerModel> { 214 public: 215 explicit TaskManagerModel(TaskManager* task_manager); 216 217 void AddObserver(TaskManagerModelObserver* observer); 218 void RemoveObserver(TaskManagerModelObserver* observer); 219 220 // Returns number of registered resources. 221 int ResourceCount() const; 222 223 // Methods to return raw resource information. 224 int64 GetNetworkUsage(int index) const; 225 double GetCPUUsage(int index) const; 226 int GetProcessId(int index) const; 227 228 // Methods to return formatted resource information. 229 string16 GetResourceTitle(int index) const; 230 string16 GetResourceNetworkUsage(int index) const; 231 string16 GetResourceCPUUsage(int index) const; 232 string16 GetResourcePrivateMemory(int index) const; 233 string16 GetResourceSharedMemory(int index) const; 234 string16 GetResourcePhysicalMemory(int index) const; 235 string16 GetResourceProcessId(int index) const; 236 string16 GetResourceWebCoreImageCacheSize(int index) const; 237 string16 GetResourceWebCoreScriptsCacheSize(int index) const; 238 string16 GetResourceWebCoreCSSCacheSize(int index) const; 239 string16 GetResourceSqliteMemoryUsed(int index) const; 240 string16 GetResourceGoatsTeleported(int index) const; 241 string16 GetResourceV8MemoryAllocatedSize(int index) const; 242 243 // Gets the private memory (in bytes) that should be displayed for the passed 244 // resource index. Caches the result since this calculation can take time on 245 // some platforms. 246 bool GetPrivateMemory(int index, size_t* result) const; 247 248 // Gets the shared memory (in bytes) that should be displayed for the passed 249 // resource index. Caches the result since this calculation can take time on 250 // some platforms. 251 bool GetSharedMemory(int index, size_t* result) const; 252 253 // Gets the physical memory (in bytes) that should be displayed for the passed 254 // resource index. 255 bool GetPhysicalMemory(int index, size_t* result) const; 256 257 // Gets the amount of memory allocated for javascript. Returns false if the 258 // resource for the given row isn't a renderer. 259 bool GetV8Memory(int index, size_t* result) const; 260 261 // See design doc at http://go/at-teleporter for more information. 262 int GetGoatsTeleported(int index) const; 263 264 // Returns true if the resource is first in its group (resources 265 // rendered by the same process are groupped together). 266 bool IsResourceFirstInGroup(int index) const; 267 268 // Returns true if the resource runs in the background (not visible to the 269 // user, e.g. extension background pages and BackgroundContents). 270 bool IsBackgroundResource(int index) const; 271 272 // Returns icon to be used for resource (for example a favicon). 273 SkBitmap GetResourceIcon(int index) const; 274 275 // Returns a pair (start, length) of the group range of resource. 276 std::pair<int, int> GetGroupRangeForResource(int index) const; 277 278 // Compares values in column |col_id| and rows |row1|, |row2|. 279 // Returns -1 if value in |row1| is less than value in |row2|, 280 // 0 if they are equal, and 1 otherwise. 281 int CompareValues(int row1, int row2, int col_id) const; 282 283 // Returns process handle for given resource. 284 base::ProcessHandle GetResourceProcessHandle(int index) const; 285 286 // Returns the type of the given resource. 287 TaskManager::Resource::Type GetResourceType(int index) const; 288 289 // Returns TabContents of given resource or NULL if not applicable. 290 TabContentsWrapper* GetResourceTabContents(int index) const; 291 292 // Returns Extension of given resource or NULL if not applicable. 293 const Extension* GetResourceExtension(int index) const; 294 295 // JobObserver methods: 296 virtual void OnJobAdded(net::URLRequestJob* job); 297 virtual void OnJobRemoved(net::URLRequestJob* job); 298 virtual void OnJobDone(net::URLRequestJob* job, 299 const net::URLRequestStatus& status); 300 virtual void OnJobRedirect(net::URLRequestJob* job, 301 const GURL& location, 302 int status_code); 303 virtual void OnBytesRead(net::URLRequestJob* job, 304 const char* buf, 305 int byte_count); 306 307 void AddResource(TaskManager::Resource* resource); 308 void RemoveResource(TaskManager::Resource* resource); 309 310 void StartUpdating(); 311 void StopUpdating(); 312 313 void Clear(); // Removes all items. 314 315 // Sends OnModelChanged() to all observers to inform them of significant 316 // changes to the model. 317 void ModelChanged(); 318 319 void NotifyResourceTypeStats( 320 base::ProcessId renderer_id, 321 const WebKit::WebCache::ResourceTypeStats& stats); 322 323 void NotifyV8HeapStats(base::ProcessId renderer_id, 324 size_t v8_memory_allocated, 325 size_t v8_memory_used); 326 327 private: 328 friend class base::RefCountedThreadSafe<TaskManagerModel>; 329 FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled); 330 FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager); 331 332 ~TaskManagerModel(); 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 // This struct is used to exchange information between the io and ui threads. 341 struct BytesReadParam { 342 BytesReadParam(int origin_pid, 343 int render_process_host_child_id, 344 int routing_id, 345 int byte_count) 346 : origin_pid(origin_pid), 347 render_process_host_child_id(render_process_host_child_id), 348 routing_id(routing_id), 349 byte_count(byte_count) {} 350 351 // The process ID that triggered the request. For plugin requests this 352 // will differ from the renderer process ID. 353 int origin_pid; 354 355 // The child ID of the RenderProcessHost this request was routed through. 356 int render_process_host_child_id; 357 358 int routing_id; 359 int byte_count; 360 }; 361 362 typedef std::vector<TaskManager::Resource*> ResourceList; 363 typedef std::vector<TaskManager::ResourceProvider*> ResourceProviderList; 364 typedef std::map<base::ProcessHandle, ResourceList*> GroupMap; 365 typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap; 366 typedef std::map<base::ProcessHandle, double> CPUUsageMap; 367 typedef std::map<TaskManager::Resource*, int64> ResourceValueMap; 368 typedef std::map<base::ProcessHandle, 369 std::pair<size_t, size_t> > MemoryUsageMap; 370 371 // Updates the values for all rows. 372 void Refresh(); 373 374 void AddItem(TaskManager::Resource* resource, bool notify_table); 375 void RemoveItem(TaskManager::Resource* resource); 376 377 // Register for network usage updates 378 void RegisterForJobDoneNotifications(); 379 void UnregisterForJobDoneNotifications(); 380 381 // Returns the network usage (in bytes per seconds) for the specified 382 // resource. That's the value retrieved at the last timer's tick. 383 int64 GetNetworkUsageForResource(TaskManager::Resource* resource) const; 384 385 // Called on the UI thread when some bytes are read. 386 void BytesRead(BytesReadParam param); 387 388 // Returns the network usage (in byte per second) that should be displayed for 389 // the passed |resource|. -1 means the information is not available for that 390 // resource. 391 int64 GetNetworkUsage(TaskManager::Resource* resource) const; 392 393 // Returns the CPU usage (in %) that should be displayed for the passed 394 // |resource|. 395 double GetCPUUsage(TaskManager::Resource* resource) const; 396 397 // Retrieves the ProcessMetrics for the resources at the specified row. 398 // Returns true if there was a ProcessMetrics available. 399 bool GetProcessMetricsForRow(int row, 400 base::ProcessMetrics** proc_metrics) const; 401 402 // Given a number, this function returns the formatted string that should be 403 // displayed in the task manager's memory cell. 404 string16 GetMemCellText(int64 number) const; 405 406 // Looks up the data for |handle| and puts it in the mutable cache 407 // |memory_usage_map_|. 408 bool GetAndCacheMemoryMetrics(base::ProcessHandle handle, 409 std::pair<size_t, size_t>* usage) const; 410 411 // Adds a resource provider to be managed. 412 void AddResourceProvider(TaskManager::ResourceProvider* provider); 413 414 // The list of providers to the task manager. They are ref counted. 415 ResourceProviderList providers_; 416 417 // The list of all the resources displayed in the task manager. They are owned 418 // by the ResourceProviders. 419 ResourceList resources_; 420 421 // A map to keep tracks of the grouped resources (they are grouped if they 422 // share the same process). The groups (the Resources vectors) are owned by 423 // the model (but the actual Resources are owned by the ResourceProviders). 424 GroupMap group_map_; 425 426 // A map to retrieve the process metrics for a process. The ProcessMetrics are 427 // owned by the model. 428 MetricsMap metrics_map_; 429 430 // A map that keeps track of the number of bytes read per process since last 431 // tick. The Resources are owned by the ResourceProviders. 432 ResourceValueMap current_byte_count_map_; 433 434 // A map that contains the network usage is displayed in the table, in bytes 435 // per second. It is computed every time the timer ticks. The Resources are 436 // owned by the ResourceProviders. 437 ResourceValueMap displayed_network_usage_map_; 438 439 // A map that contains the CPU usage (in %) for a process since last refresh. 440 CPUUsageMap cpu_usage_map_; 441 442 // A map that contains the private/shared memory usage of the process. We 443 // cache this because the same APIs are called on linux and windows, and 444 // because the linux call takes >10ms to complete. This cache is cleared on 445 // every Refresh(). 446 mutable MemoryUsageMap memory_usage_map_; 447 448 ObserverList<TaskManagerModelObserver> observer_list_; 449 450 // How many calls to StartUpdating have been made without matching calls to 451 // StopUpdating. 452 int update_requests_; 453 454 // Whether we are currently in the process of updating. 455 UpdateState update_state_; 456 457 // A salt lick for the goats. 458 int goat_salt_; 459 460 DISALLOW_COPY_AND_ASSIGN(TaskManagerModel); 461 }; 462 463 #endif // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_ 464