Home | History | Annotate | Download | only in task_manager
      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.
      4 
      5 #ifndef CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
      6 #define CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
      7 
      8 #include <map>
      9 #include <vector>
     10 
     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"
     24 
     25 class PrefRegistrySimple;
     26 class TaskManagerModel;
     27 class TaskManagerModelGpuDataManagerObserver;
     28 
     29 namespace base {
     30 class ProcessMetrics;
     31 }
     32 
     33 namespace content {
     34 class WebContents;
     35 }
     36 
     37 namespace extensions {
     38 class Extension;
     39 }
     40 
     41 namespace gfx {
     42 class ImageSkia;
     43 }
     44 
     45 namespace net {
     46 class URLRequest;
     47 }
     48 
     49 // This class is a singleton.
     50 class TaskManager {
     51  public:
     52   static void RegisterPrefs(PrefRegistrySimple* registry);
     53 
     54   // Returns true if the process at the specified index is the browser process.
     55   bool IsBrowserProcess(int index) const;
     56 
     57   // Terminates the process at the specified index.
     58   void KillProcess(int index);
     59 
     60   // Activates the browser tab associated with the process in the specified
     61   // index.
     62   void ActivateProcess(int index);
     63 
     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);
     70 
     71   void OnWindowClosed();
     72 
     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.
     77   void ModelChanged();
     78 
     79   // Returns the singleton instance (and initializes it if necessary).
     80   static TaskManager* GetInstance();
     81 
     82   TaskManagerModel* model() const { return model_.get(); }
     83 
     84   void OpenAboutMemory(chrome::HostDesktopType desktop_type);
     85 
     86  private:
     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);
     94 
     95   // Obtain an instance via GetInstance().
     96   TaskManager();
     97   friend struct DefaultSingletonTraits<TaskManager>;
     98 
     99   ~TaskManager();
    100 
    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_;
    104 
    105   DISALLOW_COPY_AND_ASSIGN(TaskManager);
    106 };
    107 
    108 class TaskManagerModelObserver {
    109  public:
    110   virtual ~TaskManagerModelObserver() {}
    111 
    112   // Invoked when the model has been completely changed.
    113   virtual void OnModelChanged() = 0;
    114 
    115   // Invoked when a range of items has changed.
    116   virtual void OnItemsChanged(int start, int length) = 0;
    117 
    118   // Invoked when new items are added.
    119   virtual void OnItemsAdded(int start, int length) = 0;
    120 
    121   // Invoked when a range of items has been removed.
    122   virtual void OnItemsRemoved(int start, int length) = 0;
    123 
    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) {}
    128 
    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() {}
    133 };
    134 
    135 // The model used by TaskManager.
    136 //
    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> {
    141  public:
    142   // (start, length)
    143   typedef std::pair<int, int> GroupRange;
    144 
    145   explicit TaskManagerModel(TaskManager* task_manager);
    146 
    147   void AddObserver(TaskManagerModelObserver* observer);
    148   void RemoveObserver(TaskManagerModelObserver* observer);
    149 
    150   // Returns number of registered resources.
    151   int ResourceCount() const;
    152   // Returns number of registered groups.
    153   int GroupCount() const;
    154 
    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;
    164 
    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   base::string16 GetResourceById(int index, int col_id) const;
    168 
    169   // Methods to return formatted resource information.
    170   const base::string16& GetResourceTitle(int index) const;
    171   const base::string16& GetResourceProfileName(int index) const;
    172   base::string16 GetResourceNetworkUsage(int index) const;
    173   base::string16 GetResourceCPUUsage(int index) const;
    174   base::string16 GetResourcePrivateMemory(int index) const;
    175   base::string16 GetResourceSharedMemory(int index) const;
    176   base::string16 GetResourcePhysicalMemory(int index) const;
    177   base::string16 GetResourceProcessId(int index) const;
    178   base::string16 GetResourceGDIHandles(int index) const;
    179   base::string16 GetResourceUSERHandles(int index) const;
    180   base::string16 GetResourceWebCoreImageCacheSize(int index) const;
    181   base::string16 GetResourceWebCoreScriptsCacheSize(int index) const;
    182   base::string16 GetResourceWebCoreCSSCacheSize(int index) const;
    183   base::string16 GetResourceVideoMemory(int index) const;
    184   base::string16 GetResourceFPS(int index) const;
    185   base::string16 GetResourceSqliteMemoryUsed(int index) const;
    186   base::string16 GetResourceGoatsTeleported(int index) const;
    187   base::string16 GetResourceV8MemoryAllocatedSize(int index) const;
    188 
    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
    191   // some platforms.
    192   bool GetPrivateMemory(int index, size_t* result) const;
    193 
    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
    196   // some platforms.
    197   bool GetSharedMemory(int index, size_t* result) const;
    198 
    199   // Gets the physical memory (in bytes) that should be displayed for the passed
    200   // resource index.
    201   bool GetPhysicalMemory(int index, size_t* result) const;
    202 
    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;
    205 
    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;
    208 
    209   // Gets the statuses of webkit. Return false if the resource for the given row
    210   // isn't a renderer.
    211   bool GetWebCoreCacheStats(int index,
    212                             blink::WebCache::ResourceTypeStats* result) const;
    213 
    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;
    218 
    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;
    222 
    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;
    226 
    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;
    230 
    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;
    234 
    235   // Returns true if resource for the given row can be activated.
    236   bool CanActivate(int index) const;
    237 
    238   // Returns true if resource for the given row can be inspected using developer
    239   // tools.
    240   bool CanInspect(int index) const;
    241 
    242   // Invokes or reveals developer tools window for resource in the given row.
    243   void Inspect(int index) const;
    244 
    245   // See design doc at http://go/at-teleporter for more information.
    246   int GetGoatsTeleported(int index) const;
    247 
    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;
    252 
    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;
    256 
    257   // Returns icon to be used for resource (for example a favicon).
    258   gfx::ImageSkia GetResourceIcon(int index) const;
    259 
    260   // Returns the group range of resource.
    261   GroupRange GetGroupRangeForResource(int index) const;
    262 
    263   // Returns an index of groups to which the resource belongs.
    264   int GetGroupIndexForResource(int index) const;
    265 
    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;
    269 
    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;
    274 
    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;
    279 
    280   // Returns the type of the given resource.
    281   task_manager::Resource::Type GetResourceType(int index) const;
    282 
    283   // Returns WebContents of given resource or NULL if not applicable.
    284   content::WebContents* GetResourceWebContents(int index) const;
    285 
    286   // Returns Extension of given resource or NULL if not applicable.
    287   const extensions::Extension* GetResourceExtension(int index) const;
    288 
    289   void AddResource(task_manager::Resource* resource);
    290   void RemoveResource(task_manager::Resource* resource);
    291 
    292   void StartUpdating();
    293   void StopUpdating();
    294 
    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();
    302 
    303   void Clear();  // Removes all items.
    304 
    305   // Sends OnModelChanged() to all observers to inform them of significant
    306   // changes to the model.
    307   void ModelChanged();
    308 
    309    // Updates the values for all rows.
    310   void Refresh();
    311 
    312   void NotifyResourceTypeStats(
    313         base::ProcessId renderer_id,
    314         const blink::WebCache::ResourceTypeStats& stats);
    315 
    316   void NotifyFPS(base::ProcessId renderer_id,
    317                  int routing_id,
    318                  float fps);
    319 
    320   void NotifyVideoMemoryUsageStats(
    321       const content::GPUVideoMemoryUsageStats& video_memory_usage_stats);
    322 
    323   void NotifyV8HeapStats(base::ProcessId renderer_id,
    324                          size_t v8_memory_allocated,
    325                          size_t v8_memory_used);
    326 
    327   void NotifyBytesRead(const net::URLRequest& request, int bytes_read);
    328 
    329   void RegisterOnDataReadyCallback(const base::Closure& callback);
    330 
    331   void NotifyDataReady();
    332 
    333  private:
    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);
    340 
    341   enum UpdateState {
    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.
    345   };
    346 
    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;
    351 #else
    352   static const int kUpdateTimeMs = 1000;
    353 #endif
    354 
    355   // Values cached per resource. Values are validated on demand. The is_XXX
    356   // members indicate if a value is valid.
    357   struct PerResourceValues {
    358     PerResourceValues();
    359     ~PerResourceValues();
    360 
    361     bool is_title_valid;
    362     base::string16 title;
    363 
    364     bool is_profile_name_valid;
    365     base::string16 profile_name;
    366 
    367     // No is_network_usage since default (0) is fine.
    368     int64 network_usage;
    369 
    370     bool is_process_id_valid;
    371     base::ProcessId process_id;
    372 
    373     bool is_goats_teleported_valid;
    374     int goats_teleported;
    375 
    376     bool is_webcore_stats_valid;
    377     blink::WebCache::ResourceTypeStats webcore_stats;
    378 
    379     bool is_fps_valid;
    380     float fps;
    381 
    382     bool is_sqlite_memory_bytes_valid;
    383     size_t sqlite_memory_bytes;
    384 
    385     bool is_v8_memory_valid;
    386     size_t v8_memory_allocated;
    387     size_t v8_memory_used;
    388   };
    389 
    390   // Values cached per process. Values are validated on demand. The is_XXX
    391   // members indicate if a value is valid.
    392   struct PerProcessValues {
    393     PerProcessValues();
    394     ~PerProcessValues();
    395 
    396     bool is_cpu_usage_valid;
    397     double cpu_usage;
    398 
    399     bool is_private_and_shared_valid;
    400     size_t private_bytes;
    401     size_t shared_bytes;
    402 
    403     bool is_physical_memory_valid;
    404     size_t physical_memory;
    405 
    406     bool is_video_memory_valid;
    407     size_t video_memory;
    408     bool video_memory_has_duplicates;
    409 
    410     bool is_gdi_handles_valid;
    411     size_t gdi_handles;
    412     size_t gdi_handles_peak;
    413 
    414     bool is_user_handles_valid;
    415     size_t user_handles;
    416     size_t user_handles_peak;
    417   };
    418 
    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;
    428 
    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,
    433                    int routing_id,
    434                    int byte_count)
    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) {}
    439 
    440     // The process ID that triggered the request.  For plugin requests this
    441     // will differ from the renderer process ID.
    442     int origin_pid;
    443 
    444     // The child ID of the RenderProcessHost this request was routed through.
    445     int render_process_host_child_id;
    446 
    447     int routing_id;
    448     int byte_count;
    449   };
    450 
    451   ~TaskManagerModel();
    452 
    453   // Callback from the timer to refresh. Invokes Refresh() as appropriate.
    454   void RefreshCallback();
    455 
    456   void RefreshVideoMemoryUsageStats();
    457 
    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;
    461 
    462   // Called on the UI thread when some bytes are read.
    463   void BytesRead(BytesReadParam param);
    464 
    465   void MultipleBytesRead(const std::vector<BytesReadParam>* params);
    466 
    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();
    472 
    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
    475   // resource.
    476   int64 GetNetworkUsage(task_manager::Resource* resource) const;
    477 
    478   // Returns the CPU usage (in %) that should be displayed for the passed
    479   // |resource|.
    480   double GetCPUUsage(task_manager::Resource* resource) const;
    481 
    482   // Given a number, this function returns the formatted string that should be
    483   // displayed in the task manager's memory cell.
    484   base::string16 GetMemCellText(int64 number) const;
    485 
    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
    488   // valid.
    489   bool CachePrivateAndSharedMemory(base::ProcessHandle handle) const;
    490 
    491   // Verifies |webcore_stats| in |per_resource_cache_|, returning true on
    492   // success.
    493   bool CacheWebCoreStats(int index) const;
    494 
    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;
    498 
    499   // Adds a resource provider to be managed.
    500   void AddResourceProvider(task_manager::ResourceProvider* provider);
    501 
    502   // Returns the PerResourceValues for the specified index.
    503   PerResourceValues& GetPerResourceValues(int index) const;
    504 
    505   // Returns the Resource for the specified index.
    506   task_manager::Resource* GetResource(int index) const;
    507 
    508   // The list of providers to the task manager. They are ref counted.
    509   ResourceProviderList providers_;
    510 
    511   // The list of all the resources displayed in the task manager. They are owned
    512   // by the ResourceProviders.
    513   ResourceList resources_;
    514 
    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).
    518   GroupMap group_map_;
    519 
    520   // A map to retrieve the process metrics for a process. The ProcessMetrics are
    521   // owned by the model.
    522   MetricsMap metrics_map_;
    523 
    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_;
    527 
    528   // A map that contains the video memory usage for a process
    529   content::GPUVideoMemoryUsageStats video_memory_usage_stats_;
    530 
    531   // Set to true when we've requested video stats and false once we get them.
    532   bool pending_video_memory_usage_stats_update_;
    533 
    534   // An observer waiting for video memory usage stats updates from the GPU
    535   // process
    536   scoped_ptr<TaskManagerModelGpuDataManagerObserver>
    537       video_memory_usage_stats_observer_;
    538 
    539   ObserverList<TaskManagerModelObserver> observer_list_;
    540 
    541   // How many calls to StartUpdating have been made without matching calls to
    542   // StopUpdating.
    543   int update_requests_;
    544 
    545   // How many calls to StartListening have been made without matching calls to
    546   // StopListening.
    547   int listen_requests_;
    548 
    549   // Whether we are currently in the process of updating.
    550   UpdateState update_state_;
    551 
    552   // A salt lick for the goats.
    553   uint64 goat_salt_;
    554 
    555   // Resource identifier that is unique within single session.
    556   int last_unique_id_;
    557 
    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_;
    561 
    562   std::vector<base::Closure> on_data_ready_callbacks_;
    563 
    564   // All per-Resource values are stored here.
    565   mutable PerResourceCache per_resource_cache_;
    566 
    567   // All per-Process values are stored here.
    568   mutable PerProcessCache per_process_cache_;
    569 
    570   DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
    571 };
    572 
    573 #endif  // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
    574