task_manager.cc revision 3551c9c881056c480085172ff9840cab31610854
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/rand_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_process_manager.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/background_resource_provider.h"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/browser_process_resource_provider.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/child_process_resource_provider.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/extension_process_resource_provider.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/guest_resource_provider.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/notification_resource_provider.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/panel_resource_provider.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/resource_provider.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/tab_contents_resource_provider.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/task_manager/worker_resource_provider.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/gpu_data_manager.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/gpu_data_manager_observer.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/result_codes.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h"
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/coll.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/text/bytes_formatting.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.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;
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class Profile;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ValueCompare(T value1, T value2) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value1 < value2)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value1 == value2)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used when one or both of the results to compare are unavailable.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int OrderUnavailableValue(bool v1, bool v2) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!v1 && !v2)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return v1 ? 1 : -1;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by TaskManagerModel::CompareValues(). See it for details of return
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// value.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class T>
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ValueCompareMember(const TaskManagerModel* model,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       bool (TaskManagerModel::*f)(int, T*) const,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       int row1,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       int row2) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  T value1;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  T value2;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool value1_valid = (model->*f)(row1, &value1);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool value2_valid = (model->*f)(row2, &value2);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return value1_valid && value2_valid ? ValueCompare(value1, value2) :
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OrderUnavailableValue(value1_valid, value2_valid);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 FormatStatsSize(const WebKit::WebCache::ResourceTypeStat& stat) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::FormatBytesWithUnits(stat.size, ui::DATA_UNITS_KIBIBYTE, false),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::FormatBytesWithUnits(stat.liveSize, ui::DATA_UNITS_KIBIBYTE, false));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if the specified id should use the first value in the group.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsSharedByGroup(int col_id) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (col_id) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
110a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN)
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GetWinGDIHandles(base::ProcessHandle process,
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      size_t* current,
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      size_t* peak) {
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *current = 0;
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *peak = 0;
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get a handle to |process| that has PROCESS_QUERY_INFORMATION rights.
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE current_process = GetCurrentProcess();
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE process_with_query_rights;
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (DuplicateHandle(current_process, process, current_process,
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      &process_with_query_rights, PROCESS_QUERY_INFORMATION,
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      false, 0)) {
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *current = GetGuiResources(process_with_query_rights, GR_GDIOBJECTS);
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *peak = GetGuiResources(process_with_query_rights, GR_GDIOBJECTS_PEAK);
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CloseHandle(process_with_query_rights);
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GetWinUSERHandles(base::ProcessHandle process,
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       size_t* current,
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       size_t* peak) {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *current = 0;
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *peak = 0;
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get a handle to |process| that has PROCESS_QUERY_INFORMATION rights.
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE current_process = GetCurrentProcess();
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HANDLE process_with_query_rights;
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (DuplicateHandle(current_process, process, current_process,
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      &process_with_query_rights, PROCESS_QUERY_INFORMATION,
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      false, 0)) {
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *current = GetGuiResources(process_with_query_rights, GR_USEROBJECTS);
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *peak = GetGuiResources(process_with_query_rights, GR_USEROBJECTS_PEAK);
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CloseHandle(process_with_query_rights);
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Counts the number of extension background pages associated with this profile.
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int CountExtensionBackgroundPagesForProfile(Profile* profile) {
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int count = 0;
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ExtensionProcessManager* manager =
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile)->process_manager();
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!manager)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return count;
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const ExtensionProcessManager::ExtensionHostSet& background_hosts =
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      manager->background_hosts();
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (ExtensionProcessManager::const_iterator iter = background_hosts.begin();
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       iter != background_hosts.end(); ++iter) {
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++count;
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return count;
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TaskManagerModelGpuDataManagerObserver
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public content::GpuDataManagerObserver {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TaskManagerModelGpuDataManagerObserver() {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::GpuDataManager::GetInstance()->AddObserver(this);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TaskManagerModelGpuDataManagerObserver() {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::GpuDataManager::GetInstance()->RemoveObserver(this);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void NotifyVideoMemoryUsageStats(
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TaskManager::GetInstance()->model()->NotifyVideoMemoryUsageStats(
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        video_memory_usage_stats);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnVideoMemoryUsageStatsUpdate(
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const content::GPUVideoMemoryUsageStats& video_memory_usage_stats)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          OVERRIDE {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NotifyVideoMemoryUsageStats(video_memory_usage_stats);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::PostTask(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          BrowserThread::UI, FROM_HERE, base::Bind(
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              &TaskManagerModelGpuDataManagerObserver::
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  NotifyVideoMemoryUsageStats,
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              video_memory_usage_stats));
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerResourceValues::PerResourceValues()
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : is_title_valid(false),
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_profile_name_valid(false),
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      network_usage(0),
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_process_id_valid(false),
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process_id(0),
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_goats_teleported_valid(false),
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      goats_teleported(0),
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_webcore_stats_valid(false),
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_fps_valid(false),
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fps(0),
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_sqlite_memory_bytes_valid(false),
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sqlite_memory_bytes(0),
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_v8_memory_valid(false),
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8_memory_allocated(0),
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8_memory_used(0) {
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerResourceValues::~PerResourceValues() {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerProcessValues::PerProcessValues()
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : is_cpu_usage_valid(false),
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cpu_usage(0),
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_private_and_shared_valid(false),
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      private_bytes(0),
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shared_bytes(0),
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_physical_memory_valid(false),
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      physical_memory(0),
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_video_memory_valid(false),
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      video_memory(0),
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      video_memory_has_duplicates(false),
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_gdi_handles_valid(false),
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gdi_handles(0),
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gdi_handles_peak(0),
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_user_handles_valid(0),
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_handles(0),
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_handles_peak(0) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerProcessValues::~PerProcessValues() {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TaskManagerModel class
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerModel::TaskManagerModel(TaskManager* task_manager)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : pending_video_memory_usage_stats_update_(false),
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      update_requests_(0),
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listen_requests_(0),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      update_state_(IDLE),
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      goat_salt_(base::RandUint64()),
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_unique_id_(0) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::BrowserProcessResourceProvider(task_manager));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::BackgroundContentsResourceProvider(task_manager));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::TabContentsResourceProvider(task_manager));
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AddResourceProvider(new task_manager::PanelResourceProvider(task_manager));
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::ChildProcessResourceProvider(task_manager));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddResourceProvider(
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new task_manager::ExtensionProcessResourceProvider(task_manager));
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AddResourceProvider(new task_manager::GuestResourceProvider(task_manager));
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_NOTIFICATIONS)
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ResourceProvider* provider =
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      task_manager::NotificationResourceProvider::Create(task_manager);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddResourceProvider(provider);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AddResourceProvider(new task_manager::WorkerResourceProvider(task_manager));
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::AddObserver(TaskManagerModelObserver* observer) {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.AddObserver(observer);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::RemoveObserver(TaskManagerModelObserver* observer) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.RemoveObserver(observer);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::ResourceCount() const {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return resources_.size();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GroupCount() const {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return group_map_.size();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int64 TaskManagerModel::GetNetworkUsage(int index) const {
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetNetworkUsage(GetResource(index));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)double TaskManagerModel::GetCPUUsage(int index) const {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetCPUUsage(GetResource(index));
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ProcessId TaskManagerModel::GetProcessId(int index) const {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_process_id_valid) {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_process_id_valid = true;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.process_id = base::GetProcId(GetResource(index)->GetProcess());
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.process_id;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ProcessHandle TaskManagerModel::GetProcess(int index) const {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetProcess();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GetResourceUniqueId(int index) const {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->get_unique_id();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GetResourceIndexByUniqueId(const int unique_id) const {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int resource_index = 0; resource_index < ResourceCount();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++resource_index) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GetResourceUniqueId(resource_index) == unique_id)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return resource_index;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 TaskManagerModel::GetResourceById(int index, int col_id) const {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSharedByGroup(col_id) && !IsResourceFirstInGroup(index))
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return string16();
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (col_id) {
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_TASK_COLUMN:
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceTitle(index);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceProfileName(index);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_NET_COLUMN:
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceNetworkUsage(index);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceCPUUsage(index);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourcePrivateMemory(index);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceSharedMemory(index);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourcePhysicalMemory(index);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceProcessId(index);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN:
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceGDIHandles(index);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_USER_HANDLES_COLUMN:
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceUSERHandles(index);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN:
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceGoatsTeleported(index);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceWebCoreImageCacheSize(index);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceWebCoreScriptsCacheSize(index);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceWebCoreCSSCacheSize(index);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_FPS_COLUMN:
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceFPS(index);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceVideoMemory(index);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceSqliteMemoryUsed(index);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetResourceV8MemoryAllocatedSize(index);
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return string16();
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const string16& TaskManagerModel::GetResourceTitle(int index) const {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values = GetPerResourceValues(index);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_title_valid) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_title_valid = true;
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.title = GetResource(index)->GetTitle();
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.title;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const string16& TaskManagerModel::GetResourceProfileName(int index) const {
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_profile_name_valid) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_profile_name_valid = true;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.profile_name = GetResource(index)->GetProfileName();
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.profile_name;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceNetworkUsage(int index) const {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 net_usage = GetNetworkUsage(index);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (net_usage == -1)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (net_usage == 0)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ASCIIToUTF16("0");
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 net_byte = ui::FormatSpeed(net_usage);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force number string to have LTR directionality.
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::i18n::GetDisplayStringInLTRDirectionality(net_byte);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceCPUUsage(int index) const {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return UTF8ToUTF16(base::StringPrintf(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Activity Monitor shows %cpu with one decimal digit -- be
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // consistent with that.
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "%.1f",
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "%.0f",
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetCPUUsage(GetResource(index))));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourcePrivateMemory(int index) const {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t private_mem;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetPrivateMemory(index, &private_mem))
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ASCIIToUTF16("N/A");
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMemCellText(private_mem);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceSharedMemory(int index) const {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t shared_mem;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetSharedMemory(index, &shared_mem))
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ASCIIToUTF16("N/A");
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMemCellText(shared_mem);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourcePhysicalMemory(int index) const {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t phys_mem;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetPhysicalMemory(index, &phys_mem);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMemCellText(phys_mem);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceProcessId(int index) const {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::IntToString16(GetProcessId(index));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 TaskManagerModel::GetResourceGDIHandles(int index) const {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t current, peak;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetGDIHandles(index, &current, &peak);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::IntToString16(current), base::IntToString16(peak));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 TaskManagerModel::GetResourceUSERHandles(int index) const {
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t current, peak;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetUSERHandles(index, &current, &peak);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::IntToString16(current), base::IntToString16(peak));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceWebCoreImageCacheSize(
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FormatStatsSize(GetPerResourceValues(index).webcore_stats.images);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FormatStatsSize(GetPerResourceValues(index).webcore_stats.scripts);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FormatStatsSize(
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetPerResourceValues(index).webcore_stats.cssStyleSheets);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceVideoMemory(int index) const {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t video_memory;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_duplicates;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetVideoMemory(index, &video_memory, &has_duplicates) || !video_memory)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ASCIIToUTF16("N/A");
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_duplicates) {
507a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return GetMemCellText(video_memory) + ASCIIToUTF16("*");
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetMemCellText(video_memory);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceFPS(
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float fps = 0;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetFPS(index, &fps))
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return UTF8ToUTF16(base::StringPrintf("%.0f", fps));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceSqliteMemoryUsed(int index) const {
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t bytes = 0;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetSqliteMemoryUsedBytes(index, &bytes))
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetMemCellText(bytes);
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 TaskManagerModel::GetResourceGoatsTeleported(int index) const {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_LT(index, ResourceCount());
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FormatNumber(GetGoatsTeleported(index));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerModel::GetResourceV8MemoryAllocatedSize(
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) const {
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t memory_allocated = 0, memory_used = 0;
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetV8MemoryUsed(index, &memory_used) ||
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !GetV8Memory(index, &memory_allocated))
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::FormatBytesWithUnits(memory_allocated,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::DATA_UNITS_KIBIBYTE,
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false),
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::FormatBytesWithUnits(memory_used,
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::DATA_UNITS_KIBIBYTE,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetPrivateMemory(int index, size_t* result) const {
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CachePrivateAndSharedMemory(handle))
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = per_process_cache_[handle].private_bytes;
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetSharedMemory(int index, size_t* result) const {
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CachePrivateAndSharedMemory(handle))
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = per_process_cache_[handle].shared_bytes;
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetPhysicalMemory(int index, size_t* result) const {
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_physical_memory_valid) {
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WorkingSetKBytes ws_usage;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MetricsMap::const_iterator iter = metrics_map_.find(handle);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter == metrics_map_.end() ||
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !iter->second->GetWorkingSetKBytes(&ws_usage))
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    values.is_physical_memory_valid = true;
579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_LINUX)
580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // On Linux private memory is also resident. Just use it.
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    values.physical_memory = ws_usage.priv * 1024;
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Memory = working_set.private + working_set.shareable.
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We exclude the shared memory.
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.physical_memory = iter->second->GetWorkingSetSize();
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.physical_memory -= ws_usage.shared * 1024;
587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = values.physical_memory;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::GetGDIHandles(int index,
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     size_t* current,
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     size_t* peak) const {
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = 0;
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = 0;
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_gdi_handles_valid) {
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetWinGDIHandles(GetResource(index)->GetProcess(),
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &values.gdi_handles,
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &values.gdi_handles_peak);
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_gdi_handles_valid = true;
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = values.gdi_handles;
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = values.gdi_handles_peak;
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::GetUSERHandles(int index,
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      size_t* current,
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      size_t* peak) const {
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = 0;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = 0;
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle handle = GetResource(index)->GetProcess();
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_user_handles_valid) {
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetWinUSERHandles(GetResource(index)->GetProcess(),
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      &values.user_handles,
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      &values.user_handles_peak);
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_user_handles_valid = true;
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *current = values.user_handles;
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *peak = values.user_handles_peak;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetWebCoreCacheStats(
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index,
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebKit::WebCache::ResourceTypeStats* result) const {
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheWebCoreStats(index))
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = GetPerResourceValues(index).webcore_stats;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetVideoMemory(int index,
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      size_t* video_memory,
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bool* has_duplicates) const {
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *video_memory = 0;
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *has_duplicates = false;
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessId pid = GetProcessId(index);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      per_process_cache_[GetResource(index)->GetProcess()]);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_video_memory_valid) {
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::GPUVideoMemoryUsageStats::ProcessMap::const_iterator i =
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        video_memory_usage_stats_.process_map.find(pid);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == video_memory_usage_stats_.process_map.end())
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_video_memory_valid = true;
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.video_memory = i->second.video_memory;
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.video_memory_has_duplicates = i->second.has_duplicates;
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *video_memory = values.video_memory;
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *has_duplicates = values.video_memory_has_duplicates;
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetFPS(int index, float* result) const {
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_fps_valid) {
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsFPS())
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_fps_valid = true;
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.fps = GetResource(index)->GetFPS();
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = values.fps;
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetSqliteMemoryUsedBytes(
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index,
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t* result) const {
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_sqlite_memory_bytes_valid) {
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsSqliteMemoryUsed())
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_sqlite_memory_bytes_valid = true;
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.sqlite_memory_bytes = GetResource(index)->SqliteMemoryUsedBytes();
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = values.sqlite_memory_bytes;
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetV8Memory(int index, size_t* result) const {
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheV8Memory(index))
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = GetPerResourceValues(index).v8_memory_allocated;
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::GetV8MemoryUsed(int index, size_t* result) const {
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = 0;
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CacheV8Memory(index))
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = GetPerResourceValues(index).v8_memory_used;
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CanActivate(int index) const {
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_LT(index, ResourceCount());
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResourceWebContents(index) != NULL;
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CanInspect(int index) const {
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->CanInspect();
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::Inspect(int index) const {
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_LT(index, ResourceCount());
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetResource(index)->Inspect();
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int TaskManagerModel::GetGoatsTeleported(int index) const {
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_goats_teleported_valid) {
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_goats_teleported_valid = true;
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.goats_teleported = goat_salt_ * (index + 1);
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.goats_teleported = (values.goats_teleported >> 16) & 255;
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.goats_teleported;
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::IsResourceFirstInGroup(int index) const {
73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = GetResource(index);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(iter != group_map_.end());
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ResourceList* group = iter->second;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ((*group)[0] == resource);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerModel::IsResourceLastInGroup(int index) const {
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = GetResource(index);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(iter != group_map_.end());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ResourceList* group = iter->second;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (group->back() == resource);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerModel::IsBackgroundResource(int index) const {
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->IsBackground();
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia TaskManagerModel::GetResourceIcon(int index) const {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia icon = GetResource(index)->GetIcon();
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!icon.isNull())
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gfx::ImageSkia* default_icon = ResourceBundle::GetSharedInstance().
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *default_icon;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerModel::GroupRange
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerModel::GetGroupRangeForResource(int index) const {
76590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = GetResource(index);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator group_iter =
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_map_.find(resource->GetProcess());
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(group_iter != group_map_.end());
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceList* group = group_iter->second;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(group);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (group->size() == 1) {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::make_pair(index, 1);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = index; i >= 0; --i) {
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (GetResource(i) == (*group)[0])
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return std::make_pair(i, group->size());
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::make_pair(-1, -1);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GetGroupIndexForResource(int index) const {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int group_index = -1;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i <= index; ++i) {
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsResourceFirstInGroup(i))
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        group_index++;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(group_index, -1);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return group_index;
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::GetResourceIndexForGroup(int group_index,
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int index_in_group) const {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int group_count = -1;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count_in_group = -1;
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < ResourceCount(); ++i) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsResourceFirstInGroup(i))
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_count++;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (group_count == group_index) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count_in_group++;
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (count_in_group == index_in_group)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return i;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (group_count > group_index) {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(row1 < ResourceCount() && row2 < ResourceCount());
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (col_id) {
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_TASK_COLUMN: {
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static icu::Collator* collator = NULL;
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!collator) {
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UErrorCode create_status = U_ZERO_ERROR;
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        collator = icu::Collator::createInstance(create_status);
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (!U_SUCCESS(create_status)) {
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          collator = NULL;
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          NOTREACHED();
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const string16& title1 = GetResourceTitle(row1);
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const string16& title2 = GetResourceTitle(row2);
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UErrorCode compare_status = U_ZERO_ERROR;
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UCollationResult compare_result = collator->compare(
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<const UChar*>(title1.c_str()),
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(title1.length()),
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<const UChar*>(title2.c_str()),
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(title2.length()),
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          compare_status);
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(U_SUCCESS(compare_status));
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return compare_result;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN: {
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const string16& profile1 = GetResourceProfileName(row1);
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const string16& profile2 = GetResourceProfileName(row2);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return profile1.compare(0, profile1.length(), profile2, 0,
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              profile2.length());
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_NET_COLUMN:
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetNetworkUsage(GetResource(row1)),
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          GetNetworkUsage(GetResource(row2)));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetCPUUsage(GetResource(row1)),
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          GetCPUUsage(GetResource(row2)));
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetPrivateMemory, row1, row2);
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetSharedMemory, row1, row2);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetPhysicalMemory, row1, row2);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetProcessId(row1), GetProcessId(row2));
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN: {
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current1, peak1;
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current2, peak2;
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetGDIHandles(row1, &current1, &peak1);
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetGDIHandles(row2, &current2, &peak2);
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(current1, current2);
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_USER_HANDLES_COLUMN: {
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current1, peak1;
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t current2, peak2;
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUSERHandles(row1, &current1, &peak1);
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUSERHandles(row2, &current2, &peak2);
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(current1, current2);
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: {
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool row1_stats_valid = CacheWebCoreStats(row1);
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool row2_stats_valid = CacheWebCoreStats(row2);
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (row1_stats_valid && row2_stats_valid) {
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const WebKit::WebCache::ResourceTypeStats& stats1(
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetPerResourceValues(row1).webcore_stats);
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const WebKit::WebCache::ResourceTypeStats& stats2(
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetPerResourceValues(row2).webcore_stats);
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switch (col_id) {
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return ValueCompare(stats1.images.size, stats2.images.size);
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return ValueCompare(stats1.scripts.size, stats2.scripts.size);
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return ValueCompare(stats1.cssStyleSheets.size,
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                stats2.cssStyleSheets.size);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default:
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            NOTREACHED();
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return 0;
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return OrderUnavailableValue(row1_stats_valid, row2_stats_valid);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_FPS_COLUMN:
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetFPS, row1, row2);
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: {
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t value1;
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t value2;
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool has_duplicates;
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool value1_valid = GetVideoMemory(row1, &value1, &has_duplicates);
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool value2_valid = GetVideoMemory(row2, &value2, &has_duplicates);
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return value1_valid && value2_valid ? ValueCompare(value1, value2) :
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          OrderUnavailableValue(value1_valid, value2_valid);
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN:
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompare(GetGoatsTeleported(row1), GetGoatsTeleported(row2));
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetV8Memory, row1, row2);
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueCompareMember(
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &TaskManagerModel::GetSqliteMemoryUsedBytes, row1, row2);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int TaskManagerModel::GetUniqueChildProcessId(int index) const {
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetUniqueChildProcessId();
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Resource::Type TaskManagerModel::GetResourceType(int index) const {
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetType();
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* TaskManagerModel::GetResourceWebContents(int index) const {
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetWebContents();
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const extensions::Extension* TaskManagerModel::GetResourceExtension(
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index) const {
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetResource(index)->GetExtension();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TaskManagerModel::AddResource(Resource* resource) {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource->unique_id_ = ++last_unique_id_;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process = resource->GetProcess();
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceList* group_entries = NULL;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::const_iterator group_iter = group_map_.find(process);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_entry_index = 0;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (group_iter == group_map_.end()) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_entries = new ResourceList();
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_map_[process] = group_entries;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_entries->push_back(resource);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not part of a group, just put at the end of the list.
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources_.push_back(resource);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_entry_index = static_cast<int>(resources_.size() - 1);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_entries = group_iter->second;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_entries->push_back(resource);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Insert the new entry right after the last entry of its group.
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResourceList::iterator iter =
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::find(resources_.begin(),
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  resources_.end(),
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  (*group_entries)[group_entries->size() - 2]);
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(iter != resources_.end());
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_entry_index = static_cast<int>(iter - resources_.begin()) + 1;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources_.insert(++iter, resource);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the ProcessMetrics for this process if needed (not in map).
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (metrics_map_.find(process) == metrics_map_.end()) {
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessMetrics* pm =
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::ProcessMetrics::CreateProcessMetrics(process);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::ProcessMetrics::CreateProcessMetrics(
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            process, content::BrowserChildProcessHost::GetPortProvider());
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    metrics_map_[process] = pm;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the table that the contents have changed for it to redraw.
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnItemsAdded(new_entry_index, 1));
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TaskManagerModel::RemoveResource(Resource* resource) {
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process = resource->GetProcess();
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the associated group.
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GroupMap::iterator group_iter = group_map_.find(process);
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(group_iter != group_map_.end());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceList* group_entries = group_iter->second;
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the entry from the group map.
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceList::iterator iter = std::find(group_entries->begin(),
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          group_entries->end(),
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          resource);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(iter != group_entries->end());
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  group_entries->erase(iter);
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there are no more entries for that process, do the clean-up.
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (group_entries->empty()) {
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete group_entries;
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group_map_.erase(process);
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Nobody is using this process, we don't need the process metrics anymore.
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MetricsMap::iterator pm_iter = metrics_map_.find(process);
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pm_iter != metrics_map_.end());
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pm_iter != metrics_map_.end()) {
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete pm_iter->second;
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      metrics_map_.erase(process);
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prepare to remove the entry from the model list.
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter = std::find(resources_.begin(), resources_.end(), resource);
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(iter != resources_.end());
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = static_cast<int>(iter - resources_.begin());
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the observers that the contents will change.
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnItemsToBeRemoved(index, 1));
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now actually remove the entry from the model list.
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resources_.erase(iter);
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the entry from the network maps.
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceValueMap::iterator net_iter =
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_byte_count_map_.find(resource);
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (net_iter != current_byte_count_map_.end())
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_byte_count_map_.erase(net_iter);
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the table that the contents have changed.
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnItemsRemoved(index, 1));
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StartUpdating() {
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Multiple StartUpdating requests may come in, and we only need to take
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // action the first time.
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_requests_++;
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_requests_ > 1)
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(1, update_requests_);
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(TASK_PENDING, update_state_);
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If update_state_ is STOPPING, it means a task is still pending.  Setting
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it to TASK_PENDING ensures the tasks keep being posted (by Refresh()).
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_state_ == IDLE) {
107490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&TaskManagerModel::RefreshCallback, this));
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_state_ = TASK_PENDING;
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we are updating.
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartListening();
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!resources_.empty()) {
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      OnReadyPeriodicalUpdate());
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StopUpdating() {
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't actually stop updating until we have heard as many calls as those
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to StartUpdating.
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_requests_--;
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_requests_ > 0)
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure that update_requests_ cannot go negative.
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(0, update_requests_);
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(TASK_PENDING, update_state_);
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  update_state_ = STOPPING;
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we are done updating.
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopListening();
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StartListening() {
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Multiple StartListening requests may come in and we only need to take
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // action the first time.
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  listen_requests_++;
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (listen_requests_ > 1)
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(1, listen_requests_);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we should start listening to events.
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ResourceProviderList::iterator iter = providers_.begin();
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != providers_.end(); ++iter) {
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->StartUpdating();
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::StopListening() {
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't actually stop listening until we have heard as many calls as those
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to StartListening.
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  listen_requests_--;
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (listen_requests_ > 0)
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0, listen_requests_);
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify resource providers that we are done listening.
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ResourceProviderList::const_iterator iter = providers_.begin();
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != providers_.end(); ++iter) {
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->StopUpdating();
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Must clear the resources before the next attempt to start listening.
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Clear();
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::Clear() {
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = ResourceCount();
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size > 0) {
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources_.clear();
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the groups.
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STLDeleteValues(&group_map_);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the process related info.
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STLDeleteValues(&metrics_map_);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the network maps.
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte_count_map_.clear();
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    per_resource_cache_.clear();
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    per_process_cache_.clear();
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnItemsRemoved(0, size));
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_unique_id_ = 0;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::ModelChanged() {
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the table that the contents have changed for it to redraw.
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_, OnModelChanged());
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyResourceTypeStats(
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessId renderer_id,
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebCache::ResourceTypeStats& stats) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator it = resources_.begin();
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != resources_.end(); ++it) {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*it)->NotifyResourceTypeStats(stats);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyFPS(base::ProcessId renderer_id,
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int routing_id,
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 float fps) {
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator it = resources_.begin();
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != resources_.end(); ++it) {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::GetProcId((*it)->GetProcess()) == renderer_id &&
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*it)->GetRoutingID() == routing_id) {
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*it)->NotifyFPS(fps);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyVideoMemoryUsageStats(
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) {
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_video_memory_usage_stats_update_);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_memory_usage_stats_ = video_memory_usage_stats;
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_video_memory_usage_stats_update_ = false;
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyV8HeapStats(base::ProcessId renderer_id,
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         size_t v8_memory_allocated,
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         size_t v8_memory_used) {
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator it = resources_.begin();
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != resources_.end(); ++it) {
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*it)->NotifyV8HeapStats(v8_memory_allocated, v8_memory_used);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::NotifyBytesRead(const net::URLRequest& request,
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int byte_count) {
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only net::URLRequestJob instances created by the ResourceDispatcherHost
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have an associated ResourceRequestInfo.
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have a render view associated.  All other jobs will have -1 returned for
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the render process child and routing ids - the jobs may still match a
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resource based on their origin id, otherwise BytesRead() will attribute
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the activity to the Browser resource.
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int render_process_host_child_id = -1, routing_id = -1;
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (info)
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->GetAssociatedRenderView(&render_process_host_child_id, &routing_id);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the origin PID of the request's originator.  This will only be set for
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // plugins - for renderer or browser initiated requests it will be zero.
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int origin_pid = 0;
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (info)
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    origin_pid = info->GetOriginPID();
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (bytes_read_buffer_.empty()) {
123090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&TaskManagerModel::NotifyMultipleBytesRead, this),
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromSeconds(1));
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bytes_read_buffer_.push_back(
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BytesReadParam(origin_pid, render_process_host_child_id,
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     routing_id, byte_count));
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This is called on the UI thread.
12423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TaskManagerModel::NotifyDataReady() {
12433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
12443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < on_data_ready_callbacks_.size(); ++i) {
12453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!on_data_ready_callbacks_[i].is_null())
12463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        on_data_ready_callbacks_[i].Run();
12473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
12483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  on_data_ready_callbacks_.clear();
12503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
12513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TaskManagerModel::RegisterOnDataReadyCallback(
12533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::Closure& callback) {
12543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  on_data_ready_callbacks_.push_back(callback);
12553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
12563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::~TaskManagerModel() {
12583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  on_data_ready_callbacks_.clear();
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::RefreshCallback() {
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(IDLE, update_state_);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_state_ == STOPPING) {
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have been asked to stop.
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    update_state_ = IDLE;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Refresh();
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Schedule the next update.
127390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TaskManagerModel::RefreshCallback, this),
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdateTimeMs));
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::Refresh() {
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  goat_salt_ = base::RandUint64();
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  per_resource_cache_.clear();
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  per_process_cache_.clear();
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compute the CPU usage values.
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we compute the CPU usage for all resources (instead of doing it
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // lazily) as process_util::GetCPUUsage() returns the CPU usage since the last
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time it was called, and not calling it everytime would skew the value the
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // next time it is retrieved (as it would be for more than 1 cycle).
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator iter = resources_.begin();
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != resources_.end(); ++iter) {
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessHandle process = (*iter)->GetProcess();
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PerProcessValues& values(per_process_cache_[process]);
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (values.is_cpu_usage_valid)
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_cpu_usage_valid = true;
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MetricsMap::iterator metrics_iter = metrics_map_.find(process);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(metrics_iter != metrics_map_.end());
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.cpu_usage = metrics_iter->second->GetCPUUsage();
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send a request to refresh GPU memory consumption values
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RefreshVideoMemoryUsageStats();
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compute the new network usage values.
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta update_time =
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdateTimeMs);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceValueMap::iterator iter = current_byte_count_map_.begin();
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != current_byte_count_map_.end(); ++iter) {
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PerResourceValues* values = &(per_resource_cache_[iter->first]);
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_time > base::TimeDelta::FromSeconds(1))
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      values->network_usage = iter->second / update_time.InSeconds();
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      values->network_usage = iter->second * (1 / update_time.InSeconds());
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Then we reset the current byte count.
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second = 0;
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let resources update themselves if they need to.
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceList::iterator iter = resources_.begin();
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != resources_.end(); ++iter) {
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (*iter)->Refresh();
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resources_.empty()) {
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnItemsChanged(0, ResourceCount()));
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManagerModel::RefreshVideoMemoryUsageStats() {
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_video_memory_usage_stats_update_)
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!video_memory_usage_stats_observer_.get()) {
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    video_memory_usage_stats_observer_.reset(
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new TaskManagerModelGpuDataManagerObserver());
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_video_memory_usage_stats_update_ = true;
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::GpuDataManager::GetInstance()->RequestVideoMemoryUsageStatsUpdate();
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
134590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 TaskManagerModel::GetNetworkUsageForResource(Resource* resource) const {
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns default of 0 if no network usage.
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return per_resource_cache_[resource].network_usage;
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::BytesRead(BytesReadParam param) {
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_state_ != TASK_PENDING || listen_requests_ == 0) {
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A notification sneaked in while we were stopping the updating, just
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore it.
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jcampan): this should be improved once we have a better way of
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // linking a network notification back to the object that initiated it.
135990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Resource* resource = NULL;
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ResourceProviderList::iterator iter = providers_.begin();
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != providers_.end(); ++iter) {
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = (*iter)->GetResource(param.origin_pid,
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    param.render_process_host_child_id,
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    param.routing_id);
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (resource)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resource == NULL) {
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can't match a resource to the notification.  That might mean the
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tab that started a download was closed, or the request may have had
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // no originating resource associated with it in the first place.
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We attribute orphaned/unaccounted activity to the Browser process.
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(param.origin_pid || (param.render_process_host_child_id != -1));
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    param.origin_pid = 0;
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    param.render_process_host_child_id = param.routing_id = -1;
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BytesRead(param);
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do support network usage, mark the resource as such so it can report 0
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead of N/A.
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resource->SupportNetworkUsage())
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource->SetSupportNetworkUsage();
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceValueMap::const_iterator iter_res =
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_byte_count_map_.find(resource);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter_res == current_byte_count_map_.end())
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte_count_map_[resource] = param.byte_count;
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte_count_map_[resource] = iter_res->second + param.byte_count;
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::MultipleBytesRead(
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<BytesReadParam>* params) {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<BytesReadParam>::const_iterator it = params->begin();
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != params->end(); ++it) {
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BytesRead(*it);
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerModel::NotifyMultipleBytesRead() {
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!bytes_read_buffer_.empty());
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<BytesReadParam>* bytes_read_buffer =
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new std::vector<BytesReadParam>;
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_read_buffer_.swap(*bytes_read_buffer);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TaskManagerModel::MultipleBytesRead, this,
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(bytes_read_buffer)));
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 TaskManagerModel::GetNetworkUsage(Resource* resource) const {
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 net_usage = GetNetworkUsageForResource(resource);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (net_usage == 0 && !resource->SupportNetworkUsage())
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return -1;
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return net_usage;
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)double TaskManagerModel::GetCPUUsage(Resource* resource) const {
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const PerProcessValues& values(per_process_cache_[resource->GetProcess()]);
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns 0 if not valid, which is fine.
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return values.cpu_usage;
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 TaskManagerModel::GetMemCellText(int64 number) const {
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_MACOSX)
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 str = base::FormatNumber(number / 1024);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adjust number string if necessary.
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::i18n::AdjustStringForLocaleDirection(&str);
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_MEM_CELL_TEXT, str);
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // System expectation is to show "100 kB", "200 MB", etc.
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(thakis): Switch to metric units (as opposed to powers of two).
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui::FormatBytes(number);
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CachePrivateAndSharedMemory(
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessHandle handle) const {
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerProcessValues& values(per_process_cache_[handle]);
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (values.is_private_and_shared_valid)
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MetricsMap::const_iterator iter = metrics_map_.find(handle);
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == metrics_map_.end() ||
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !iter->second->GetMemoryBytes(&values.private_bytes,
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    &values.shared_bytes)) {
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  values.is_private_and_shared_valid = true;
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CacheWebCoreStats(int index) const {
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_webcore_stats_valid) {
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsCacheStats())
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_webcore_stats_valid = true;
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.webcore_stats = GetResource(index)->GetWebCoreCacheStats();
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TaskManagerModel::CacheV8Memory(int index) const {
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerResourceValues& values(GetPerResourceValues(index));
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!values.is_v8_memory_valid) {
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetResource(index)->ReportsV8MemoryStats())
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.is_v8_memory_valid = true;
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.v8_memory_allocated = GetResource(index)->GetV8MemoryAllocated();
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values.v8_memory_used = GetResource(index)->GetV8MemoryUsed();
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
148390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TaskManagerModel::AddResourceProvider(ResourceProvider* provider) {
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(provider);
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  providers_.push_back(provider);
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManagerModel::PerResourceValues& TaskManagerModel::GetPerResourceValues(
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index) const {
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return per_resource_cache_[GetResource(index)];
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
149390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Resource* TaskManagerModel::GetResource(int index) const {
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_GE(index, 0);
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_LT(index, static_cast<int>(resources_.size()));
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return resources_[index];
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TaskManager class
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManager::RegisterPrefs(PrefRegistrySimple* registry) {
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(prefs::kTaskManagerWindowPlacement);
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManager::IsBrowserProcess(int index) const {
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If some of the selection is out of bounds, ignore. This may happen when
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // killing a process that manages several pages.
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return index < model_->ResourceCount() &&
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model_->GetProcess(index) == base::GetCurrentProcessHandle();
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::KillProcess(int index) {
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessHandle process = model_->GetProcess(index);
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(process);
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (process != base::GetCurrentProcessHandle())
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::KillProcess(process, content::RESULT_CODE_KILLED, false);
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::ActivateProcess(int index) {
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetResourceWebContents returns a pointer to the relevant web contents for
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the resource.  If the index doesn't correspond to any web contents
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (i.e. refers to the Browser process or a plugin), GetWebContents will
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return NULL.
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* chosen_web_contents = model_->GetResourceWebContents(index);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chosen_web_contents && chosen_web_contents->GetDelegate())
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chosen_web_contents->GetDelegate()->ActivateContents(chosen_web_contents);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::AddResource(Resource* resource) {
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->AddResource(resource);
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::RemoveResource(Resource* resource) {
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->RemoveResource(resource);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::OnWindowClosed() {
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->StopUpdating();
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManager::ModelChanged() {
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->ModelChanged();
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManager* TaskManager::GetInstance() {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Singleton<TaskManager>::get();
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TaskManager::OpenAboutMemory(chrome::HostDesktopType desktop_type) {
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser = chrome::FindOrCreateTabbedBrowser(
1554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ProfileManager::GetLastUsedProfileAllowedByPolicy(), desktop_type);
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NavigateParams params(browser, GURL(chrome::kChromeUIMemoryURL),
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                content::PAGE_TRANSITION_LINK);
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.disposition = NEW_FOREGROUND_TAB;
1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Navigate(&params);
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManager::TaskManager()
1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : model_(new TaskManagerModel(this)) {
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TaskManager::~TaskManager() {
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1568