#include "chrome/browser/task_manager/sampling/task_group.h"
#include <algorithm>
#include <limits>
#include <vector>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/task/sequenced_task_runner.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/task_manager/sampling/shared_sampler.h"
#include "chrome/browser/task_manager/task_manager_observer.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "gpu/ipc/common/memory_stats.h"
#if BUILDFLAG(ENABLE_NACL)
#include "components/nacl/browser/nacl_browser.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/task_manager/providers/crosapi/crosapi_task_provider_ash.h"
#endif
namespace task_manager {
namespace {
const int kBackgroundRefreshTypesMask = …;
#if BUILDFLAG(IS_WIN)
void GetWindowsHandles(base::ProcessHandle handle,
int64_t* out_gdi_current,
int64_t* out_gdi_peak,
int64_t* out_user_current,
int64_t* out_user_peak) {
*out_gdi_current = 0;
*out_gdi_peak = 0;
*out_user_current = 0;
*out_user_peak = 0;
HANDLE current_process = GetCurrentProcess();
HANDLE process_with_query_rights;
if (DuplicateHandle(current_process, handle, current_process,
&process_with_query_rights, PROCESS_QUERY_INFORMATION,
false, 0)) {
*out_gdi_current = static_cast<int64_t>(
GetGuiResources(process_with_query_rights, GR_GDIOBJECTS));
*out_gdi_peak = static_cast<int64_t>(
GetGuiResources(process_with_query_rights, GR_GDIOBJECTS_PEAK));
*out_user_current = static_cast<int64_t>(
GetGuiResources(process_with_query_rights, GR_USEROBJECTS));
*out_user_peak = static_cast<int64_t>(
GetGuiResources(process_with_query_rights, GR_USEROBJECTS_PEAK));
CloseHandle(process_with_query_rights);
}
}
#endif
#if BUILDFLAG(ENABLE_NACL)
int GetNaClDebugStubPortOnProcessThread(int process_id) {
return nacl::NaClBrowser::GetInstance()->GetProcessGdbDebugStubPort(
process_id);
}
#endif
}
TaskGroup::TaskGroup(
base::ProcessHandle proc_handle,
base::ProcessId proc_id,
bool is_running_in_vm,
const base::RepeatingClosure& on_background_calculations_done,
const scoped_refptr<SharedSampler>& shared_sampler,
#if BUILDFLAG(IS_CHROMEOS_ASH)
CrosapiTaskProviderAsh* crosapi_task_provider,
#endif
const scoped_refptr<base::SequencedTaskRunner>& blocking_pool_runner)
: … { … }
TaskGroup::~TaskGroup() { … }
void TaskGroup::AddTask(Task* task) { … }
void TaskGroup::RemoveTask(Task* task) { … }
void TaskGroup::Refresh(const gpu::VideoMemoryUsageStats& gpu_memory_stats,
base::TimeDelta update_interval,
int64_t refresh_flags) { … }
Task* TaskGroup::GetTaskById(TaskId task_id) const { … }
void TaskGroup::ClearCurrentBackgroundCalculationsFlags() { … }
bool TaskGroup::AreBackgroundCalculationsDone() const { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void TaskGroup::SetArcSampler(ArcSharedSampler* sampler) {
DCHECK(sampler);
arc_shared_sampler_ = sampler;
arc_shared_sampler_->RegisterCallback(
process_id_, base::BindRepeating(&TaskGroup::OnArcSamplerRefreshDone,
weak_ptr_factory_.GetWeakPtr()));
}
#endif
void TaskGroup::RefreshGpuMemory(
const gpu::VideoMemoryUsageStats& gpu_memory_stats) { … }
void TaskGroup::RefreshWindowsHandles() { … }
#if BUILDFLAG(ENABLE_NACL)
void TaskGroup::RefreshNaClDebugStubPort(int child_process_unique_id) {
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce(&TaskGroup::OnRefreshNaClDebugStubPortDone,
weak_ptr_factory_.GetWeakPtr(),
GetNaClDebugStubPortOnProcessThread(
child_process_unique_id)));
}
void TaskGroup::OnRefreshNaClDebugStubPortDone(int nacl_debug_stub_port) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
nacl_debug_stub_port_ = nacl_debug_stub_port;
OnBackgroundRefreshTypeFinished(REFRESH_TYPE_NACL);
}
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
void TaskGroup::OnOpenFdCountRefreshDone(int open_fd_count) { … }
#endif
void TaskGroup::OnCpuRefreshDone(double cpu_usage) { … }
void TaskGroup::OnSwappedMemRefreshDone(int64_t swapped_mem_bytes) { … }
void TaskGroup::OnProcessPriorityDone(base::Process::Priority priority) { … }
void TaskGroup::OnIdleWakeupsRefreshDone(int idle_wakeups_per_second) { … }
void TaskGroup::OnSamplerRefreshDone(
std::optional<SharedSampler::SamplingResult> results) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void TaskGroup::OnArcSamplerRefreshDone(
std::optional<ArcSharedSampler::MemoryFootprintBytes> memory_footprint) {
if (memory_footprint)
set_footprint_bytes(*memory_footprint);
}
#endif
void TaskGroup::OnBackgroundRefreshTypeFinished(int64_t finished_refresh_type) { … }
}