This source file includes following definitions.
- ValueCompare
- OrderUnavailableValue
- ValueCompareMember
- FormatStatsSize
- IsSharedByGroup
- GetWinGDIHandles
- GetWinUSERHandles
- NotifyVideoMemoryUsageStats
- OnVideoMemoryUsageStatsUpdate
- v8_memory_used
- user_handles_peak
- goat_salt_
- AddObserver
- RemoveObserver
- ResourceCount
- GroupCount
- GetNaClDebugStubPort
- GetNetworkUsage
- GetCPUUsage
- GetIdleWakeupsPerSecond
- GetProcessId
- GetProcess
- GetResourceById
- GetResourceTitle
- GetResourceProfileName
- GetResourceNaClDebugStubPort
- GetResourceNetworkUsage
- GetResourceCPUUsage
- GetResourcePrivateMemory
- GetResourceSharedMemory
- GetResourcePhysicalMemory
- GetResourceProcessId
- GetResourceGDIHandles
- GetResourceUSERHandles
- GetResourceWebCoreImageCacheSize
- GetResourceWebCoreScriptsCacheSize
- GetResourceWebCoreCSSCacheSize
- GetResourceVideoMemory
- GetResourceFPS
- GetResourceSqliteMemoryUsed
- GetResourceIdleWakeupsPerSecond
- GetResourceGoatsTeleported
- GetResourceV8MemoryAllocatedSize
- GetPrivateMemory
- GetSharedMemory
- GetPhysicalMemory
- GetGDIHandles
- GetUSERHandles
- GetWebCoreCacheStats
- GetVideoMemory
- GetFPS
- GetSqliteMemoryUsedBytes
- GetV8Memory
- GetV8MemoryUsed
- CanActivate
- CanInspect
- Inspect
- GetGoatsTeleported
- IsResourceFirstInGroup
- IsResourceLastInGroup
- GetResourceIcon
- GetGroupRangeForResource
- GetGroupIndexForResource
- GetResourceIndexForGroup
- CompareValues
- GetUniqueChildProcessId
- GetResourceType
- GetResourceWebContents
- AddResource
- RemoveResource
- StartUpdating
- StopUpdating
- StartListening
- StopListening
- Clear
- ModelChanged
- Refresh
- NotifyResourceTypeStats
- NotifyFPS
- NotifyVideoMemoryUsageStats
- NotifyV8HeapStats
- NotifyBytesRead
- NotifyDataReady
- RegisterOnDataReadyCallback
- RefreshCallback
- RefreshVideoMemoryUsageStats
- GetNetworkUsageForResource
- BytesRead
- MultipleBytesRead
- NotifyMultipleBytesRead
- GetNetworkUsage
- GetCPUUsage
- GetIdleWakeupsPerSecond
- GetMemCellText
- CachePrivateAndSharedMemory
- CacheWebCoreStats
- CacheV8Memory
- AddResourceProvider
- GetPerResourceValues
- GetResource
- RegisterPrefs
- IsBrowserProcess
- KillProcess
- ActivateProcess
- AddResource
- RemoveResource
- OnWindowClosed
- ModelChanged
- GetInstance
- OpenAboutMemory
#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/prefs/pref_registry_simple.h"
#include "base/process/process_metrics.h"
#include "base/rand_util.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 "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.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/task_manager/worker_resource_provider.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.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/common/result_codes.h"
#include "extensions/browser/extension_system.h"
#include "grit/generated_resources.h"
#include "grit/ui_resources.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"
#if !defined(OS_CHROMEOS)
#include "chrome/browser/task_manager/notification_resource_provider.h"
#endif
#if defined(OS_MACOSX)
#include "content/public/browser/browser_child_process_host.h"
#endif
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;
}
int OrderUnavailableValue(bool v1, bool v2) {
if (!v1 && !v2)
return 0;
return v1 ? 1 : -1;
}
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));
}
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;
}
}
#if defined(OS_WIN)
void GetWinGDIHandles(base::ProcessHandle process,
size_t* current,
size_t* peak) {
*current = 0;
*peak = 0;
HANDLE current_process = GetCurrentProcess();
HANDLE process_with_query_rights;
if (DuplicateHandle(current_process, process, current_process,
&process_with_query_rights, PROCESS_QUERY_INFORMATION,
false, 0)) {
*current = GetGuiResources(process_with_query_rights, GR_GDIOBJECTS);
*peak = GetGuiResources(process_with_query_rights, GR_GDIOBJECTS_PEAK);
CloseHandle(process_with_query_rights);
}
}
void GetWinUSERHandles(base::ProcessHandle process,
size_t* current,
size_t* peak) {
*current = 0;
*peak = 0;
HANDLE current_process = GetCurrentProcess();
HANDLE process_with_query_rights;
if (DuplicateHandle(current_process, process, current_process,
&process_with_query_rights, PROCESS_QUERY_INFORMATION,
false, 0)) {
*current = GetGuiResources(process_with_query_rights, GR_USEROBJECTS);
*peak = GetGuiResources(process_with_query_rights, GR_USEROBJECTS_PEAK);
CloseHandle(process_with_query_rights);
}
}
#endif
}
class TaskManagerModelGpuDataManagerObserver
: public content::GpuDataManagerObserver {
public:
TaskManagerModelGpuDataManagerObserver() {
content::GpuDataManager::GetInstance()->AddObserver(this);
}
virtual ~TaskManagerModelGpuDataManagerObserver() {
content::GpuDataManager::GetInstance()->RemoveObserver(this);
}
static void NotifyVideoMemoryUsageStats(
const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) {
TaskManager::GetInstance()->model()->NotifyVideoMemoryUsageStats(
video_memory_usage_stats);
}
virtual void OnVideoMemoryUsageStatsUpdate(
const content::GPUVideoMemoryUsageStats& 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_nacl_debug_stub_port_valid(false),
nacl_debug_stub_port(0),
is_title_valid(false),
is_profile_name_valid(false),
network_usage(0),
is_process_id_valid(false),
process_id(0),
is_goats_teleported_valid(false),
goats_teleported(0),
is_webcore_stats_valid(false),
is_fps_valid(false),
fps(0),
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() {}
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) {}
TaskManagerModel::PerProcessValues::~PerProcessValues() {}
TaskManagerModel::TaskManagerModel(TaskManager* task_manager)
: pending_video_memory_usage_stats_update_(false),
update_requests_(0),
listen_requests_(0),
update_state_(IDLE),
goat_salt_(base::RandUint64()) {
AddResourceProvider(
new task_manager::BrowserProcessResourceProvider(task_manager));
AddResourceProvider(new task_manager::WebContentsResourceProvider(
task_manager,
scoped_ptr<WebContentsInformation>(
new task_manager::BackgroundInformation())));
AddResourceProvider(new task_manager::WebContentsResourceProvider(
task_manager,
scoped_ptr<WebContentsInformation>(
new task_manager::TabContentsInformation())));
AddResourceProvider(new task_manager::WebContentsResourceProvider(
task_manager,
scoped_ptr<WebContentsInformation>(
new task_manager::PrintingInformation())));
AddResourceProvider(new task_manager::WebContentsResourceProvider(
task_manager,
scoped_ptr<WebContentsInformation>(
new task_manager::PanelInformation())));
AddResourceProvider(
new task_manager::ChildProcessResourceProvider(task_manager));
AddResourceProvider(new task_manager::WebContentsResourceProvider(
task_manager,
scoped_ptr<WebContentsInformation>(
new task_manager::ExtensionInformation())));
AddResourceProvider(new task_manager::WebContentsResourceProvider(
task_manager,
scoped_ptr<WebContentsInformation>(
new task_manager::GuestInformation())));
#if !defined(OS_CHROMEOS) && defined(ENABLE_NOTIFICATIONS)
ResourceProvider* provider =
task_manager::NotificationResourceProvider::Create(task_manager);
if (provider)
AddResourceProvider(provider);
#endif
AddResourceProvider(new task_manager::WorkerResourceProvider(task_manager));
}
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 {
PerResourceValues& values(GetPerResourceValues(index));
if (!values.is_nacl_debug_stub_port_valid) {
values.is_nacl_debug_stub_port_valid = true;
values.nacl_debug_stub_port = GetResource(index)->GetNaClDebugStubPort();
}
return values.nacl_debug_stub_port;
}
int64 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;
values.process_id = base::GetProcId(GetResource(index)->GetProcess());
}
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_GOATS_TELEPORTED_COLUMN:
return GetResourceGoatsTeleported(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_FPS_COLUMN:
return GetResourceFPS(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 == 0) {
return base::ASCIIToUTF16("N/A");
} else {
return base::IntToString16(port);
}
}
base::string16 TaskManagerModel::GetResourceNetworkUsage(int index) const {
int64 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);
return base::i18n::GetDisplayStringInLTRDirectionality(net_byte);
}
base::string16 TaskManagerModel::GetResourceCPUUsage(int index) const {
return base::UTF8ToUTF16(base::StringPrintf(
#if defined(OS_MACOSX)
"%.1f",
#else
"%.0f",
#endif
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::IntToString16(current), base::IntToString16(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::IntToString16(current), base::IntToString16(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::GetResourceFPS(
int index) const {
float fps = 0;
if (!GetFPS(index, &fps))
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
return base::UTF8ToUTF16(base::StringPrintf("%.0f", fps));
}
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::GetResourceGoatsTeleported(int index) const {
CHECK_LT(index, ResourceCount());
return base::FormatNumber(GetGoatsTeleported(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;
#if defined(OS_LINUX)
values.physical_memory = ws_usage.priv * 1024;
#else
values.physical_memory = iter->second->GetWorkingSetSize();
values.physical_memory -= ws_usage.shared * 1024;
#endif
}
*result = values.physical_memory;
return true;
}
void TaskManagerModel::GetGDIHandles(int index,
size_t* current,
size_t* peak) const {
*current = 0;
*peak = 0;
#if defined(OS_WIN)
base::ProcessHandle handle = GetResource(index)->GetProcess();
PerProcessValues& values(per_process_cache_[handle]);
if (!values.is_gdi_handles_valid) {
GetWinGDIHandles(GetResource(index)->GetProcess(),
&values.gdi_handles,
&values.gdi_handles_peak);
values.is_gdi_handles_valid = true;
}
*current = values.gdi_handles;
*peak = values.gdi_handles_peak;
#endif
}
void TaskManagerModel::GetUSERHandles(int index,
size_t* current,
size_t* peak) const {
*current = 0;
*peak = 0;
#if defined(OS_WIN)
base::ProcessHandle handle = GetResource(index)->GetProcess();
PerProcessValues& values(per_process_cache_[handle]);
if (!values.is_user_handles_valid) {
GetWinUSERHandles(GetResource(index)->GetProcess(),
&values.user_handles,
&values.user_handles_peak);
values.is_user_handles_valid = true;
}
*current = values.user_handles;
*peak = values.user_handles_peak;
#endif
}
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) {
content::GPUVideoMemoryUsageStats::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;
values.video_memory = 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::GetFPS(int index, float* result) const {
*result = 0;
PerResourceValues& values(GetPerResourceValues(index));
if (!values.is_fps_valid) {
if (!GetResource(index)->ReportsFPS())
return false;
values.is_fps_valid = true;
values.fps = GetResource(index)->GetFPS();
}
*result = values.fps;
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::CanInspect(int index) const {
return GetResource(index)->CanInspect();
}
void TaskManagerModel::Inspect(int index) const {
CHECK_LT(index, ResourceCount());
GetResource(index)->Inspect();
}
int TaskManagerModel::GetGoatsTeleported(int index) const {
PerResourceValues& values(GetPerResourceValues(index));
if (!values.is_goats_teleported_valid) {
values.is_goats_teleported_valid = true;
values.goats_teleported = goat_salt_ * (index + 1);
values.goats_teleported = (values.goats_teleported >> 16) & 255;
}
return values.goats_teleported;
}
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 gfx::ImageSkia* default_icon = ResourceBundle::GetSharedInstance().
GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
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());
ResourceList* group = group_iter->second;
DCHECK(group);
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_FPS_COLUMN:
return ValueCompareMember(
this, &TaskManagerModel::GetFPS, row1, row2);
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_GOATS_TELEPORTED_COLUMN:
return ValueCompare(GetGoatsTeleported(row1), GetGoatsTeleported(row2));
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();
ResourceList* group_entries = NULL;
GroupMap::const_iterator group_iter = group_map_.find(process);
int new_entry_index = 0;
if (group_iter == group_map_.end()) {
group_entries = new ResourceList();
group_map_[process] = group_entries;
group_entries->push_back(resource);
resources_.push_back(resource);
new_entry_index = static_cast<int>(resources_.size() - 1);
} else {
group_entries = group_iter->second;
group_entries->push_back(resource);
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);
}
if (metrics_map_.find(process) == metrics_map_.end()) {
base::ProcessMetrics* pm =
#if !defined(OS_MACOSX)
base::ProcessMetrics::CreateProcessMetrics(process);
#else
base::ProcessMetrics::CreateProcessMetrics(
process, content::BrowserChildProcessHost::GetPortProvider());
#endif
metrics_map_[process] = pm;
}
FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
OnItemsAdded(new_entry_index, 1));
}
void TaskManagerModel::RemoveResource(Resource* resource) {
base::ProcessHandle process = resource->GetProcess();
GroupMap::iterator group_iter = group_map_.find(process);
DCHECK(group_iter != group_map_.end());
ResourceList* group_entries = group_iter->second;
ResourceList::iterator iter = std::find(group_entries->begin(),
group_entries->end(),
resource);
DCHECK(iter != group_entries->end());
group_entries->erase(iter);
if (group_entries->empty()) {
delete group_entries;
group_map_.erase(process);
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);
}
}
iter = std::find(resources_.begin(), resources_.end(), resource);
DCHECK(iter != resources_.end());
int index = static_cast<int>(iter - resources_.begin());
FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
OnItemsToBeRemoved(index, 1));
resources_.erase(iter);
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);
FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
OnItemsRemoved(index, 1));
}
void TaskManagerModel::StartUpdating() {
update_requests_++;
if (update_requests_ > 1)
return;
DCHECK_EQ(1, update_requests_);
DCHECK_NE(TASK_PENDING, update_state_);
if (update_state_ == IDLE) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&TaskManagerModel::RefreshCallback, this));
}
update_state_ = TASK_PENDING;
StartListening();
if (!resources_.empty()) {
FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_,
OnReadyPeriodicalUpdate());
}
}
void TaskManagerModel::StopUpdating() {
update_requests_--;
if (update_requests_ > 0)
return;
CHECK_EQ(0, update_requests_);
DCHECK_EQ(TASK_PENDING, update_state_);
update_state_ = STOPPING;
StopListening();
}
void TaskManagerModel::StartListening() {
listen_requests_++;
if (listen_requests_ > 1)
return;
DCHECK_EQ(1, listen_requests_);
for (ResourceProviderList::iterator iter = providers_.begin();
iter != providers_.end(); ++iter) {
(*iter)->StartUpdating();
}
}
void TaskManagerModel::StopListening() {
listen_requests_--;
if (listen_requests_ > 0)
return;
DCHECK_EQ(0, listen_requests_);
for (ResourceProviderList::const_iterator iter = providers_.begin();
iter != providers_.end(); ++iter) {
(*iter)->StopUpdating();
}
Clear();
}
void TaskManagerModel::Clear() {
int size = ResourceCount();
if (size > 0) {
resources_.clear();
STLDeleteValues(&group_map_);
STLDeleteValues(&metrics_map_);
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() {
FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_, OnModelChanged());
}
void TaskManagerModel::Refresh() {
goat_salt_ = base::RandUint64();
per_resource_cache_.clear();
per_process_cache_.clear();
for (ResourceList::iterator iter = resources_.begin();
iter != resources_.end(); ++iter) {
base::ProcessHandle process = (*iter)->GetProcess();
PerProcessValues& values(per_process_cache_[process]);
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();
}
#if defined(OS_MACOSX)
if (!values.is_idle_wakeups_valid) {
values.is_idle_wakeups_valid = true;
values.idle_wakeups = metrics_iter->second->GetIdleWakeupsPerSecond();
}
#endif
}
RefreshVideoMemoryUsageStats();
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());
iter->second = 0;
}
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::NotifyResourceTypeStats(
base::ProcessId renderer_id,
const blink::WebCache::ResourceTypeStats& stats) {
for (ResourceList::iterator it = resources_.begin();
it != resources_.end(); ++it) {
if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
(*it)->NotifyResourceTypeStats(stats);
}
}
}
void TaskManagerModel::NotifyFPS(base::ProcessId renderer_id,
int routing_id,
float fps) {
for (ResourceList::iterator it = resources_.begin();
it != resources_.end(); ++it) {
if (base::GetProcId((*it)->GetProcess()) == renderer_id &&
(*it)->GetRoutingID() == routing_id) {
(*it)->NotifyFPS(fps);
}
}
}
void TaskManagerModel::NotifyVideoMemoryUsageStats(
const content::GPUVideoMemoryUsageStats& 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::NotifyV8HeapStats(base::ProcessId renderer_id,
size_t v8_memory_allocated,
size_t v8_memory_used) {
for (ResourceList::iterator it = resources_.begin();
it != resources_.end(); ++it) {
if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
(*it)->NotifyV8HeapStats(v8_memory_allocated, v8_memory_used);
}
}
}
void TaskManagerModel::NotifyBytesRead(const net::URLRequest& request,
int byte_count) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
int child_id = -1, route_id = -1;
if (info)
info->GetAssociatedRenderFrame(&child_id, &route_id);
int origin_pid = 0;
if (info)
origin_pid = info->GetOriginPID();
if (bytes_read_buffer_.empty()) {
base::MessageLoop::current()->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));
}
void TaskManagerModel::NotifyDataReady() {
DCHECK(BrowserThread::CurrentlyOn(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) {
update_state_ = IDLE;
return;
}
Refresh();
base::MessageLoop::current()->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 TaskManagerModel::GetNetworkUsageForResource(Resource* resource) const {
return per_resource_cache_[resource].network_usage;
}
void TaskManagerModel::BytesRead(BytesReadParam param) {
if (update_state_ != TASK_PENDING || listen_requests_ == 0) {
return;
}
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) {
CHECK(param.origin_pid || (param.child_id != -1));
param.origin_pid = 0;
param.child_id = param.route_id = -1;
BytesRead(param);
return;
}
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(BrowserThread::CurrentlyOn(BrowserThread::UI));
for (std::vector<BytesReadParam>::const_iterator it = params->begin();
it != params->end(); ++it) {
BytesRead(*it);
}
}
void TaskManagerModel::NotifyMultipleBytesRead() {
DCHECK(BrowserThread::CurrentlyOn(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)));
}
int64 TaskManagerModel::GetNetworkUsage(Resource* resource) const {
int64 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()]);
return values.cpu_usage;
}
int TaskManagerModel::GetIdleWakeupsPerSecond(Resource* resource) const {
const PerProcessValues& values(per_process_cache_[resource->GetProcess()]);
return values.idle_wakeups;
}
base::string16 TaskManagerModel::GetMemCellText(int64 number) const {
#if !defined(OS_MACOSX)
base::string16 str = base::FormatNumber(number / 1024);
base::i18n::AdjustStringForLocaleDirection(&str);
return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_MEM_CELL_TEXT, str);
#else
return ui::FormatBytes(number);
#endif
}
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];
}
void TaskManager::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(prefs::kTaskManagerWindowPlacement);
}
bool TaskManager::IsBrowserProcess(int index) const {
return index < model_->ResourceCount() &&
model_->GetProcess(index) == base::GetCurrentProcessHandle();
}
void TaskManager::KillProcess(int index) {
base::ProcessHandle process = model_->GetProcess(index);
DCHECK(process);
if (process != base::GetCurrentProcessHandle())
base::KillProcess(process, content::RESULT_CODE_KILLED, false);
}
void TaskManager::ActivateProcess(int index) {
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();
}
TaskManager* TaskManager::GetInstance() {
return Singleton<TaskManager>::get();
}
void TaskManager::OpenAboutMemory(chrome::HostDesktopType desktop_type) {
chrome::NavigateParams params(
ProfileManager::GetLastUsedProfileAllowedByPolicy(),
GURL(chrome::kChromeUIMemoryURL),
content::PAGE_TRANSITION_LINK);
params.disposition = NEW_FOREGROUND_TAB;
params.host_desktop_type = desktop_type;
chrome::Navigate(¶ms);
}
TaskManager::TaskManager()
: model_(new TaskManagerModel(this)) {
}
TaskManager::~TaskManager() {
}