Home | History | Annotate | Download | only in task_manager
      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