cef/libcef/browser/task_manager_impl.cc

184 lines
5.2 KiB
C++

// Copyright (c) 2024 The Chromium Embedded Framework 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 "cef/libcef/browser/task_manager_impl.h"
#include "base/check.h"
#include "base/ranges/algorithm.h"
#include "base/system/sys_info.h"
#include "cef/libcef/browser/browser_host_base.h"
#include "cef/libcef/browser/context.h"
#include "cef/libcef/browser/thread_util.h"
#include "chrome/browser/task_manager/task_manager_interface.h"
namespace {
#if BUILDFLAG(IS_MAC)
// Match Activity Monitor's default refresh rate.
const int64_t kRefreshTimeMS = 2000;
#else
const int64_t kRefreshTimeMS = 1000;
#endif // BUILDFLAG(IS_MAC)
CefTaskManager::TaskType toCefTaskType(task_manager::Task::Type type) {
switch (type) {
case task_manager::Task::UNKNOWN:
case task_manager::Task::ARC:
case task_manager::Task::CROSTINI:
case task_manager::Task::PLUGIN_VM:
case task_manager::Task::NACL:
case task_manager::Task::LACROS:
return CEF_TASK_TYPE_UNKNOWN;
case task_manager::Task::BROWSER:
return CEF_TASK_TYPE_BROWSER;
case task_manager::Task::GPU:
return CEF_TASK_TYPE_GPU;
case task_manager::Task::ZYGOTE:
return CEF_TASK_TYPE_ZYGOTE;
case task_manager::Task::UTILITY:
return CEF_TASK_TYPE_UTILITY;
case task_manager::Task::RENDERER:
return CEF_TASK_TYPE_RENDERER;
case task_manager::Task::EXTENSION:
return CEF_TASK_TYPE_EXTENSION;
case task_manager::Task::GUEST:
return CEF_TASK_TYPE_GUEST;
case task_manager::Task::PLUGIN:
return CEF_TASK_TYPE_PLUGIN;
case task_manager::Task::SANDBOX_HELPER:
return CEF_TASK_TYPE_SANDBOX_HELPER;
case task_manager::Task::DEDICATED_WORKER:
return CEF_TASK_TYPE_DEDICATED_WORKER;
case task_manager::Task::SHARED_WORKER:
return CEF_TASK_TYPE_SHARED_WORKER;
case task_manager::Task::SERVICE_WORKER:
return CEF_TASK_TYPE_SERVICE_WORKER;
}
return CEF_TASK_TYPE_UNKNOWN;
}
int64_t GetRefreshTypes() {
return task_manager::REFRESH_TYPE_CPU |
task_manager::REFRESH_TYPE_GPU_MEMORY |
task_manager::REFRESH_TYPE_MEMORY_FOOTPRINT;
}
} // namespace
CefTaskManagerImpl::CefTaskManagerImpl(
task_manager::TaskManagerInterface* task_manager)
: TaskManagerObserver(base::Milliseconds(kRefreshTimeMS),
GetRefreshTypes()),
task_manager_(task_manager) {
DCHECK(task_manager_);
task_manager_->AddObserver(this);
tasks_ = task_manager->GetTaskIdsList();
}
CefTaskManagerImpl::~CefTaskManagerImpl() {
task_manager_->RemoveObserver(this);
}
void CefTaskManagerImpl::OnTaskAdded(int64_t id) {
tasks_ = observed_task_manager()->GetTaskIdsList();
}
void CefTaskManagerImpl::OnTaskToBeRemoved(int64_t id) {
auto index = base::ranges::find(tasks_, id);
if (index != tasks_.end()) {
tasks_.erase(index);
}
}
void CefTaskManagerImpl::OnTasksRefreshed(
const task_manager::TaskIdList& task_ids) {
tasks_ = task_ids;
}
size_t CefTaskManagerImpl::GetTasksCount() {
CEF_REQUIRE_UIT_RETURN(0U);
return tasks_.size();
}
bool CefTaskManagerImpl::GetTaskIdsList(TaskIdList& task_ids) {
CEF_REQUIRE_UIT_RETURN(false);
task_ids = tasks_;
return true;
}
bool CefTaskManagerImpl::GetTaskInfo(int64_t task_id, CefTaskInfo& info) {
CEF_REQUIRE_UIT_RETURN(false);
if (!IsValidTaskId(task_id)) {
return false;
}
info.id = task_id;
info.type = toCefTaskType(task_manager_->GetType(task_id));
info.is_killable = task_manager_->IsTaskKillable(task_id);
CefString(&info.title) = task_manager_->GetTitle(task_id);
info.cpu_usage = task_manager_->GetPlatformIndependentCPUUsage(task_id);
// Avoid returning quiet_NaN for CPU usage.
if (info.cpu_usage != info.cpu_usage) {
info.cpu_usage = 0.0;
}
info.number_of_processors = base::SysInfo::NumberOfProcessors();
info.memory = task_manager_->GetMemoryFootprintUsage(task_id);
bool has_duplicates = false;
info.gpu_memory = task_manager_->GetGpuMemoryUsage(task_id, &has_duplicates);
info.is_gpu_memory_inflated = has_duplicates;
return true;
}
bool CefTaskManagerImpl::KillTask(int64_t task_id) {
CEF_REQUIRE_UIT_RETURN(false);
if (!IsValidTaskId(task_id)) {
return false;
}
if (!task_manager_->IsTaskKillable(task_id)) {
return false;
}
task_manager_->KillTask(task_id);
return true;
}
int64_t CefTaskManagerImpl::GetTaskIdForBrowserId(int browser_id) {
CEF_REQUIRE_UIT_RETURN(-1);
auto browser = CefBrowserHostBase::GetBrowserForBrowserId(browser_id);
if (!browser) {
return -1;
}
auto* web_contents = browser->GetWebContents();
if (!web_contents) {
return -1;
}
return task_manager_->GetTaskIdForWebContents(web_contents);
}
bool CefTaskManagerImpl::IsValidTaskId(int64_t task_id) const {
return base::ranges::find(tasks_, task_id) != tasks_.end();
}
CefRefPtr<CefTaskManager> CefTaskManager::GetTaskManager() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
DCHECK(false) << "context not valid";
return nullptr;
}
CEF_REQUIRE_UIT_RETURN(nullptr);
return new CefTaskManagerImpl(
task_manager::TaskManagerInterface::GetTaskManager());
}