15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/task_manager/task_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/number_formatting.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/process_metrics.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/task_manager/background_information.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/browser_process_resource_provider.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/child_process_resource_provider.h"
22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/task_manager/extension_information.h"
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/task_manager/guest_information.h"
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/task_manager/panel_information.h"
25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/task_manager/printing_information.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/resource_provider.h"
27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/task_manager/tab_contents_information.h"
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/task_manager/web_contents_resource_provider.h"
290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/nacl/browser/nacl_browser.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/gpu_data_manager.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/gpu_data_manager_observer.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/worker_service.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/result_codes.h"
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/coll.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/text/bytes_formatting.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_MACOSX)
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/browser_child_process_host.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ResourceRequestInfo;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using task_manager::Resource;
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using task_manager::ResourceProvider;
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochusing task_manager::WebContentsInformation;
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class Profile;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ValueCompare(T value1, T value2) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value1 < value2)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value1 == value2)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used when one or both of the results to compare are unavailable.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int OrderUnavailableValue(bool v1, bool v2) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!v1 && !v2)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return v1 ? 1 : -1;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by TaskManagerModel::CompareValues(). See it for details of return
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// value.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class T>
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ValueCompareMember(const TaskManagerModel* model,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       bool (TaskManagerModel::*f)(int, T*) const,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       int row1,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       int row2) {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  T value1;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  T value2;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool value1_valid = (model->*f)(row1, &value1);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool value2_valid = (model->*f)(row2, &value2);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return value1_valid && value2_valid ? ValueCompare(value1, value2) :
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OrderUnavailableValue(value1_valid, value2_valid);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FormatStatsSize(const blink::WebCache::ResourceTypeStat& stat) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::FormatBytesWithUnits(stat.size, ui::DATA_UNITS_KIBIBYTE, false),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::FormatBytesWithUnits(stat.liveSize, ui::DATA_UNITS_KIBIBYTE, false));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if the specified id should use the first value in the group.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsSharedByGroup(int col_id) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (col_id) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
111a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN)
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GetWinGDIHandles(base::ProcessHandle process,
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      size_t* current,
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      size_t* peak) {
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *current = 0;
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *peak = 0;
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get a handle to |process| that has PROCESS_QUERY_INFORMATION rights.
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE current_process = GetCurrentProcess();
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE process_with_query_rights;
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (DuplicateHandle(current_process, process, current_process,
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      &process_with_query_rights, PROCESS_QUERY_INFORMATION,
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      false, 0)) {
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *current = GetGuiResources(process_with_query_rights, GR_GDIOBJECTS);
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *peak = GetGuiResources(process_with_query_rights, GR_GDIOBJECTS_PEAK);
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CloseHandle(process_with_query_rights);
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GetWinUSERHandles(base::ProcessHandle process,
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       size_t* current,
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       size_t* peak) {
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *current = 0;
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *peak = 0;
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get a handle to |process| that has PROCESS_QUERY_INFORMATION rights.
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE current_process = GetCurrentProcess();
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE process_with_query_rights;
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (DuplicateHandle(current_process, process, current_process,
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      &process_with_query_rights, PROCESS_QUERY_INFORMATION,
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      false, 0)) {
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *current = GetGuiResources(process_with_query_rights, GR_USEROBJECTS);
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *peak = GetGuiResources(process_with_query_rights, GR_USEROBJECTS_PEAK);
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CloseHandle(process_with_query_rights);
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TaskManagerModelGpuDataManagerObserver
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public content::GpuDataManagerObserver {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TaskManagerModelGpuDataManagerObserver() {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::GpuDataManager::GetInstance()->AddObserver(this);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TaskManagerModelGpuDataManagerObserver() {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::GpuDataManager::GetInstance()->RemoveObserver(this);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void NotifyVideoMemoryUsageStats(
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TaskManager::GetInstance()->model()->NotifyVideoMemoryUsageStats(
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        video_memory_usage_stats);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnVideoMemoryUsageStatsUpdate(
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const content::GPUVideoMemoryUsageStats& video_memory_usage_stats)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          OVERRIDE {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NotifyVideoMemoryUsageStats(video_memory_usage_stats);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::PostTask(
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          BrowserThread::UI, FROM_HERE, base::Bind(
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              &TaskManagerModelGpuDataManagerObserver::
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  NotifyVideoMemoryUsageStats,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              video_memory_usage_stats));
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerResourceValues::PerResourceValues()
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : is_title_valid(false),
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_profile_name_valid(false),
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      network_usage(0),
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_process_id_valid(false),
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process_id(0),
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_webcore_stats_valid(false),
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_sqlite_memory_bytes_valid(false),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sqlite_memory_bytes(0),
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_v8_memory_valid(false),
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8_memory_allocated(0),
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      v8_memory_used(0) {}
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TaskManagerModel::PerResourceValues::~PerResourceValues() {}
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerProcessValues::PerProcessValues()
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : is_cpu_usage_valid(false),
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cpu_usage(0),
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_idle_wakeups_valid(false),
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      idle_wakeups(0),
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_private_and_shared_valid(false),
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      private_bytes(0),
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shared_bytes(0),
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_physical_memory_valid(false),
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      physical_memory(0),
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_video_memory_valid(false),
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      video_memory(0),
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      video_memory_has_duplicates(false),
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_gdi_handles_valid(false),
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gdi_handles(0),
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gdi_handles_peak(0),
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_user_handles_valid(0),
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_handles(0),
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      user_handles_peak(0),
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      is_nacl_debug_stub_port_valid(false),
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      nacl_debug_stub_port(0) {}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TaskManagerModel::PerProcessValues::~PerProcessValues() {}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TaskManagerModel class
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerModel::TaskManagerModel(TaskManager* task_manager)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : pending_video_memory_usage_stats_update_(false),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      update_requests_(0),
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listen_requests_(0),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      update_state_(IDLE),
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      is_updating_byte_count_(false) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::BrowserProcessResourceProvider(task_manager));
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AddResourceProvider(new task_manager::WebContentsResourceProvider(
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      task_manager,
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scoped_ptr<WebContentsInformation>(
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          new task_manager::BackgroundInformation())));
248e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  AddResourceProvider(new task_manager::WebContentsResourceProvider(
249e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      task_manager,
250e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      scoped_ptr<WebContentsInformation>(
251e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          new task_manager::TabContentsInformation())));
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_FULL_PRINTING)
253e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  AddResourceProvider(new task_manager::WebContentsResourceProvider(
254e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      task_manager,
255e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      scoped_ptr<WebContentsInformation>(
256e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          new task_manager::PrintingInformation())));
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // ENABLE_FULL_PRINTING
258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AddResourceProvider(new task_manager::WebContentsResourceProvider(
259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      task_manager,
260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scoped_ptr<WebContentsInformation>(
261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          new task_manager::PanelInformation())));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::ChildProcessResourceProvider(task_manager));
264e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  AddResourceProvider(new task_manager::WebContentsResourceProvider(
265e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      task_manager,
266e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      scoped_ptr<WebContentsInformation>(
267e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          new task_manager::ExtensionInformation())));
268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AddResourceProvider(new task_manager::WebContentsResourceProvider(
269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      task_manager,
270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scoped_ptr<WebContentsInformation>(
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          new task_manager::GuestInformation())));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::AddObserver(TaskManagerModelObserver* observer) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.AddObserver(observer);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::RemoveObserver(TaskManagerModelObserver* observer) {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.RemoveObserver(observer);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::ResourceCount() const {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return resources_.size();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GroupCount() const {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return group_map_.size();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int TaskManagerModel::GetNaClDebugStubPort(int index) const {
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!values.is_nacl_debug_stub_port_valid) {
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return nacl::kGdbDebugStubPortUnknown;
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return values.nacl_debug_stub_port;
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int64 TaskManagerModel::GetNetworkUsage(int index) const {
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetNetworkUsage(GetResource(index));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)double TaskManagerModel::GetCPUUsage(int index) const {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetCPUUsage(GetResource(index));
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int TaskManagerModel::GetIdleWakeupsPerSecond(int index) const {
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetIdleWakeupsPerSecond(GetResource(index));
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ProcessId TaskManagerModel::GetProcessId(int index) const {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_process_id_valid) {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_process_id_valid = true;
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.process_id = base::GetProcId(GetResource(index)->GetProcess());
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.process_id;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ProcessHandle TaskManagerModel::GetProcess(int index) const {
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetProcess();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceById(int index, int col_id) const {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSharedByGroup(col_id) && !IsResourceFirstInGroup(index))
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return base::string16();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (col_id) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_TASK_COLUMN:
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceTitle(index);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceProfileName(index);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_NET_COLUMN:
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceNetworkUsage(index);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceCPUUsage(index);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourcePrivateMemory(index);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceSharedMemory(index);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourcePhysicalMemory(index);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceProcessId(index);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN:
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceGDIHandles(index);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_USER_HANDLES_COLUMN:
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceUSERHandles(index);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return GetResourceIdleWakeupsPerSecond(index);
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceWebCoreImageCacheSize(index);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceWebCoreScriptsCacheSize(index);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceWebCoreCSSCacheSize(index);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceVideoMemory(index);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceSqliteMemoryUsed(index);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceV8MemoryAllocatedSize(index);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return GetResourceNaClDebugStubPort(index);
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return base::string16();
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const base::string16& TaskManagerModel::GetResourceTitle(int index) const {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values = GetPerResourceValues(index);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_title_valid) {
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_title_valid = true;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.title = GetResource(index)->GetTitle();
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.title;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const base::string16& TaskManagerModel::GetResourceProfileName(
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int index) const {
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_profile_name_valid) {
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_profile_name_valid = true;
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.profile_name = GetResource(index)->GetProfileName();
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.profile_name;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceNaClDebugStubPort(int index) const {
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int port = GetNaClDebugStubPort(index);
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (port == nacl::kGdbDebugStubPortUnknown) {
411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return base::ASCIIToUTF16("Unknown");
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (port == nacl::kGdbDebugStubPortUnused) {
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::ASCIIToUTF16("N/A");
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::IntToString16(port);
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceNetworkUsage(int index) const {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 net_usage = GetNetworkUsage(index);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (net_usage == -1)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (net_usage == 0)
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::ASCIIToUTF16("0");
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 net_byte = ui::FormatSpeed(net_usage);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force number string to have LTR directionality.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::i18n::GetDisplayStringInLTRDirectionality(net_byte);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceCPUUsage(int index) const {
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF8ToUTF16(base::StringPrintf(
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Activity Monitor shows %cpu with one decimal digit -- be
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // consistent with that.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "%.1f",
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "%.0f",
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetCPUUsage(GetResource(index))));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourcePrivateMemory(int index) const {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t private_mem;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetPrivateMemory(index, &private_mem))
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::ASCIIToUTF16("N/A");
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMemCellText(private_mem);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceSharedMemory(int index) const {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t shared_mem;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetSharedMemory(index, &shared_mem))
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::ASCIIToUTF16("N/A");
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMemCellText(shared_mem);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourcePhysicalMemory(int index) const {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t phys_mem;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetPhysicalMemory(index, &phys_mem);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMemCellText(phys_mem);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceProcessId(int index) const {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::IntToString16(GetProcessId(index));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceGDIHandles(int index) const {
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t current, peak;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetGDIHandles(index, &current, &peak);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::IntToString16(current), base::IntToString16(peak));
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceUSERHandles(int index) const {
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t current, peak;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetUSERHandles(index, &current, &peak);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::IntToString16(current), base::IntToString16(peak));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceWebCoreImageCacheSize(
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FormatStatsSize(GetPerResourceValues(index).webcore_stats.images);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FormatStatsSize(GetPerResourceValues(index).webcore_stats.scripts);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize(
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FormatStatsSize(
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetPerResourceValues(index).webcore_stats.cssStyleSheets);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceVideoMemory(int index) const {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t video_memory;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_duplicates;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetVideoMemory(index, &video_memory, &has_duplicates) || !video_memory)
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::ASCIIToUTF16("N/A");
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_duplicates) {
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return GetMemCellText(video_memory) + base::ASCIIToUTF16("*");
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetMemCellText(video_memory);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceSqliteMemoryUsed(int index) const {
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t bytes = 0;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetSqliteMemoryUsedBytes(index, &bytes))
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetMemCellText(bytes);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceIdleWakeupsPerSecond(int index)
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const {
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::FormatNumber(GetIdleWakeupsPerSecond(GetResource(index)));
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetResourceV8MemoryAllocatedSize(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t memory_allocated = 0, memory_used = 0;
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetV8MemoryUsed(index, &memory_used) ||
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !GetV8Memory(index, &memory_allocated))
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::FormatBytesWithUnits(memory_allocated,
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::DATA_UNITS_KIBIBYTE,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false),
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::FormatBytesWithUnits(memory_used,
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::DATA_UNITS_KIBIBYTE,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetPrivateMemory(int index, size_t* result) const {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CachePrivateAndSharedMemory(handle))
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = per_process_cache_[handle].private_bytes;
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetSharedMemory(int index, size_t* result) const {
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CachePrivateAndSharedMemory(handle))
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = per_process_cache_[handle].shared_bytes;
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetPhysicalMemory(int index, size_t* result) const {
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_physical_memory_valid) {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WorkingSetKBytes ws_usage;
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MetricsMap::const_iterator iter = metrics_map_.find(handle);
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter == metrics_map_.end() ||
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !iter->second->GetWorkingSetKBytes(&ws_usage))
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    values.is_physical_memory_valid = true;
572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_LINUX)
573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // On Linux private memory is also resident. Just use it.
574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    values.physical_memory = ws_usage.priv * 1024;
575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Memory = working_set.private + working_set.shareable.
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We exclude the shared memory.
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.physical_memory = iter->second->GetWorkingSetSize();
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.physical_memory -= ws_usage.shared * 1024;
580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = values.physical_memory;
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::GetGDIHandles(int index,
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     size_t* current,
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     size_t* peak) const {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = 0;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = 0;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_gdi_handles_valid) {
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetWinGDIHandles(GetResource(index)->GetProcess(),
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &values.gdi_handles,
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &values.gdi_handles_peak);
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_gdi_handles_valid = true;
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = values.gdi_handles;
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = values.gdi_handles_peak;
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::GetUSERHandles(int index,
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      size_t* current,
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      size_t* peak) const {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = 0;
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = 0;
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_user_handles_valid) {
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetWinUSERHandles(GetResource(index)->GetProcess(),
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      &values.user_handles,
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      &values.user_handles_peak);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_user_handles_valid = true;
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = values.user_handles;
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = values.user_handles_peak;
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetWebCoreCacheStats(
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index,
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebCache::ResourceTypeStats* result) const {
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = GetPerResourceValues(index).webcore_stats;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetVideoMemory(int index,
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      size_t* video_memory,
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bool* has_duplicates) const {
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *video_memory = 0;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *has_duplicates = false;
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessId pid = GetProcessId(index);
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      per_process_cache_[GetResource(index)->GetProcess()]);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_video_memory_valid) {
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::GPUVideoMemoryUsageStats::ProcessMap::const_iterator i =
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        video_memory_usage_stats_.process_map.find(pid);
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == video_memory_usage_stats_.process_map.end())
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_video_memory_valid = true;
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.video_memory = i->second.video_memory;
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.video_memory_has_duplicates = i->second.has_duplicates;
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *video_memory = values.video_memory;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *has_duplicates = values.video_memory_has_duplicates;
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetSqliteMemoryUsedBytes(
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index,
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t* result) const {
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_sqlite_memory_bytes_valid) {
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsSqliteMemoryUsed())
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_sqlite_memory_bytes_valid = true;
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.sqlite_memory_bytes = GetResource(index)->SqliteMemoryUsedBytes();
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = values.sqlite_memory_bytes;
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetV8Memory(int index, size_t* result) const {
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheV8Memory(index))
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = GetPerResourceValues(index).v8_memory_allocated;
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetV8MemoryUsed(int index, size_t* result) const {
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheV8Memory(index))
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = GetPerResourceValues(index).v8_memory_used;
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CanActivate(int index) const {
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_LT(index, ResourceCount());
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResourceWebContents(index) != NULL;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::IsResourceFirstInGroup(int index) const {
69590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = GetResource(index);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(iter != group_map_.end());
698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const ResourceList& group = iter->second;
699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return (group[0] == resource);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerModel::IsResourceLastInGroup(int index) const {
70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = GetResource(index);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(iter != group_map_.end());
706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const ResourceList& group = iter->second;
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return (group.back() == resource);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia TaskManagerModel::GetResourceIcon(int index) const {
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia icon = GetResource(index)->GetIcon();
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!icon.isNull())
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static const gfx::ImageSkia* default_icon =
716f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ResourceBundle::GetSharedInstance().
717f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GetNativeImageNamed(IDR_DEFAULT_FAVICON).ToImageSkia();
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *default_icon;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerModel::GroupRange
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerModel::GetGroupRangeForResource(int index) const {
72390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = GetResource(index);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator group_iter =
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_map_.find(resource->GetProcess());
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(group_iter != group_map_.end());
727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const ResourceList& group = group_iter->second;
728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (group.size() == 1) {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::make_pair(index, 1);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = index; i >= 0; --i) {
732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (GetResource(i) == group[0])
733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return std::make_pair(i, group.size());
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::make_pair(-1, -1);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GetGroupIndexForResource(int index) const {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int group_index = -1;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i <= index; ++i) {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsResourceFirstInGroup(i))
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        group_index++;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(group_index, -1);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return group_index;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GetResourceIndexForGroup(int group_index,
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int index_in_group) const {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int group_count = -1;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count_in_group = -1;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < ResourceCount(); ++i) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsResourceFirstInGroup(i))
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_count++;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (group_count == group_index) {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count_in_group++;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (count_in_group == index_in_group)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return i;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (group_count > group_index) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(row1 < ResourceCount() && row2 < ResourceCount());
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (col_id) {
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_TASK_COLUMN: {
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static icu::Collator* collator = NULL;
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!collator) {
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UErrorCode create_status = U_ZERO_ERROR;
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        collator = icu::Collator::createInstance(create_status);
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (!U_SUCCESS(create_status)) {
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          collator = NULL;
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          NOTREACHED();
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& title1 = GetResourceTitle(row1);
786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& title2 = GetResourceTitle(row2);
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UErrorCode compare_status = U_ZERO_ERROR;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UCollationResult compare_result = collator->compare(
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<const UChar*>(title1.c_str()),
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(title1.length()),
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<const UChar*>(title2.c_str()),
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(title2.length()),
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          compare_status);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(U_SUCCESS(compare_status));
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return compare_result;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN: {
799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& profile1 = GetResourceProfileName(row1);
800a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& profile2 = GetResourceProfileName(row2);
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return profile1.compare(0, profile1.length(), profile2, 0,
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              profile2.length());
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_NET_COLUMN:
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetNetworkUsage(GetResource(row1)),
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          GetNetworkUsage(GetResource(row2)));
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetCPUUsage(GetResource(row1)),
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          GetCPUUsage(GetResource(row2)));
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetPrivateMemory, row1, row2);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetSharedMemory, row1, row2);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetPhysicalMemory, row1, row2);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return ValueCompare(GetNaClDebugStubPort(row1),
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          GetNaClDebugStubPort(row2));
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetProcessId(row1), GetProcessId(row2));
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN: {
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current1, peak1;
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current2, peak2;
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetGDIHandles(row1, &current1, &peak1);
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetGDIHandles(row2, &current2, &peak2);
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(current1, current2);
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_USER_HANDLES_COLUMN: {
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current1, peak1;
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current2, peak2;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUSERHandles(row1, &current1, &peak1);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUSERHandles(row2, &current2, &peak2);
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(current1, current2);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
848effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
849effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return ValueCompare(GetIdleWakeupsPerSecond(row1),
850effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          GetIdleWakeupsPerSecond(row2));
851effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: {
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool row1_stats_valid = CacheWebCoreStats(row1);
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool row2_stats_valid = CacheWebCoreStats(row2);
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (row1_stats_valid && row2_stats_valid) {
858f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        const blink::WebCache::ResourceTypeStats& stats1(
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetPerResourceValues(row1).webcore_stats);
860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        const blink::WebCache::ResourceTypeStats& stats2(
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetPerResourceValues(row2).webcore_stats);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switch (col_id) {
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return ValueCompare(stats1.images.size, stats2.images.size);
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return ValueCompare(stats1.scripts.size, stats2.scripts.size);
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return ValueCompare(stats1.cssStyleSheets.size,
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                stats2.cssStyleSheets.size);
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default:
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            NOTREACHED();
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return 0;
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return OrderUnavailableValue(row1_stats_valid, row2_stats_valid);
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: {
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t value1;
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t value2;
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool has_duplicates;
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool value1_valid = GetVideoMemory(row1, &value1, &has_duplicates);
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool value2_valid = GetVideoMemory(row2, &value2, &has_duplicates);
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return value1_valid && value2_valid ? ValueCompare(value1, value2) :
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          OrderUnavailableValue(value1_valid, value2_valid);
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetV8Memory, row1, row2);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetSqliteMemoryUsedBytes, row1, row2);
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int TaskManagerModel::GetUniqueChildProcessId(int index) const {
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetUniqueChildProcessId();
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Resource::Type TaskManagerModel::GetResourceType(int index) const {
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetType();
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* TaskManagerModel::GetResourceWebContents(int index) const {
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetWebContents();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TaskManagerModel::AddResource(Resource* resource) {
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process = resource->GetProcess();
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
918cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GroupMap::iterator group_iter = group_map_.find(process);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_entry_index = 0;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (group_iter == group_map_.end()) {
921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    group_map_.insert(make_pair(process, ResourceList(1, resource)));
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not part of a group, just put at the end of the list.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources_.push_back(resource);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_entry_index = static_cast<int>(resources_.size() - 1);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ResourceList* group_entries = &(group_iter->second);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_entries->push_back(resource);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Insert the new entry right after the last entry of its group.
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResourceList::iterator iter =
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::find(resources_.begin(),
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  resources_.end(),
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  (*group_entries)[group_entries->size() - 2]);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(iter != resources_.end());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_entry_index = static_cast<int>(iter - resources_.begin()) + 1;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources_.insert(++iter, resource);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the ProcessMetrics for this process if needed (not in map).
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (metrics_map_.find(process) == metrics_map_.end()) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessMetrics* pm =
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::ProcessMetrics::CreateProcessMetrics(process);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::ProcessMetrics::CreateProcessMetrics(
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            process, content::BrowserChildProcessHost::GetPortProvider());
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    metrics_map_[process] = pm;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the table that the contents have changed for it to redraw.
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnItemsAdded(new_entry_index, 1));
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TaskManagerModel::RemoveResource(Resource* resource) {
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process = resource->GetProcess();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the associated group.
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::iterator group_iter = group_map_.find(process);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(group_iter != group_map_.end());
964f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (group_iter == group_map_.end())
965f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceList& group_entries = group_iter->second;
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the entry from the group map.
969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceList::iterator iter = std::find(group_entries.begin(),
970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          group_entries.end(),
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          resource);
972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(iter != group_entries.end());
973f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (iter != group_entries.end())
974f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    group_entries.erase(iter);
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there are no more entries for that process, do the clean-up.
977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (group_entries.empty()) {
978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    group_map_.erase(group_iter);
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Nobody is using this process, we don't need the process metrics anymore.
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MetricsMap::iterator pm_iter = metrics_map_.find(process);
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pm_iter != metrics_map_.end());
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pm_iter != metrics_map_.end()) {
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete pm_iter->second;
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      metrics_map_.erase(process);
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
989f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Remove the entry from the model list.
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter = std::find(resources_.begin(), resources_.end(), resource);
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(iter != resources_.end());
992f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (iter != resources_.end()) {
993f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int index = static_cast<int>(iter - resources_.begin());
994f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Notify the observers that the contents will change.
995f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
996f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      OnItemsToBeRemoved(index, 1));
997f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Now actually remove the entry from the model list.
998f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    resources_.erase(iter);
999f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Notify the table that the contents have changed.
1000f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
1001f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      OnItemsRemoved(index, 1));
1002f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the entry from the network maps.
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceValueMap::iterator net_iter =
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_byte_count_map_.find(resource);
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (net_iter != current_byte_count_map_.end())
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_byte_count_map_.erase(net_iter);
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StartUpdating() {
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Multiple StartUpdating requests may come in, and we only need to take
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // action the first time.
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_requests_++;
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_requests_ > 1)
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(1, update_requests_);
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(TASK_PENDING, update_state_);
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If update_state_ is STOPPING, it means a task is still pending.  Setting
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it to TASK_PENDING ensures the tasks keep being posted (by Refresh()).
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_state_ == IDLE) {
102390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&TaskManagerModel::RefreshCallback, this));
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_state_ = TASK_PENDING;
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we are updating.
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartListening();
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!resources_.empty()) {
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      OnReadyPeriodicalUpdate());
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BrowserThread::PostTask(
10381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BrowserThread::IO, FROM_HERE,
10391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&TaskManagerModel::SetUpdatingByteCount, this, true));
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StopUpdating() {
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't actually stop updating until we have heard as many calls as those
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to StartUpdating.
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_requests_--;
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_requests_ > 0)
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure that update_requests_ cannot go negative.
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(0, update_requests_);
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(TASK_PENDING, update_state_);
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_state_ = STOPPING;
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we are done updating.
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopListening();
10551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BrowserThread::PostTask(
10571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BrowserThread::IO, FROM_HERE,
10581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&TaskManagerModel::SetUpdatingByteCount, this, false));
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StartListening() {
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Multiple StartListening requests may come in and we only need to take
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // action the first time.
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  listen_requests_++;
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (listen_requests_ > 1)
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(1, listen_requests_);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we should start listening to events.
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ResourceProviderList::iterator iter = providers_.begin();
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != providers_.end(); ++iter) {
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->StartUpdating();
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StopListening() {
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't actually stop listening until we have heard as many calls as those
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to StartListening.
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  listen_requests_--;
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (listen_requests_ > 0)
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0, listen_requests_);
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we are done listening.
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ResourceProviderList::const_iterator iter = providers_.begin();
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != providers_.end(); ++iter) {
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->StopUpdating();
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Must clear the resources before the next attempt to start listening.
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Clear();
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::Clear() {
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = ResourceCount();
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size > 0) {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources_.clear();
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the groups.
1101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    group_map_.clear();
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the process related info.
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STLDeleteValues(&metrics_map_);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the network maps.
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte_count_map_.clear();
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    per_resource_cache_.clear();
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    per_process_cache_.clear();
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnItemsRemoved(0, size));
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::ModelChanged() {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the table that the contents have changed for it to redraw.
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_, OnModelChanged());
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TaskManagerModel::Refresh() {
112358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  per_resource_cache_.clear();
112458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  per_process_cache_.clear();
112558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(DISABLE_NACL)
1127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance();
1128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // !defined(DISABLE_NACL)
1129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Compute the CPU usage values and check if NaCl GDB debug stub port is
1131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // known.
113258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Note that we compute the CPU usage for all resources (instead of doing it
113358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // lazily) as process_util::GetCPUUsage() returns the CPU usage since the last
113458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // time it was called, and not calling it everytime would skew the value the
113558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // next time it is retrieved (as it would be for more than 1 cycle).
11365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The same is true for idle wakeups.
113758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (ResourceList::iterator iter = resources_.begin();
113858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       iter != resources_.end(); ++iter) {
113958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::ProcessHandle process = (*iter)->GetProcess();
114058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PerProcessValues& values(per_process_cache_[process]);
1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(DISABLE_NACL)
1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Debug stub port doesn't change once known.
1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!values.is_nacl_debug_stub_port_valid) {
1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      values.nacl_debug_stub_port = nacl_browser->GetProcessGdbDebugStubPort(
1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          (*iter)->GetUniqueChildProcessId());
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (values.nacl_debug_stub_port != nacl::kGdbDebugStubPortUnknown) {
1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        values.is_nacl_debug_stub_port_valid = true;
1148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
1149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // !defined(DISABLE_NACL)
11515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (values.is_cpu_usage_valid && values.is_idle_wakeups_valid)
115258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
115358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    MetricsMap::iterator metrics_iter = metrics_map_.find(process);
115458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(metrics_iter != metrics_map_.end());
11555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!values.is_cpu_usage_valid) {
11565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      values.is_cpu_usage_valid = true;
11575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      values.cpu_usage = metrics_iter->second->GetCPUUsage();
11585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
11591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_MACOSX) || defined(OS_LINUX)
11601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(port): Implement GetIdleWakeupsPerSecond() on other platforms,
11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // crbug.com/120488
11625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!values.is_idle_wakeups_valid) {
11635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      values.is_idle_wakeups_valid = true;
11645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      values.idle_wakeups = metrics_iter->second->GetIdleWakeupsPerSecond();
11655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
11661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // defined(OS_MACOSX) || defined(OS_LINUX)
116758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
116858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
116958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Send a request to refresh GPU memory consumption values
117058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RefreshVideoMemoryUsageStats();
117158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
117258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Compute the new network usage values.
117358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta update_time =
117458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdateTimeMs);
117558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (ResourceValueMap::iterator iter = current_byte_count_map_.begin();
117658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       iter != current_byte_count_map_.end(); ++iter) {
117758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PerResourceValues* values = &(per_resource_cache_[iter->first]);
117858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (update_time > base::TimeDelta::FromSeconds(1))
117958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      values->network_usage = iter->second / update_time.InSeconds();
118058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    else
118158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      values->network_usage = iter->second * (1 / update_time.InSeconds());
118258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
118358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Then we reset the current byte count.
118458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    iter->second = 0;
118558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
118658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
118758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Let resources update themselves if they need to.
118858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (ResourceList::iterator iter = resources_.begin();
118958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       iter != resources_.end(); ++iter) {
119058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)     (*iter)->Refresh();
119158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
119258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
119358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!resources_.empty()) {
119458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
119558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      OnItemsChanged(0, ResourceCount()));
119658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
119758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
119858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyResourceTypeStats(
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessId renderer_id,
1201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebCache::ResourceTypeStats& stats) {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator it = resources_.begin();
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != resources_.end(); ++it) {
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*it)->NotifyResourceTypeStats(stats);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyVideoMemoryUsageStats(
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) {
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_video_memory_usage_stats_update_);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_memory_usage_stats_ = video_memory_usage_stats;
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_video_memory_usage_stats_update_ = false;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyV8HeapStats(base::ProcessId renderer_id,
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         size_t v8_memory_allocated,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         size_t v8_memory_used) {
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator it = resources_.begin();
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != resources_.end(); ++it) {
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*it)->NotifyV8HeapStats(v8_memory_allocated, v8_memory_used);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::NotifyBytesRead(const net::URLRequest& request,
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int byte_count) {
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
12311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!is_updating_byte_count_)
12321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only net::URLRequestJob instances created by the ResourceDispatcherHost
12355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // have an associated ResourceRequestInfo and a render frame associated.
12365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // All other jobs will have -1 returned for the render process child and
12375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // routing ids - the jobs may still match a resource based on their origin id,
12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // otherwise BytesRead() will attribute the activity to the Browser resource.
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
12405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int child_id = -1, route_id = -1;
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (info)
12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    info->GetAssociatedRenderFrame(&child_id, &route_id);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the origin PID of the request's originator.  This will only be set for
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // plugins - for renderer or browser initiated requests it will be zero.
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int origin_pid = 0;
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (info)
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    origin_pid = info->GetOriginPID();
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (bytes_read_buffer_.empty()) {
125190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&TaskManagerModel::NotifyMultipleBytesRead, this),
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromSeconds(1));
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bytes_read_buffer_.push_back(
12585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BytesReadParam(origin_pid, child_id, route_id, byte_count));
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This is called on the UI thread.
12623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TaskManagerModel::NotifyDataReady() {
12633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
12643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < on_data_ready_callbacks_.size(); ++i) {
12653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!on_data_ready_callbacks_[i].is_null())
12663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        on_data_ready_callbacks_[i].Run();
12673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
12683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  on_data_ready_callbacks_.clear();
12703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
12713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TaskManagerModel::RegisterOnDataReadyCallback(
12733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::Closure& callback) {
12743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  on_data_ready_callbacks_.push_back(callback);
12753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
12763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::~TaskManagerModel() {
12783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  on_data_ready_callbacks_.clear();
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::RefreshCallback() {
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(IDLE, update_state_);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_state_ == STOPPING) {
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have been asked to stop.
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    update_state_ = IDLE;
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Refresh();
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Schedule the next update.
129390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TaskManagerModel::RefreshCallback, this),
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdateTimeMs));
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::RefreshVideoMemoryUsageStats() {
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_video_memory_usage_stats_update_)
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!video_memory_usage_stats_observer_.get()) {
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    video_memory_usage_stats_observer_.reset(
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new TaskManagerModelGpuDataManagerObserver());
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_video_memory_usage_stats_update_ = true;
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::GpuDataManager::GetInstance()->RequestVideoMemoryUsageStatsUpdate();
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 TaskManagerModel::GetNetworkUsageForResource(Resource* resource) const {
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns default of 0 if no network usage.
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return per_resource_cache_[resource].network_usage;
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::BytesRead(BytesReadParam param) {
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_state_ != TASK_PENDING || listen_requests_ == 0) {
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A notification sneaked in while we were stopping the updating, just
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore it.
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jcampan): this should be improved once we have a better way of
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // linking a network notification back to the object that initiated it.
132590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = NULL;
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceProviderList::iterator iter = providers_.begin();
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != providers_.end(); ++iter) {
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = (*iter)->GetResource(param.origin_pid,
13295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    param.child_id,
13305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    param.route_id);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (resource)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resource == NULL) {
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can't match a resource to the notification.  That might mean the
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tab that started a download was closed, or the request may have had
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // no originating resource associated with it in the first place.
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We attribute orphaned/unaccounted activity to the Browser process.
13405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CHECK(param.origin_pid || (param.child_id != -1));
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    param.origin_pid = 0;
13425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    param.child_id = param.route_id = -1;
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BytesRead(param);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do support network usage, mark the resource as such so it can report 0
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead of N/A.
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resource->SupportNetworkUsage())
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource->SetSupportNetworkUsage();
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceValueMap::const_iterator iter_res =
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_byte_count_map_.find(resource);
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter_res == current_byte_count_map_.end())
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte_count_map_[resource] = param.byte_count;
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte_count_map_[resource] = iter_res->second + param.byte_count;
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::MultipleBytesRead(
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<BytesReadParam>* params) {
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<BytesReadParam>::const_iterator it = params->begin();
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != params->end(); ++it) {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BytesRead(*it);
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyMultipleBytesRead() {
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!bytes_read_buffer_.empty());
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<BytesReadParam>* bytes_read_buffer =
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new std::vector<BytesReadParam>;
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_read_buffer_.swap(*bytes_read_buffer);
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TaskManagerModel::MultipleBytesRead, this,
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(bytes_read_buffer)));
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TaskManagerModel::SetUpdatingByteCount(bool is_updating) {
13831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
13841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  is_updating_byte_count_ = is_updating;
13851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
13861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
138790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 TaskManagerModel::GetNetworkUsage(Resource* resource) const {
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 net_usage = GetNetworkUsageForResource(resource);
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (net_usage == 0 && !resource->SupportNetworkUsage())
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return -1;
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return net_usage;
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)double TaskManagerModel::GetCPUUsage(Resource* resource) const {
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const PerProcessValues& values(per_process_cache_[resource->GetProcess()]);
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns 0 if not valid, which is fine.
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.cpu_usage;
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int TaskManagerModel::GetIdleWakeupsPerSecond(Resource* resource) const {
14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const PerProcessValues& values(per_process_cache_[resource->GetProcess()]);
14025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns 0 if not valid, which is fine.
14035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return values.idle_wakeups;
14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 TaskManagerModel::GetMemCellText(int64 number) const {
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_MACOSX)
1408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 str = base::FormatNumber(number / 1024);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adjust number string if necessary.
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::i18n::AdjustStringForLocaleDirection(&str);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_MEM_CELL_TEXT, str);
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // System expectation is to show "100 kB", "200 MB", etc.
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(thakis): Switch to metric units (as opposed to powers of two).
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui::FormatBytes(number);
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CachePrivateAndSharedMemory(
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessHandle handle) const {
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (values.is_private_and_shared_valid)
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MetricsMap::const_iterator iter = metrics_map_.find(handle);
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == metrics_map_.end() ||
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !iter->second->GetMemoryBytes(&values.private_bytes,
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    &values.shared_bytes)) {
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  values.is_private_and_shared_valid = true;
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CacheWebCoreStats(int index) const {
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_webcore_stats_valid) {
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsCacheStats())
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_webcore_stats_valid = true;
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.webcore_stats = GetResource(index)->GetWebCoreCacheStats();
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CacheV8Memory(int index) const {
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_v8_memory_valid) {
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsV8MemoryStats())
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_v8_memory_valid = true;
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.v8_memory_allocated = GetResource(index)->GetV8MemoryAllocated();
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.v8_memory_used = GetResource(index)->GetV8MemoryUsed();
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TaskManagerModel::AddResourceProvider(ResourceProvider* provider) {
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(provider);
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  providers_.push_back(provider);
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerResourceValues& TaskManagerModel::GetPerResourceValues(
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index) const {
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return per_resource_cache_[GetResource(index)];
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Resource* TaskManagerModel::GetResource(int index) const {
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_GE(index, 0);
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_LT(index, static_cast<int>(resources_.size()));
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return resources_[index];
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TaskManager class
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManager::RegisterPrefs(PrefRegistrySimple* registry) {
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(prefs::kTaskManagerWindowPlacement);
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManager::IsBrowserProcess(int index) const {
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If some of the selection is out of bounds, ignore. This may happen when
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // killing a process that manages several pages.
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return index < model_->ResourceCount() &&
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model_->GetProcess(index) == base::GetCurrentProcessHandle();
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::KillProcess(int index) {
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle process = model_->GetProcess(index);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(process);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (process != base::GetCurrentProcessHandle())
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::KillProcess(process, content::RESULT_CODE_KILLED, false);
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::ActivateProcess(int index) {
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetResourceWebContents returns a pointer to the relevant web contents for
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the resource.  If the index doesn't correspond to any web contents
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (i.e. refers to the Browser process or a plugin), GetWebContents will
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return NULL.
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* chosen_web_contents = model_->GetResourceWebContents(index);
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chosen_web_contents && chosen_web_contents->GetDelegate())
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chosen_web_contents->GetDelegate()->ActivateContents(chosen_web_contents);
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::AddResource(Resource* resource) {
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->AddResource(resource);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::RemoveResource(Resource* resource) {
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->RemoveResource(resource);
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::OnWindowClosed() {
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->StopUpdating();
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::ModelChanged() {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->ModelChanged();
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManager* TaskManager::GetInstance() {
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Singleton<TaskManager>::get();
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManager::OpenAboutMemory(chrome::HostDesktopType desktop_type) {
15300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  chrome::NavigateParams params(
15310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      ProfileManager::GetLastUsedProfileAllowedByPolicy(),
15320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      GURL(chrome::kChromeUIMemoryURL),
15331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::PAGE_TRANSITION_LINK);
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.disposition = NEW_FOREGROUND_TAB;
15350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  params.host_desktop_type = desktop_type;
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Navigate(&params);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManager::TaskManager()
1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : model_(new TaskManagerModel(this)) {
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManager::~TaskManager() {
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1545