| Index: chrome/browser/task_manager/task_manager.cc
|
| diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc
|
| deleted file mode 100644
|
| index b5d8a4e3b7ef2ea543ee98cedb325715f2064be8..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/task_manager/task_manager.cc
|
| +++ /dev/null
|
| @@ -1,1445 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/task_manager/task_manager.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/i18n/number_formatting.h"
|
| -#include "base/i18n/rtl.h"
|
| -#include "base/location.h"
|
| -#include "base/numerics/safe_conversions.h"
|
| -#include "base/process/process_metrics.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/threading/thread_task_runner_handle.h"
|
| -#include "build/build_config.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/profiles/profile_manager.h"
|
| -#include "chrome/browser/profiles/profile_window.h"
|
| -#include "chrome/browser/task_management/task_manager_interface.h"
|
| -#include "chrome/browser/task_manager/background_information.h"
|
| -#include "chrome/browser/task_manager/browser_process_resource_provider.h"
|
| -#include "chrome/browser/task_manager/child_process_resource_provider.h"
|
| -#include "chrome/browser/task_manager/extension_information.h"
|
| -#include "chrome/browser/task_manager/guest_information.h"
|
| -#include "chrome/browser/task_manager/panel_information.h"
|
| -#include "chrome/browser/task_manager/printing_information.h"
|
| -#include "chrome/browser/task_manager/resource_provider.h"
|
| -#include "chrome/browser/task_manager/tab_contents_information.h"
|
| -#include "chrome/browser/task_manager/web_contents_resource_provider.h"
|
| -#include "chrome/browser/ui/browser_navigator.h"
|
| -#include "chrome/browser/ui/browser_navigator_params.h"
|
| -#include "chrome/browser/ui/user_manager.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "chrome/common/url_constants.h"
|
| -#include "chrome/grit/generated_resources.h"
|
| -#include "components/nacl/browser/nacl_browser.h"
|
| -#include "components/prefs/pref_registry_simple.h"
|
| -#include "components/prefs/pref_service.h"
|
| -#include "content/public/browser/browser_child_process_host.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/gpu_data_manager.h"
|
| -#include "content/public/browser/gpu_data_manager_observer.h"
|
| -#include "content/public/browser/resource_request_info.h"
|
| -#include "content/public/browser/web_contents.h"
|
| -#include "content/public/browser/web_contents_delegate.h"
|
| -#include "content/public/browser/worker_service.h"
|
| -#include "content/public/common/result_codes.h"
|
| -#include "extensions/browser/extension_system.h"
|
| -#include "third_party/icu/source/i18n/unicode/coll.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/resource/resource_bundle.h"
|
| -#include "ui/base/text/bytes_formatting.h"
|
| -#include "ui/gfx/image/image_skia.h"
|
| -#include "ui/resources/grit/ui_resources.h"
|
| -
|
| -using content::BrowserThread;
|
| -using content::ResourceRequestInfo;
|
| -using content::WebContents;
|
| -using task_manager::Resource;
|
| -using task_manager::ResourceProvider;
|
| -using task_manager::WebContentsInformation;
|
| -
|
| -class Profile;
|
| -
|
| -namespace {
|
| -
|
| -template <class T>
|
| -int ValueCompare(T value1, T value2) {
|
| - if (value1 < value2)
|
| - return -1;
|
| - if (value1 == value2)
|
| - return 0;
|
| - return 1;
|
| -}
|
| -
|
| -// Used when one or both of the results to compare are unavailable.
|
| -int OrderUnavailableValue(bool v1, bool v2) {
|
| - if (!v1 && !v2)
|
| - return 0;
|
| - return v1 ? 1 : -1;
|
| -}
|
| -
|
| -// Used by TaskManagerModel::CompareValues(). See it for details of return
|
| -// value.
|
| -template <class T>
|
| -int ValueCompareMember(const TaskManagerModel* model,
|
| - bool (TaskManagerModel::*f)(int, T*) const,
|
| - int row1,
|
| - int row2) {
|
| - T value1;
|
| - T value2;
|
| - bool value1_valid = (model->*f)(row1, &value1);
|
| - bool value2_valid = (model->*f)(row2, &value2);
|
| - return value1_valid && value2_valid ? ValueCompare(value1, value2) :
|
| - OrderUnavailableValue(value1_valid, value2_valid);
|
| -}
|
| -
|
| -base::string16 FormatStatsSize(const blink::WebCache::ResourceTypeStat& stat) {
|
| - return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
|
| - ui::FormatBytesWithUnits(stat.size, ui::DATA_UNITS_KIBIBYTE, false),
|
| - ui::FormatBytesWithUnits(stat.liveSize, ui::DATA_UNITS_KIBIBYTE, false));
|
| -}
|
| -
|
| -// Returns true if the specified id should use the first value in the group.
|
| -bool IsSharedByGroup(int col_id) {
|
| - switch (col_id) {
|
| - case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
|
| - case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
|
| - case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
|
| - case IDS_TASK_MANAGER_CPU_COLUMN:
|
| - case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
|
| - case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
|
| - case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
|
| - case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
|
| - case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
|
| - case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
|
| - case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
|
| - case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
|
| - return true;
|
| - default:
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -class TaskManagerModelGpuDataManagerObserver
|
| - : public content::GpuDataManagerObserver {
|
| - public:
|
| - TaskManagerModelGpuDataManagerObserver() {
|
| - content::GpuDataManager::GetInstance()->AddObserver(this);
|
| - }
|
| -
|
| - ~TaskManagerModelGpuDataManagerObserver() override {
|
| - content::GpuDataManager::GetInstance()->RemoveObserver(this);
|
| - }
|
| -
|
| - static void NotifyVideoMemoryUsageStats(
|
| - const gpu::VideoMemoryUsageStats& video_memory_usage_stats) {
|
| - TaskManager::GetInstance()->model()->NotifyVideoMemoryUsageStats(
|
| - video_memory_usage_stats);
|
| - }
|
| -
|
| - void OnVideoMemoryUsageStatsUpdate(
|
| - const gpu::VideoMemoryUsageStats& video_memory_usage_stats) override {
|
| - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| - NotifyVideoMemoryUsageStats(video_memory_usage_stats);
|
| - } else {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::UI, FROM_HERE, base::Bind(
|
| - &TaskManagerModelGpuDataManagerObserver::
|
| - NotifyVideoMemoryUsageStats,
|
| - video_memory_usage_stats));
|
| - }
|
| - }
|
| -};
|
| -
|
| -TaskManagerModel::PerResourceValues::PerResourceValues()
|
| - : is_title_valid(false),
|
| - is_profile_name_valid(false),
|
| - network_usage(0),
|
| - is_process_id_valid(false),
|
| - process_id(0),
|
| - is_webcore_stats_valid(false),
|
| - is_sqlite_memory_bytes_valid(false),
|
| - sqlite_memory_bytes(0),
|
| - is_v8_memory_valid(false),
|
| - v8_memory_allocated(0),
|
| - v8_memory_used(0) {}
|
| -
|
| -TaskManagerModel::PerResourceValues::PerResourceValues(
|
| - const PerResourceValues& other) = default;
|
| -
|
| -TaskManagerModel::PerResourceValues::~PerResourceValues() {}
|
| -
|
| -TaskManagerModel::PerProcessValues::PerProcessValues()
|
| - : is_cpu_usage_valid(false),
|
| - cpu_usage(0),
|
| - is_idle_wakeups_valid(false),
|
| - idle_wakeups(0),
|
| - is_private_and_shared_valid(false),
|
| - private_bytes(0),
|
| - shared_bytes(0),
|
| - is_physical_memory_valid(false),
|
| - physical_memory(0),
|
| - is_video_memory_valid(false),
|
| - video_memory(0),
|
| - video_memory_has_duplicates(false),
|
| - is_gdi_handles_valid(false),
|
| - gdi_handles(0),
|
| - gdi_handles_peak(0),
|
| - is_user_handles_valid(0),
|
| - user_handles(0),
|
| - user_handles_peak(0),
|
| - is_nacl_debug_stub_port_valid(false),
|
| - nacl_debug_stub_port(0) {}
|
| -
|
| -TaskManagerModel::PerProcessValues::PerProcessValues(
|
| - const PerProcessValues& other) = default;
|
| -
|
| -TaskManagerModel::PerProcessValues::~PerProcessValues() {}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// TaskManagerModel class
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -TaskManagerModel::TaskManagerModel(TaskManager* task_manager)
|
| - : pending_video_memory_usage_stats_update_(false),
|
| - update_requests_(0),
|
| - listen_requests_(0),
|
| - update_state_(IDLE),
|
| - is_updating_byte_count_(false) {
|
| - AddResourceProvider(
|
| - new task_manager::BrowserProcessResourceProvider(task_manager));
|
| - AddResourceProvider(new task_manager::WebContentsResourceProvider(
|
| - task_manager, std::unique_ptr<WebContentsInformation>(
|
| - new task_manager::BackgroundInformation())));
|
| - AddResourceProvider(new task_manager::WebContentsResourceProvider(
|
| - task_manager, std::unique_ptr<WebContentsInformation>(
|
| - new task_manager::TabContentsInformation())));
|
| -#if defined(ENABLE_PRINT_PREVIEW)
|
| - AddResourceProvider(new task_manager::WebContentsResourceProvider(
|
| - task_manager, std::unique_ptr<WebContentsInformation>(
|
| - new task_manager::PrintingInformation())));
|
| -#endif // ENABLE_PRINT_PREVIEW
|
| - AddResourceProvider(new task_manager::WebContentsResourceProvider(
|
| - task_manager, std::unique_ptr<WebContentsInformation>(
|
| - new task_manager::PanelInformation())));
|
| - AddResourceProvider(
|
| - new task_manager::ChildProcessResourceProvider(task_manager));
|
| - AddResourceProvider(new task_manager::WebContentsResourceProvider(
|
| - task_manager, std::unique_ptr<WebContentsInformation>(
|
| - new task_manager::ExtensionInformation())));
|
| - AddResourceProvider(new task_manager::WebContentsResourceProvider(
|
| - task_manager, std::unique_ptr<WebContentsInformation>(
|
| - new task_manager::GuestInformation())));
|
| -}
|
| -
|
| -void TaskManagerModel::AddObserver(TaskManagerModelObserver* observer) {
|
| - observer_list_.AddObserver(observer);
|
| -}
|
| -
|
| -void TaskManagerModel::RemoveObserver(TaskManagerModelObserver* observer) {
|
| - observer_list_.RemoveObserver(observer);
|
| -}
|
| -
|
| -int TaskManagerModel::ResourceCount() const {
|
| - return resources_.size();
|
| -}
|
| -
|
| -int TaskManagerModel::GroupCount() const {
|
| - return group_map_.size();
|
| -}
|
| -
|
| -int TaskManagerModel::GetNaClDebugStubPort(int index) const {
|
| - base::ProcessHandle handle = GetResource(index)->GetProcess();
|
| - PerProcessValues& values(per_process_cache_[handle]);
|
| - if (!values.is_nacl_debug_stub_port_valid) {
|
| - return nacl::kGdbDebugStubPortUnknown;
|
| - }
|
| - return values.nacl_debug_stub_port;
|
| -}
|
| -
|
| -int64_t TaskManagerModel::GetNetworkUsage(int index) const {
|
| - return GetNetworkUsage(GetResource(index));
|
| -}
|
| -
|
| -double TaskManagerModel::GetCPUUsage(int index) const {
|
| - return GetCPUUsage(GetResource(index));
|
| -}
|
| -
|
| -int TaskManagerModel::GetIdleWakeupsPerSecond(int index) const {
|
| - return GetIdleWakeupsPerSecond(GetResource(index));
|
| -}
|
| -
|
| -base::ProcessId TaskManagerModel::GetProcessId(int index) const {
|
| - PerResourceValues& values(GetPerResourceValues(index));
|
| - if (!values.is_process_id_valid) {
|
| - values.is_process_id_valid = true;
|
| - base::ProcessHandle process(GetResource(index)->GetProcess());
|
| - DCHECK(process);
|
| - values.process_id = base::GetProcId(process);
|
| - DCHECK(values.process_id);
|
| - }
|
| - return values.process_id;
|
| -}
|
| -
|
| -base::ProcessHandle TaskManagerModel::GetProcess(int index) const {
|
| - return GetResource(index)->GetProcess();
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceById(int index, int col_id) const {
|
| - if (IsSharedByGroup(col_id) && !IsResourceFirstInGroup(index))
|
| - return base::string16();
|
| -
|
| - switch (col_id) {
|
| - case IDS_TASK_MANAGER_TASK_COLUMN:
|
| - return GetResourceTitle(index);
|
| -
|
| - case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:
|
| - return GetResourceProfileName(index);
|
| -
|
| - case IDS_TASK_MANAGER_NET_COLUMN:
|
| - return GetResourceNetworkUsage(index);
|
| -
|
| - case IDS_TASK_MANAGER_CPU_COLUMN:
|
| - return GetResourceCPUUsage(index);
|
| -
|
| - case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
|
| - return GetResourcePrivateMemory(index);
|
| -
|
| - case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
|
| - return GetResourceSharedMemory(index);
|
| -
|
| - case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
|
| - return GetResourcePhysicalMemory(index);
|
| -
|
| - case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
|
| - return GetResourceProcessId(index);
|
| -
|
| - case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN:
|
| - return GetResourceGDIHandles(index);
|
| -
|
| - case IDS_TASK_MANAGER_USER_HANDLES_COLUMN:
|
| - return GetResourceUSERHandles(index);
|
| -
|
| - case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
|
| - return GetResourceIdleWakeupsPerSecond(index);
|
| -
|
| - case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
|
| - return GetResourceWebCoreImageCacheSize(index);
|
| -
|
| - case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
|
| - return GetResourceWebCoreScriptsCacheSize(index);
|
| -
|
| - case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
|
| - return GetResourceWebCoreCSSCacheSize(index);
|
| -
|
| - case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
|
| - return GetResourceVideoMemory(index);
|
| -
|
| - case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
|
| - return GetResourceSqliteMemoryUsed(index);
|
| -
|
| - case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
|
| - return GetResourceV8MemoryAllocatedSize(index);
|
| -
|
| - case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
|
| - return GetResourceNaClDebugStubPort(index);
|
| -
|
| - default:
|
| - NOTREACHED();
|
| - return base::string16();
|
| - }
|
| -}
|
| -
|
| -const base::string16& TaskManagerModel::GetResourceTitle(int index) const {
|
| - PerResourceValues& values = GetPerResourceValues(index);
|
| - if (!values.is_title_valid) {
|
| - values.is_title_valid = true;
|
| - values.title = GetResource(index)->GetTitle();
|
| - }
|
| - return values.title;
|
| -}
|
| -
|
| -const base::string16& TaskManagerModel::GetResourceProfileName(
|
| - int index) const {
|
| - PerResourceValues& values(GetPerResourceValues(index));
|
| - if (!values.is_profile_name_valid) {
|
| - values.is_profile_name_valid = true;
|
| - values.profile_name = GetResource(index)->GetProfileName();
|
| - }
|
| - return values.profile_name;
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceNaClDebugStubPort(int index) const {
|
| - int port = GetNaClDebugStubPort(index);
|
| - if (port == nacl::kGdbDebugStubPortUnknown) {
|
| - return base::ASCIIToUTF16("Unknown");
|
| - } else if (port == nacl::kGdbDebugStubPortUnused) {
|
| - return base::ASCIIToUTF16("N/A");
|
| - } else {
|
| - return base::IntToString16(port);
|
| - }
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceNetworkUsage(int index) const {
|
| - int64_t net_usage = GetNetworkUsage(index);
|
| - if (net_usage == -1)
|
| - return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
|
| - if (net_usage == 0)
|
| - return base::ASCIIToUTF16("0");
|
| - base::string16 net_byte = ui::FormatSpeed(net_usage);
|
| - // Force number string to have LTR directionality.
|
| - return base::i18n::GetDisplayStringInLTRDirectionality(net_byte);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceCPUUsage(int index) const {
|
| - return base::UTF8ToUTF16(base::StringPrintf(
|
| - // Activity Monitor shows %cpu with one decimal digit -- be
|
| - // consistent with that.
|
| - "%.1f",
|
| - GetCPUUsage(GetResource(index))));
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourcePrivateMemory(int index) const {
|
| - size_t private_mem;
|
| - if (!GetPrivateMemory(index, &private_mem))
|
| - return base::ASCIIToUTF16("N/A");
|
| - return GetMemCellText(private_mem);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceSharedMemory(int index) const {
|
| - size_t shared_mem;
|
| - if (!GetSharedMemory(index, &shared_mem))
|
| - return base::ASCIIToUTF16("N/A");
|
| - return GetMemCellText(shared_mem);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourcePhysicalMemory(int index) const {
|
| - size_t phys_mem;
|
| - GetPhysicalMemory(index, &phys_mem);
|
| - return GetMemCellText(phys_mem);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceProcessId(int index) const {
|
| - return base::IntToString16(GetProcessId(index));
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceGDIHandles(int index) const {
|
| - size_t current, peak;
|
| - GetGDIHandles(index, ¤t, &peak);
|
| - return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
|
| - base::SizeTToString16(current), base::SizeTToString16(peak));
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceUSERHandles(int index) const {
|
| - size_t current, peak;
|
| - GetUSERHandles(index, ¤t, &peak);
|
| - return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
|
| - base::SizeTToString16(current), base::SizeTToString16(peak));
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceWebCoreImageCacheSize(
|
| - int index) const {
|
| - if (!CacheWebCoreStats(index))
|
| - return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
|
| - return FormatStatsSize(GetPerResourceValues(index).webcore_stats.images);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize(
|
| - int index) const {
|
| - if (!CacheWebCoreStats(index))
|
| - return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
|
| - return FormatStatsSize(GetPerResourceValues(index).webcore_stats.scripts);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize(
|
| - int index) const {
|
| - if (!CacheWebCoreStats(index))
|
| - return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
|
| - return FormatStatsSize(
|
| - GetPerResourceValues(index).webcore_stats.cssStyleSheets);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceVideoMemory(int index) const {
|
| - size_t video_memory;
|
| - bool has_duplicates;
|
| - if (!GetVideoMemory(index, &video_memory, &has_duplicates) || !video_memory)
|
| - return base::ASCIIToUTF16("N/A");
|
| - if (has_duplicates) {
|
| - return GetMemCellText(video_memory) + base::ASCIIToUTF16("*");
|
| - }
|
| - return GetMemCellText(video_memory);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceSqliteMemoryUsed(int index) const {
|
| - size_t bytes = 0;
|
| - if (!GetSqliteMemoryUsedBytes(index, &bytes))
|
| - return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
|
| - return GetMemCellText(bytes);
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceIdleWakeupsPerSecond(int index)
|
| - const {
|
| - return base::FormatNumber(GetIdleWakeupsPerSecond(GetResource(index)));
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetResourceV8MemoryAllocatedSize(
|
| - int index) const {
|
| - size_t memory_allocated = 0, memory_used = 0;
|
| - if (!GetV8MemoryUsed(index, &memory_used) ||
|
| - !GetV8Memory(index, &memory_allocated))
|
| - return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
|
| - return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
|
| - ui::FormatBytesWithUnits(memory_allocated,
|
| - ui::DATA_UNITS_KIBIBYTE,
|
| - false),
|
| - ui::FormatBytesWithUnits(memory_used,
|
| - ui::DATA_UNITS_KIBIBYTE,
|
| - false));
|
| -}
|
| -
|
| -bool TaskManagerModel::GetPrivateMemory(int index, size_t* result) const {
|
| - *result = 0;
|
| - base::ProcessHandle handle = GetResource(index)->GetProcess();
|
| - if (!CachePrivateAndSharedMemory(handle))
|
| - return false;
|
| - *result = per_process_cache_[handle].private_bytes;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetSharedMemory(int index, size_t* result) const {
|
| - *result = 0;
|
| - base::ProcessHandle handle = GetResource(index)->GetProcess();
|
| - if (!CachePrivateAndSharedMemory(handle))
|
| - return false;
|
| - *result = per_process_cache_[handle].shared_bytes;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetPhysicalMemory(int index, size_t* result) const {
|
| - *result = 0;
|
| -
|
| - base::ProcessHandle handle = GetResource(index)->GetProcess();
|
| - PerProcessValues& values(per_process_cache_[handle]);
|
| -
|
| - if (!values.is_physical_memory_valid) {
|
| - base::WorkingSetKBytes ws_usage;
|
| - MetricsMap::const_iterator iter = metrics_map_.find(handle);
|
| - if (iter == metrics_map_.end() ||
|
| - !iter->second->GetWorkingSetKBytes(&ws_usage))
|
| - return false;
|
| -
|
| - values.is_physical_memory_valid = true;
|
| - // Memory = working_set.private which is working set minus shareable. This
|
| - // avoids the unpredictable counting that occurs when calculating memory as
|
| - // working set minus shared (renderer code counted when one tab is open and
|
| - // not counted when two or more are open) and it is much more efficient to
|
| - // calculate on Windows.
|
| - values.physical_memory = iter->second->GetWorkingSetSize();
|
| - values.physical_memory -= ws_usage.shareable * 1024;
|
| - }
|
| - *result = values.physical_memory;
|
| - return true;
|
| -}
|
| -
|
| -void TaskManagerModel::GetGDIHandles(int index,
|
| - size_t* current,
|
| - size_t* peak) const {
|
| - *current = 0;
|
| - *peak = 0;
|
| -}
|
| -
|
| -void TaskManagerModel::GetUSERHandles(int index,
|
| - size_t* current,
|
| - size_t* peak) const {
|
| - *current = 0;
|
| - *peak = 0;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetWebCoreCacheStats(
|
| - int index,
|
| - blink::WebCache::ResourceTypeStats* result) const {
|
| - if (!CacheWebCoreStats(index))
|
| - return false;
|
| - *result = GetPerResourceValues(index).webcore_stats;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetVideoMemory(int index,
|
| - size_t* video_memory,
|
| - bool* has_duplicates) const {
|
| - *video_memory = 0;
|
| - *has_duplicates = false;
|
| -
|
| - base::ProcessId pid = GetProcessId(index);
|
| - PerProcessValues& values(
|
| - per_process_cache_[GetResource(index)->GetProcess()]);
|
| - if (!values.is_video_memory_valid) {
|
| - gpu::VideoMemoryUsageStats::ProcessMap::const_iterator i =
|
| - video_memory_usage_stats_.process_map.find(pid);
|
| - if (i == video_memory_usage_stats_.process_map.end())
|
| - return false;
|
| - values.is_video_memory_valid = true;
|
| - // If this checked_cast asserts, then need to change this code to use
|
| - // uint64_t instead of size_t.
|
| - values.video_memory = base::checked_cast<size_t>(i->second.video_memory);
|
| - values.video_memory_has_duplicates = i->second.has_duplicates;
|
| - }
|
| - *video_memory = values.video_memory;
|
| - *has_duplicates = values.video_memory_has_duplicates;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetSqliteMemoryUsedBytes(
|
| - int index,
|
| - size_t* result) const {
|
| - *result = 0;
|
| - PerResourceValues& values(GetPerResourceValues(index));
|
| - if (!values.is_sqlite_memory_bytes_valid) {
|
| - if (!GetResource(index)->ReportsSqliteMemoryUsed())
|
| - return false;
|
| - values.is_sqlite_memory_bytes_valid = true;
|
| - values.sqlite_memory_bytes = GetResource(index)->SqliteMemoryUsedBytes();
|
| - }
|
| - *result = values.sqlite_memory_bytes;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetV8Memory(int index, size_t* result) const {
|
| - *result = 0;
|
| - if (!CacheV8Memory(index))
|
| - return false;
|
| - *result = GetPerResourceValues(index).v8_memory_allocated;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::GetV8MemoryUsed(int index, size_t* result) const {
|
| - *result = 0;
|
| - if (!CacheV8Memory(index))
|
| - return false;
|
| - *result = GetPerResourceValues(index).v8_memory_used;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::CanActivate(int index) const {
|
| - CHECK_LT(index, ResourceCount());
|
| - return GetResourceWebContents(index) != NULL;
|
| -}
|
| -
|
| -bool TaskManagerModel::IsResourceFirstInGroup(int index) const {
|
| - Resource* resource = GetResource(index);
|
| - GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
|
| - DCHECK(iter != group_map_.end());
|
| - const ResourceList& group = iter->second;
|
| - return (group[0] == resource);
|
| -}
|
| -
|
| -bool TaskManagerModel::IsResourceLastInGroup(int index) const {
|
| - Resource* resource = GetResource(index);
|
| - GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
|
| - DCHECK(iter != group_map_.end());
|
| - const ResourceList& group = iter->second;
|
| - return (group.back() == resource);
|
| -}
|
| -
|
| -gfx::ImageSkia TaskManagerModel::GetResourceIcon(int index) const {
|
| - gfx::ImageSkia icon = GetResource(index)->GetIcon();
|
| - if (!icon.isNull())
|
| - return icon;
|
| -
|
| - static const gfx::ImageSkia* default_icon =
|
| - ResourceBundle::GetSharedInstance().
|
| - GetNativeImageNamed(IDR_DEFAULT_FAVICON).ToImageSkia();
|
| - return *default_icon;
|
| -}
|
| -
|
| -TaskManagerModel::GroupRange
|
| -TaskManagerModel::GetGroupRangeForResource(int index) const {
|
| - Resource* resource = GetResource(index);
|
| - GroupMap::const_iterator group_iter =
|
| - group_map_.find(resource->GetProcess());
|
| - DCHECK(group_iter != group_map_.end());
|
| - const ResourceList& group = group_iter->second;
|
| - if (group.size() == 1) {
|
| - return std::make_pair(index, 1);
|
| - } else {
|
| - for (int i = index; i >= 0; --i) {
|
| - if (GetResource(i) == group[0])
|
| - return std::make_pair(i, group.size());
|
| - }
|
| - NOTREACHED();
|
| - return std::make_pair(-1, -1);
|
| - }
|
| -}
|
| -
|
| -int TaskManagerModel::GetGroupIndexForResource(int index) const {
|
| - int group_index = -1;
|
| - for (int i = 0; i <= index; ++i) {
|
| - if (IsResourceFirstInGroup(i))
|
| - group_index++;
|
| - }
|
| -
|
| - DCHECK_NE(group_index, -1);
|
| - return group_index;
|
| -}
|
| -
|
| -int TaskManagerModel::GetResourceIndexForGroup(int group_index,
|
| - int index_in_group) const {
|
| - int group_count = -1;
|
| - int count_in_group = -1;
|
| - for (int i = 0; i < ResourceCount(); ++i) {
|
| - if (IsResourceFirstInGroup(i))
|
| - group_count++;
|
| -
|
| - if (group_count == group_index) {
|
| - count_in_group++;
|
| - if (count_in_group == index_in_group)
|
| - return i;
|
| - } else if (group_count > group_index) {
|
| - break;
|
| - }
|
| - }
|
| -
|
| - NOTREACHED();
|
| - return -1;
|
| -}
|
| -
|
| -int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const {
|
| - CHECK(row1 < ResourceCount() && row2 < ResourceCount());
|
| - switch (col_id) {
|
| - case IDS_TASK_MANAGER_TASK_COLUMN: {
|
| - static icu::Collator* collator = NULL;
|
| - if (!collator) {
|
| - UErrorCode create_status = U_ZERO_ERROR;
|
| - collator = icu::Collator::createInstance(create_status);
|
| - if (!U_SUCCESS(create_status)) {
|
| - collator = NULL;
|
| - NOTREACHED();
|
| - }
|
| - }
|
| - const base::string16& title1 = GetResourceTitle(row1);
|
| - const base::string16& title2 = GetResourceTitle(row2);
|
| - UErrorCode compare_status = U_ZERO_ERROR;
|
| - UCollationResult compare_result = collator->compare(
|
| - static_cast<const UChar*>(title1.c_str()),
|
| - static_cast<int>(title1.length()),
|
| - static_cast<const UChar*>(title2.c_str()),
|
| - static_cast<int>(title2.length()),
|
| - compare_status);
|
| - DCHECK(U_SUCCESS(compare_status));
|
| - return compare_result;
|
| - }
|
| -
|
| - case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN: {
|
| - const base::string16& profile1 = GetResourceProfileName(row1);
|
| - const base::string16& profile2 = GetResourceProfileName(row2);
|
| - return profile1.compare(0, profile1.length(), profile2, 0,
|
| - profile2.length());
|
| - }
|
| -
|
| - case IDS_TASK_MANAGER_NET_COLUMN:
|
| - return ValueCompare(GetNetworkUsage(GetResource(row1)),
|
| - GetNetworkUsage(GetResource(row2)));
|
| -
|
| - case IDS_TASK_MANAGER_CPU_COLUMN:
|
| - return ValueCompare(GetCPUUsage(GetResource(row1)),
|
| - GetCPUUsage(GetResource(row2)));
|
| -
|
| - case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
|
| - return ValueCompareMember(
|
| - this, &TaskManagerModel::GetPrivateMemory, row1, row2);
|
| -
|
| - case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
|
| - return ValueCompareMember(
|
| - this, &TaskManagerModel::GetSharedMemory, row1, row2);
|
| -
|
| - case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
|
| - return ValueCompareMember(
|
| - this, &TaskManagerModel::GetPhysicalMemory, row1, row2);
|
| -
|
| - case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
|
| - return ValueCompare(GetNaClDebugStubPort(row1),
|
| - GetNaClDebugStubPort(row2));
|
| -
|
| - case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
|
| - return ValueCompare(GetProcessId(row1), GetProcessId(row2));
|
| -
|
| - case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN: {
|
| - size_t current1, peak1;
|
| - size_t current2, peak2;
|
| - GetGDIHandles(row1, ¤t1, &peak1);
|
| - GetGDIHandles(row2, ¤t2, &peak2);
|
| - return ValueCompare(current1, current2);
|
| - }
|
| -
|
| - case IDS_TASK_MANAGER_USER_HANDLES_COLUMN: {
|
| - size_t current1, peak1;
|
| - size_t current2, peak2;
|
| - GetUSERHandles(row1, ¤t1, &peak1);
|
| - GetUSERHandles(row2, ¤t2, &peak2);
|
| - return ValueCompare(current1, current2);
|
| - }
|
| -
|
| - case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
|
| - return ValueCompare(GetIdleWakeupsPerSecond(row1),
|
| - GetIdleWakeupsPerSecond(row2));
|
| -
|
| - case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
|
| - case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
|
| - case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: {
|
| - bool row1_stats_valid = CacheWebCoreStats(row1);
|
| - bool row2_stats_valid = CacheWebCoreStats(row2);
|
| - if (row1_stats_valid && row2_stats_valid) {
|
| - const blink::WebCache::ResourceTypeStats& stats1(
|
| - GetPerResourceValues(row1).webcore_stats);
|
| - const blink::WebCache::ResourceTypeStats& stats2(
|
| - GetPerResourceValues(row2).webcore_stats);
|
| - switch (col_id) {
|
| - case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
|
| - return ValueCompare(stats1.images.size, stats2.images.size);
|
| - case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
|
| - return ValueCompare(stats1.scripts.size, stats2.scripts.size);
|
| - case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
|
| - return ValueCompare(stats1.cssStyleSheets.size,
|
| - stats2.cssStyleSheets.size);
|
| - default:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - }
|
| - return OrderUnavailableValue(row1_stats_valid, row2_stats_valid);
|
| - }
|
| -
|
| - case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: {
|
| - size_t value1;
|
| - size_t value2;
|
| - bool has_duplicates;
|
| - bool value1_valid = GetVideoMemory(row1, &value1, &has_duplicates);
|
| - bool value2_valid = GetVideoMemory(row2, &value2, &has_duplicates);
|
| - return value1_valid && value2_valid ? ValueCompare(value1, value2) :
|
| - OrderUnavailableValue(value1_valid, value2_valid);
|
| - }
|
| -
|
| - case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
|
| - return ValueCompareMember(
|
| - this, &TaskManagerModel::GetV8Memory, row1, row2);
|
| -
|
| - case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
|
| - return ValueCompareMember(
|
| - this, &TaskManagerModel::GetSqliteMemoryUsedBytes, row1, row2);
|
| -
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -int TaskManagerModel::GetUniqueChildProcessId(int index) const {
|
| - return GetResource(index)->GetUniqueChildProcessId();
|
| -}
|
| -
|
| -Resource::Type TaskManagerModel::GetResourceType(int index) const {
|
| - return GetResource(index)->GetType();
|
| -}
|
| -
|
| -WebContents* TaskManagerModel::GetResourceWebContents(int index) const {
|
| - return GetResource(index)->GetWebContents();
|
| -}
|
| -
|
| -void TaskManagerModel::AddResource(Resource* resource) {
|
| - base::ProcessHandle process = resource->GetProcess();
|
| - DCHECK(process);
|
| -
|
| - GroupMap::iterator group_iter = group_map_.find(process);
|
| - int new_entry_index = 0;
|
| - if (group_iter == group_map_.end()) {
|
| - group_map_.insert(make_pair(process, ResourceList(1, resource)));
|
| -
|
| - // Not part of a group, just put at the end of the list.
|
| - resources_.push_back(resource);
|
| - new_entry_index = static_cast<int>(resources_.size() - 1);
|
| - } else {
|
| - ResourceList* group_entries = &(group_iter->second);
|
| - group_entries->push_back(resource);
|
| -
|
| - // Insert the new entry right after the last entry of its group.
|
| - ResourceList::iterator iter =
|
| - std::find(resources_.begin(),
|
| - resources_.end(),
|
| - (*group_entries)[group_entries->size() - 2]);
|
| - DCHECK(iter != resources_.end());
|
| - new_entry_index = static_cast<int>(iter - resources_.begin()) + 1;
|
| - resources_.insert(++iter, resource);
|
| - }
|
| -
|
| - // Create the ProcessMetrics for this process if needed (not in map).
|
| - if (metrics_map_.find(process) == metrics_map_.end()) {
|
| - std::unique_ptr<base::ProcessMetrics> pm =
|
| - base::ProcessMetrics::CreateProcessMetrics(
|
| - process, content::BrowserChildProcessHost::GetPortProvider());
|
| - metrics_map_[process] = pm.release();
|
| - }
|
| -
|
| - // Notify the table that the contents have changed for it to redraw.
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
|
| - OnItemsAdded(new_entry_index, 1));
|
| -}
|
| -
|
| -void TaskManagerModel::RemoveResource(Resource* resource) {
|
| - base::ProcessHandle process = resource->GetProcess();
|
| -
|
| - // Find the associated group.
|
| - GroupMap::iterator group_iter = group_map_.find(process);
|
| - DCHECK(group_iter != group_map_.end());
|
| - if (group_iter == group_map_.end())
|
| - return;
|
| - ResourceList& group_entries = group_iter->second;
|
| -
|
| - // Remove the entry from the group map.
|
| - ResourceList::iterator iter = std::find(group_entries.begin(),
|
| - group_entries.end(),
|
| - resource);
|
| - DCHECK(iter != group_entries.end());
|
| - if (iter != group_entries.end())
|
| - group_entries.erase(iter);
|
| -
|
| - // If there are no more entries for that process, do the clean-up.
|
| - if (group_entries.empty()) {
|
| - group_map_.erase(group_iter);
|
| -
|
| - // Nobody is using this process, we don't need the process metrics anymore.
|
| - MetricsMap::iterator pm_iter = metrics_map_.find(process);
|
| - DCHECK(pm_iter != metrics_map_.end());
|
| - if (pm_iter != metrics_map_.end()) {
|
| - delete pm_iter->second;
|
| - metrics_map_.erase(process);
|
| - }
|
| - }
|
| -
|
| - // Remove the entry from the model list.
|
| - iter = std::find(resources_.begin(), resources_.end(), resource);
|
| - DCHECK(iter != resources_.end());
|
| - if (iter != resources_.end()) {
|
| - int index = static_cast<int>(iter - resources_.begin());
|
| - // Notify the observers that the contents will change.
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
|
| - OnItemsToBeRemoved(index, 1));
|
| - // Now actually remove the entry from the model list.
|
| - resources_.erase(iter);
|
| - // Notify the table that the contents have changed.
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
|
| - OnItemsRemoved(index, 1));
|
| - }
|
| -
|
| - // Remove the entry from the network maps.
|
| - ResourceValueMap::iterator net_iter =
|
| - current_byte_count_map_.find(resource);
|
| - if (net_iter != current_byte_count_map_.end())
|
| - current_byte_count_map_.erase(net_iter);
|
| -}
|
| -
|
| -void TaskManagerModel::StartUpdating() {
|
| - // Multiple StartUpdating requests may come in, and we only need to take
|
| - // action the first time.
|
| - update_requests_++;
|
| - if (update_requests_ > 1)
|
| - return;
|
| - DCHECK_EQ(1, update_requests_);
|
| - DCHECK_NE(TASK_PENDING, update_state_);
|
| -
|
| - // If update_state_ is STOPPING, it means a task is still pending. Setting
|
| - // it to TASK_PENDING ensures the tasks keep being posted (by Refresh()).
|
| - if (update_state_ == IDLE) {
|
| - base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| - FROM_HERE, base::Bind(&TaskManagerModel::RefreshCallback, this));
|
| - }
|
| - update_state_ = TASK_PENDING;
|
| -
|
| - // Notify resource providers that we are updating.
|
| - StartListening();
|
| -
|
| - if (!resources_.empty()) {
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
|
| - OnReadyPeriodicalUpdate());
|
| - }
|
| -
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&TaskManagerModel::SetUpdatingByteCount, this, true));
|
| -}
|
| -
|
| -void TaskManagerModel::StopUpdating() {
|
| - // Don't actually stop updating until we have heard as many calls as those
|
| - // to StartUpdating.
|
| - update_requests_--;
|
| - if (update_requests_ > 0)
|
| - return;
|
| - // Make sure that update_requests_ cannot go negative.
|
| - CHECK_EQ(0, update_requests_);
|
| - DCHECK_EQ(TASK_PENDING, update_state_);
|
| - update_state_ = STOPPING;
|
| -
|
| - // Notify resource providers that we are done updating.
|
| - StopListening();
|
| -
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&TaskManagerModel::SetUpdatingByteCount, this, false));
|
| -}
|
| -
|
| -void TaskManagerModel::StartListening() {
|
| - // Multiple StartListening requests may come in and we only need to take
|
| - // action the first time.
|
| - listen_requests_++;
|
| - if (listen_requests_ > 1)
|
| - return;
|
| - DCHECK_EQ(1, listen_requests_);
|
| -
|
| - // Notify resource providers that we should start listening to events.
|
| - for (ResourceProviderList::iterator iter = providers_.begin();
|
| - iter != providers_.end(); ++iter) {
|
| - (*iter)->StartUpdating();
|
| - }
|
| -}
|
| -
|
| -void TaskManagerModel::StopListening() {
|
| - // Don't actually stop listening until we have heard as many calls as those
|
| - // to StartListening.
|
| - listen_requests_--;
|
| - if (listen_requests_ > 0)
|
| - return;
|
| -
|
| - DCHECK_EQ(0, listen_requests_);
|
| -
|
| - // Notify resource providers that we are done listening.
|
| - for (ResourceProviderList::const_iterator iter = providers_.begin();
|
| - iter != providers_.end(); ++iter) {
|
| - (*iter)->StopUpdating();
|
| - }
|
| -
|
| - // Must clear the resources before the next attempt to start listening.
|
| - Clear();
|
| -}
|
| -
|
| -void TaskManagerModel::Clear() {
|
| - int size = ResourceCount();
|
| - if (size > 0) {
|
| - resources_.clear();
|
| -
|
| - // Clear the groups.
|
| - group_map_.clear();
|
| -
|
| - // Clear the process related info.
|
| - STLDeleteValues(&metrics_map_);
|
| -
|
| - // Clear the network maps.
|
| - current_byte_count_map_.clear();
|
| -
|
| - per_resource_cache_.clear();
|
| - per_process_cache_.clear();
|
| -
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
|
| - OnItemsRemoved(0, size));
|
| - }
|
| -}
|
| -
|
| -void TaskManagerModel::ModelChanged() {
|
| - // Notify the table that the contents have changed for it to redraw.
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_, OnModelChanged());
|
| -}
|
| -
|
| -void TaskManagerModel::RefreshPhysicalMemoryFromWorkingSetSnapshot() {
|
| -// This is a NOP on other platforms because they can efficiently retrieve
|
| -// the private working-set data on a per-process basis.
|
| -}
|
| -
|
| -void TaskManagerModel::Refresh() {
|
| - per_resource_cache_.clear();
|
| - per_process_cache_.clear();
|
| - RefreshPhysicalMemoryFromWorkingSetSnapshot();
|
| -
|
| -#if !defined(DISABLE_NACL)
|
| - nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance();
|
| -#endif // !defined(DISABLE_NACL)
|
| -
|
| - // Compute the CPU usage values and check if NaCl GDB debug stub port is
|
| - // known.
|
| - // Note that we compute the CPU usage for all resources (instead of doing it
|
| - // lazily) as process_util::GetCPUUsage() returns the CPU usage since the last
|
| - // time it was called, and not calling it everytime would skew the value the
|
| - // next time it is retrieved (as it would be for more than 1 cycle).
|
| - // The same is true for idle wakeups.
|
| - for (ResourceList::iterator iter = resources_.begin();
|
| - iter != resources_.end(); ++iter) {
|
| - base::ProcessHandle process = (*iter)->GetProcess();
|
| - PerProcessValues& values(per_process_cache_[process]);
|
| -#if !defined(DISABLE_NACL)
|
| - // Debug stub port doesn't change once known.
|
| - if (!values.is_nacl_debug_stub_port_valid) {
|
| - values.nacl_debug_stub_port = nacl_browser->GetProcessGdbDebugStubPort(
|
| - (*iter)->GetUniqueChildProcessId());
|
| - if (values.nacl_debug_stub_port != nacl::kGdbDebugStubPortUnknown) {
|
| - values.is_nacl_debug_stub_port_valid = true;
|
| - }
|
| - }
|
| -#endif // !defined(DISABLE_NACL)
|
| - if (values.is_cpu_usage_valid && values.is_idle_wakeups_valid)
|
| - continue;
|
| - MetricsMap::iterator metrics_iter = metrics_map_.find(process);
|
| - DCHECK(metrics_iter != metrics_map_.end());
|
| - if (!values.is_cpu_usage_valid) {
|
| - values.is_cpu_usage_valid = true;
|
| - values.cpu_usage = metrics_iter->second->GetCPUUsage();
|
| - }
|
| - // TODO(port): Implement GetIdleWakeupsPerSecond() on other platforms,
|
| - // crbug.com/120488
|
| - if (!values.is_idle_wakeups_valid) {
|
| - values.is_idle_wakeups_valid = true;
|
| - values.idle_wakeups = metrics_iter->second->GetIdleWakeupsPerSecond();
|
| - }
|
| - }
|
| -
|
| - // Send a request to refresh GPU memory consumption values
|
| - RefreshVideoMemoryUsageStats();
|
| -
|
| - // Compute the new network usage values.
|
| - base::TimeDelta update_time =
|
| - base::TimeDelta::FromMilliseconds(kUpdateTimeMs);
|
| - for (ResourceValueMap::iterator iter = current_byte_count_map_.begin();
|
| - iter != current_byte_count_map_.end(); ++iter) {
|
| - PerResourceValues* values = &(per_resource_cache_[iter->first]);
|
| - if (update_time > base::TimeDelta::FromSeconds(1))
|
| - values->network_usage = iter->second / update_time.InSeconds();
|
| - else
|
| - values->network_usage = iter->second * (1 / update_time.InSeconds());
|
| -
|
| - // Then we reset the current byte count.
|
| - iter->second = 0;
|
| - }
|
| -
|
| - // Let resources update themselves if they need to.
|
| - for (ResourceList::iterator iter = resources_.begin();
|
| - iter != resources_.end(); ++iter) {
|
| - (*iter)->Refresh();
|
| - }
|
| -
|
| - if (!resources_.empty()) {
|
| - FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
|
| - OnItemsChanged(0, ResourceCount()));
|
| - }
|
| -}
|
| -
|
| -void TaskManagerModel::NotifyVideoMemoryUsageStats(
|
| - const gpu::VideoMemoryUsageStats& video_memory_usage_stats) {
|
| - DCHECK(pending_video_memory_usage_stats_update_);
|
| - video_memory_usage_stats_ = video_memory_usage_stats;
|
| - pending_video_memory_usage_stats_update_ = false;
|
| -}
|
| -
|
| -void TaskManagerModel::NotifyBytesRead(const net::URLRequest& request,
|
| - int64_t byte_count) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - if (!is_updating_byte_count_)
|
| - return;
|
| -
|
| - // Only net::URLRequestJob instances created by the ResourceDispatcherHost
|
| - // have an associated ResourceRequestInfo and a render frame associated.
|
| - // All other jobs will have -1 returned for the render process child and
|
| - // routing ids - the jobs may still match a resource based on their origin id,
|
| - // otherwise BytesRead() will attribute the activity to the Browser resource.
|
| - const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
|
| - int child_id = -1, route_id = -1;
|
| - if (info)
|
| - info->GetAssociatedRenderFrame(&child_id, &route_id);
|
| -
|
| - // Get the origin PID of the request's originator. This will only be set for
|
| - // plugins - for renderer or browser initiated requests it will be zero.
|
| - int origin_pid = 0;
|
| - if (info)
|
| - origin_pid = info->GetOriginPID();
|
| -
|
| - if (bytes_read_buffer_.empty()) {
|
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
| - FROM_HERE, base::Bind(&TaskManagerModel::NotifyMultipleBytesRead, this),
|
| - base::TimeDelta::FromSeconds(1));
|
| - }
|
| -
|
| - bytes_read_buffer_.push_back(
|
| - BytesReadParam(origin_pid, child_id, route_id, byte_count));
|
| -}
|
| -
|
| -// This is called on the UI thread.
|
| -void TaskManagerModel::NotifyDataReady() {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - for (size_t i = 0; i < on_data_ready_callbacks_.size(); ++i) {
|
| - if (!on_data_ready_callbacks_[i].is_null())
|
| - on_data_ready_callbacks_[i].Run();
|
| - }
|
| -
|
| - on_data_ready_callbacks_.clear();
|
| -}
|
| -
|
| -void TaskManagerModel::RegisterOnDataReadyCallback(
|
| - const base::Closure& callback) {
|
| - on_data_ready_callbacks_.push_back(callback);
|
| -}
|
| -
|
| -TaskManagerModel::~TaskManagerModel() {
|
| - on_data_ready_callbacks_.clear();
|
| -}
|
| -
|
| -void TaskManagerModel::RefreshCallback() {
|
| - DCHECK_NE(IDLE, update_state_);
|
| -
|
| - if (update_state_ == STOPPING) {
|
| - // We have been asked to stop.
|
| - update_state_ = IDLE;
|
| - return;
|
| - }
|
| -
|
| - Refresh();
|
| -
|
| - // Schedule the next update.
|
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
| - FROM_HERE, base::Bind(&TaskManagerModel::RefreshCallback, this),
|
| - base::TimeDelta::FromMilliseconds(kUpdateTimeMs));
|
| -}
|
| -
|
| -void TaskManagerModel::RefreshVideoMemoryUsageStats() {
|
| - if (pending_video_memory_usage_stats_update_)
|
| - return;
|
| -
|
| - if (!video_memory_usage_stats_observer_.get()) {
|
| - video_memory_usage_stats_observer_.reset(
|
| - new TaskManagerModelGpuDataManagerObserver());
|
| - }
|
| - pending_video_memory_usage_stats_update_ = true;
|
| - content::GpuDataManager::GetInstance()->RequestVideoMemoryUsageStatsUpdate();
|
| -}
|
| -
|
| -int64_t TaskManagerModel::GetNetworkUsageForResource(Resource* resource) const {
|
| - // Returns default of 0 if no network usage.
|
| - return per_resource_cache_[resource].network_usage;
|
| -}
|
| -
|
| -void TaskManagerModel::BytesRead(BytesReadParam param) {
|
| - if (update_state_ != TASK_PENDING || listen_requests_ == 0) {
|
| - // A notification sneaked in while we were stopping the updating, just
|
| - // ignore it.
|
| - return;
|
| - }
|
| -
|
| - // TODO(jcampan): this should be improved once we have a better way of
|
| - // linking a network notification back to the object that initiated it.
|
| - Resource* resource = NULL;
|
| - for (ResourceProviderList::iterator iter = providers_.begin();
|
| - iter != providers_.end(); ++iter) {
|
| - resource = (*iter)->GetResource(param.origin_pid,
|
| - param.child_id,
|
| - param.route_id);
|
| - if (resource)
|
| - break;
|
| - }
|
| -
|
| - if (resource == NULL) {
|
| - // We can't match a resource to the notification. That might mean the
|
| - // tab that started a download was closed, or the request may have had
|
| - // no originating resource associated with it in the first place.
|
| - // We attribute orphaned/unaccounted activity to the Browser process.
|
| - CHECK(param.origin_pid || (param.child_id != -1));
|
| - param.origin_pid = 0;
|
| - param.child_id = param.route_id = -1;
|
| - BytesRead(param);
|
| - return;
|
| - }
|
| -
|
| - // We do support network usage, mark the resource as such so it can report 0
|
| - // instead of N/A.
|
| - if (!resource->SupportNetworkUsage())
|
| - resource->SetSupportNetworkUsage();
|
| -
|
| - ResourceValueMap::const_iterator iter_res =
|
| - current_byte_count_map_.find(resource);
|
| - if (iter_res == current_byte_count_map_.end())
|
| - current_byte_count_map_[resource] = param.byte_count;
|
| - else
|
| - current_byte_count_map_[resource] = iter_res->second + param.byte_count;
|
| -}
|
| -
|
| -void TaskManagerModel::MultipleBytesRead(
|
| - const std::vector<BytesReadParam>* params) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - for (std::vector<BytesReadParam>::const_iterator it = params->begin();
|
| - it != params->end(); ++it) {
|
| - BytesRead(*it);
|
| - }
|
| -}
|
| -
|
| -void TaskManagerModel::NotifyMultipleBytesRead() {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - DCHECK(!bytes_read_buffer_.empty());
|
| -
|
| - std::vector<BytesReadParam>* bytes_read_buffer =
|
| - new std::vector<BytesReadParam>;
|
| - bytes_read_buffer_.swap(*bytes_read_buffer);
|
| - BrowserThread::PostTask(
|
| - BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&TaskManagerModel::MultipleBytesRead, this,
|
| - base::Owned(bytes_read_buffer)));
|
| -}
|
| -
|
| -void TaskManagerModel::SetUpdatingByteCount(bool is_updating) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - is_updating_byte_count_ = is_updating;
|
| -}
|
| -
|
| -int64_t TaskManagerModel::GetNetworkUsage(Resource* resource) const {
|
| - int64_t net_usage = GetNetworkUsageForResource(resource);
|
| - if (net_usage == 0 && !resource->SupportNetworkUsage())
|
| - return -1;
|
| - return net_usage;
|
| -}
|
| -
|
| -double TaskManagerModel::GetCPUUsage(Resource* resource) const {
|
| - const PerProcessValues& values(per_process_cache_[resource->GetProcess()]);
|
| - // Returns 0 if not valid, which is fine.
|
| - return values.cpu_usage;
|
| -}
|
| -
|
| -int TaskManagerModel::GetIdleWakeupsPerSecond(Resource* resource) const {
|
| - const PerProcessValues& values(per_process_cache_[resource->GetProcess()]);
|
| - // Returns 0 if not valid, which is fine.
|
| - return values.idle_wakeups;
|
| -}
|
| -
|
| -base::string16 TaskManagerModel::GetMemCellText(int64_t number) const {
|
| - // System expectation is to show "100 kB", "200 MB", etc.
|
| - // TODO(thakis): Switch to metric units (as opposed to powers of two).
|
| - return ui::FormatBytes(number);
|
| -}
|
| -
|
| -bool TaskManagerModel::CachePrivateAndSharedMemory(
|
| - base::ProcessHandle handle) const {
|
| - PerProcessValues& values(per_process_cache_[handle]);
|
| - if (values.is_private_and_shared_valid)
|
| - return true;
|
| -
|
| - MetricsMap::const_iterator iter = metrics_map_.find(handle);
|
| - if (iter == metrics_map_.end() ||
|
| - !iter->second->GetMemoryBytes(&values.private_bytes,
|
| - &values.shared_bytes)) {
|
| - return false;
|
| - }
|
| -
|
| - values.is_private_and_shared_valid = true;
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::CacheWebCoreStats(int index) const {
|
| - PerResourceValues& values(GetPerResourceValues(index));
|
| - if (!values.is_webcore_stats_valid) {
|
| - if (!GetResource(index)->ReportsCacheStats())
|
| - return false;
|
| - values.is_webcore_stats_valid = true;
|
| - values.webcore_stats = GetResource(index)->GetWebCoreCacheStats();
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool TaskManagerModel::CacheV8Memory(int index) const {
|
| - PerResourceValues& values(GetPerResourceValues(index));
|
| - if (!values.is_v8_memory_valid) {
|
| - if (!GetResource(index)->ReportsV8MemoryStats())
|
| - return false;
|
| - values.is_v8_memory_valid = true;
|
| - values.v8_memory_allocated = GetResource(index)->GetV8MemoryAllocated();
|
| - values.v8_memory_used = GetResource(index)->GetV8MemoryUsed();
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -void TaskManagerModel::AddResourceProvider(ResourceProvider* provider) {
|
| - DCHECK(provider);
|
| - providers_.push_back(provider);
|
| -}
|
| -
|
| -TaskManagerModel::PerResourceValues& TaskManagerModel::GetPerResourceValues(
|
| - int index) const {
|
| - return per_resource_cache_[GetResource(index)];
|
| -}
|
| -
|
| -Resource* TaskManagerModel::GetResource(int index) const {
|
| - CHECK_GE(index, 0);
|
| - CHECK_LT(index, static_cast<int>(resources_.size()));
|
| - return resources_[index];
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// TaskManager class
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -bool TaskManager::IsBrowserProcess(int index) const {
|
| - // If some of the selection is out of bounds, ignore. This may happen when
|
| - // killing a process that manages several pages.
|
| - return index < model_->ResourceCount() &&
|
| - model_->GetProcess(index) == base::GetCurrentProcessHandle();
|
| -}
|
| -
|
| -void TaskManager::KillProcess(int index) {
|
| - base::ProcessHandle process_handle = model_->GetProcess(index);
|
| - DCHECK(process_handle);
|
| - if (process_handle != base::GetCurrentProcessHandle()) {
|
| - base::Process process =
|
| - base::Process::DeprecatedGetProcessFromHandle(process_handle);
|
| - process.Terminate(content::RESULT_CODE_KILLED, false);
|
| - }
|
| -}
|
| -
|
| -void TaskManager::ActivateProcess(int index) {
|
| - // GetResourceWebContents returns a pointer to the relevant web contents for
|
| - // the resource. If the index doesn't correspond to any web contents
|
| - // (i.e. refers to the Browser process or a plugin), GetWebContents will
|
| - // return NULL.
|
| - WebContents* chosen_web_contents = model_->GetResourceWebContents(index);
|
| - if (chosen_web_contents && chosen_web_contents->GetDelegate())
|
| - chosen_web_contents->GetDelegate()->ActivateContents(chosen_web_contents);
|
| -}
|
| -
|
| -void TaskManager::AddResource(Resource* resource) {
|
| - model_->AddResource(resource);
|
| -}
|
| -
|
| -void TaskManager::RemoveResource(Resource* resource) {
|
| - model_->RemoveResource(resource);
|
| -}
|
| -
|
| -void TaskManager::OnWindowClosed() {
|
| - model_->StopUpdating();
|
| -}
|
| -
|
| -void TaskManager::ModelChanged() {
|
| - model_->ModelChanged();
|
| -}
|
| -
|
| -// static
|
| -TaskManager* TaskManager::GetInstance() {
|
| - CHECK(!task_management::TaskManagerInterface::IsNewTaskManagerEnabled());
|
| - return base::Singleton<TaskManager>::get();
|
| -}
|
| -
|
| -TaskManager::TaskManager()
|
| - : model_(new TaskManagerModel(this)) {
|
| -}
|
| -
|
| -TaskManager::~TaskManager() {
|
| -}
|
|
|