Add callbacks for unresponsive render process (fixes #3661)
The client can optionally wait or terminate the render process. Expose process exit codes via OnRenderProcessTerminated and CefGetExitCode (fixes #2126). cefclient: Add a new https://tests/hang page for testing hang behavior. cefclient: Move message and resource handling to a new BaseClientHandler class to support loading of test pages in default Chrome UI windows.
This commit is contained in:
parent
5e616b2df0
commit
b8f91c5431
2
BUILD.gn
2
BUILD.gn
|
@ -620,6 +620,8 @@ source_set("libcef_static") {
|
|||
"libcef/browser/frame_service_base.h",
|
||||
"libcef/browser/global_preference_manager_impl.cc",
|
||||
"libcef/browser/global_preference_manager_impl.h",
|
||||
"libcef/browser/hang_monitor.cc",
|
||||
"libcef/browser/hang_monitor.h",
|
||||
"libcef/browser/image_impl.cc",
|
||||
"libcef/browser/image_impl.h",
|
||||
"libcef/browser/iothread_state.cc",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# by hand. See the translator.README.txt file in the tools directory for
|
||||
# more information.
|
||||
#
|
||||
# $hash=25599539f43226aac01bfcb74f19ac74217aee9a$
|
||||
# $hash=3b28f3236c16d2b776a44674ae3bae0a070e9f27$
|
||||
#
|
||||
|
||||
{
|
||||
|
@ -85,6 +85,7 @@
|
|||
'include/cef_task.h',
|
||||
'include/cef_thread.h',
|
||||
'include/cef_trace.h',
|
||||
'include/cef_unresponsive_process_callback.h',
|
||||
'include/cef_urlrequest.h',
|
||||
'include/cef_v8.h',
|
||||
'include/cef_values.h',
|
||||
|
@ -189,6 +190,7 @@
|
|||
'include/capi/cef_task_capi.h',
|
||||
'include/capi/cef_thread_capi.h',
|
||||
'include/capi/cef_trace_capi.h',
|
||||
'include/capi/cef_unresponsive_process_callback_capi.h',
|
||||
'include/capi/cef_urlrequest_capi.h',
|
||||
'include/capi/cef_v8_capi.h',
|
||||
'include/capi/cef_values_capi.h',
|
||||
|
@ -508,6 +510,8 @@
|
|||
'libcef_dll/cpptoc/urlrequest_cpptoc.h',
|
||||
'libcef_dll/ctocpp/urlrequest_client_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/urlrequest_client_ctocpp.h',
|
||||
'libcef_dll/cpptoc/unresponsive_process_callback_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/unresponsive_process_callback_cpptoc.h',
|
||||
'libcef_dll/ctocpp/v8accessor_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/v8accessor_ctocpp.h',
|
||||
'libcef_dll/ctocpp/v8array_buffer_release_callback_ctocpp.cc',
|
||||
|
@ -836,6 +840,8 @@
|
|||
'libcef_dll/ctocpp/urlrequest_ctocpp.h',
|
||||
'libcef_dll/cpptoc/urlrequest_client_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/urlrequest_client_cpptoc.h',
|
||||
'libcef_dll/ctocpp/unresponsive_process_callback_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/unresponsive_process_callback_ctocpp.h',
|
||||
'libcef_dll/cpptoc/v8accessor_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/v8accessor_cpptoc.h',
|
||||
'libcef_dll/cpptoc/v8array_buffer_release_callback_cpptoc.cc',
|
||||
|
|
|
@ -220,6 +220,8 @@
|
|||
'tests/shared/browser/util_win.h',
|
||||
],
|
||||
'cefclient_sources_browser': [
|
||||
'tests/cefclient/browser/base_client_handler.cc',
|
||||
'tests/cefclient/browser/base_client_handler.h',
|
||||
'tests/cefclient/browser/binary_transfer_test.cc',
|
||||
'tests/cefclient/browser/binary_transfer_test.h',
|
||||
'tests/cefclient/browser/binding_test.cc',
|
||||
|
@ -240,10 +242,11 @@
|
|||
'tests/cefclient/browser/client_prefs.cc',
|
||||
'tests/cefclient/browser/client_prefs.h',
|
||||
'tests/cefclient/browser/client_types.h',
|
||||
'tests/cefclient/browser/default_client_handler.cc',
|
||||
'tests/cefclient/browser/default_client_handler.h',
|
||||
'tests/cefclient/browser/dialog_test.cc',
|
||||
'tests/cefclient/browser/dialog_test.h',
|
||||
'tests/cefclient/browser/hang_test.cc',
|
||||
'tests/cefclient/browser/hang_test.h',
|
||||
'tests/cefclient/browser/image_cache.cc',
|
||||
'tests/cefclient/browser/image_cache.h',
|
||||
'tests/cefclient/browser/main_context.cc',
|
||||
|
@ -309,11 +312,11 @@
|
|||
'tests/cefclient/renderer/performance_test_tests.cc',
|
||||
],
|
||||
'cefclient_sources_resources': [
|
||||
'tests/cefclient/resources/binary_transfer.html',
|
||||
'tests/cefclient/resources/binding.html',
|
||||
'tests/cefclient/resources/dialogs.html',
|
||||
'tests/cefclient/resources/draggable.html',
|
||||
'tests/cefclient/resources/hang.html',
|
||||
'tests/cefclient/resources/ipc_performance.html',
|
||||
'tests/cefclient/resources/binary_transfer.html',
|
||||
'tests/cefclient/resources/localstorage.html',
|
||||
'tests/cefclient/resources/logo.png',
|
||||
'tests/cefclient/resources/media_router.html',
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=b9a2bad4a30bcb99384197c9f7409116dc5b376e$
|
||||
// $hash=dfa0d4d2da319b2fd5e92324fd14301b500ceb5c$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_APP_CAPI_H_
|
||||
|
@ -137,15 +137,26 @@ CEF_EXPORT int cef_execute_process(const cef_main_args_t* args,
|
|||
/// true (1) if initialization succeeds. Returns false (0) if initialization
|
||||
/// fails or if early exit is desired (for example, due to process singleton
|
||||
/// relaunch behavior). If this function returns false (0) then the application
|
||||
/// should exit immediately without calling any other CEF functions. The
|
||||
/// |windows_sandbox_info| parameter is only used on Windows and may be NULL
|
||||
/// (see cef_sandbox_win.h for details).
|
||||
/// should exit immediately without calling any other CEF functions except,
|
||||
/// optionally, CefGetErrorCode. The |windows_sandbox_info| parameter is only
|
||||
/// used on Windows and may be NULL (see cef_sandbox_win.h for details).
|
||||
///
|
||||
CEF_EXPORT int cef_initialize(const cef_main_args_t* args,
|
||||
const struct _cef_settings_t* settings,
|
||||
cef_app_t* application,
|
||||
void* windows_sandbox_info);
|
||||
|
||||
///
|
||||
/// This function can optionally be called on the main application thread after
|
||||
/// CefInitialize to retrieve the initialization exit code. When CefInitialize
|
||||
/// returns true (1) the exit code will be 0 (CEF_RESULT_CODE_NORMAL_EXIT).
|
||||
/// Otherwise, see cef_resultcode_t for possible exit code values including
|
||||
/// browser process initialization errors and normal early exit conditions (such
|
||||
/// as CEF_RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED for process singleton
|
||||
/// relaunch behavior).
|
||||
///
|
||||
CEF_EXPORT int cef_get_exit_code(void);
|
||||
|
||||
///
|
||||
/// This function should be called on the main application thread to shut down
|
||||
/// the CEF browser process before the application exits. Do not call any other
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=e7f9480661f77931890085d6c5bf23d9842212e2$
|
||||
// $hash=abcb584dbf5965834f415a0f2daeda3e361696b2$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
||||
|
@ -974,6 +974,17 @@ typedef struct _cef_browser_host_t {
|
|||
struct _cef_browser_host_t* self,
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition);
|
||||
|
||||
///
|
||||
/// Returns true (1) if the render process associated with this browser is
|
||||
/// currently unresponsive as indicated by a lack of input event processing
|
||||
/// for at least 15 seconds. To receive associated state change notifications
|
||||
/// and optionally handle an unresponsive render process implement
|
||||
/// cef_request_handler_t::OnRenderProcessUnresponsive. This function can only
|
||||
/// be called on the UI thread.
|
||||
///
|
||||
int(CEF_CALLBACK* is_render_process_unresponsive)(
|
||||
struct _cef_browser_host_t* self);
|
||||
} cef_browser_host_t;
|
||||
|
||||
///
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=3b59c0bc014d773dedc24649071141ee2dd2125c$
|
||||
// $hash=2e8b5c5107f61e3d4c333dc02c76a9f30cd0cf83$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_HANDLER_CAPI_H_
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include "include/capi/cef_request_capi.h"
|
||||
#include "include/capi/cef_resource_request_handler_capi.h"
|
||||
#include "include/capi/cef_ssl_info_capi.h"
|
||||
#include "include/capi/cef_unresponsive_process_callback_capi.h"
|
||||
#include "include/capi/cef_x509_certificate_capi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -222,14 +223,53 @@ typedef struct _cef_request_handler_t {
|
|||
void(CEF_CALLBACK* on_render_view_ready)(struct _cef_request_handler_t* self,
|
||||
struct _cef_browser_t* browser);
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the render process is
|
||||
/// unresponsive as indicated by a lack of input event processing for at least
|
||||
/// 15 seconds. Return false (0) for the default behavior which is an
|
||||
/// indefinite wait with the Alloy runtime or display of the "Page
|
||||
/// unresponsive" dialog with the Chrome runtime. Return true (1) and don't
|
||||
/// execute the callback for an indefinite wait without display of the Chrome
|
||||
/// runtime dialog. Return true (1) and call
|
||||
/// cef_unresponsive_process_callback_t::Wait either in this function or at a
|
||||
/// later time to reset the wait timer, potentially triggering another call to
|
||||
/// this function if the process remains unresponsive. Return true (1) and
|
||||
/// call cef_unresponsive_process_callback_t:: Terminate either in this
|
||||
/// function or at a later time to terminate the unresponsive process,
|
||||
/// resulting in a call to OnRenderProcessTerminated.
|
||||
/// OnRenderProcessResponsive will be called if the process becomes responsive
|
||||
/// after this function is called. This functionality depends on the hang
|
||||
/// monitor which can be disabled by passing the `--disable-hang-monitor`
|
||||
/// command-line flag.
|
||||
///
|
||||
int(CEF_CALLBACK* on_render_process_unresponsive)(
|
||||
struct _cef_request_handler_t* self,
|
||||
struct _cef_browser_t* browser,
|
||||
struct _cef_unresponsive_process_callback_t* callback);
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the render process becomes
|
||||
/// responsive after previously being unresponsive. See documentation on
|
||||
/// OnRenderProcessUnresponsive.
|
||||
///
|
||||
void(CEF_CALLBACK* on_render_process_responsive)(
|
||||
struct _cef_request_handler_t* self,
|
||||
struct _cef_browser_t* browser);
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the render process terminates
|
||||
/// unexpectedly. |status| indicates how the process terminated.
|
||||
/// unexpectedly. |status| indicates how the process terminated. |error_code|
|
||||
/// and |error_string| represent the error that would be displayed in Chrome's
|
||||
/// "Aw, Snap!" view. Possible |error_code| values include cef_resultcode_t
|
||||
/// non-normal exit values and platform-specific crash values (for example, a
|
||||
/// Posix signal or Windows hardware exception).
|
||||
///
|
||||
void(CEF_CALLBACK* on_render_process_terminated)(
|
||||
struct _cef_request_handler_t* self,
|
||||
struct _cef_browser_t* browser,
|
||||
cef_termination_status_t status);
|
||||
cef_termination_status_t status,
|
||||
int error_code,
|
||||
const cef_string_t* error_string);
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the window.document object of
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
// 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=9ad38f2709d9e3b1bd0e99c279b0497b8aa4c82a$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_UNRESPONSIVE_PROCESS_CALLBACK_CAPI_H_
|
||||
#define CEF_INCLUDE_CAPI_CEF_UNRESPONSIVE_PROCESS_CALLBACK_CAPI_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/capi/cef_base_capi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Callback structure for asynchronous handling of an unresponsive process.
|
||||
///
|
||||
typedef struct _cef_unresponsive_process_callback_t {
|
||||
///
|
||||
/// Base structure.
|
||||
///
|
||||
cef_base_ref_counted_t base;
|
||||
|
||||
///
|
||||
/// Reset the timeout for the unresponsive process.
|
||||
///
|
||||
void(CEF_CALLBACK* wait)(struct _cef_unresponsive_process_callback_t* self);
|
||||
|
||||
///
|
||||
/// Terminate the unresponsive process.
|
||||
///
|
||||
void(CEF_CALLBACK* terminate)(
|
||||
struct _cef_unresponsive_process_callback_t* self);
|
||||
} cef_unresponsive_process_callback_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CEF_INCLUDE_CAPI_CEF_UNRESPONSIVE_PROCESS_CALLBACK_CAPI_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 "93050a5111ee3131f5589bd7d3be5376539a64c2"
|
||||
#define CEF_API_HASH_UNIVERSAL "6c5009ba08bb760e60f7e17845c532b30f19fbae"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "ebcca93f53d935802a4cd02606864ff1eb1a1baa"
|
||||
#define CEF_API_HASH_PLATFORM "09f5a8a3088d2a8384c648be2047e0cb25b1221e"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "a2c1ee5ae59a181773019412084903e4824aa300"
|
||||
#define CEF_API_HASH_PLATFORM "ddee29d0c0de65874ff50f3ff7bc5de51089b9eb"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "915ea22829d9814cb6481891de4619f0aafda72f"
|
||||
#define CEF_API_HASH_PLATFORM "a27764fa2599737204faad84b00c31bb32dba54f"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -71,9 +71,9 @@ int CefExecuteProcess(const CefMainArgs& args,
|
|||
/// true if initialization succeeds. Returns false if initialization fails or if
|
||||
/// early exit is desired (for example, due to process singleton relaunch
|
||||
/// behavior). If this function returns false then the application should exit
|
||||
/// immediately without calling any other CEF functions. The
|
||||
/// |windows_sandbox_info| parameter is only used on Windows and may be NULL
|
||||
/// (see cef_sandbox_win.h for details).
|
||||
/// immediately without calling any other CEF functions except, optionally,
|
||||
/// CefGetErrorCode. The |windows_sandbox_info| parameter is only used on
|
||||
/// Windows and may be NULL (see cef_sandbox_win.h for details).
|
||||
///
|
||||
/*--cef(api_hash_check,optional_param=application,
|
||||
optional_param=windows_sandbox_info)--*/
|
||||
|
@ -82,6 +82,18 @@ bool CefInitialize(const CefMainArgs& args,
|
|||
CefRefPtr<CefApp> application,
|
||||
void* windows_sandbox_info);
|
||||
|
||||
///
|
||||
/// This function can optionally be called on the main application thread after
|
||||
/// CefInitialize to retrieve the initialization exit code. When CefInitialize
|
||||
/// returns true the exit code will be 0 (CEF_RESULT_CODE_NORMAL_EXIT).
|
||||
/// Otherwise, see cef_resultcode_t for possible exit code values including
|
||||
/// browser process initialization errors and normal early exit conditions (such
|
||||
/// as CEF_RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED for process singleton
|
||||
/// relaunch behavior).
|
||||
///
|
||||
/*--cef()--*/
|
||||
int CefGetExitCode();
|
||||
|
||||
///
|
||||
/// This function should be called on the main application thread to shut down
|
||||
/// the CEF browser process before the application exits. Do not call any
|
||||
|
|
|
@ -1007,6 +1007,17 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
|||
virtual void ExecuteChromeCommand(
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition) = 0;
|
||||
|
||||
///
|
||||
/// Returns true if the render process associated with this browser is
|
||||
/// currently unresponsive as indicated by a lack of input event processing
|
||||
/// for at least 15 seconds. To receive associated state change notifications
|
||||
/// and optionally handle an unresponsive render process implement
|
||||
/// CefRequestHandler::OnRenderProcessUnresponsive. This method can only be
|
||||
/// called on the UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsRenderProcessUnresponsive() = 0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_BROWSER_H_
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "include/cef_request.h"
|
||||
#include "include/cef_resource_request_handler.h"
|
||||
#include "include/cef_ssl_info.h"
|
||||
#include "include/cef_unresponsive_process_callback.h"
|
||||
#include "include/cef_x509_certificate.h"
|
||||
|
||||
///
|
||||
|
@ -221,14 +222,52 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
|
|||
/*--cef()--*/
|
||||
virtual void OnRenderViewReady(CefRefPtr<CefBrowser> browser) {}
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the render process is
|
||||
/// unresponsive as indicated by a lack of input event processing for at
|
||||
/// least 15 seconds. Return false for the default behavior which is an
|
||||
/// indefinite wait with the Alloy runtime or display of the "Page
|
||||
/// unresponsive" dialog with the Chrome runtime. Return true and don't
|
||||
/// execute the callback for an indefinite wait without display of the Chrome
|
||||
/// runtime dialog. Return true and call CefUnresponsiveProcessCallback::Wait
|
||||
/// either in this method or at a later time to reset the wait timer,
|
||||
/// potentially triggering another call to this method if the process remains
|
||||
/// unresponsive. Return true and call CefUnresponsiveProcessCallback::
|
||||
/// Terminate either in this method or at a later time to terminate the
|
||||
/// unresponsive process, resulting in a call to OnRenderProcessTerminated.
|
||||
/// OnRenderProcessResponsive will be called if the process becomes responsive
|
||||
/// after this method is called. This functionality depends on the hang
|
||||
/// monitor which can be disabled by passing the `--disable-hang-monitor`
|
||||
/// command-line flag.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool OnRenderProcessUnresponsive(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the render process becomes
|
||||
/// responsive after previously being unresponsive. See documentation on
|
||||
/// OnRenderProcessUnresponsive.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnRenderProcessResponsive(CefRefPtr<CefBrowser> browser) {}
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the render process
|
||||
/// terminates unexpectedly. |status| indicates how the process
|
||||
/// terminated.
|
||||
/// terminates unexpectedly. |status| indicates how the process terminated.
|
||||
/// |error_code| and |error_string| represent the error that would be
|
||||
/// displayed in Chrome's "Aw, Snap!" view. Possible |error_code| values
|
||||
/// include cef_resultcode_t non-normal exit values and platform-specific
|
||||
/// crash values (for example, a Posix signal or Windows hardware exception).
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) {}
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {}
|
||||
|
||||
///
|
||||
/// Called on the browser process UI thread when the window.document object of
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// 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_UNRESPONSIVE_PROCESS_CALLBACK_H_
|
||||
#define CEF_INCLUDE_CEF_UNRESPONSIVE_PROCESS_CALLBACK_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_base.h"
|
||||
|
||||
///
|
||||
/// Callback interface for asynchronous handling of an unresponsive process.
|
||||
///
|
||||
/*--cef(source=library)--*/
|
||||
class CefUnresponsiveProcessCallback : public virtual CefBaseRefCounted {
|
||||
public:
|
||||
///
|
||||
/// Reset the timeout for the unresponsive process.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void Wait() = 0;
|
||||
|
||||
///
|
||||
/// Terminate the unresponsive process.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void Terminate() = 0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_UNRESPONSIVE_PROCESS_CALLBACK_H_
|
|
@ -917,6 +917,16 @@ typedef enum {
|
|||
/// Out of memory. Some platforms may use TS_PROCESS_CRASHED instead.
|
||||
///
|
||||
TS_PROCESS_OOM,
|
||||
|
||||
///
|
||||
/// Child process never launched.
|
||||
///
|
||||
TS_LAUNCH_FAILED,
|
||||
|
||||
///
|
||||
/// On Windows, the OS terminated the process due to code integrity failure.
|
||||
///
|
||||
TS_INTEGRITY_FAILURE,
|
||||
} cef_termination_status_t;
|
||||
|
||||
///
|
||||
|
@ -1027,6 +1037,100 @@ typedef enum {
|
|||
CERT_STATUS_CT_COMPLIANCE_FAILED = 1 << 20,
|
||||
} cef_cert_status_t;
|
||||
|
||||
///
|
||||
/// Process result codes. This is not a comprehensive list, as result codes
|
||||
/// might also include platform-specific crash values (Posix signal or Windows
|
||||
/// hardware exception), or internal-only implementation values.
|
||||
///
|
||||
typedef enum {
|
||||
// The following values should be kept in sync with Chromium's
|
||||
// content::ResultCode type.
|
||||
|
||||
CEF_RESULT_CODE_NORMAL_EXIT,
|
||||
|
||||
/// Process was killed by user or system.
|
||||
CEF_RESULT_CODE_KILLED,
|
||||
|
||||
/// Process hung.
|
||||
CEF_RESULT_CODE_HUNG,
|
||||
|
||||
/// A bad message caused the process termination.
|
||||
CEF_RESULT_CODE_KILLED_BAD_MESSAGE,
|
||||
|
||||
/// The GPU process exited because initialization failed.
|
||||
CEF_RESULT_CODE_GPU_DEAD_ON_ARRIVAL,
|
||||
|
||||
// The following values should be kept in sync with Chromium's
|
||||
// chrome::ResultCode type. Unused chrome values are excluded.
|
||||
|
||||
CEF_RESULT_CODE_CHROME_FIRST,
|
||||
|
||||
/// A critical chrome file is missing.
|
||||
CEF_RESULT_CODE_MISSING_DATA = 7,
|
||||
|
||||
/// Command line parameter is not supported.
|
||||
CEF_RESULT_CODE_UNSUPPORTED_PARAM = 13,
|
||||
|
||||
/// The profile was in use on another host.
|
||||
CEF_RESULT_CODE_PROFILE_IN_USE = 21,
|
||||
|
||||
/// Failed to pack an extension via the command line.
|
||||
CEF_RESULT_CODE_PACK_EXTENSION_ERROR = 22,
|
||||
|
||||
/// The browser process exited early by passing the command line to another
|
||||
/// running browser.
|
||||
CEF_RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED = 24,
|
||||
|
||||
/// A browser process was sandboxed. This should never happen.
|
||||
CEF_RESULT_CODE_INVALID_SANDBOX_STATE = 31,
|
||||
|
||||
/// Cloud policy enrollment failed or was given up by user.
|
||||
CEF_RESULT_CODE_CLOUD_POLICY_ENROLLMENT_FAILED = 32,
|
||||
|
||||
/// The GPU process was terminated due to context lost.
|
||||
CEF_RESULT_CODE_GPU_EXIT_ON_CONTEXT_LOST = 34,
|
||||
|
||||
/// An early startup command was executed and the browser must exit.
|
||||
CEF_RESULT_CODE_NORMAL_EXIT_PACK_EXTENSION_SUCCESS = 36,
|
||||
|
||||
/// The browser process exited because system resources are exhausted. The
|
||||
/// system state can't be recovered and will be unstable.
|
||||
CEF_RESULT_CODE_SYSTEM_RESOURCE_EXHAUSTED = 37,
|
||||
|
||||
CEF_RESULT_CODE_CHROME_LAST = 39,
|
||||
|
||||
// The following values should be kept in sync with Chromium's
|
||||
// sandbox::TerminationCodes type.
|
||||
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_FIRST = 7006,
|
||||
|
||||
/// Windows sandbox could not set the integrity level.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_INTEGRITY = CEF_RESULT_CODE_SANDBOX_FATAL_FIRST,
|
||||
|
||||
/// Windows sandbox could not lower the token.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_DROPTOKEN,
|
||||
|
||||
/// Windows sandbox failed to flush registry handles.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_FLUSHANDLES,
|
||||
|
||||
/// Windows sandbox failed to forbid HCKU caching.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_CACHEDISABLE,
|
||||
|
||||
/// Windows sandbox failed to close pending handles.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_CLOSEHANDLES,
|
||||
|
||||
/// Windows sandbox could not set the mitigation policy.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_MITIGATION,
|
||||
|
||||
/// Windows sandbox exceeded the job memory limit.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_MEMORY_EXCEEDED,
|
||||
|
||||
/// Windows sandbox failed to warmup.
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_WARMUP,
|
||||
|
||||
CEF_RESULT_CODE_SANDBOX_FATAL_LAST,
|
||||
} cef_resultcode_t;
|
||||
|
||||
///
|
||||
/// The manner in which a link click should be opened. These constants match
|
||||
/// their equivalents in Chromium's window_open_disposition.h and should not be
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/devtools/devtools_manager.h"
|
||||
#include "libcef/browser/hang_monitor.h"
|
||||
#include "libcef/browser/media_access_query.h"
|
||||
#include "libcef/browser/osr/osr_util.h"
|
||||
#include "libcef/browser/request_context_impl.h"
|
||||
|
@ -1196,6 +1197,20 @@ void AlloyBrowserHostImpl::WebContentsCreated(
|
|||
std::move(platform_delegate), /*extension=*/nullptr);
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::RendererUnresponsive(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
hang_monitor::RendererUnresponsive(this, render_widget_host,
|
||||
hang_monitor_restarter);
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::RendererResponsive(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
hang_monitor::RendererResponsive(this, render_widget_host);
|
||||
}
|
||||
|
||||
content::JavaScriptDialogManager*
|
||||
AlloyBrowserHostImpl::GetJavaScriptDialogManager(content::WebContents* source) {
|
||||
if (!javascript_dialog_manager_) {
|
||||
|
|
|
@ -233,6 +233,13 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
|||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
content::WebContents* new_contents) override;
|
||||
void RendererUnresponsive(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) override;
|
||||
void RendererResponsive(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
void RunFileChooser(content::RenderFrameHost* render_frame_host,
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "libcef/browser/native/cursor_util.h"
|
||||
#include "libcef/common/frame_util.h"
|
||||
|
||||
#include "chrome/browser/ui/views/sad_tab_view.h"
|
||||
#include "chrome/common/chrome_result_codes.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/public/browser/focused_node_details.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
|
@ -25,6 +27,10 @@
|
|||
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
|
||||
#include "third_party/blink/public/mojom/widget/platform_widget.mojom-test-utils.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
#endif
|
||||
|
||||
using content::KeyboardEventProcessingResult;
|
||||
|
||||
namespace {
|
||||
|
@ -351,6 +357,22 @@ void CefBrowserContentsDelegate::RenderViewReady() {
|
|||
|
||||
void CefBrowserContentsDelegate::PrimaryMainFrameRenderProcessGone(
|
||||
base::TerminationStatus status) {
|
||||
static_assert(static_cast<int>(CEF_RESULT_CODE_CHROME_FIRST) ==
|
||||
static_cast<int>(chrome::RESULT_CODE_CHROME_START),
|
||||
"enum mismatch");
|
||||
static_assert(static_cast<int>(CEF_RESULT_CODE_CHROME_LAST) ==
|
||||
static_cast<int>(chrome::RESULT_CODE_CHROME_LAST_CODE),
|
||||
"enum mismatch");
|
||||
|
||||
#if defined(OS_WIN)
|
||||
static_assert(static_cast<int>(CEF_RESULT_CODE_SANDBOX_FATAL_FIRST) ==
|
||||
static_cast<int>(sandbox::SBOX_FATAL_INTEGRITY),
|
||||
"enum mismatch");
|
||||
static_assert(static_cast<int>(CEF_RESULT_CODE_SANDBOX_FATAL_LAST) ==
|
||||
static_cast<int>(sandbox::SBOX_FATAL_LAST),
|
||||
"enum mismatch");
|
||||
#endif
|
||||
|
||||
cef_termination_status_t ts = TS_ABNORMAL_TERMINATION;
|
||||
if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
|
||||
ts = TS_PROCESS_WAS_KILLED;
|
||||
|
@ -358,14 +380,22 @@ void CefBrowserContentsDelegate::PrimaryMainFrameRenderProcessGone(
|
|||
ts = TS_PROCESS_CRASHED;
|
||||
} else if (status == base::TERMINATION_STATUS_OOM) {
|
||||
ts = TS_PROCESS_OOM;
|
||||
} else if (status == base::TERMINATION_STATUS_LAUNCH_FAILED) {
|
||||
ts = TS_LAUNCH_FAILED;
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
} else if (status == base::TERMINATION_STATUS_INTEGRITY_FAILURE) {
|
||||
ts = TS_INTEGRITY_FAILURE;
|
||||
#endif
|
||||
} else if (status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto c = client()) {
|
||||
if (auto handler = c->GetRequestHandler()) {
|
||||
int error_code = web_contents()->GetCrashedErrorCode();
|
||||
auto navigation_lock = browser_info_->CreateNavigationLock();
|
||||
handler->OnRenderProcessTerminated(browser(), ts);
|
||||
handler->OnRenderProcessTerminated(browser(), ts, error_code,
|
||||
SadTabView::ErrorToString(error_code));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "libcef/browser/browser_info_manager.h"
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/hang_monitor.h"
|
||||
#include "libcef/browser/image_impl.h"
|
||||
#include "libcef/browser/navigation_entry_impl.h"
|
||||
#include "libcef/browser/printing/print_util.h"
|
||||
|
@ -31,6 +32,8 @@
|
|||
#include "content/public/browser/download_request_utils.h"
|
||||
#include "content/public/browser/file_select_listener.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "ui/base/resource/resource_scale_factor.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/shell_dialogs/select_file_policy.h"
|
||||
|
@ -256,6 +259,11 @@ void CefBrowserHostBase::DestroyBrowser() {
|
|||
contents_delegate_->RemoveObserver(this);
|
||||
contents_delegate_->ObserveWebContents(nullptr);
|
||||
|
||||
if (unresponsive_process_callback_) {
|
||||
hang_monitor::Detach(unresponsive_process_callback_);
|
||||
unresponsive_process_callback_.reset();
|
||||
}
|
||||
|
||||
CefBrowserInfoManager::GetInstance()->RemoveBrowserInfo(browser_info_);
|
||||
browser_info_->SetBrowser(nullptr);
|
||||
}
|
||||
|
@ -707,6 +715,22 @@ void CefBrowserHostBase::ExitFullscreen(bool will_cause_resize) {
|
|||
}
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::IsRenderProcessUnresponsive() {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
DCHECK(false) << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto* web_contents = GetWebContents()) {
|
||||
if (auto* rvh = web_contents->GetRenderViewHost()) {
|
||||
if (auto* rwh = rvh->GetWidget()) {
|
||||
return rwh->IsCurrentlyUnresponsive();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserHostBase::ReplaceMisspelling(const CefString& word) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_client.h"
|
||||
#include "include/cef_unresponsive_process_callback.h"
|
||||
#include "include/views/cef_browser_view.h"
|
||||
#include "libcef/browser/browser_contents_delegate.h"
|
||||
#include "libcef/browser/browser_info.h"
|
||||
|
@ -238,6 +239,7 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
void NotifyMoveOrResizeStarted() override;
|
||||
bool IsFullscreen() override;
|
||||
void ExitFullscreen(bool will_cause_resize) override;
|
||||
bool IsRenderProcessUnresponsive() override;
|
||||
|
||||
// CefBrowser methods:
|
||||
bool IsValid() override;
|
||||
|
@ -341,6 +343,15 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
}
|
||||
CefMediaStreamRegistrar* GetMediaStreamRegistrar();
|
||||
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> unresponsive_process_callback()
|
||||
const {
|
||||
return unresponsive_process_callback_;
|
||||
}
|
||||
void set_unresponsive_process_callback(
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> callback) {
|
||||
unresponsive_process_callback_ = callback;
|
||||
}
|
||||
|
||||
// Returns the Widget owner for the browser window. Only used with windowed
|
||||
// browsers.
|
||||
views::Widget* GetWindowWidget() const;
|
||||
|
@ -391,6 +402,7 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
|
||||
// Only accessed on the UI thread.
|
||||
std::unique_ptr<CefBrowserContentsDelegate> contents_delegate_;
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> unresponsive_process_callback_;
|
||||
|
||||
// Observers that want to be notified of changes to this object.
|
||||
// Only accessed on the UI thread.
|
||||
|
|
|
@ -119,6 +119,21 @@ class BrowserDelegate : public content::WebContentsDelegate {
|
|||
return callback;
|
||||
}
|
||||
|
||||
// Same as RendererUnresponsive but returning false if unhandled.
|
||||
virtual bool RendererUnresponsiveEx(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Same as RendererResponsive but returning false if unhandled.
|
||||
virtual bool RendererResponsiveEx(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Optionally override support for the specified window feature of type
|
||||
// Browser::WindowFeature.
|
||||
virtual std::optional<bool> SupportsWindowFeature(int feature) const {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
|
||||
#include "libcef/browser/chrome/views/chrome_browser_view.h"
|
||||
#include "libcef/browser/chrome/views/chrome_child_window.h"
|
||||
#include "libcef/browser/hang_monitor.h"
|
||||
#include "libcef/browser/media_access_query.h"
|
||||
#include "libcef/browser/request_context_impl.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
|
@ -361,6 +362,26 @@ ChromeBrowserDelegate::RequestMediaAccessPermissionEx(
|
|||
return callback;
|
||||
}
|
||||
|
||||
bool ChromeBrowserDelegate::RendererUnresponsiveEx(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
|
||||
return hang_monitor::RendererUnresponsive(browser.get(), render_widget_host,
|
||||
hang_monitor_restarter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChromeBrowserDelegate::RendererResponsiveEx(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
|
||||
return hang_monitor::RendererResponsive(browser.get(), render_widget_host);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChromeBrowserDelegate::SupportsFramelessPictureInPicture() const {
|
||||
if (!browser_->is_type_picture_in_picture()) {
|
||||
return false;
|
||||
|
|
|
@ -76,6 +76,13 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
|||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) override;
|
||||
bool RendererUnresponsiveEx(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) override;
|
||||
bool RendererResponsiveEx(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
std::optional<bool> SupportsWindowFeature(int feature) const override;
|
||||
bool SupportsDraggableRegion() const override;
|
||||
const std::optional<SkRegion> GetDraggableRegion() const override;
|
||||
|
|
|
@ -34,6 +34,9 @@ namespace {
|
|||
|
||||
CefContext* g_context = nullptr;
|
||||
|
||||
// Invalid value before CefInitialize is called.
|
||||
int g_exit_code = -1;
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
// When the process terminates check if CefShutdown() has been called.
|
||||
class CefShutdownChecker {
|
||||
|
@ -309,8 +312,11 @@ bool CefInitialize(const CefMainArgs& args,
|
|||
g_context = new CefContext();
|
||||
|
||||
// Initialize the global context.
|
||||
if (!g_context->Initialize(args, settings, application,
|
||||
windows_sandbox_info)) {
|
||||
const bool initialized =
|
||||
g_context->Initialize(args, settings, application, windows_sandbox_info);
|
||||
g_exit_code = g_context->exit_code();
|
||||
|
||||
if (!initialized) {
|
||||
// Initialization failed. Delete the global context object.
|
||||
delete g_context;
|
||||
g_context = nullptr;
|
||||
|
@ -320,6 +326,11 @@ bool CefInitialize(const CefMainArgs& args,
|
|||
return true;
|
||||
}
|
||||
|
||||
int CefGetExitCode() {
|
||||
DCHECK_NE(g_exit_code, -1) << "invalid call to CefGetExitCode";
|
||||
return g_exit_code;
|
||||
}
|
||||
|
||||
void CefShutdown() {
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
|
@ -477,10 +488,14 @@ bool CefContext::Initialize(const CefMainArgs& args,
|
|||
|
||||
main_runner_ = std::make_unique<CefMainRunner>(
|
||||
settings_.multi_threaded_message_loop, settings_.external_message_pump);
|
||||
if (!main_runner_->Initialize(
|
||||
&settings_, application, args, windows_sandbox_info, &initialized_,
|
||||
base::BindOnce(&CefContext::OnContextInitialized,
|
||||
base::Unretained(this)))) {
|
||||
|
||||
const bool initialized = main_runner_->Initialize(
|
||||
&settings_, application, args, windows_sandbox_info, &initialized_,
|
||||
base::BindOnce(&CefContext::OnContextInitialized,
|
||||
base::Unretained(this)));
|
||||
exit_code_ = main_runner_->exit_code();
|
||||
|
||||
if (!initialized) {
|
||||
shutting_down_ = true;
|
||||
FinalizeShutdown();
|
||||
return false;
|
||||
|
|
|
@ -52,10 +52,13 @@ class CefContext {
|
|||
bool OnInitThread();
|
||||
|
||||
// Returns true if the context is initialized.
|
||||
bool initialized() { return initialized_; }
|
||||
bool initialized() const { return initialized_; }
|
||||
|
||||
// Returns true if the context is shutting down.
|
||||
bool shutting_down() { return shutting_down_; }
|
||||
bool shutting_down() const { return shutting_down_; }
|
||||
|
||||
// Only valid after Initialize is called.
|
||||
int exit_code() const { return exit_code_; }
|
||||
|
||||
const CefSettings& settings() const { return settings_; }
|
||||
|
||||
|
@ -100,6 +103,7 @@ class CefContext {
|
|||
// Track context state.
|
||||
bool initialized_ = false;
|
||||
bool shutting_down_ = false;
|
||||
int exit_code_ = -1;
|
||||
|
||||
// The thread on which the context was initialized.
|
||||
base::PlatformThreadId init_thread_id_ = 0;
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
// Copyright 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 "libcef/browser/hang_monitor.h"
|
||||
|
||||
#include "include/cef_client.h"
|
||||
#include "libcef/browser/browser_host_base.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/hang_monitor/hang_crash_dump.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
|
||||
namespace hang_monitor {
|
||||
|
||||
namespace {
|
||||
|
||||
// Based on HungRendererDialogView::ForceCrashHungRenderer.
|
||||
void ForceCrashHungRenderer(content::RenderWidgetHost* render_widget_host) {
|
||||
content::RenderProcessHost* rph = render_widget_host->GetProcess();
|
||||
if (rph) {
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
// A generic |CrashDumpHungChildProcess()| is not implemented for Linux.
|
||||
// Instead we send an explicit IPC to crash on the renderer's IO thread.
|
||||
rph->ForceCrash();
|
||||
#else
|
||||
// Try to generate a crash report for the hung process.
|
||||
CrashDumpHungChildProcess(rph->GetProcess().Handle());
|
||||
rph->Shutdown(content::RESULT_CODE_HUNG);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
class CefUnresponsiveProcessCallbackImpl
|
||||
: public CefUnresponsiveProcessCallback {
|
||||
public:
|
||||
CefUnresponsiveProcessCallbackImpl(
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter)
|
||||
: render_widget_host_(render_widget_host),
|
||||
hang_monitor_restarter_(hang_monitor_restarter) {}
|
||||
|
||||
CefUnresponsiveProcessCallbackImpl(
|
||||
const CefUnresponsiveProcessCallbackImpl&) = delete;
|
||||
CefUnresponsiveProcessCallbackImpl& operator=(
|
||||
const CefUnresponsiveProcessCallbackImpl&) = delete;
|
||||
|
||||
~CefUnresponsiveProcessCallbackImpl() override {
|
||||
// Do nothing on destruction.
|
||||
}
|
||||
|
||||
void Wait() override { ContinueNow(true); }
|
||||
|
||||
void Terminate() override { ContinueNow(false); }
|
||||
|
||||
void Detach() {
|
||||
render_widget_host_ = nullptr;
|
||||
hang_monitor_restarter_.Reset();
|
||||
}
|
||||
|
||||
bool IsDetached() const { return !render_widget_host_; }
|
||||
|
||||
private:
|
||||
void ContinueNow(bool wait) {
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
if (!IsDetached()) {
|
||||
RunNow(render_widget_host_, hang_monitor_restarter_, wait);
|
||||
Detach();
|
||||
}
|
||||
} else {
|
||||
CEF_POST_TASK(
|
||||
CEF_UIT,
|
||||
base::BindOnce(&CefUnresponsiveProcessCallbackImpl::ContinueNow, this,
|
||||
wait));
|
||||
}
|
||||
}
|
||||
|
||||
static void RunNow(content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter,
|
||||
bool wait) {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (wait) {
|
||||
hang_monitor_restarter.Run();
|
||||
} else {
|
||||
ForceCrashHungRenderer(render_widget_host);
|
||||
}
|
||||
}
|
||||
|
||||
content::RenderWidgetHost* render_widget_host_;
|
||||
base::RepeatingClosure hang_monitor_restarter_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefUnresponsiveProcessCallbackImpl);
|
||||
};
|
||||
|
||||
bool ResetRendererCallback(CefBrowserHostBase* browser) {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (auto callback = browser->unresponsive_process_callback()) {
|
||||
Detach(callback);
|
||||
browser->set_unresponsive_process_callback(nullptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestHandler> GetRequestHandler(CefBrowserHostBase* browser) {
|
||||
if (auto client = browser->GetClient()) {
|
||||
return client->GetRequestHandler();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool RendererUnresponsive(CefBrowserHostBase* browser,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
// There should be no callback currently.
|
||||
DCHECK(!browser->unresponsive_process_callback());
|
||||
|
||||
if (auto handler = GetRequestHandler(browser)) {
|
||||
CefRefPtr<CefUnresponsiveProcessCallbackImpl> callbackImpl(
|
||||
new CefUnresponsiveProcessCallbackImpl(render_widget_host,
|
||||
hang_monitor_restarter));
|
||||
if (!handler->OnRenderProcessUnresponsive(browser, callbackImpl.get())) {
|
||||
if (!callbackImpl->IsDetached()) {
|
||||
// Proceed with default handling.
|
||||
callbackImpl->Detach();
|
||||
return false;
|
||||
} else {
|
||||
LOG(ERROR) << "Should return true from OnRenderProcessUnresponsive "
|
||||
"when executing the callback";
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed with client handling. The callback may already be executed, but
|
||||
// we still want to wait for RendererResponsive.
|
||||
browser->set_unresponsive_process_callback(callbackImpl.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Proceed with default handling.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RendererResponsive(CefBrowserHostBase* browser,
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
// |handled| will be true if the client handled OnRenderProcessUnresponsive.
|
||||
bool handled = ResetRendererCallback(browser);
|
||||
|
||||
// Always execute the client callback.
|
||||
if (auto handler = GetRequestHandler(browser)) {
|
||||
handler->OnRenderProcessResponsive(browser);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void Detach(CefRefPtr<CefUnresponsiveProcessCallback> callback) {
|
||||
CEF_REQUIRE_UIT();
|
||||
auto* callback_impl =
|
||||
static_cast<CefUnresponsiveProcessCallbackImpl*>(callback.get());
|
||||
callback_impl->Detach();
|
||||
}
|
||||
|
||||
} // namespace hang_monitor
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 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_HANG_MONITOR_H_
|
||||
#define CEF_LIBCEF_BROWSER_HANG_MONITOR_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_unresponsive_process_callback.h"
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
|
||||
namespace content {
|
||||
class RenderWidgetHost;
|
||||
}
|
||||
|
||||
class CefBrowserHostBase;
|
||||
|
||||
namespace hang_monitor {
|
||||
|
||||
// Called from WebContentsDelegate::RendererUnresponsive.
|
||||
// Returns false for default handling.
|
||||
bool RendererUnresponsive(CefBrowserHostBase* browser,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter);
|
||||
|
||||
// Called from WebContentsDelegate::RendererResponsive.
|
||||
// Returns false for default handling.
|
||||
bool RendererResponsive(CefBrowserHostBase* browser,
|
||||
content::RenderWidgetHost* render_widget_host);
|
||||
|
||||
// Detach an existing callback object.
|
||||
void Detach(CefRefPtr<CefUnresponsiveProcessCallback> callback);
|
||||
|
||||
} // namespace hang_monitor
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_HANG_MONITOR_H_
|
|
@ -245,20 +245,20 @@ bool CefMainRunner::Initialize(CefSettings* settings,
|
|||
settings->chrome_runtime ? RuntimeType::CHROME : RuntimeType::ALLOY, this,
|
||||
settings, application);
|
||||
|
||||
int exit_code =
|
||||
exit_code_ =
|
||||
ContentMainInitialize(args, windows_sandbox_info, &settings->no_sandbox);
|
||||
if (exit_code >= 0) {
|
||||
LOG(ERROR) << "ContentMainInitialize failed with exit code " << exit_code;
|
||||
if (exit_code_ >= 0) {
|
||||
LOG(ERROR) << "ContentMainInitialize failed with exit code " << exit_code_;
|
||||
return false;
|
||||
}
|
||||
|
||||
exit_code = ContentMainRun(initialized, std::move(context_initialized));
|
||||
if (exit_code != content::RESULT_CODE_NORMAL_EXIT) {
|
||||
exit_code_ = ContentMainRun(initialized, std::move(context_initialized));
|
||||
if (exit_code_ != content::RESULT_CODE_NORMAL_EXIT) {
|
||||
// Some exit codes are used to exit early, but are otherwise a normal
|
||||
// result. Don't log for those codes.
|
||||
if (!chrome::IsNormalResultCode(
|
||||
static_cast<chrome::ResultCode>(exit_code))) {
|
||||
LOG(ERROR) << "ContentMainRun failed with exit code " << exit_code;
|
||||
static_cast<chrome::ResultCode>(exit_code_))) {
|
||||
LOG(ERROR) << "ContentMainRun failed with exit code " << exit_code_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ class CefMainRunner : public CefMainRunnerHandler {
|
|||
bool* initialized,
|
||||
base::OnceClosure context_initialized);
|
||||
|
||||
// Only valid after Initialize is called.
|
||||
int exit_code() const { return exit_code_; }
|
||||
|
||||
// Called from CefContext::Shutdown.
|
||||
void Shutdown(base::OnceClosure shutdown_on_ui_thread,
|
||||
base::OnceClosure finalize_shutdown);
|
||||
|
@ -90,6 +93,8 @@ class CefMainRunner : public CefMainRunnerHandler {
|
|||
|
||||
// Used to quit the current base::RunLoop.
|
||||
base::OnceClosure quit_callback_;
|
||||
|
||||
int exit_code_ = -1;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_MAIN_RUNNER_H_
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=c1afe37bef47447905f9dc6b6ba56f550e24021f$
|
||||
// $hash=790f88d9d22bbef9882470f0980f5e7e446d30c5$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
||||
|
@ -1506,6 +1506,24 @@ browser_host_execute_chrome_command(struct _cef_browser_host_t* self,
|
|||
disposition);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK
|
||||
browser_host_is_render_process_unresponsive(struct _cef_browser_host_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute
|
||||
bool _retval = CefBrowserHostCppToC::Get(self)->IsRenderProcessUnresponsive();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
@ -1588,6 +1606,8 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
|
|||
GetStruct()->can_execute_chrome_command =
|
||||
browser_host_can_execute_chrome_command;
|
||||
GetStruct()->execute_chrome_command = browser_host_execute_chrome_command;
|
||||
GetStruct()->is_render_process_unresponsive =
|
||||
browser_host_is_render_process_unresponsive;
|
||||
}
|
||||
|
||||
// DESTRUCTOR - Do not edit by hand.
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=4a0c9cb5d77d315e067d07ed633b623a8e12a1fc$
|
||||
// $hash=436eb7d254d6edc452b8b529758967d274fa2f85$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/request_handler_cpptoc.h"
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include "libcef_dll/ctocpp/request_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/select_client_certificate_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/sslinfo_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/unresponsive_process_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/x509certificate_ctocpp.h"
|
||||
#include "libcef_dll/shutdown_checker.h"
|
||||
|
||||
|
@ -345,10 +346,42 @@ request_handler_on_render_view_ready(struct _cef_request_handler_t* self,
|
|||
CefBrowserCToCpp::Wrap(browser));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK request_handler_on_render_process_terminated(
|
||||
int CEF_CALLBACK request_handler_on_render_process_unresponsive(
|
||||
struct _cef_request_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
cef_termination_status_t status) {
|
||||
struct _cef_unresponsive_process_callback_t* callback) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return 0;
|
||||
}
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser) {
|
||||
return 0;
|
||||
}
|
||||
// Verify param: callback; type: refptr_diff
|
||||
DCHECK(callback);
|
||||
if (!callback) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute
|
||||
bool _retval =
|
||||
CefRequestHandlerCppToC::Get(self)->OnRenderProcessUnresponsive(
|
||||
CefBrowserCToCpp::Wrap(browser),
|
||||
CefUnresponsiveProcessCallbackCToCpp::Wrap(callback));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK request_handler_on_render_process_responsive(
|
||||
struct _cef_request_handler_t* self,
|
||||
cef_browser_t* browser) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
@ -363,9 +396,40 @@ void CEF_CALLBACK request_handler_on_render_process_terminated(
|
|||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefRequestHandlerCppToC::Get(self)->OnRenderProcessResponsive(
|
||||
CefBrowserCToCpp::Wrap(browser));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK request_handler_on_render_process_terminated(
|
||||
struct _cef_request_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
cef_termination_status_t status,
|
||||
int error_code,
|
||||
const cef_string_t* error_string) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser) {
|
||||
return;
|
||||
}
|
||||
// Verify param: error_string; type: string_byref_const
|
||||
DCHECK(error_string);
|
||||
if (!error_string) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefRequestHandlerCppToC::Get(self)->OnRenderProcessTerminated(
|
||||
CefBrowserCToCpp::Wrap(browser), status);
|
||||
CefBrowserCToCpp::Wrap(browser), status, error_code,
|
||||
CefString(error_string));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK request_handler_on_document_available_in_main_frame(
|
||||
|
@ -404,6 +468,10 @@ CefRequestHandlerCppToC::CefRequestHandlerCppToC() {
|
|||
GetStruct()->on_select_client_certificate =
|
||||
request_handler_on_select_client_certificate;
|
||||
GetStruct()->on_render_view_ready = request_handler_on_render_view_ready;
|
||||
GetStruct()->on_render_process_unresponsive =
|
||||
request_handler_on_render_process_unresponsive;
|
||||
GetStruct()->on_render_process_responsive =
|
||||
request_handler_on_render_process_responsive;
|
||||
GetStruct()->on_render_process_terminated =
|
||||
request_handler_on_render_process_terminated;
|
||||
GetStruct()->on_document_available_in_main_frame =
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
// 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=d31cea8b172629a308a7d54f8dd6fccff4cc8823$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/unresponsive_process_callback_cpptoc.h"
|
||||
#include "libcef_dll/shutdown_checker.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
void CEF_CALLBACK unresponsive_process_callback_wait(
|
||||
struct _cef_unresponsive_process_callback_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefUnresponsiveProcessCallbackCppToC::Get(self)->Wait();
|
||||
}
|
||||
|
||||
void CEF_CALLBACK unresponsive_process_callback_terminate(
|
||||
struct _cef_unresponsive_process_callback_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefUnresponsiveProcessCallbackCppToC::Get(self)->Terminate();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefUnresponsiveProcessCallbackCppToC::CefUnresponsiveProcessCallbackCppToC() {
|
||||
GetStruct()->wait = unresponsive_process_callback_wait;
|
||||
GetStruct()->terminate = unresponsive_process_callback_terminate;
|
||||
}
|
||||
|
||||
// DESTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefUnresponsiveProcessCallbackCppToC::~CefUnresponsiveProcessCallbackCppToC() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
}
|
||||
|
||||
template <>
|
||||
CefRefPtr<CefUnresponsiveProcessCallback>
|
||||
CefCppToCRefCounted<CefUnresponsiveProcessCallbackCppToC,
|
||||
CefUnresponsiveProcessCallback,
|
||||
cef_unresponsive_process_callback_t>::
|
||||
UnwrapDerived(CefWrapperType type, cef_unresponsive_process_callback_t* s) {
|
||||
DCHECK(false) << "Unexpected class type: " << type;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <>
|
||||
CefWrapperType
|
||||
CefCppToCRefCounted<CefUnresponsiveProcessCallbackCppToC,
|
||||
CefUnresponsiveProcessCallback,
|
||||
cef_unresponsive_process_callback_t>::kWrapperType =
|
||||
WT_UNRESPONSIVE_PROCESS_CALLBACK;
|
|
@ -0,0 +1,38 @@
|
|||
// 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=1816748407afd5599d8582de51b3289d1ea24a33$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CPPTOC_UNRESPONSIVE_PROCESS_CALLBACK_CPPTOC_H_
|
||||
#define CEF_LIBCEF_DLL_CPPTOC_UNRESPONSIVE_PROCESS_CALLBACK_CPPTOC_H_
|
||||
#pragma once
|
||||
|
||||
#if !defined(BUILDING_CEF_SHARED)
|
||||
#error This file can be included DLL-side only
|
||||
#endif
|
||||
|
||||
#include "include/capi/cef_unresponsive_process_callback_capi.h"
|
||||
#include "include/cef_unresponsive_process_callback.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 CefUnresponsiveProcessCallbackCppToC
|
||||
: public CefCppToCRefCounted<CefUnresponsiveProcessCallbackCppToC,
|
||||
CefUnresponsiveProcessCallback,
|
||||
cef_unresponsive_process_callback_t> {
|
||||
public:
|
||||
CefUnresponsiveProcessCallbackCppToC();
|
||||
virtual ~CefUnresponsiveProcessCallbackCppToC();
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CPPTOC_UNRESPONSIVE_PROCESS_CALLBACK_CPPTOC_H_
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=736aa196beae8c3c35ef330eb78fb0908fccf70b$
|
||||
// $hash=da0fdd0a724301aa3ca12055bce970b9d3d0f708$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
||||
|
@ -1296,6 +1296,24 @@ void CefBrowserHostCToCpp::ExecuteChromeCommand(
|
|||
_struct->execute_chrome_command(_struct, command_id, disposition);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefBrowserHostCToCpp::IsRenderProcessUnresponsive() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_render_process_unresponsive)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_render_process_unresponsive(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefBrowserHostCToCpp::CefBrowserHostCToCpp() {}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=8b1e4268c2b68437b5022e9baf3f1c56bf036fe7$
|
||||
// $hash=ec03d4b0c8e59ba8f8eb3060e374b4d76e22669b$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
||||
|
@ -139,6 +139,7 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted<CefBrowserHostCToCpp,
|
|||
bool CanExecuteChromeCommand(int command_id) override;
|
||||
void ExecuteChromeCommand(int command_id,
|
||||
cef_window_open_disposition_t disposition) override;
|
||||
bool IsRenderProcessUnresponsive() override;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=a93a6c9d3656f1c7fd70795abb89d608e996f834$
|
||||
// $hash=19b44051658f9e6419dc37d33ed9a70239b5f857$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/request_handler_ctocpp.h"
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include "libcef_dll/cpptoc/request_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/select_client_certificate_callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/sslinfo_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/unresponsive_process_callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/x509certificate_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/resource_request_handler_ctocpp.h"
|
||||
#include "libcef_dll/shutdown_checker.h"
|
||||
|
@ -340,10 +341,68 @@ void CefRequestHandlerCToCpp::OnRenderViewReady(CefRefPtr<CefBrowser> browser) {
|
|||
_struct->on_render_view_ready(_struct, CefBrowserCppToC::Wrap(browser));
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefRequestHandlerCToCpp::OnRenderProcessUnresponsive(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> callback) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_request_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_render_process_unresponsive)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get()) {
|
||||
return false;
|
||||
}
|
||||
// Verify param: callback; type: refptr_diff
|
||||
DCHECK(callback.get());
|
||||
if (!callback.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->on_render_process_unresponsive(
|
||||
_struct, CefBrowserCppToC::Wrap(browser),
|
||||
CefUnresponsiveProcessCallbackCppToC::Wrap(callback));
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefRequestHandlerCToCpp::OnRenderProcessResponsive(
|
||||
CefRefPtr<CefBrowser> browser) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_request_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_render_process_responsive)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
_struct->on_render_process_responsive(_struct,
|
||||
CefBrowserCppToC::Wrap(browser));
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefRequestHandlerCToCpp::OnRenderProcessTerminated(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) {
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_request_handler_t* _struct = GetStruct();
|
||||
|
@ -358,10 +417,16 @@ void CefRequestHandlerCToCpp::OnRenderProcessTerminated(
|
|||
if (!browser.get()) {
|
||||
return;
|
||||
}
|
||||
// Verify param: error_string; type: string_byref_const
|
||||
DCHECK(!error_string.empty());
|
||||
if (error_string.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
_struct->on_render_process_terminated(
|
||||
_struct, CefBrowserCppToC::Wrap(browser), status);
|
||||
_struct->on_render_process_terminated(_struct,
|
||||
CefBrowserCppToC::Wrap(browser), status,
|
||||
error_code, error_string.GetStruct());
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=272831fa944a45a447a333f81c9e5501a3a7db64$
|
||||
// $hash=af82af05fec824761f5ff735ff6c9831938deb16$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_HANDLER_CTOCPP_H_
|
||||
|
@ -74,8 +74,14 @@ class CefRequestHandlerCToCpp
|
|||
const X509CertificateList& certificates,
|
||||
CefRefPtr<CefSelectClientCertificateCallback> callback) override;
|
||||
void OnRenderViewReady(CefRefPtr<CefBrowser> browser) override;
|
||||
bool OnRenderProcessUnresponsive(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> callback) override;
|
||||
void OnRenderProcessResponsive(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) override;
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override;
|
||||
void OnDocumentAvailableInMainFrame(CefRefPtr<CefBrowser> browser) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
// 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=c8f9d6f148a367be5eef1b3512ba023da0f9ac84$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/unresponsive_process_callback_ctocpp.h"
|
||||
#include "libcef_dll/shutdown_checker.h"
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
NO_SANITIZE("cfi-icall") void CefUnresponsiveProcessCallbackCToCpp::Wait() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_unresponsive_process_callback_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, wait)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->wait(_struct);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefUnresponsiveProcessCallbackCToCpp::Terminate() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_unresponsive_process_callback_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, terminate)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->terminate(_struct);
|
||||
}
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefUnresponsiveProcessCallbackCToCpp::CefUnresponsiveProcessCallbackCToCpp() {}
|
||||
|
||||
// DESTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefUnresponsiveProcessCallbackCToCpp::~CefUnresponsiveProcessCallbackCToCpp() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
}
|
||||
|
||||
template <>
|
||||
cef_unresponsive_process_callback_t*
|
||||
CefCToCppRefCounted<CefUnresponsiveProcessCallbackCToCpp,
|
||||
CefUnresponsiveProcessCallback,
|
||||
cef_unresponsive_process_callback_t>::
|
||||
UnwrapDerived(CefWrapperType type, CefUnresponsiveProcessCallback* c) {
|
||||
DCHECK(false) << "Unexpected class type: " << type;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <>
|
||||
CefWrapperType
|
||||
CefCToCppRefCounted<CefUnresponsiveProcessCallbackCToCpp,
|
||||
CefUnresponsiveProcessCallback,
|
||||
cef_unresponsive_process_callback_t>::kWrapperType =
|
||||
WT_UNRESPONSIVE_PROCESS_CALLBACK;
|
|
@ -0,0 +1,42 @@
|
|||
// 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=4c04a490cc0609560e711890eeb286431675bf54$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_UNRESPONSIVE_PROCESS_CALLBACK_CTOCPP_H_
|
||||
#define CEF_LIBCEF_DLL_CTOCPP_UNRESPONSIVE_PROCESS_CALLBACK_CTOCPP_H_
|
||||
#pragma once
|
||||
|
||||
#if !defined(WRAPPING_CEF_SHARED)
|
||||
#error This file can be included wrapper-side only
|
||||
#endif
|
||||
|
||||
#include "include/capi/cef_unresponsive_process_callback_capi.h"
|
||||
#include "include/cef_unresponsive_process_callback.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 CefUnresponsiveProcessCallbackCToCpp
|
||||
: public CefCToCppRefCounted<CefUnresponsiveProcessCallbackCToCpp,
|
||||
CefUnresponsiveProcessCallback,
|
||||
cef_unresponsive_process_callback_t> {
|
||||
public:
|
||||
CefUnresponsiveProcessCallbackCToCpp();
|
||||
virtual ~CefUnresponsiveProcessCallbackCToCpp();
|
||||
|
||||
// CefUnresponsiveProcessCallback methods.
|
||||
void Wait() override;
|
||||
void Terminate() override;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CTOCPP_UNRESPONSIVE_PROCESS_CALLBACK_CTOCPP_H_
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=215fc5a9025e8b0cd3d1bc7259ad6e6ac53b2125$
|
||||
// $hash=716d8a4bb86c9ee9ebe8dfe28ec2c37411507830$
|
||||
//
|
||||
|
||||
#include "include/capi/cef_app_capi.h"
|
||||
|
@ -118,6 +118,16 @@ CEF_EXPORT int cef_initialize(const cef_main_args_t* args,
|
|||
return _retval;
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_get_exit_code() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = CefGetExitCode();
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
CEF_EXPORT void cef_shutdown() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=f882e920463e6681b19a06c9d897b09b17e27bd3$
|
||||
// $hash=fd77a51eeea378bb56d43ba2995a0417d905c247$
|
||||
//
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
@ -92,6 +92,7 @@ void* libcef_get_ptr(const char* path, const char* name) {
|
|||
struct libcef_pointers {
|
||||
decltype(&cef_execute_process) cef_execute_process;
|
||||
decltype(&cef_initialize) cef_initialize;
|
||||
decltype(&cef_get_exit_code) cef_get_exit_code;
|
||||
decltype(&cef_shutdown) cef_shutdown;
|
||||
decltype(&cef_do_message_loop_work) cef_do_message_loop_work;
|
||||
decltype(&cef_run_message_loop) cef_run_message_loop;
|
||||
|
@ -337,6 +338,7 @@ struct libcef_pointers {
|
|||
int libcef_init_pointers(const char* path) {
|
||||
INIT_ENTRY(cef_execute_process);
|
||||
INIT_ENTRY(cef_initialize);
|
||||
INIT_ENTRY(cef_get_exit_code);
|
||||
INIT_ENTRY(cef_shutdown);
|
||||
INIT_ENTRY(cef_do_message_loop_work);
|
||||
INIT_ENTRY(cef_run_message_loop);
|
||||
|
@ -590,6 +592,10 @@ int cef_initialize(const cef_main_args_t* args,
|
|||
windows_sandbox_info);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") int cef_get_exit_code() {
|
||||
return g_libcef_pointers.cef_get_exit_code();
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") void cef_shutdown() {
|
||||
g_libcef_pointers.cef_shutdown();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=f2b284f21cdb59e621ecddbe2f07392d24d48ddd$
|
||||
// $hash=23f943f8e59a48f29ba3095642bc05d7f987a2f2$
|
||||
//
|
||||
|
||||
#include "include/capi/cef_app_capi.h"
|
||||
|
@ -106,6 +106,16 @@ CEF_GLOBAL bool CefInitialize(const CefMainArgs& args,
|
|||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") CEF_GLOBAL int CefGetExitCode() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = cef_get_exit_code();
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") CEF_GLOBAL void CefShutdown() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=613fb0a830ebbd0ad913f60a482b8ba9d6f01ff4$
|
||||
// $hash=f250db632dc9f127b3aaff303d6105ca235ff462$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
|
||||
|
@ -162,6 +162,7 @@ enum CefWrapperType {
|
|||
WT_TRANSLATOR_TEST_SCOPED_LIBRARY_CHILD_CHILD,
|
||||
WT_URLREQUEST,
|
||||
WT_URLREQUEST_CLIENT,
|
||||
WT_UNRESPONSIVE_PROCESS_CALLBACK,
|
||||
WT_V8ACCESSOR,
|
||||
WT_V8ARRAY_BUFFER_RELEASE_CALLBACK,
|
||||
WT_V8CONTEXT,
|
||||
|
|
|
@ -340,6 +340,11 @@ patches = [
|
|||
# Add BrowserPluginGuest::owner_web_contents() method.
|
||||
'name': 'chrome_plugins',
|
||||
},
|
||||
{
|
||||
# Expose sad tab error strings.
|
||||
# https://github.com/chromiumembedded/cef/issues/3661
|
||||
'name': 'chrome_sad_tab_error',
|
||||
},
|
||||
{
|
||||
# Don't create databases, blob_storage or VideoDecodeStats directories when
|
||||
# cache_path is empty.
|
||||
|
|
|
@ -132,7 +132,7 @@ index 768e11b9e5648..b4ba1800def14 100644
|
|||
]
|
||||
}
|
||||
diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc
|
||||
index 0791cc8f55a92..d94ac23dc878a 100644
|
||||
index 0791cc8f55a92..df3fb31c5c787 100644
|
||||
--- chrome/browser/ui/browser.cc
|
||||
+++ chrome/browser/ui/browser.cc
|
||||
@@ -264,6 +264,25 @@
|
||||
|
@ -301,7 +301,7 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
void Browser::BeforeUnloadFired(WebContents* web_contents,
|
||||
bool proceed,
|
||||
bool* proceed_to_fire_unload) {
|
||||
@@ -1975,6 +2060,10 @@ void Browser::WebContentsCreated(WebContents* source_contents,
|
||||
@@ -1975,12 +2060,24 @@ void Browser::WebContentsCreated(WebContents* source_contents,
|
||||
|
||||
// Make the tab show up in the task manager.
|
||||
task_manager::WebContentsTags::CreateForTabContents(new_contents);
|
||||
|
@ -312,7 +312,35 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
}
|
||||
|
||||
void Browser::RendererUnresponsive(
|
||||
@@ -2119,11 +2208,15 @@ void Browser::EnterFullscreenModeForTab(
|
||||
WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (cef_browser_delegate_ &&
|
||||
+ cef_browser_delegate_->RendererUnresponsiveEx(source, render_widget_host,
|
||||
+ hang_monitor_restarter)) {
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
// Don't show the page hung dialog when a HTML popup hangs because
|
||||
// the dialog will take the focus and immediately close the popup.
|
||||
RenderWidgetHostView* view = render_widget_host->GetView();
|
||||
@@ -1993,6 +2090,13 @@ void Browser::RendererUnresponsive(
|
||||
void Browser::RendererResponsive(
|
||||
WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (cef_browser_delegate_ &&
|
||||
+ cef_browser_delegate_->RendererResponsiveEx(source, render_widget_host)) {
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
RenderWidgetHostView* view = render_widget_host->GetView();
|
||||
if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) {
|
||||
TabDialogs::FromWebContents(source)->HideHungRendererDialog(
|
||||
@@ -2119,11 +2223,15 @@ void Browser::EnterFullscreenModeForTab(
|
||||
const blink::mojom::FullscreenOptions& options) {
|
||||
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
|
||||
requesting_frame, options.display_id);
|
||||
|
@ -328,7 +356,7 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
}
|
||||
|
||||
bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
|
||||
@@ -2322,6 +2415,15 @@ void Browser::RequestMediaAccessPermission(
|
||||
@@ -2322,6 +2430,15 @@ void Browser::RequestMediaAccessPermission(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) {
|
||||
|
@ -344,7 +372,7 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
const extensions::Extension* extension =
|
||||
GetExtensionForOrigin(profile_, request.security_origin);
|
||||
MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
|
||||
@@ -2858,9 +2960,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
|
||||
@@ -2858,9 +2975,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
|
||||
// Browser, Getters for UI (private):
|
||||
|
||||
StatusBubble* Browser::GetStatusBubble() {
|
||||
|
@ -357,7 +385,7 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
}
|
||||
|
||||
// We hide the status bar for web apps windows as this matches native
|
||||
@@ -2868,6 +2972,12 @@ StatusBubble* Browser::GetStatusBubble() {
|
||||
@@ -2868,6 +2987,12 @@ StatusBubble* Browser::GetStatusBubble() {
|
||||
// mode, as the minimal browser UI includes the status bar.
|
||||
if (web_app::AppBrowserController::IsWebApp(this) &&
|
||||
!app_controller()->HasMinimalUiButtons()) {
|
||||
|
@ -370,7 +398,7 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -3004,6 +3114,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
|
||||
@@ -3004,6 +3129,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
|
||||
BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
|
||||
web_contents_collection_.StopObserving(web_contents);
|
||||
}
|
||||
|
@ -379,7 +407,7 @@ index 0791cc8f55a92..d94ac23dc878a 100644
|
|||
}
|
||||
|
||||
void Browser::TabDetachedAtImpl(content::WebContents* contents,
|
||||
@@ -3158,6 +3270,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
|
||||
@@ -3158,6 +3285,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
|
||||
|
||||
bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
|
||||
bool check_can_support) const {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
diff --git chrome/browser/ui/views/sad_tab_view.cc chrome/browser/ui/views/sad_tab_view.cc
|
||||
index 26d1d804f74e7..87f411df5a49c 100644
|
||||
--- chrome/browser/ui/views/sad_tab_view.cc
|
||||
+++ chrome/browser/ui/views/sad_tab_view.cc
|
||||
@@ -680,6 +680,11 @@ void SadTabView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
|
||||
title_->SizeToFit(max_width);
|
||||
}
|
||||
|
||||
+// static
|
||||
+std::u16string SadTabView::ErrorToString(int error_code) {
|
||||
+ return ::ErrorToString(error_code);
|
||||
+}
|
||||
+
|
||||
SadTab* SadTab::Create(content::WebContents* web_contents, SadTabKind kind) {
|
||||
return new SadTabView(web_contents, kind);
|
||||
}
|
||||
diff --git chrome/browser/ui/views/sad_tab_view.h chrome/browser/ui/views/sad_tab_view.h
|
||||
index d6cb0e1a28eb2..59aca7bbb17c3 100644
|
||||
--- chrome/browser/ui/views/sad_tab_view.h
|
||||
+++ chrome/browser/ui/views/sad_tab_view.h
|
||||
@@ -56,6 +56,8 @@ class SadTabView : public SadTab, public views::View {
|
||||
// Overridden from views::View:
|
||||
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
|
||||
|
||||
+ static std::u16string ErrorToString(int error_code);
|
||||
+
|
||||
protected:
|
||||
// Overridden from views::View:
|
||||
void OnPaint(gfx::Canvas* canvas) override;
|
|
@ -0,0 +1,154 @@
|
|||
// 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/base_client_handler.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
BaseClientHandler::BaseClientHandler() {
|
||||
resource_manager_ = new CefResourceManager();
|
||||
test_runner::SetupResourceManager(resource_manager_, &string_resource_map_);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<BaseClientHandler> BaseClientHandler::GetForBrowser(
|
||||
CefRefPtr<CefBrowser> browser) {
|
||||
return static_cast<BaseClientHandler*>(browser->GetHost()->GetClient().get());
|
||||
}
|
||||
|
||||
bool BaseClientHandler::OnProcessMessageReceived(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefProcessId source_process,
|
||||
CefRefPtr<CefProcessMessage> message) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return message_router_->OnProcessMessageReceived(browser, frame,
|
||||
source_process, message);
|
||||
}
|
||||
|
||||
void BaseClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
browser_count_++;
|
||||
|
||||
if (!message_router_) {
|
||||
// Create the browser-side router for query handling.
|
||||
CefMessageRouterConfig config;
|
||||
message_router_ = CefMessageRouterBrowserSide::Create(config);
|
||||
|
||||
// Register handlers with the router.
|
||||
test_runner::CreateMessageHandlers(message_handler_set_);
|
||||
for (auto* message_handler : message_handler_set_) {
|
||||
message_router_->AddHandler(message_handler, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (--browser_count_ == 0) {
|
||||
// Remove and delete message router handlers.
|
||||
for (auto* message_handler : message_handler_set_) {
|
||||
message_router_->RemoveHandler(message_handler);
|
||||
delete message_handler;
|
||||
}
|
||||
message_handler_set_.clear();
|
||||
message_router_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool user_gesture,
|
||||
bool is_redirect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
message_router_->OnBeforeBrowse(browser, frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BaseClientHandler::OnRenderProcessUnresponsive(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> callback) {
|
||||
switch (hang_action_) {
|
||||
case HangAction::kDefault:
|
||||
return false;
|
||||
case HangAction::kWait:
|
||||
callback->Wait();
|
||||
break;
|
||||
case HangAction::kTerminate:
|
||||
callback->Terminate();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseClientHandler::OnRenderProcessTerminated(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
message_router_->OnRenderProcessTerminated(browser);
|
||||
}
|
||||
|
||||
cef_return_value_t BaseClientHandler::OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->OnBeforeResourceLoad(browser, frame, request,
|
||||
callback);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> BaseClientHandler::GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->GetResourceHandler(browser, frame, request);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResponseFilter> BaseClientHandler::GetResourceResponseFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return test_runner::GetResourceResponseFilter(browser, frame, request,
|
||||
response);
|
||||
}
|
||||
|
||||
int BaseClientHandler::GetBrowserCount() const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return browser_count_;
|
||||
}
|
||||
|
||||
void BaseClientHandler::SetStringResource(const std::string& page,
|
||||
const std::string& data) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO, base::BindOnce(&BaseClientHandler::SetStringResource,
|
||||
this, page, data));
|
||||
return;
|
||||
}
|
||||
|
||||
string_resource_map_[page] = data;
|
||||
}
|
||||
|
||||
void BaseClientHandler::SetHangAction(HangAction action) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
hang_action_ = action;
|
||||
}
|
||||
|
||||
BaseClientHandler::HangAction BaseClientHandler::GetHangAction() const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return hang_action_;
|
||||
}
|
||||
|
||||
} // namespace client
|
|
@ -0,0 +1,125 @@
|
|||
// 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_BASE_CLIENT_HANDLER_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_BASE_CLIENT_HANDLER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_client.h"
|
||||
#include "include/wrapper/cef_message_router.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Abstract base class for client handlers.
|
||||
class BaseClientHandler : public CefClient,
|
||||
public CefLifeSpanHandler,
|
||||
public CefRequestHandler,
|
||||
public CefResourceRequestHandler {
|
||||
public:
|
||||
BaseClientHandler();
|
||||
|
||||
// Returns the BaseClientHandler associated with |browser|.
|
||||
static CefRefPtr<BaseClientHandler> GetForBrowser(
|
||||
CefRefPtr<CefBrowser> browser);
|
||||
|
||||
// CefClient methods
|
||||
CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
|
||||
CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }
|
||||
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefProcessId source_process,
|
||||
CefRefPtr<CefProcessMessage> message) override;
|
||||
|
||||
// CefLifeSpanHandler methods
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
|
||||
// CefRequestHandler methods
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool user_gesture,
|
||||
bool is_redirect) override;
|
||||
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_navigation,
|
||||
bool is_download,
|
||||
const CefString& request_initiator,
|
||||
bool& disable_default_handling) override {
|
||||
return this;
|
||||
}
|
||||
bool OnRenderProcessUnresponsive(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefUnresponsiveProcessCallback> callback) override;
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override;
|
||||
|
||||
// CefResourceRequestHandler methods
|
||||
cef_return_value_t OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override;
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override;
|
||||
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) override;
|
||||
|
||||
// Returns the number of browsers currently using this handler. Can only be
|
||||
// called on the CEF UI thread.
|
||||
int GetBrowserCount() const;
|
||||
|
||||
// Set a string resource for loading via StringResourceProvider.
|
||||
void SetStringResource(const std::string& page, const std::string& data);
|
||||
|
||||
// Action to be taken when the render process becomes unresponsive.
|
||||
enum class HangAction {
|
||||
kDefault,
|
||||
kWait,
|
||||
kTerminate,
|
||||
};
|
||||
void SetHangAction(HangAction action);
|
||||
HangAction GetHangAction() const;
|
||||
|
||||
protected:
|
||||
CefRefPtr<CefResourceManager> GetResourceManager() const {
|
||||
return resource_manager_;
|
||||
}
|
||||
|
||||
private:
|
||||
// The current number of browsers using this handler.
|
||||
int browser_count_ = 0;
|
||||
|
||||
// Handles the browser side of query routing. The renderer side is handled
|
||||
// in client_renderer.cc.
|
||||
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
|
||||
|
||||
// Set of Handlers registered with the message router.
|
||||
test_runner::MessageHandlerSet message_handler_set_;
|
||||
|
||||
// Manages the registration and delivery of resources.
|
||||
CefRefPtr<CefResourceManager> resource_manager_;
|
||||
|
||||
// Used to manage string resources in combination with StringResourceProvider.
|
||||
// Only accessed on the IO thread.
|
||||
test_runner::StringResourceMap string_resource_map_;
|
||||
|
||||
HangAction hang_action_ = HangAction::kDefault;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BaseClientHandler);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_BASE_CLIENT_HANDLER_H_
|
|
@ -168,19 +168,22 @@ std::string GetContentStatusString(cef_ssl_content_status_t status) {
|
|||
|
||||
// Load a data: URI containing the error message.
|
||||
void LoadErrorPage(CefRefPtr<CefFrame> frame,
|
||||
const std::string& title,
|
||||
const std::string& failed_url,
|
||||
cef_errorcode_t error_code,
|
||||
const std::string& error_string,
|
||||
const std::string& other_info) {
|
||||
std::stringstream ss;
|
||||
ss << "<html><head><title>Page failed to load</title></head>"
|
||||
"<body bgcolor=\"white\">"
|
||||
"<h3>Page failed to load.</h3>"
|
||||
"URL: <a href=\""
|
||||
<< failed_url << "\">" << failed_url
|
||||
<< "</a><br/>Error: " << test_runner::GetErrorString(error_code) << " ("
|
||||
<< error_code << ")";
|
||||
if (MainContext::Get()->UseChromeRuntime()) {
|
||||
// Use default error pages with Chrome runtime.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!other_info.empty()) {
|
||||
std::stringstream ss;
|
||||
ss << "<html><head><title>" << title
|
||||
<< "</title></head><body bgcolor=\"white\"><h3>" << title
|
||||
<< "</h3>URL: <a href=\"" << failed_url << "\">" << failed_url
|
||||
<< "</a><br/>Error: " << error_string;
|
||||
|
||||
if (!other_info.empty() && other_info != error_string) {
|
||||
ss << "<br/>" << other_info;
|
||||
}
|
||||
|
||||
|
@ -463,9 +466,6 @@ ClientHandler::ClientHandler(Delegate* delegate,
|
|||
console_log_file_(MainContext::Get()->GetConsoleLogPath()) {
|
||||
DCHECK(!console_log_file_.empty());
|
||||
|
||||
resource_manager_ = new CefResourceManager();
|
||||
test_runner::SetupResourceManager(resource_manager_, &string_resource_map_);
|
||||
|
||||
// Read command line settings.
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
|
@ -538,8 +538,8 @@ bool ClientHandler::OnProcessMessageReceived(
|
|||
|
||||
const auto finish_time = bv_utils::Now();
|
||||
|
||||
if (message_router_->OnProcessMessageReceived(browser, frame, source_process,
|
||||
message)) {
|
||||
if (BaseClientHandler::OnProcessMessageReceived(browser, frame,
|
||||
source_process, message)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -973,21 +973,7 @@ void ClientHandler::OnBeforeDevToolsPopup(
|
|||
|
||||
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
browser_count_++;
|
||||
|
||||
if (!message_router_) {
|
||||
// Create the browser-side router for query handling.
|
||||
CefMessageRouterConfig config;
|
||||
message_router_ = CefMessageRouterBrowserSide::Create(config);
|
||||
|
||||
// Register handlers with the router.
|
||||
test_runner::CreateMessageHandlers(message_handler_set_);
|
||||
MessageHandlerSet::const_iterator it = message_handler_set_.begin();
|
||||
for (; it != message_handler_set_.end(); ++it) {
|
||||
message_router_->AddHandler(*(it), false);
|
||||
}
|
||||
}
|
||||
BaseClientHandler::OnAfterCreated(browser);
|
||||
|
||||
// Set offline mode if requested via the command-line flag.
|
||||
if (offline_) {
|
||||
|
@ -1002,8 +988,8 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
|||
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
|
||||
if (extension_util::IsInternalExtension(extension->GetPath())) {
|
||||
// Register the internal handler for extension resources.
|
||||
extension_util::AddInternalExtensionToResourceManager(extension,
|
||||
resource_manager_);
|
||||
extension_util::AddInternalExtensionToResourceManager(
|
||||
extension, GetResourceManager());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1022,18 +1008,7 @@ bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
|
|||
|
||||
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (--browser_count_ == 0) {
|
||||
// Remove and delete message router handlers.
|
||||
MessageHandlerSet::const_iterator it = message_handler_set_.begin();
|
||||
for (; it != message_handler_set_.end(); ++it) {
|
||||
message_router_->RemoveHandler(*(it));
|
||||
delete *(it);
|
||||
}
|
||||
message_handler_set_.clear();
|
||||
message_router_ = nullptr;
|
||||
}
|
||||
|
||||
BaseClientHandler::OnBeforeClose(browser);
|
||||
NotifyBrowserClosed(browser);
|
||||
}
|
||||
|
||||
|
@ -1072,7 +1047,8 @@ void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
|
|||
}
|
||||
|
||||
// Load the error page.
|
||||
LoadErrorPage(frame, failedUrl, errorCode, errorText);
|
||||
LoadErrorPage(frame, "Page failed to load", failedUrl,
|
||||
test_runner::GetErrorString(errorCode), errorText);
|
||||
}
|
||||
|
||||
bool ClientHandler::OnRequestMediaAccessPermission(
|
||||
|
@ -1086,17 +1062,6 @@ bool ClientHandler::OnRequestMediaAccessPermission(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool user_gesture,
|
||||
bool is_redirect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
message_router_->OnBeforeBrowse(browser, frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientHandler::OnOpenURLFromTab(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
|
@ -1176,7 +1141,8 @@ bool ClientHandler::OnCertificateError(CefRefPtr<CefBrowser> browser,
|
|||
CefRefPtr<CefX509Certificate> cert = ssl_info->GetX509Certificate();
|
||||
if (cert.get()) {
|
||||
// Load the error page.
|
||||
LoadErrorPage(browser->GetMainFrame(), request_url, cert_error,
|
||||
LoadErrorPage(browser->GetMainFrame(), "SSL certificate error", request_url,
|
||||
test_runner::GetErrorString(cert_error),
|
||||
GetCertificateInformation(cert, ssl_info->GetCertStatus()));
|
||||
}
|
||||
|
||||
|
@ -1220,10 +1186,12 @@ bool ClientHandler::OnSelectClientCertificate(
|
|||
}
|
||||
|
||||
void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) {
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
message_router_->OnRenderProcessTerminated(browser);
|
||||
BaseClientHandler::OnRenderProcessTerminated(browser, status, error_code,
|
||||
error_string);
|
||||
|
||||
// Don't reload if there's no start URL, or if the crash URL was specified.
|
||||
if (startup_url_.empty() || startup_url_ == "chrome://crash") {
|
||||
|
@ -1245,6 +1213,10 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
|||
|
||||
// Don't reload the URL that just resulted in termination.
|
||||
if (url.find(start_url) == 0) {
|
||||
LoadErrorPage(frame, "Render process terminated", frame->GetURL(),
|
||||
test_runner::GetErrorString(status) + " (" +
|
||||
error_string.ToString() + ")",
|
||||
std::string());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1262,37 +1234,6 @@ void ClientHandler::OnDocumentAvailableInMainFrame(
|
|||
}
|
||||
}
|
||||
|
||||
cef_return_value_t ClientHandler::OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->OnBeforeResourceLoad(browser, frame, request,
|
||||
callback);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->GetResourceHandler(browser, frame, request);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResponseFilter> ClientHandler::GetResourceResponseFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return test_runner::GetResourceResponseFilter(browser, frame, request,
|
||||
response);
|
||||
}
|
||||
|
||||
void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
|
@ -1307,11 +1248,6 @@ void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
|
|||
}
|
||||
}
|
||||
|
||||
int ClientHandler::GetBrowserCount() const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return browser_count_;
|
||||
}
|
||||
|
||||
void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser,
|
||||
const CefPoint& inspect_element_at) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
|
@ -1404,17 +1340,6 @@ void ClientHandler::ShowSSLInformation(CefRefPtr<CefBrowser> browser) {
|
|||
std::move(config));
|
||||
}
|
||||
|
||||
void ClientHandler::SetStringResource(const std::string& page,
|
||||
const std::string& data) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO, base::BindOnce(&ClientHandler::SetStringResource, this,
|
||||
page, data));
|
||||
return;
|
||||
}
|
||||
|
||||
string_resource_map_[page] = data;
|
||||
}
|
||||
|
||||
bool ClientHandler::CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
|
||||
#include "include/cef_client.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "include/wrapper/cef_message_router.h"
|
||||
#include "include/wrapper/cef_resource_manager.h"
|
||||
#include "tests/cefclient/browser/base_client_handler.h"
|
||||
#include "tests/cefclient/browser/client_types.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
|
@ -27,7 +26,7 @@ class ClientDownloadImageCallback;
|
|||
|
||||
// Client handler abstract base class. Provides common functionality shared by
|
||||
// all concrete client handler implementations.
|
||||
class ClientHandler : public CefClient,
|
||||
class ClientHandler : public BaseClientHandler,
|
||||
public CefCommandHandler,
|
||||
public CefContextMenuHandler,
|
||||
public CefDisplayHandler,
|
||||
|
@ -35,11 +34,8 @@ class ClientHandler : public CefClient,
|
|||
public CefDragHandler,
|
||||
public CefFocusHandler,
|
||||
public CefKeyboardHandler,
|
||||
public CefLifeSpanHandler,
|
||||
public CefLoadHandler,
|
||||
public CefPermissionHandler,
|
||||
public CefRequestHandler,
|
||||
public CefResourceRequestHandler {
|
||||
public CefPermissionHandler {
|
||||
public:
|
||||
// Implement this interface to receive notification of ClientHandler
|
||||
// events. The methods of this class will be called on the main thread unless
|
||||
|
@ -89,8 +85,6 @@ class ClientHandler : public CefClient,
|
|||
virtual ~Delegate() = default;
|
||||
};
|
||||
|
||||
typedef std::set<CefMessageRouterBrowserSide::Handler*> MessageHandlerSet;
|
||||
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object or DetachDelegate() must be called.
|
||||
ClientHandler(Delegate* delegate,
|
||||
|
@ -112,9 +106,7 @@ class ClientHandler : public CefClient,
|
|||
CefRefPtr<CefDragHandler> GetDragHandler() override { return this; }
|
||||
CefRefPtr<CefFocusHandler> GetFocusHandler() override { return this; }
|
||||
CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() override { return this; }
|
||||
CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
|
||||
CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
|
||||
CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }
|
||||
CefRefPtr<CefPermissionHandler> GetPermissionHandler() override {
|
||||
return this;
|
||||
}
|
||||
|
@ -254,11 +246,6 @@ class ClientHandler : public CefClient,
|
|||
CefRefPtr<CefMediaAccessCallback> callback) override;
|
||||
|
||||
// CefRequestHandler methods
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool user_gesture,
|
||||
bool is_redirect) override;
|
||||
bool OnOpenURLFromTab(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
|
@ -294,33 +281,17 @@ class ClientHandler : public CefClient,
|
|||
const X509CertificateList& certificates,
|
||||
CefRefPtr<CefSelectClientCertificateCallback> callback) override;
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) override;
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override;
|
||||
void OnDocumentAvailableInMainFrame(CefRefPtr<CefBrowser> browser) override;
|
||||
|
||||
// CefResourceRequestHandler methods
|
||||
cef_return_value_t OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override;
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override;
|
||||
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) override;
|
||||
void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool& allow_os_execution) override;
|
||||
|
||||
// Returns the number of browsers currently using this handler. Can only be
|
||||
// called on the CEF UI thread.
|
||||
int GetBrowserCount() const;
|
||||
|
||||
// Show a new DevTools popup window.
|
||||
void ShowDevTools(CefRefPtr<CefBrowser> browser,
|
||||
const CefPoint& inspect_element_at);
|
||||
|
@ -334,9 +305,6 @@ class ClientHandler : public CefClient,
|
|||
// Show SSL information for the current site.
|
||||
void ShowSSLInformation(CefRefPtr<CefBrowser> browser);
|
||||
|
||||
// Set a string resource for loading via StringResourceProvider.
|
||||
void SetStringResource(const std::string& page, const std::string& data);
|
||||
|
||||
// Returns the Delegate.
|
||||
Delegate* delegate() const { return delegate_; }
|
||||
|
||||
|
@ -416,17 +384,6 @@ class ClientHandler : public CefClient,
|
|||
CefRefPtr<ClientPrintHandlerGtk> print_handler_;
|
||||
#endif
|
||||
|
||||
// Handles the browser side of query routing. The renderer side is handled
|
||||
// in client_renderer.cc.
|
||||
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
|
||||
|
||||
// Manages the registration and delivery of resources.
|
||||
CefRefPtr<CefResourceManager> resource_manager_;
|
||||
|
||||
// Used to manage string resources in combination with StringResourceProvider.
|
||||
// Only accessed on the IO thread.
|
||||
test_runner::StringResourceMap string_resource_map_;
|
||||
|
||||
// MAIN THREAD MEMBERS
|
||||
// The following members will only be accessed on the main thread. This will
|
||||
// be the same as the CEF UI thread except when using multi-threaded message
|
||||
|
@ -444,9 +401,6 @@ class ClientHandler : public CefClient,
|
|||
int radio_item = 0;
|
||||
} test_menu_state_;
|
||||
|
||||
// The current number of browsers using this handler.
|
||||
int browser_count_ = 0;
|
||||
|
||||
// Console logging state.
|
||||
const std::string console_log_file_;
|
||||
|
||||
|
@ -456,9 +410,6 @@ class ClientHandler : public CefClient,
|
|||
// True for the initial navigation after browser creation.
|
||||
bool initial_navigation_ = true;
|
||||
|
||||
// Set of Handlers registered with the message router.
|
||||
MessageHandlerSet message_handler_set_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientHandler);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) 2023 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/default_client_handler.h"
|
||||
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
DefaultClientHandler::DefaultClientHandler() {
|
||||
resource_manager_ = new CefResourceManager();
|
||||
test_runner::SetupResourceManager(resource_manager_, nullptr);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceRequestHandler>
|
||||
DefaultClientHandler::GetResourceRequestHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_navigation,
|
||||
bool is_download,
|
||||
const CefString& request_initiator,
|
||||
bool& disable_default_handling) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
return this;
|
||||
}
|
||||
|
||||
cef_return_value_t DefaultClientHandler::OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->OnBeforeResourceLoad(browser, frame, request,
|
||||
callback);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> DefaultClientHandler::GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->GetResourceHandler(browser, frame, request);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResponseFilter> DefaultClientHandler::GetResourceResponseFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return test_runner::GetResourceResponseFilter(browser, frame, request,
|
||||
response);
|
||||
}
|
||||
|
||||
} // namespace client
|
|
@ -6,52 +6,17 @@
|
|||
#define CEF_TESTS_CEFCLIENT_BROWSER_DEFAULT_CLIENT_HANDLER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_client.h"
|
||||
#include "include/wrapper/cef_resource_manager.h"
|
||||
#include "tests/cefclient/browser/base_client_handler.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Default client handler for unmanaged browser windows. Used with the Chrome
|
||||
// runtime only.
|
||||
class DefaultClientHandler : public CefClient,
|
||||
public CefRequestHandler,
|
||||
public CefResourceRequestHandler {
|
||||
class DefaultClientHandler : public BaseClientHandler {
|
||||
public:
|
||||
DefaultClientHandler();
|
||||
|
||||
// CefClient methods
|
||||
CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }
|
||||
|
||||
// CefRequestHandler methods
|
||||
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_navigation,
|
||||
bool is_download,
|
||||
const CefString& request_initiator,
|
||||
bool& disable_default_handling) override;
|
||||
|
||||
// CefResourceRequestHandler methods
|
||||
cef_return_value_t OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override;
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override;
|
||||
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) override;
|
||||
DefaultClientHandler() = default;
|
||||
|
||||
private:
|
||||
// Manages the registration and delivery of resources.
|
||||
CefRefPtr<CefResourceManager> resource_manager_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(DefaultClientHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(DefaultClientHandler);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// 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/hang_test.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "tests/cefclient/browser/base_client_handler.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client::hang_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrlPath[] = "/hang";
|
||||
const char kTestMessageName[] = "HangTest";
|
||||
|
||||
// Handle messages in the browser process.
|
||||
class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
public:
|
||||
Handler() = default;
|
||||
|
||||
// Called due to cefQuery execution in hang.html.
|
||||
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64_t query_id,
|
||||
const CefString& request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) override {
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto client_handler = BaseClientHandler::GetForBrowser(browser)) {
|
||||
using HangAction = BaseClientHandler::HangAction;
|
||||
|
||||
const std::string& message_name = request;
|
||||
if (message_name.find(kTestMessageName) == 0) {
|
||||
const std::string& command =
|
||||
message_name.substr(sizeof(kTestMessageName));
|
||||
if (command == "getcommand") {
|
||||
std::string current;
|
||||
switch (client_handler->GetHangAction()) {
|
||||
case HangAction::kDefault:
|
||||
current = "default";
|
||||
break;
|
||||
case HangAction::kWait:
|
||||
current = "wait";
|
||||
break;
|
||||
case HangAction::kTerminate:
|
||||
current = "terminate";
|
||||
break;
|
||||
}
|
||||
callback->Success(current);
|
||||
} else if (command == "setdefault") {
|
||||
client_handler->SetHangAction(HangAction::kDefault);
|
||||
} else if (command == "setwait") {
|
||||
client_handler->SetHangAction(HangAction::kWait);
|
||||
} else if (command == "setterminate") {
|
||||
client_handler->SetHangAction(HangAction::kTerminate);
|
||||
} else {
|
||||
LOG(ERROR) << "Unrecognized command: " << command;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
|
||||
handlers.insert(new Handler());
|
||||
}
|
||||
|
||||
} // namespace client::hang_test
|
|
@ -0,0 +1,18 @@
|
|||
// 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_HANG_TEST_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_HANG_TEST_H_
|
||||
#pragma once
|
||||
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client::hang_test {
|
||||
|
||||
// Create message handlers. Called from test_runner.cc.
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
|
||||
|
||||
} // namespace client::hang_test
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_HANG_TEST_H_
|
|
@ -46,28 +46,29 @@
|
|||
#define IDS_BINDING_HTML 1001
|
||||
#define IDS_DIALOGS_HTML 1002
|
||||
#define IDS_DRAGGABLE_HTML 1003
|
||||
#define IDS_IPC_PERFORMANCE_HTML 1004
|
||||
#define IDS_LOCALSTORAGE_HTML 1005
|
||||
#define IDS_LOGO_PNG 1006
|
||||
#define IDS_MEDIA_ROUTER_HTML 1007
|
||||
#define IDS_MENU_ICON_1X_PNG 1008
|
||||
#define IDS_MENU_ICON_2X_PNG 1009
|
||||
#define IDS_OSRTEST_HTML 1010
|
||||
#define IDS_OTHER_TESTS_HTML 1011
|
||||
#define IDS_PDF_HTML 1012
|
||||
#define IDS_PDF_PDF 1013
|
||||
#define IDS_PERFORMANCE_HTML 1014
|
||||
#define IDS_PERFORMANCE2_HTML 1015
|
||||
#define IDS_PREFERENCES_HTML 1016
|
||||
#define IDS_RESPONSE_FILTER_HTML 1017
|
||||
#define IDS_SERVER_HTML 1018
|
||||
#define IDS_TRANSPARENCY_HTML 1019
|
||||
#define IDS_URLREQUEST_HTML 1020
|
||||
#define IDS_WEBSOCKET_HTML 1021
|
||||
#define IDS_WINDOW_HTML 1022
|
||||
#define IDS_WINDOW_ICON_1X_PNG 1023
|
||||
#define IDS_WINDOW_ICON_2X_PNG 1024
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1025
|
||||
#define IDS_HANG_HTML 1004
|
||||
#define IDS_IPC_PERFORMANCE_HTML 1005
|
||||
#define IDS_LOCALSTORAGE_HTML 1006
|
||||
#define IDS_LOGO_PNG 1007
|
||||
#define IDS_MEDIA_ROUTER_HTML 1008
|
||||
#define IDS_MENU_ICON_1X_PNG 1009
|
||||
#define IDS_MENU_ICON_2X_PNG 1010
|
||||
#define IDS_OSRTEST_HTML 1011
|
||||
#define IDS_OTHER_TESTS_HTML 1012
|
||||
#define IDS_PDF_HTML 1013
|
||||
#define IDS_PDF_PDF 1014
|
||||
#define IDS_PERFORMANCE_HTML 1015
|
||||
#define IDS_PERFORMANCE2_HTML 1016
|
||||
#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_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
|
||||
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031
|
||||
|
|
|
@ -25,6 +25,7 @@ int GetResourceId(const char* resource_name) {
|
|||
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML},
|
||||
{"extensions/set_page_color/popup.js",
|
||||
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS},
|
||||
{"hang.html", IDS_HANG_HTML},
|
||||
{"ipc_performance.html", IDS_IPC_PERFORMANCE_HTML},
|
||||
{"localstorage.html", IDS_LOCALSTORAGE_HTML},
|
||||
{"logo.png", IDS_LOGO_PNG},
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_callback.h"
|
||||
#include "include/cef_parser.h"
|
||||
|
@ -16,10 +17,11 @@
|
|||
#include "include/views/cef_browser_view.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||
#include "tests/cefclient/browser/base_client_handler.h"
|
||||
#include "tests/cefclient/browser/binary_transfer_test.h"
|
||||
#include "tests/cefclient/browser/binding_test.h"
|
||||
#include "tests/cefclient/browser/client_handler.h"
|
||||
#include "tests/cefclient/browser/dialog_test.h"
|
||||
#include "tests/cefclient/browser/hang_test.h"
|
||||
#include "tests/cefclient/browser/main_context.h"
|
||||
#include "tests/cefclient/browser/media_router_test.h"
|
||||
#include "tests/cefclient/browser/preferences_test.h"
|
||||
|
@ -50,9 +52,7 @@ const char kTestGetTextPage[] = "get_text.html";
|
|||
void LoadStringResourcePage(CefRefPtr<CefBrowser> browser,
|
||||
const std::string& page,
|
||||
const std::string& data) {
|
||||
CefRefPtr<CefClient> client = browser->GetHost()->GetClient();
|
||||
ClientHandler* client_handler = static_cast<ClientHandler*>(client.get());
|
||||
client_handler->SetStringResource(page, data);
|
||||
BaseClientHandler::GetForBrowser(browser)->SetStringResource(page, data);
|
||||
browser->GetMainFrame()->LoadURL(kTestOrigin + page);
|
||||
}
|
||||
|
||||
|
@ -752,10 +752,29 @@ std::string GetErrorString(cef_errorcode_t code) {
|
|||
CASE(ERR_CACHE_MISS);
|
||||
CASE(ERR_INSECURE_RESPONSE);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
return std::to_string(static_cast<int>(code));
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetErrorString(cef_termination_status_t status) {
|
||||
switch (status) {
|
||||
case TS_ABNORMAL_TERMINATION:
|
||||
return "ABNORMAL_TERMINATION";
|
||||
case TS_PROCESS_WAS_KILLED:
|
||||
return "PROCESS_WAS_KILLED";
|
||||
case TS_PROCESS_CRASHED:
|
||||
return "PROCESS_CRASHED";
|
||||
case TS_PROCESS_OOM:
|
||||
return "PROCESS_OOM";
|
||||
case TS_LAUNCH_FAILED:
|
||||
return "LAUNCH_FAILED";
|
||||
case TS_INTEGRITY_FAILURE:
|
||||
return "INTEGRITY_FAILURE";
|
||||
}
|
||||
NOTREACHED();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager,
|
||||
StringResourceMap* string_resource_map) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
|
@ -851,6 +870,9 @@ void CreateMessageHandlers(MessageHandlerSet& handlers) {
|
|||
// Create the dialog test handlers.
|
||||
dialog_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the hang test handlers.
|
||||
hang_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the media router test handlers.
|
||||
media_router_test::CreateMessageHandlers(handlers);
|
||||
|
||||
|
|
|
@ -33,8 +33,9 @@ std::string GetDataURI(const std::string& data, const std::string& mime_type);
|
|||
|
||||
// Returns the string representation of the specified error code.
|
||||
std::string GetErrorString(cef_errorcode_t code);
|
||||
std::string GetErrorString(cef_termination_status_t status);
|
||||
|
||||
typedef std::map<std::string, std::string> StringResourceMap;
|
||||
using StringResourceMap = std::map<std::string, std::string>;
|
||||
|
||||
// Set up the resource manager for tests.
|
||||
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager,
|
||||
|
@ -52,7 +53,7 @@ bool IsTestURL(const std::string& url, const std::string& path);
|
|||
|
||||
// Create all CefMessageRouterBrowserSide::Handler objects. They will be
|
||||
// deleted when the ClientHandler is destroyed.
|
||||
typedef std::set<CefMessageRouterBrowserSide::Handler*> MessageHandlerSet;
|
||||
using MessageHandlerSet = std::set<CefMessageRouterBrowserSide::Handler*>;
|
||||
void CreateMessageHandlers(MessageHandlerSet& handlers);
|
||||
|
||||
// Register scheme handlers for tests.
|
||||
|
|
|
@ -110,7 +110,7 @@ int RunMain(int argc, char* argv[]) {
|
|||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!context->Initialize(main_args, settings, app, nullptr)) {
|
||||
return 1;
|
||||
return CefGetExitCode();
|
||||
}
|
||||
|
||||
// Force Gtk to use Xwayland (in case a Wayland compositor is being used).
|
||||
|
|
|
@ -583,7 +583,7 @@ int RunMain(int argc, char* argv[]) {
|
|||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!context->Initialize(main_args, settings, app, nullptr)) {
|
||||
return 1;
|
||||
return CefGetExitCode();
|
||||
}
|
||||
|
||||
// Register scheme handlers.
|
||||
|
|
|
@ -99,7 +99,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
|||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!context->Initialize(main_args, settings, app, sandbox_info)) {
|
||||
return 1;
|
||||
return CefGetExitCode();
|
||||
}
|
||||
|
||||
// Register scheme handlers.
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Dialog Test</title>
|
||||
<style>
|
||||
#loading {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 3px solid rgba(0,0,0,.3);
|
||||
border-radius: 50%;
|
||||
border-top-color: #000;
|
||||
animation: spin 1s ease-in-out infinite;
|
||||
-webkit-animation: spin 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
@-webkit-keyframes spin {
|
||||
to { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function show_alert() {
|
||||
alert("I am an alert box!");
|
||||
|
@ -74,7 +93,19 @@ Click a button to show the associated dialog type.
|
|||
<br/><input type="button" onclick="show_file_dialog('fom', 'FileOpenMultiple');" value="Show File Open (multiple types/files)" disabled="true"> <span id="fom"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fof', 'FileOpenFolder');" value="Show File Open Folder" disabled="true"> <span id="fof"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fs', 'FileSave');" value="Show File Save" disabled="true"> <span id="fs"></span>
|
||||
<p id="time"></p>
|
||||
</form>
|
||||
|
||||
Observe page responsiveness:
|
||||
<br/><br/>
|
||||
<table><tr>
|
||||
<td valign="top">
|
||||
CSS:<br/><div id="loading"></div>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td valign="top">
|
||||
JavaScript:<br/><div id="time"></div>
|
||||
</td>
|
||||
</tr></table>
|
||||
(JavaScript will stop updating while alert/confirm/prompt is displayed)
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Render Process Hang Test</title>
|
||||
<style>
|
||||
#loading {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 3px solid rgba(0,0,0,.3);
|
||||
border-radius: 50%;
|
||||
border-top-color: #000;
|
||||
animation: spin 1s ease-in-out infinite;
|
||||
-webkit-animation: spin 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
@-webkit-keyframes spin {
|
||||
to { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
#hangtime {
|
||||
width: 40px;
|
||||
}
|
||||
</style>
|
||||
<script language="JavaScript">
|
||||
|
||||
function setFormEnabled(enabled) {
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = !enabled;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTime() {
|
||||
document.getElementById('time').innerText = new Date().toLocaleString();
|
||||
}
|
||||
|
||||
function setupTest() {
|
||||
// Retrieve the currently configured command.
|
||||
// Results in a call to the OnQuery method in hang_test.cc
|
||||
window.cefQuery({
|
||||
request: 'HangTest:getcommand',
|
||||
onSuccess: function(response) {
|
||||
document.getElementById(response).checked = true;
|
||||
setFormEnabled(true);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function setup() {
|
||||
// Disable all elements.
|
||||
setFormEnabled(false);
|
||||
|
||||
updateTime();
|
||||
setInterval(updateTime, 1000);
|
||||
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost') {
|
||||
setupTest();
|
||||
return;
|
||||
}
|
||||
|
||||
alert('This page can only be run from tests or localhost.');
|
||||
}
|
||||
|
||||
// Send a query to the browser process.
|
||||
function sendCommand(command) {
|
||||
// Set the configured command.
|
||||
// Results in a call to the OnQuery method in hang_test.cc
|
||||
window.cefQuery({
|
||||
request: 'HangTest:' + command
|
||||
});
|
||||
}
|
||||
|
||||
// Hang the render process for the specified number of seconds.
|
||||
function triggerHang() {
|
||||
const delayMs = parseInt(document.getElementById('hangtime').value) * 1000;
|
||||
const startTime = performance.now();
|
||||
while(performance.now() - startTime < delayMs) {}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<form id="form">
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<div>Use the below controls to trigger a render process hang.</div>
|
||||
<br/>
|
||||
<div>Hang for <input type="number" id="hangtime" min="1" max="99" step="1" value="20"/> seconds.</div>
|
||||
<br/>
|
||||
<div>Action after hanging for at least 15 seconds:</div>
|
||||
<br/>
|
||||
<div><input type="radio" name="command" id="default" value="default" onclick="sendCommand('setdefault')"/>
|
||||
<label for="default">Default behavior (Alloy runtime: Wait; Chrome runtime: show "Page unresponsive" dialog [1])</label></div>
|
||||
<div><input type="radio" name="command" id="wait" value="wait" onclick="sendCommand('setwait')"/>
|
||||
<label for="wait">Wait</label></div>
|
||||
<div><input type="radio" name="command" id="terminate" value="terminate" onclick="sendCommand('setterminate')"/>
|
||||
<label for="terminate">Terminate the render process [2]</label></div>
|
||||
<br/>
|
||||
<div>[1] The "Page unresponsive" dialog will be auto-dismissed when the hang ends.</div>
|
||||
<div>[2] After termination the browser navigates to the startup URL or shows an error page.</div>
|
||||
<br/>
|
||||
<div><input type="button" value="Trigger Hang" onclick="triggerHang()"/></div>
|
||||
</form>
|
||||
Observe page responsiveness:
|
||||
<br/><br/>
|
||||
<table><tr>
|
||||
<td valign="top">
|
||||
CSS:<br/><div id="loading"></div>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td valign="top">
|
||||
JavaScript:<br/><div id="time"></div>
|
||||
</td>
|
||||
</tr></table>
|
||||
(JavaScript will stop updating during the hang)
|
||||
</body>
|
||||
</html>
|
|
@ -41,6 +41,7 @@
|
|||
<li><a href="xmlhttprequest">XMLHttpRequest</a></li>
|
||||
<li><a href="javascript:window.print();">Print this page with "javascript:window.print();"</a></li>
|
||||
<li><a href="https://patrickhlauke.github.io/touch">Touch Feature Tests</a> - requires "touch-events=enabled" flag (and CAPS LOCK on Mac for Trackpad simulation)</li>
|
||||
<li><a href="hang">Render process hang test</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -33,6 +33,7 @@ IDS_BINARY_TRANSFER_HTML BINARY "..\\binary_transfer.html"
|
|||
IDS_BINDING_HTML BINARY "..\\binding.html"
|
||||
IDS_DIALOGS_HTML BINARY "..\\dialogs.html"
|
||||
IDS_DRAGGABLE_HTML BINARY "..\\draggable.html"
|
||||
IDS_HANG_HTML BINARY "..\\hang.html"
|
||||
IDS_IPC_PERFORMANCE_HTML BINARY "..\\ipc_performance.html"
|
||||
IDS_LOCALSTORAGE_HTML BINARY "..\\localstorage.html"
|
||||
IDS_LOGO_PNG BINARY "..\\logo.png"
|
||||
|
|
|
@ -82,7 +82,7 @@ int main(int argc, char* argv[]) {
|
|||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!CefInitialize(main_args, settings, app.get(), nullptr)) {
|
||||
return 1;
|
||||
return CefGetExitCode();
|
||||
}
|
||||
|
||||
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
|
||||
|
|
|
@ -174,7 +174,7 @@ int main(int argc, char* argv[]) {
|
|||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!CefInitialize(main_args, settings, app.get(), nullptr)) {
|
||||
return 1;
|
||||
return CefGetExitCode();
|
||||
}
|
||||
|
||||
// Create the application delegate.
|
||||
|
|
|
@ -95,7 +95,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
|||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!CefInitialize(main_args, settings, app.get(), sandbox_info)) {
|
||||
return 1;
|
||||
return CefGetExitCode();
|
||||
}
|
||||
|
||||
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
|
||||
|
|
|
@ -184,7 +184,9 @@ void MRTestHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|||
}
|
||||
|
||||
void MRTestHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) {
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {
|
||||
message_router_->OnRenderProcessTerminated(browser);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,9 @@ class MRTestHandler : public TestHandler {
|
|||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) override;
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override;
|
||||
|
||||
// Only call this method if the navigation isn't canceled.
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
|
|
|
@ -259,13 +259,16 @@ class NetNotifyTestHandler : public TestHandler {
|
|||
}
|
||||
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) override {
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override {
|
||||
got_process_terminated_ct_++;
|
||||
|
||||
// Termination is expected for cross-origin requests initiated from the
|
||||
// renderer process.
|
||||
if (!(test_type_ == NNTT_DELAYED_RENDERER && !same_origin_)) {
|
||||
TestHandler::OnRenderProcessTerminated(browser, status);
|
||||
TestHandler::OnRenderProcessTerminated(browser, status, error_code,
|
||||
error_string);
|
||||
}
|
||||
|
||||
FinishTest();
|
||||
|
|
|
@ -78,7 +78,9 @@ void RoutingTestHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|||
|
||||
void RoutingTestHandler::OnRenderProcessTerminated(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) {
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {
|
||||
message_router_->OnRenderProcessTerminated(browser);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@ class RoutingTestHandler : public TestHandler,
|
|||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) override;
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override;
|
||||
|
||||
// Only call this method if the navigation isn't canceled.
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
|
|
|
@ -437,8 +437,11 @@ CefRefPtr<CefResourceHandler> TestHandler::GetResourceHandler(
|
|||
}
|
||||
|
||||
void TestHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) {
|
||||
LOG(WARNING) << "OnRenderProcessTerminated: status = " << status << ".";
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) {
|
||||
LOG(WARNING) << "OnRenderProcessTerminated: status = " << status
|
||||
<< ", error = " << error_string.ToString() << ".";
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> TestHandler::GetBrowser() const {
|
||||
|
|
|
@ -180,7 +180,9 @@ class TestHandler : public CefClient,
|
|||
CefRefPtr<CefRequest> request) override;
|
||||
|
||||
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||
TerminationStatus status) override;
|
||||
TerminationStatus status,
|
||||
int error_code,
|
||||
const CefString& error_string) override;
|
||||
|
||||
// These methods should only be used if at most one non-popup browser exists.
|
||||
CefRefPtr<CefBrowser> GetBrowser() const;
|
||||
|
|
Loading…
Reference in New Issue