From d470cf82048160089be360abe595c670ea37e0c6 Mon Sep 17 00:00:00 2001 From: Nik Pavlov Date: Thu, 18 Jul 2024 11:09:19 -0400 Subject: [PATCH] Add CefTaskManager API See https://tests/task_manager example in cefclient. --- BUILD.gn | 2 + cef_paths.gypi | 8 +- cef_paths2.gypi | 3 + include/capi/cef_task_manager_capi.h | 107 ++++++++++ include/cef_api_hash.h | 8 +- include/cef_task_manager.h | 100 ++++++++++ include/internal/cef_types.h | 61 ++++++ include/internal/cef_types_wrappers.h | 27 +++ libcef/browser/task_manager_impl.cc | 166 ++++++++++++++++ libcef/browser/task_manager_impl.h | 47 +++++ libcef_dll/cpptoc/task_manager_cpptoc.cc | 187 ++++++++++++++++++ libcef_dll/cpptoc/task_manager_cpptoc.h | 37 ++++ libcef_dll/ctocpp/task_manager_ctocpp.cc | 157 +++++++++++++++ libcef_dll/ctocpp/task_manager_ctocpp.h | 43 ++++ libcef_dll/wrapper/libcef_dll_dylib.cc | 9 +- libcef_dll/wrapper_types.h | 3 +- tests/cefclient/browser/resource.h | 15 +- .../browser/resource_util_win_idmap.cc | 1 + tests/cefclient/browser/task_manager_test.cc | 128 ++++++++++++ tests/cefclient/browser/task_manager_test.h | 17 ++ tests/cefclient/browser/test_runner.cc | 4 + tests/cefclient/resources/other_tests.html | 11 +- tests/cefclient/resources/task_manager.html | 119 +++++++++++ tests/cefclient/resources/win/cefclient.rc | 1 + 24 files changed, 1242 insertions(+), 19 deletions(-) create mode 100644 include/capi/cef_task_manager_capi.h create mode 100644 include/cef_task_manager.h create mode 100644 libcef/browser/task_manager_impl.cc create mode 100644 libcef/browser/task_manager_impl.h create mode 100644 libcef_dll/cpptoc/task_manager_cpptoc.cc create mode 100644 libcef_dll/cpptoc/task_manager_cpptoc.h create mode 100644 libcef_dll/ctocpp/task_manager_ctocpp.cc create mode 100644 libcef_dll/ctocpp/task_manager_ctocpp.h create mode 100644 tests/cefclient/browser/task_manager_test.cc create mode 100644 tests/cefclient/browser/task_manager_test.h create mode 100644 tests/cefclient/resources/task_manager.html diff --git a/BUILD.gn b/BUILD.gn index b185f929d..b486eb6a8 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -678,6 +678,8 @@ source_set("libcef_static") { "libcef/browser/ssl_status_impl.h", "libcef/browser/stream_impl.cc", "libcef/browser/stream_impl.h", + "libcef/browser/task_manager_impl.cc", + "libcef/browser/task_manager_impl.h", "libcef/browser/trace_impl.cc", "libcef/browser/trace_subscriber.cc", "libcef/browser/trace_subscriber.h", diff --git a/cef_paths.gypi b/cef_paths.gypi index 754eb0c60..64eb6f653 100644 --- a/cef_paths.gypi +++ b/cef_paths.gypi @@ -8,7 +8,7 @@ # by hand. See the translator.README.txt file in the tools directory for # more information. # -# $hash=29c508f2fb23e0ed2899163039384fb0a230be70$ +# $hash=e092ed49124ef5969b2052fd6ae5f6e6d89390ba$ # { @@ -81,6 +81,7 @@ 'include/cef_stream.h', 'include/cef_string_visitor.h', 'include/cef_task.h', + 'include/cef_task_manager.h', 'include/cef_thread.h', 'include/cef_trace.h', 'include/cef_unresponsive_process_callback.h', @@ -184,6 +185,7 @@ 'include/capi/cef_stream_capi.h', 'include/capi/cef_string_visitor_capi.h', 'include/capi/cef_task_capi.h', + 'include/capi/cef_task_manager_capi.h', 'include/capi/cef_thread_capi.h', 'include/capi/cef_trace_capi.h', 'include/capi/cef_unresponsive_process_callback_capi.h', @@ -460,6 +462,8 @@ 'libcef_dll/ctocpp/string_visitor_ctocpp.h', 'libcef_dll/ctocpp/task_ctocpp.cc', 'libcef_dll/ctocpp/task_ctocpp.h', + 'libcef_dll/cpptoc/task_manager_cpptoc.cc', + 'libcef_dll/cpptoc/task_manager_cpptoc.h', 'libcef_dll/cpptoc/task_runner_cpptoc.cc', 'libcef_dll/cpptoc/task_runner_cpptoc.h', 'libcef_dll/cpptoc/test/test_server_cpptoc.cc', @@ -784,6 +788,8 @@ 'libcef_dll/cpptoc/string_visitor_cpptoc.h', 'libcef_dll/cpptoc/task_cpptoc.cc', 'libcef_dll/cpptoc/task_cpptoc.h', + 'libcef_dll/ctocpp/task_manager_ctocpp.cc', + 'libcef_dll/ctocpp/task_manager_ctocpp.h', 'libcef_dll/ctocpp/task_runner_ctocpp.cc', 'libcef_dll/ctocpp/task_runner_ctocpp.h', 'libcef_dll/ctocpp/test/test_server_ctocpp.cc', diff --git a/cef_paths2.gypi b/cef_paths2.gypi index 704b75854..eb90bae4d 100644 --- a/cef_paths2.gypi +++ b/cef_paths2.gypi @@ -278,6 +278,8 @@ 'tests/cefclient/browser/scheme_test.h', 'tests/cefclient/browser/server_test.cc', 'tests/cefclient/browser/server_test.h', + 'tests/cefclient/browser/task_manager_test.cc', + 'tests/cefclient/browser/task_manager_test.h', 'tests/cefclient/browser/temp_window.h', 'tests/cefclient/browser/test_runner.cc', 'tests/cefclient/browser/test_runner.h', @@ -332,6 +334,7 @@ 'tests/cefclient/resources/preferences.html', 'tests/cefclient/resources/response_filter.html', 'tests/cefclient/resources/server.html', + 'tests/cefclient/resources/task_manager.html', 'tests/cefclient/resources/transparency.html', 'tests/cefclient/resources/urlrequest.html', 'tests/cefclient/resources/websocket.html', diff --git a/include/capi/cef_task_manager_capi.h b/include/capi/cef_task_manager_capi.h new file mode 100644 index 000000000..e5ec5db8e --- /dev/null +++ b/include/capi/cef_task_manager_capi.h @@ -0,0 +1,107 @@ +// Copyright (c) 2024 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// +// $hash=944e04f8c3213981c3955d6b5ede036b887d4d9e$ +// + +#ifndef CEF_INCLUDE_CAPI_CEF_TASK_MANAGER_CAPI_H_ +#define CEF_INCLUDE_CAPI_CEF_TASK_MANAGER_CAPI_H_ +#pragma once + +#include "include/capi/cef_base_capi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +/// Structure that facilitates managing the browser-related tasks. The functions +/// of this structure may only be called on the UI thread. +/// +typedef struct _cef_task_manager_t { + /// + /// Base structure. + /// + cef_base_ref_counted_t base; + + /// + /// Returns the number of tasks currently tracked by the task manager. Returns + /// 0 if the function was called from the incorrect thread. + /// + size_t(CEF_CALLBACK* get_tasks_count)(struct _cef_task_manager_t* self); + + /// + /// Gets the list of task IDs currently tracked by the task manager. Tasks + /// that share the same process id will always be consecutive. The list will + /// be sorted in a way that reflects the process tree: the browser process + /// will be first, followed by the gpu process if it exists. Related processes + /// (e.g., a subframe process and its parent) will be kept together if + /// possible. Callers can expect this ordering to be stable when a process is + /// added or removed. The task IDs are unique within the application lifespan. + /// Returns false (0) if the function was called from the incorrect thread. + /// + int(CEF_CALLBACK* get_task_ids_list)(struct _cef_task_manager_t* self, + size_t* task_idsCount, + int64_t* task_ids); + + /// + /// Gets information about the task with |task_id|. Returns true (1) if the + /// information about the task was successfully retrieved and false (0) if the + /// |task_id| is invalid or the function was called from the incorrect thread. + /// + int(CEF_CALLBACK* get_task_info)(struct _cef_task_manager_t* self, + int64_t task_id, + struct _cef_task_info_t* info); + + /// + /// Attempts to terminate a task with |task_id|. Returns false (0) if the + /// |task_id| is invalid, the call is made from an incorrect thread, or if the + /// task cannot be terminated. + /// + int(CEF_CALLBACK* kill_task)(struct _cef_task_manager_t* self, + int64_t task_id); +} cef_task_manager_t; + +/// +/// Returns the global task manager object. Returns nullptr if the function was +/// called from the incorrect thread. +/// +CEF_EXPORT cef_task_manager_t* cef_task_manager_get(void); + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_CAPI_CEF_TASK_MANAGER_CAPI_H_ diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index a0aca3ae3..7dcb5e028 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -42,13 +42,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "ea36c0aa57b37523b5677f107729dbf4d0b23933" +#define CEF_API_HASH_UNIVERSAL "af31a52a9b7a67e9e43aecc3dca57be096bd3c52" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "42cdaa02d9babfd5409c5d7cb4abf77ea9f0b8d4" +#define CEF_API_HASH_PLATFORM "b24a9d79201dabc26957dc207746d8b6248e0e58" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "832e89ccb2ee279fb7b6fe9a30c83863ffa42fa1" +#define CEF_API_HASH_PLATFORM "1b1e2db70d324c123a5be09fd9c528acbf49b9a4" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "7b768d2e27822636321fb437be8d17cb0c3b7809" +#define CEF_API_HASH_PLATFORM "9d549b9917bc2f0be789a75179e1aeea134798ef" #endif #ifdef __cplusplus diff --git a/include/cef_task_manager.h b/include/cef_task_manager.h new file mode 100644 index 000000000..c49235410 --- /dev/null +++ b/include/cef_task_manager.h @@ -0,0 +1,100 @@ +// Copyright (c) 2024 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_TASK_MANAGER_H_ +#define CEF_INCLUDE_CEF_TASK_MANAGER_H_ +#pragma once + +#include + +#include "include/cef_base.h" + +/// +/// Class that facilitates managing the browser-related tasks. +/// The methods of this class may only be called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefTaskManager : public virtual CefBaseRefCounted { + public: + typedef std::vector TaskIdList; + typedef cef_task_type_t TaskType; + + /// + /// Returns the global task manager object. + /// Returns nullptr if the method was called from the incorrect thread. + /// + /*--cef()--*/ + static CefRefPtr GetTaskManager(); + + /// + /// Returns the number of tasks currently tracked by the task manager. + /// Returns 0 if the method was called from the incorrect thread. + /// + /*--cef()--*/ + virtual size_t GetTasksCount() = 0; + + /// + /// Gets the list of task IDs currently tracked by the task manager. Tasks + /// that share the same process id will always be consecutive. The list will + /// be sorted in a way that reflects the process tree: the browser process + /// will be first, followed by the gpu process if it exists. Related processes + /// (e.g., a subframe process and its parent) will be kept together if + /// possible. Callers can expect this ordering to be stable when a process is + /// added or removed. The task IDs are unique within the application lifespan. + /// Returns false if the method was called from the incorrect thread. + /// + /*--cef(count_func=task_ids:GetTasksCount)--*/ + virtual bool GetTaskIdsList(TaskIdList& task_ids) = 0; + + /// + /// Gets information about the task with |task_id|. + /// Returns true if the information about the task was successfully + /// retrieved and false if the |task_id| is invalid or the method was called + /// from the incorrect thread. + /// + /*--cef()--*/ + virtual bool GetTaskInfo(int64_t task_id, CefTaskInfo& info) = 0; + + /// + /// Attempts to terminate a task with |task_id|. + /// Returns false if the |task_id| is invalid, the call is made from an + /// incorrect thread, or if the task cannot be terminated. + /// + /*--cef()--*/ + virtual bool KillTask(int64_t task_id) = 0; +}; + +#endif // CEF_INCLUDE_CEF_TASK_MANAGER_H_ diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index d26e15a69..a8d3c2a10 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -3812,6 +3812,67 @@ typedef enum { CEF_COLOR_VARIANT_EXPRESSIVE, } cef_color_variant_t; +/// +/// Specifies the task type variants supported by CefTaskManager. +/// Should be kept in sync with Chromium's task_manager::Task::Type type. +/// +typedef enum { + CEF_TASK_TYPE_UNKNOWN = 0, + /// The main browser process. + CEF_TASK_TYPE_BROWSER, + /// A graphics process. + CEF_TASK_TYPE_GPU, + /// A Linux zygote process. + CEF_TASK_TYPE_ZYGOTE, + /// A browser utility process. + CEF_TASK_TYPE_UTILITY, + /// A normal WebContents renderer process. + CEF_TASK_TYPE_RENDERER, + /// An extension or app process. + CEF_TASK_TYPE_EXTENSION, + /// A browser plugin guest process. + CEF_TASK_TYPE_GUEST, + /// A plugin process. + CEF_TASK_TYPE_PLUGIN, + /// A sandbox helper process + CEF_TASK_TYPE_SANDBOX_HELPER, + /// A dedicated worker running on the renderer process. + CEF_TASK_TYPE_DEDICATED_WORKER, + /// A shared worker running on the renderer process. + CEF_TASK_TYPE_SHARED_WORKER, + /// A service worker running on the renderer process. + CEF_TASK_TYPE_SERVICE_WORKER, +} cef_task_type_t; + +/// +/// Structure representing task information provided by CefTaskManager. +/// +typedef struct _cef_task_info_t { + /// The task ID. + int64_t id; + /// The task type. + cef_task_type_t type; + /// Set to true (1) if the task is killable. + int is_killable; + /// The task title. + cef_string_t title; + /// The CPU usage of the process on which the task is running. The value is + /// in the range zero to number_of_processors * 100%. + double cpu_usage; + /// The number of processors available on the system. + int number_of_processors; + /// The memory footprint of the task in bytes. A value of -1 means no valid + /// value is currently available. + int64_t memory; + /// The GPU memory usage of the task in bytes. A value of -1 means no valid + /// value is currently available. + int64_t gpu_memory; + /// Set to true (1) if this task process' GPU resource count is inflated + /// because it is counting other processes' resources (e.g, the GPU process + /// has this value set to true because it is the aggregate of all processes). + int is_gpu_memory_inflated; +} cef_task_info_t; + #ifdef __cplusplus } #endif diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 400d134af..b04ee5d88 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -756,4 +756,31 @@ class CefAcceleratedPaintInfo : public cef_accelerated_paint_info_t { : cef_accelerated_paint_info_t(r) {} }; +struct CefTaskInfoTraits { + using struct_type = cef_task_info_t; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { cef_string_clear(&s->title); } + + static inline void set(const struct_type* src, + struct_type* target, + bool copy) { + target->id = src->id; + target->type = src->type; + target->is_killable = src->is_killable; + cef_string_set(src->title.str, src->title.length, &target->title, copy); + target->cpu_usage = src->cpu_usage; + target->number_of_processors = src->number_of_processors; + target->memory = src->memory; + target->gpu_memory = src->gpu_memory; + target->is_gpu_memory_inflated = src->is_gpu_memory_inflated; + } +}; + +/// +/// Class representing task information. +/// +using CefTaskInfo = CefStructBase; + #endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ diff --git a/libcef/browser/task_manager_impl.cc b/libcef/browser/task_manager_impl.cc new file mode 100644 index 000000000..ef38f33f0 --- /dev/null +++ b/libcef/browser/task_manager_impl.cc @@ -0,0 +1,166 @@ +// 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/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; +} + +bool CefTaskManagerImpl::IsValidTaskId(int64_t task_id) const { + return base::ranges::find(tasks_, task_id) != tasks_.end(); +} + +CefRefPtr 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()); +} diff --git a/libcef/browser/task_manager_impl.h b/libcef/browser/task_manager_impl.h new file mode 100644 index 000000000..1b90d83ad --- /dev/null +++ b/libcef/browser/task_manager_impl.h @@ -0,0 +1,47 @@ +// 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. + +#ifndef CEF_LIBCEF_BROWSER_TASK_MANAGER_IMPL_H_ +#define CEF_LIBCEF_BROWSER_TASK_MANAGER_IMPL_H_ +#pragma once + +#include "base/memory/raw_ptr.h" +#include "cef/include/cef_task_manager.h" +#include "cef/libcef/browser/thread_util.h" +#include "chrome/browser/task_manager/task_manager_observer.h" + +namespace task_manager { +class TaskManagerInterface; +} + +class CefTaskManagerImpl : public task_manager::TaskManagerObserver, + public CefTaskManager { + public: + explicit CefTaskManagerImpl(task_manager::TaskManagerInterface* task_manager); + ~CefTaskManagerImpl(); + + CefTaskManagerImpl(const CefTaskManagerImpl&) = delete; + CefTaskManagerImpl& operator=(const CefTaskManagerImpl&) = delete; + + // CefTaskManager methods: + size_t GetTasksCount() override; + bool GetTaskIdsList(TaskIdList& task_ids) override; + bool GetTaskInfo(int64_t task_id, CefTaskInfo& info) override; + bool KillTask(int64_t task_id) override; + + private: + bool IsValidTaskId(int64_t task_id) const; + + // task_manager::TaskManagerObserver: + void OnTaskAdded(int64_t id) override; + void OnTaskToBeRemoved(int64_t id) override; + void OnTasksRefreshed(const task_manager::TaskIdList& task_ids) override; + + raw_ptr task_manager_; + TaskIdList tasks_; + + IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefTaskManagerImpl); +}; + +#endif // CEF_LIBCEF_BROWSER_TASK_MANAGER_IMPL_H_ diff --git a/libcef_dll/cpptoc/task_manager_cpptoc.cc b/libcef_dll/cpptoc/task_manager_cpptoc.cc new file mode 100644 index 000000000..c27ead1ec --- /dev/null +++ b/libcef_dll/cpptoc/task_manager_cpptoc.cc @@ -0,0 +1,187 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=07933b22615488a634fd4df87e9691156ae23ec4$ +// + +#include "libcef_dll/cpptoc/task_manager_cpptoc.h" + +#include + +#include "libcef_dll/shutdown_checker.h" +#include "libcef_dll/template_util.h" + +// GLOBAL FUNCTIONS - Body may be edited by hand. + +CEF_EXPORT cef_task_manager_t* cef_task_manager_get() { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + CefRefPtr _retval = CefTaskManager::GetTaskManager(); + + // Return type: refptr_same + return CefTaskManagerCppToC::Wrap(_retval); +} + +namespace { + +// MEMBER FUNCTIONS - Body may be edited by hand. + +size_t CEF_CALLBACK +task_manager_get_tasks_count(struct _cef_task_manager_t* self) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return 0; + } + + // Execute + size_t _retval = CefTaskManagerCppToC::Get(self)->GetTasksCount(); + + // Return type: simple + return _retval; +} + +int CEF_CALLBACK +task_manager_get_task_ids_list(struct _cef_task_manager_t* self, + size_t* task_idsCount, + int64_t* task_ids) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return 0; + } + // Verify param: task_ids; type: simple_vec_byref + DCHECK(task_idsCount && (*task_idsCount == 0 || task_ids)); + if (!task_idsCount || (*task_idsCount > 0 && !task_ids)) { + return 0; + } + + // Translate param: task_ids; type: simple_vec_byref + std::vector task_idsList; + if (task_idsCount && *task_idsCount > 0 && task_ids) { + for (size_t i = 0; i < *task_idsCount; ++i) { + task_idsList.push_back(task_ids[i]); + } + } + + // Execute + bool _retval = CefTaskManagerCppToC::Get(self)->GetTaskIdsList(task_idsList); + + // Restore param: task_ids; type: simple_vec_byref + if (task_idsCount && task_ids) { + *task_idsCount = std::min(task_idsList.size(), *task_idsCount); + if (*task_idsCount > 0) { + for (size_t i = 0; i < *task_idsCount; ++i) { + task_ids[i] = task_idsList[i]; + } + } + } + + // Return type: bool + return _retval; +} + +int CEF_CALLBACK task_manager_get_task_info(struct _cef_task_manager_t* self, + int64_t task_id, + struct _cef_task_info_t* info) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return 0; + } + // Verify param: info; type: struct_byref + DCHECK(info); + if (!info) { + return 0; + } + if (!template_util::has_valid_size(info)) { + DCHECK(false) << "invalid info->[base.]size"; + return 0; + } + + // Translate param: info; type: struct_byref + CefTaskInfo infoObj; + if (info) { + infoObj.AttachTo(*info); + } + + // Execute + bool _retval = CefTaskManagerCppToC::Get(self)->GetTaskInfo(task_id, infoObj); + + // Restore param: info; type: struct_byref + if (info) { + infoObj.DetachTo(*info); + } + + // Return type: bool + return _retval; +} + +int CEF_CALLBACK task_manager_kill_task(struct _cef_task_manager_t* self, + int64_t task_id) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return 0; + } + + // Execute + bool _retval = CefTaskManagerCppToC::Get(self)->KillTask(task_id); + + // Return type: bool + return _retval; +} + +} // namespace + +// CONSTRUCTOR - Do not edit by hand. + +CefTaskManagerCppToC::CefTaskManagerCppToC() { + GetStruct()->get_tasks_count = task_manager_get_tasks_count; + GetStruct()->get_task_ids_list = task_manager_get_task_ids_list; + GetStruct()->get_task_info = task_manager_get_task_info; + GetStruct()->kill_task = task_manager_kill_task; +} + +// DESTRUCTOR - Do not edit by hand. + +CefTaskManagerCppToC::~CefTaskManagerCppToC() { + shutdown_checker::AssertNotShutdown(); +} + +template <> +CefRefPtr +CefCppToCRefCounted:: + UnwrapDerived(CefWrapperType type, cef_task_manager_t* s) { + DCHECK(false) << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_TASK_MANAGER; diff --git a/libcef_dll/cpptoc/task_manager_cpptoc.h b/libcef_dll/cpptoc/task_manager_cpptoc.h new file mode 100644 index 000000000..f34a1fc0d --- /dev/null +++ b/libcef_dll/cpptoc/task_manager_cpptoc.h @@ -0,0 +1,37 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=a4441969f52770b61b08e6e0873c4ad0a1b55bf3$ +// + +#ifndef CEF_LIBCEF_DLL_CPPTOC_TASK_MANAGER_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_TASK_MANAGER_CPPTOC_H_ +#pragma once + +#if !defined(BUILDING_CEF_SHARED) +#error This file can be included DLL-side only +#endif + +#include "include/capi/cef_task_manager_capi.h" +#include "include/cef_task_manager.h" +#include "libcef_dll/cpptoc/cpptoc_ref_counted.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefTaskManagerCppToC : public CefCppToCRefCounted { + public: + CefTaskManagerCppToC(); + virtual ~CefTaskManagerCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_TASK_MANAGER_CPPTOC_H_ diff --git a/libcef_dll/ctocpp/task_manager_ctocpp.cc b/libcef_dll/ctocpp/task_manager_ctocpp.cc new file mode 100644 index 000000000..fdcb0d0a5 --- /dev/null +++ b/libcef_dll/ctocpp/task_manager_ctocpp.cc @@ -0,0 +1,157 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=56907c5bc7334bc3289f0a97dbc4a70c3ac9b41a$ +// + +#include "libcef_dll/ctocpp/task_manager_ctocpp.h" + +#include + +#include "libcef_dll/shutdown_checker.h" + +// STATIC METHODS - Body may be edited by hand. + +NO_SANITIZE("cfi-icall") +CefRefPtr CefTaskManager::GetTaskManager() { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_task_manager_t* _retval = cef_task_manager_get(); + + // Return type: refptr_same + return CefTaskManagerCToCpp::Wrap(_retval); +} + +// VIRTUAL METHODS - Body may be edited by hand. + +NO_SANITIZE("cfi-icall") size_t CefTaskManagerCToCpp::GetTasksCount() { + shutdown_checker::AssertNotShutdown(); + + cef_task_manager_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_tasks_count)) { + return 0; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + size_t _retval = _struct->get_tasks_count(_struct); + + // Return type: simple + return _retval; +} + +NO_SANITIZE("cfi-icall") +bool CefTaskManagerCToCpp::GetTaskIdsList(TaskIdList& task_ids) { + shutdown_checker::AssertNotShutdown(); + + cef_task_manager_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_task_ids_list)) { + return false; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Translate param: task_ids; type: simple_vec_byref + size_t task_idsSize = task_ids.size(); + size_t task_idsCount = std::max(GetTasksCount(), task_idsSize); + int64_t* task_idsList = NULL; + if (task_idsCount > 0) { + task_idsList = new int64_t[task_idsCount]; + DCHECK(task_idsList); + if (task_idsList) { + memset(task_idsList, 0, sizeof(int64_t) * task_idsCount); + } + if (task_idsList && task_idsSize > 0) { + for (size_t i = 0; i < task_idsSize; ++i) { + task_idsList[i] = task_ids[i]; + } + } + } + + // Execute + int _retval = + _struct->get_task_ids_list(_struct, &task_idsCount, task_idsList); + + // Restore param:task_ids; type: simple_vec_byref + task_ids.clear(); + if (task_idsCount > 0 && task_idsList) { + for (size_t i = 0; i < task_idsCount; ++i) { + task_ids.push_back(task_idsList[i]); + } + delete[] task_idsList; + } + + // Return type: bool + return _retval ? true : false; +} + +NO_SANITIZE("cfi-icall") +bool CefTaskManagerCToCpp::GetTaskInfo(int64_t task_id, CefTaskInfo& info) { + shutdown_checker::AssertNotShutdown(); + + cef_task_manager_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_task_info)) { + return false; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->get_task_info(_struct, task_id, &info); + + // Return type: bool + return _retval ? true : false; +} + +NO_SANITIZE("cfi-icall") bool CefTaskManagerCToCpp::KillTask(int64_t task_id) { + shutdown_checker::AssertNotShutdown(); + + cef_task_manager_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, kill_task)) { + return false; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->kill_task(_struct, task_id); + + // Return type: bool + return _retval ? true : false; +} + +// CONSTRUCTOR - Do not edit by hand. + +CefTaskManagerCToCpp::CefTaskManagerCToCpp() {} + +// DESTRUCTOR - Do not edit by hand. + +CefTaskManagerCToCpp::~CefTaskManagerCToCpp() { + shutdown_checker::AssertNotShutdown(); +} + +template <> +cef_task_manager_t* +CefCToCppRefCounted:: + UnwrapDerived(CefWrapperType type, CefTaskManager* c) { + DCHECK(false) << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_TASK_MANAGER; diff --git a/libcef_dll/ctocpp/task_manager_ctocpp.h b/libcef_dll/ctocpp/task_manager_ctocpp.h new file mode 100644 index 000000000..bac210136 --- /dev/null +++ b/libcef_dll/ctocpp/task_manager_ctocpp.h @@ -0,0 +1,43 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=d51db130ffb459b22574d7393e63e87c87dd75e0$ +// + +#ifndef CEF_LIBCEF_DLL_CTOCPP_TASK_MANAGER_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_TASK_MANAGER_CTOCPP_H_ +#pragma once + +#if !defined(WRAPPING_CEF_SHARED) +#error This file can be included wrapper-side only +#endif + +#include "include/capi/cef_task_manager_capi.h" +#include "include/cef_task_manager.h" +#include "libcef_dll/ctocpp/ctocpp_ref_counted.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefTaskManagerCToCpp : public CefCToCppRefCounted { + public: + CefTaskManagerCToCpp(); + virtual ~CefTaskManagerCToCpp(); + + // CefTaskManager methods. + size_t GetTasksCount() override; + bool GetTaskIdsList(TaskIdList& task_ids) override; + bool GetTaskInfo(int64_t task_id, CefTaskInfo& info) override; + bool KillTask(int64_t task_id) override; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_TASK_MANAGER_CTOCPP_H_ diff --git a/libcef_dll/wrapper/libcef_dll_dylib.cc b/libcef_dll/wrapper/libcef_dll_dylib.cc index 45ed1a928..260de63b8 100644 --- a/libcef_dll/wrapper/libcef_dll_dylib.cc +++ b/libcef_dll/wrapper/libcef_dll_dylib.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=fd47567e105e5fc15bee190670216f0f007c6d27$ +// $hash=fd61a77bd549fb94bba963f9c0737ebceac324ac$ // #include @@ -44,6 +44,7 @@ #include "include/capi/cef_ssl_info_capi.h" #include "include/capi/cef_stream_capi.h" #include "include/capi/cef_task_capi.h" +#include "include/capi/cef_task_manager_capi.h" #include "include/capi/cef_thread_capi.h" #include "include/capi/cef_trace_capi.h" #include "include/capi/cef_urlrequest_capi.h" @@ -189,6 +190,7 @@ struct libcef_pointers { decltype(&cef_task_runner_get_for_current_thread) cef_task_runner_get_for_current_thread; decltype(&cef_task_runner_get_for_thread) cef_task_runner_get_for_thread; + decltype(&cef_task_manager_get) cef_task_manager_get; decltype(&cef_thread_create) cef_thread_create; decltype(&cef_urlrequest_create) cef_urlrequest_create; decltype(&cef_v8context_get_current_context) @@ -420,6 +422,7 @@ int libcef_init_pointers(const char* path) { INIT_ENTRY(cef_stream_writer_create_for_handler); INIT_ENTRY(cef_task_runner_get_for_current_thread); INIT_ENTRY(cef_task_runner_get_for_thread); + INIT_ENTRY(cef_task_manager_get); INIT_ENTRY(cef_thread_create); INIT_ENTRY(cef_urlrequest_create); INIT_ENTRY(cef_v8context_get_current_context); @@ -1045,6 +1048,10 @@ struct _cef_task_runner_t* cef_task_runner_get_for_thread( return g_libcef_pointers.cef_task_runner_get_for_thread(threadId); } +NO_SANITIZE("cfi-icall") struct _cef_task_manager_t* cef_task_manager_get() { + return g_libcef_pointers.cef_task_manager_get(); +} + NO_SANITIZE("cfi-icall") struct _cef_thread_t* cef_thread_create( const cef_string_t* display_name, diff --git a/libcef_dll/wrapper_types.h b/libcef_dll/wrapper_types.h index 3e35b6453..064714ea5 100644 --- a/libcef_dll/wrapper_types.h +++ b/libcef_dll/wrapper_types.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=a5b7766d0bc37a91c8b7d298d217480794398730$ +// $hash=84d0397db9557d427b354b262832b15de99992dd$ // #ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_ @@ -139,6 +139,7 @@ enum CefWrapperType { WT_STREAM_WRITER, WT_STRING_VISITOR, WT_TASK, + WT_TASK_MANAGER, WT_TASK_RUNNER, WT_TEST_SERVER, WT_TEST_SERVER_CONNECTION, diff --git a/tests/cefclient/browser/resource.h b/tests/cefclient/browser/resource.h index d1e685e86..81742d923 100644 --- a/tests/cefclient/browser/resource.h +++ b/tests/cefclient/browser/resource.h @@ -63,13 +63,14 @@ #define IDS_PREFERENCES_HTML 1017 #define IDS_RESPONSE_FILTER_HTML 1018 #define IDS_SERVER_HTML 1019 -#define IDS_TRANSPARENCY_HTML 1020 -#define IDS_URLREQUEST_HTML 1021 -#define IDS_WEBSOCKET_HTML 1022 -#define IDS_WINDOW_HTML 1023 -#define IDS_WINDOW_ICON_1X_PNG 1024 -#define IDS_WINDOW_ICON_2X_PNG 1025 -#define IDS_XMLHTTPREQUEST_HTML 1026 +#define IDS_TASK_MANAGER_HTML 1020 +#define IDS_TRANSPARENCY_HTML 1021 +#define IDS_URLREQUEST_HTML 1022 +#define IDS_WEBSOCKET_HTML 1023 +#define IDS_WINDOW_HTML 1024 +#define IDS_WINDOW_ICON_1X_PNG 1025 +#define IDS_WINDOW_ICON_2X_PNG 1026 +#define IDS_XMLHTTPREQUEST_HTML 1027 // Next default values for new objects // diff --git a/tests/cefclient/browser/resource_util_win_idmap.cc b/tests/cefclient/browser/resource_util_win_idmap.cc index 40e1bdfd1..3e22daa61 100644 --- a/tests/cefclient/browser/resource_util_win_idmap.cc +++ b/tests/cefclient/browser/resource_util_win_idmap.cc @@ -33,6 +33,7 @@ int GetResourceId(const char* resource_name) { {"preferences.html", IDS_PREFERENCES_HTML}, {"response_filter.html", IDS_RESPONSE_FILTER_HTML}, {"server.html", IDS_SERVER_HTML}, + {"task_manager.html", IDS_TASK_MANAGER_HTML}, {"transparency.html", IDS_TRANSPARENCY_HTML}, {"urlrequest.html", IDS_URLREQUEST_HTML}, {"websocket.html", IDS_WEBSOCKET_HTML}, diff --git a/tests/cefclient/browser/task_manager_test.cc b/tests/cefclient/browser/task_manager_test.cc new file mode 100644 index 000000000..bb230709f --- /dev/null +++ b/tests/cefclient/browser/task_manager_test.cc @@ -0,0 +1,128 @@ +// 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 "tests/cefclient/browser/task_manager_test.h" + +#include "include/cef_task_manager.h" + +namespace { + +constexpr auto kTestUrlPath = "/task_manager"; + +struct TaskInfo { + int64_t task_id; + CefString title; + cef_task_type_t type; + bool is_killable; +}; + +std::string TaskTypeToString(cef_task_type_t type) { + switch (type) { + case CEF_TASK_TYPE_UNKNOWN: + return "Unknown"; + case CEF_TASK_TYPE_BROWSER: + return "Browser"; + case CEF_TASK_TYPE_GPU: + return "GPU"; + case CEF_TASK_TYPE_ZYGOTE: + return "Zygote"; + case CEF_TASK_TYPE_UTILITY: + return "Utility"; + case CEF_TASK_TYPE_RENDERER: + return "Renderer"; + case CEF_TASK_TYPE_EXTENSION: + return "Extension"; + case CEF_TASK_TYPE_GUEST: + return "Guest"; + case CEF_TASK_TYPE_PLUGIN: + return "Plugin"; + case CEF_TASK_TYPE_SANDBOX_HELPER: + return "Sandbox Helper"; + case CEF_TASK_TYPE_DEDICATED_WORKER: + return "Dedicated Worker"; + case CEF_TASK_TYPE_SHARED_WORKER: + return "Shared Worker"; + case CEF_TASK_TYPE_SERVICE_WORKER: + return "Service Worker"; + } + return "Unknown"; +} + +std::string TasksToJsonString(const std::vector& tasks) { + std::string json = "["; + for (size_t i = 0; i < tasks.size(); ++i) { + const auto& task = tasks[i]; + if (i > 0) { + json += ","; + } + json += "{"; + json += "\"id\":" + std::to_string(task.id) + ","; + json += "\"type\":\"" + TaskTypeToString(task.type) + "\","; + json += "\"is_killable\":"; + json += (task.is_killable ? "true," : "false,"); + json += "\"title\":\"" + CefString(&task.title).ToString() + "\","; + json += "\"cpu_usage\":" + std::to_string(task.cpu_usage) + ","; + json += "\"number_of_processors\":" + + std::to_string(task.number_of_processors) + ","; + json += "\"memory\":" + std::to_string(task.memory) + ","; + json += "\"gpu_memory\":" + std::to_string(task.gpu_memory) + ","; + json += "\"is_gpu_memory_inflated\":"; + json += (task.is_gpu_memory_inflated ? "true" : "false"); + json += "}"; + } + json += "]"; + return json; +} + +// Handle messages in the browser process. +class Handler final : public CefMessageRouterBrowserSide::Handler { + public: + explicit Handler() : task_manager_(CefTaskManager::GetTaskManager()) {} + // Called due to cefQuery execution in binary_transfer.html. + bool OnQuery(CefRefPtr browser, + CefRefPtr frame, + int64_t query_id, + const CefString& request, + bool persistent, + CefRefPtr callback) override { + // Only handle messages from the test URL. + const std::string& url = frame->GetURL(); + if (!client::test_runner::IsTestURL(url, kTestUrlPath)) { + return false; + } + + if (request == "get_tasks") { + CefTaskManager::TaskIdList task_ids; + task_manager_->GetTaskIdsList(task_ids); + + std::vector tasks; + for (auto task_id : task_ids) { + CefTaskInfo info; + task_manager_->GetTaskInfo(task_id, info); + tasks.push_back(info); + } + callback->Success(TasksToJsonString(tasks)); + return true; + } + + // Otherwise assume that task id was passed as string to kill it + int64_t task_id = std::stoll(request.ToString()); + task_manager_->KillTask(task_id); + callback->Success(""); + return true; + } + + private: + CefRefPtr task_manager_; +}; + +} // namespace + +namespace client::task_manager_test { + +void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) { + handlers.insert(new Handler()); +} + +} // namespace client::task_manager_test diff --git a/tests/cefclient/browser/task_manager_test.h b/tests/cefclient/browser/task_manager_test.h new file mode 100644 index 000000000..3078009cd --- /dev/null +++ b/tests/cefclient/browser/task_manager_test.h @@ -0,0 +1,17 @@ +// 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. + +#ifndef CEF_TESTS_CEFCLIENT_BROWSER_TASK_MANAGER_TEST_H_ +#define CEF_TESTS_CEFCLIENT_BROWSER_TASK_MANAGER_TEST_H_ +#pragma once + +#include "tests/cefclient/browser/test_runner.h" + +namespace client::task_manager_test { + +void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers); + +} // namespace client::task_manager_test + +#endif // CEF_TESTS_CEFCLIENT_BROWSER_TASK_MANAGER_TEST_H_ diff --git a/tests/cefclient/browser/test_runner.cc b/tests/cefclient/browser/test_runner.cc index 71d25a00b..5527eae2b 100644 --- a/tests/cefclient/browser/test_runner.cc +++ b/tests/cefclient/browser/test_runner.cc @@ -31,6 +31,7 @@ #include "tests/cefclient/browser/root_window_manager.h" #include "tests/cefclient/browser/scheme_test.h" #include "tests/cefclient/browser/server_test.h" +#include "tests/cefclient/browser/task_manager_test.h" #include "tests/cefclient/browser/urlrequest_test.h" #include "tests/cefclient/browser/window_test.h" #include "tests/shared/browser/resource_util.h" @@ -877,6 +878,9 @@ void CreateMessageHandlers(MessageHandlerSet& handlers) { // Create the server test handlers. server_test::CreateMessageHandlers(handlers); + // Create the task manager handlers. + task_manager_test::CreateMessageHandlers(handlers); + // Create the urlrequest test handlers. urlrequest_test::CreateMessageHandlers(handlers); diff --git a/tests/cefclient/resources/other_tests.html b/tests/cefclient/resources/other_tests.html index 260d75f20..9e8fcbaec 100644 --- a/tests/cefclient/resources/other_tests.html +++ b/tests/cefclient/resources/other_tests.html @@ -28,20 +28,21 @@
  • PDF Viewer direct
  • PDF Viewer iframe
  • Preferences
  • +
  • Print this page with "javascript:window.print();"
  • +
  • Render process hang test
  • requestAnimationFrame
  • Response Filtering
  • Scheme Handler
  • -
  • HTTP/WebSocket Server
  • -
  • WebSocket Client
  • Speech Input - requires "enable-speech-input" flag
  • +
  • Task Manager
  • +
  • Touch Feature Tests - requires "touch-events=enabled" flag (and CAPS LOCK on Mac for Trackpad simulation)
  • Transparency
  • WebGL
  • WebRTC - requires "enable-media-stream" flag
  • +
  • HTTP/WebSocket Server
  • +
  • WebSocket Client
  • CefURLRequest
  • XMLHttpRequest
  • -
  • Print this page with "javascript:window.print();"
  • -
  • Touch Feature Tests - requires "touch-events=enabled" flag (and CAPS LOCK on Mac for Trackpad simulation)
  • -
  • Render process hang test
  • diff --git a/tests/cefclient/resources/task_manager.html b/tests/cefclient/resources/task_manager.html new file mode 100644 index 000000000..7f7ac55f1 --- /dev/null +++ b/tests/cefclient/resources/task_manager.html @@ -0,0 +1,119 @@ + + + + + Task Manager + + + + + + + + + + + + + +
    Task IDNameTypeCPU UsageMemory FootprintGPU MemoryActions
    + + + diff --git a/tests/cefclient/resources/win/cefclient.rc b/tests/cefclient/resources/win/cefclient.rc index 756dd4da3..1eb7f0ade 100644 --- a/tests/cefclient/resources/win/cefclient.rc +++ b/tests/cefclient/resources/win/cefclient.rc @@ -49,6 +49,7 @@ IDS_PERFORMANCE2_HTML BINARY "..\\performance2.html" IDS_PREFERENCES_HTML BINARY "..\\preferences.html" IDS_RESPONSE_FILTER_HTML BINARY "..\\response_filter.html" IDS_SERVER_HTML BINARY "..\\server.html" +IDS_TASK_MANAGER_HTML BINARY "..\\task_manager.html" IDS_TRANSPARENCY_HTML BINARY "..\\transparency.html" IDS_URLREQUEST_HTML BINARY "..\\urlrequest.html" IDS_WEBSOCKET_HTML BINARY "..\\websocket.html"